Slide 1

Slide 1 text

Rails: Still the Best Framework for Bootstrapping Anthony Eden Founder of DNSimple Sunday, October 6, 13

Slide 2

Slide 2 text

2001 http://www.flickr.com/photos/84518681@N00/22752982 Sunday, October 6, 13 Built a framework. Quite extensible And it grew to be over-architected

Slide 3

Slide 3 text

2005 Sunday, October 6, 13 Java frameworks became unwieldy Came full circle with Servlets and JSP Simplify

Slide 4

Slide 4 text

2006 http://www.flickr.com/photos/30784280@N05/4338666833 Sunday, October 6, 13 First RailsConf Feels all brand new Rails development cuts time to market significantly Testing is baked in This framework is opinionated Antidote to the complexity of Java

Slide 5

Slide 5 text

2013 http://www.flickr.com/photos/9491236@N03/2844346957 Sunday, October 6, 13 Time to market is even better thanks to gems and established techniques This framework is still opinionated Antidote to the problem of too many choices and over engineering

Slide 6

Slide 6 text

Why Isn’t It Stale? http://www.flickr.com/photos/26406919@N00/4511498998 Sunday, October 6, 13

Slide 7

Slide 7 text

Libraries http://www.flickr.com/photos/37921614@N00/510243975 Sunday, October 6, 13

Slide 8

Slide 8 text

Documentation http://www.flickr.com/photos/7424779@N05/2964294812 Sunday, October 6, 13

Slide 9

Slide 9 text

Community http://www.flickr.com/photos/48973657@N00/2149309015 Sunday, October 6, 13

Slide 10

Slide 10 text

It’s still MVC http://www.flickr.com/photos/57884042@N00/4563162714 Sunday, October 6, 13

Slide 11

Slide 11 text

Model your problem http://www.flickr.com/photos/36317426@N00/3580987940 Sunday, October 6, 13

Slide 12

Slide 12 text

Control the flow http://www.flickr.com/photos/36317426@N00/3580145091 Sunday, October 6, 13

Slide 13

Slide 13 text

View the outcome http://www.flickr.com/photos/36317426@N00/3580207475 Sunday, October 6, 13

Slide 14

Slide 14 text

Keys to Success http://www.flickr.com/photos/48888605@N03/6141822934 Sunday, October 6, 13 How do you bootstrap successfully with Rails

Slide 15

Slide 15 text

Have Problem. Solve Problem. http://www.flickr.com/photos/57503924@N07/5368461966 Sunday, October 6, 13

Slide 16

Slide 16 text

Cut the cruft http://www.flickr.com/photos/14316700@N08/3210447964 Sunday, October 6, 13

Slide 17

Slide 17 text

Don’t cut the tests http://www.flickr.com/photos/24029425@N06/8139290608 Sunday, October 6, 13

Slide 18

Slide 18 text

Feature flags http://www.flickr.com/photos/68977046@N00/2221278307 Sunday, October 6, 13

Slide 19

Slide 19 text

Launch http://www.flickr.com/photos/24662369@N07/8464918661 Sunday, October 6, 13

Slide 20

Slide 20 text

SaaS = speed to launch http://www.flickr.com/photos/9549598@N02/768973472 Sunday, October 6, 13

Slide 21

Slide 21 text

Billing http://www.flickr.com/photos/29468339@N02/4634443529 Sunday, October 6, 13 Stripe or Chargify

Slide 22

Slide 22 text

Error Notification http://www.flickr.com/photos/16013376@N00/3053460290 Sunday, October 6, 13 BugSnag HoneyBadger

Slide 23

Slide 23 text

Logging http://www.flickr.com/photos/41964203@N00/301191575 Sunday, October 6, 13 Papertrail

Slide 24

Slide 24 text

Customer Support http://www.flickr.com/photos/73932893@N00/5774597743 Sunday, October 6, 13 Intercom.io

Slide 25

Slide 25 text

So you’re sold... http://www.flickr.com/photos/68751915@N05/6757871357 Sunday, October 6, 13

Slide 26

Slide 26 text

...but http://www.flickr.com/photos/47854931@N00/3205277810 Sunday, October 6, 13

Slide 27

Slide 27 text

When should you not use Rails? http://www.flickr.com/photos/12348847@N00/2536358399 Sunday, October 6, 13 And why

Slide 28

Slide 28 text

When resource usage matters http://www.flickr.com/photos/22470474@N03/2954044975 Sunday, October 6, 13 Golang

Slide 29

Slide 29 text

When you want low- latency soft-realtime systems http://www.flickr.com/photos/57578461@N00/4733385644 Sunday, October 6, 13 Erlang

Slide 30

Slide 30 text

Go Sunday, October 6, 13

Slide 31

Slide 31 text

API-first Web Service Sunday, October 6, 13 Sinatra or Rack Golang

Slide 32

Slide 32 text

package main import ( "net/http" "code.google.com/p/go.net/websocket" ) Sunday, October 6, 13

Slide 33

Slide 33 text

/* Zone and record representations */ type ZoneNotification struct { Name string `json:"name"` " Sha string `json:"sha"` " Url string `json:"url"` " Action string `json:"action"` } Sunday, October 6, 13

Slide 34

Slide 34 text

type hub struct { broadcast chan string " connections map[*connection]bool " register chan *connection " unregister chan *connection } Sunday, October 6, 13

Slide 35

Slide 35 text

var h = hub{ " broadcast: make(chan string), " connections: make(map[*connection]bool), " register: make(chan *connection), " unregister: make(chan *connection), } Sunday, October 6, 13

Slide 36

Slide 36 text

func (h *hub) run() { for { select { case c := <-h.register: h.connections[c] = true case c := <-h.unregister: delete(h.connections, c) close(c.send) case m := <-h.broadcast: for c := range h.connections { select { case c.send <- m: default: delete(h.connections, c) close(c.send) go c.ws.Close() } } } } } Sunday, October 6, 13

Slide 37

Slide 37 text

Erlang Sunday, October 6, 13

Slide 38

Slide 38 text

Authoritative DNS Sunday, October 6, 13

Slide 39

Slide 39 text

-module(erldns_packet_cache). -behavior(gen_server). % API -export([start_link/0, get/1, put/2, sweep/0, clear/0]). % Gen server hooks -export([init/1, handle_call/3, " handle_cast/2, " handle_info/2, " terminate/2, " code_change/3 ]). -define(SERVER, ?MODULE). -define(SWEEP_INTERVAL, 1000 * 60 * 10). % Every 10 minutes -record(state, {ttl, tref}). Sunday, October 6, 13

Slide 40

Slide 40 text

%% Public API start_link() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). get(Question) -> gen_server:call(?SERVER, {get_packet, Question}). put(Question, Response) -> gen_server:call(?SERVER, {set_packet, [Question, Response]}). sweep() -> gen_server:cast(?SERVER, {sweep, []}). clear() -> gen_server:cast(?SERVER, {clear}). Sunday, October 6, 13

Slide 41

Slide 41 text

init([]) -> init([20]); init([TTL]) -> ets:new(packet_cache, [set, named_table]), {ok, Tref} = timer:apply_interval(?SWEEP_INTERVAL, ?MODULE, sweep, []), {ok, #state{ttl = TTL, tref = Tref}}. Sunday, October 6, 13

Slide 42

Slide 42 text

handle_call({get_packet, Question}, _From, State) -> case ets:lookup(packet_cache, Question) of [{Question, {Response, ExpiresAt}}] -> {_,T,_} = erlang:now(), case T > ExpiresAt of true -> lager:debug("Cache hit but expired"), {reply, {error, cache_expired}, State}; false -> lager:debug("Time is ~p. Packet hit expires at ~p.", [T, ExpiresAt]), {reply, {ok, Response}, State} end; _ -> {reply, {error, cache_miss}, State} end; Sunday, October 6, 13

Slide 43

Slide 43 text

handle_call({set_packet, [Question, Response]}, _From, State) -> {_,T,_} = erlang:now(), ets:insert(packet_cache, {Question, {Response, T + State#state.ttl}}), {reply, ok, State}. Sunday, October 6, 13

Slide 44

Slide 44 text

handle_cast({sweep, []}, State) -> lager:debug("Sweeping packet cache"), {_, T, _} = erlang:now(), Keys = ets:select(packet_cache, [ {{'$1', {'_', '$2'}}, [{'<', '$2', T - 10}], ['$1']} ]), lager:debug("Found keys: ~p", [Keys]), lists:foreach(fun(K) -> ets:delete(packet_cache, K) end, Keys), {noreply, State}; handle_cast({clear}, State) -> ets:delete_all_objects(packet_cache), {noreply, State}. Sunday, October 6, 13

Slide 45

Slide 45 text

Clojure Sunday, October 6, 13

Slide 46

Slide 46 text

(ns cbe.functions (:use [clojure.test])) ;Anonymous function (let [f (fn [x] (+ x 1))] (is (= 3 (f 2)))) ;Define a function (def add-fn (fn [a b] (+ a b))) (is (= 3 (add-fn 1 2))) ;Define a function with defn macro (defn add-defn [a b] (+ a b)) (is (= 3 (add-defn 1 2))) Sunday, October 6, 13

Slide 47

Slide 47 text

(ns cbe.functions (:use [clojure.test])) ;Anonymous function (let [f (fn [x] (+ x 1))] (is (= 3 (f 2)))) ;Define a function (def add-fn (fn [a b] (+ a b))) (is (= 3 (add-fn 1 2))) ;Define a function with defn macro (defn add-defn [a b] (+ a b)) (is (= 3 (add-defn 1 2))) JUST KIDDING! Sunday, October 6, 13

Slide 48

Slide 48 text

http://learnyousomeerlang.com http://tour.golang.org/ Sunday, October 6, 13

Slide 49

Slide 49 text

Conclusion http://www.flickr.com/photos/59707463@N00/1312379342 Sunday, October 6, 13

Slide 50

Slide 50 text

Rails is good http://www.flickr.com/photos/95394384@N00/2616644625 Sunday, October 6, 13

Slide 51

Slide 51 text

Go and Erlang are good Sunday, October 6, 13

Slide 52

Slide 52 text

Even Clojure is good Sunday, October 6, 13

Slide 53

Slide 53 text

Go forth and learn http://www.flickr.com/photos/27482959@N08/3154841718 Sunday, October 6, 13

Slide 54

Slide 54 text

Go forth and build http://www.flickr.com/photos/33049952@N08/9902960523 Sunday, October 6, 13

Slide 55

Slide 55 text

Launch! http://www.flickr.com/photos/38021965@N00/14473233 Sunday, October 6, 13

Slide 56

Slide 56 text

And above all... Sunday, October 6, 13

Slide 57

Slide 57 text

Have fun! http://www.flickr.com/photos/46084814@N04/5678412190 Sunday, October 6, 13

Slide 58

Slide 58 text

Rails: Still the Best Framework for Bootstrapping Anthony Eden Founder of DNSimple Sunday, October 6, 13