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