My first 

Erlang App


Alan Gardner


Big Data Engineer at Pythian

Normally program in Java and Python

FP Novice


The Problem

Route users between points on a map

Map is in JSON, expose an HTTP interface

Deploy on Heroku


Mochiweb

Erlang library for handling HTTP requests

Not a framework like Rails, Django or Express

Accepts a loop function which is called on request
start(Options) ->    Loop = fun (Req) ->
                   ?MODULE:loop(Req)
           end,
    mochiweb_http:start([{name, ?MODULE}, {loop, Loop} | Options]).

stop() ->
    mochiweb_http:stop(?MODULE).

loop(Req)->
    "/" ++ Path = Req:get(path),
    Method = Req:get(method),
    case Method of
        'POST' ->
            case Path of 
                "navigate" ->
                    Req:respond({200, [{"Content-Type", "application/json"}, {"Access-Control-Allow-Origin", "*"}], mochijson2:encode(NavRoute)});
                _ ->
                    erlang:display("invalid path"),
                    Req:not_found()
            end;
        'GET' ->
            Req:not_found()
    end.


MOchijson

{ "key1" : "value1", "key2" : "value2"}


serializes to


{ struct, [ { <<"key1">>, <<"value1">> }, { <<"key2">>, <<"value2">> ] }


djikstra's Algorithm

Maintain a list of prospective routes, sorted by length

Take the shortest route and add a step

Not very efficient, but it's good enough for our small graphs

http://en.wikipedia.org/wiki/Dijkstra's_algorithm
get_lowest_unused(ShortRoute, Node, RouteList)->
    case route_intermediate_contains(Node#route.finish, ShortRoute) of
    	true -> RouteList;
    	false -> insert_sorted(route_append(ShortRoute, Node), RouteList)
    end.

add_to_route(ShortRoute, RouteDict, RouteList)->
    NextNodes=dict:fetch(ShortRoute#route.finish, RouteDict),
    lists:foldl(fun(X,Acc) -> get_lowest_unused(ShortRoute, X, Acc) end, RouteList, NextNodes).

djikstra_iter(StartID, EndID, [ShortRoute | PriorityRoutes], RouteDict) -> 
    case ShortRoute#route.finish == EndID of
    	true -> ShortRoute;
    	false -> djikstra_iter(StartID, EndID, add_to_route(ShortRoute, RouteDict, PriorityRoutes), RouteDict)
    end.

djikstra(StartID, EndID, RouteDict)->
    {route, Start, End, Nodes, Distance}=djikstra_iter(StartID, EndID, dict:fetch(StartID, RouteDict), RouteDict),
    {struct, [{start, Start}, {finish, End}, {path, Nodes}, {distance, Distance}]}.


Packaging

Boilerplate code for the supervisor and worker

Rebar configuration for dependencies

Procfile and Buildpack for Heroku



 %% -*- erlang -*-
{erl_opts, [debug_info]}.
{deps, [
   {mochiweb, ".*",
       {git, "https://github.com/mochi/mochiweb.git", "master"}}]}.
{cover_enabled, true}.
 web: erl -pa ebin deps/mochiweb/ebin -noshell -noinput -s capstoneroute
 {application, capstoneroute,
 [
  {description, ""},
  {vsn, "1"},
  {modules,[capstoneroute, route]},
  {registered, []},
  {applications, [kernel,stdlib]},
  {mod, { capstoneroute_app, []}},
  {env, []}
 ]}.





Thank You

My first Erlang App

By Alan Gardner

My first Erlang App

  • 935