http://www.apache.org/licenses/LICENSE-2.0
Allows public/private derivations.
- TODO: discuss each of the cool libraries that are brought in.
- TODO: discuss why the various (older) revisions are being used
Question: why is webmachine both started as a dependency and started as a worker under api_sup.erl?
Question: [33] Ip = case os:getenv("WEBMACHINE_IP") of false -> "0.0.0.0"; Any -> Any end,
api.app.src
* project configuration
->
api.erl
* start dependencies
inets
crypto
bcrypt
lager
mochiweb
folsom
webmachine
worker_master
* starts app
->
api_app.erl
* starts a supervisor
->
api_sup.erl
* loads config for webmachine
* specifies a supervision strategy for webmachine
* launches webmachine as a worker
Question: why is webmachine both started as a dependency and started as a worker under api_sup.erl?
- api.erl
- uses private method ensure_started/1 to start dependencies
- uses application:set_env/3 to set the webmachine logger
- See: http://erldocs.com/R15B/kernel/application.html?i=0&search=application:set#set_env/3
- application:start(api), which api.app.src says is 'api_app'
- api_app.erl
- starts api_sup.erl
- api_sup.erl
Question: [33] Ip = case os:getenv("WEBMACHINE_IP") of false -> "0.0.0.0"; Any -> Any end,
Why grab the ip address from an env var? isn't there a cleaner way to do this? could you simply query webmachine and ask it it's ip address? or if you have to store it, store it in an ets/dets/mnesia/riak?
Read erlang terms sep by '.' from a file
f.txt: {person, "kalle", 25}.
{person, "pelle", 30}.
1> file:consult("f.txt").
{ok,[{person,"kalle",25},{person,"pelle",30}]}
-
filename:join(http://erldocs.com/R15B/stdlib/filename.html?i=0&search=filename:join#join/1)
Joins a list of file name Components with directory separators. If one of the elements of Components includes an absolute path, for example "/xxx", the preceding elements, if any, are removed from the result.
The result is "normalized": Redundant directory separators are removed. In Windows, all directory separators are forward slashes and the drive letter is in lower case.
17> filename:join(["/usr", "local", "bin"]).
"/usr/local/bin"
18> filename:join(["a/b///c/"]).
"a/b/c"
6> filename:join(["B:a\\b///c/"]). % Windows
"b:a/b/c"
- filename:dirname/1(http://erldocs.com/R15B/stdlib/filename.html?i=0&search=filename:dir#dirname/1)
Returns the directory part of Filename
13> filename:dirname("/usr/src/kalle.erl").
"/usr/src"
14> filename:dirname("kalle.erl").
"."
If the module is not loaded, this function searches the code path for the first file which contains object code for Module and returns the absolute file name
- [34] loads an erlang 'properties' file from nodes/apps/api/priv/dispatch.conf
{[], api_home_redirect_resource, []}.
{["static", '*'], api_fs_resource, [{root, "../"}]}.
{["signup"], api_signup_resource, []}.
{["signin"], api_signin_resource, []}.
{["signout"], api_signout_resource, []}.
<snip>
-
application:get_env(http://www.erlang.org/doc/apps/kernel/application.html#get_env-1)
Returns the value of the configuration parameter Par for Application. If the application argument is omitted, it defaults to the application of the calling process.
If the specified application is not loaded, or the configuration parameter does not exist, or if the process executing the call does not belong to any application, the function returns undefined.
-
Q: [37] get the api/port value... where was this set? A: in the api.app.src::env stanza.
Extra stuff elided for clarity...
{application, api, [{env, [ {port, 8000}]} ]}.
- [38] create a configuration object
- [44] Q: really not sure what's going on here,
supervisor definition
http://www.erlang.org/doc/man/supervisor.html
supervisor:init
Module:init(Args) -> Result
Types:
Args = term()
Result = {ok,{{RestartStrategy,MaxR,MaxT},[ChildSpec]}} | ignore
RestartStrategy = strategy()
MaxR = integer()>=0
MaxT = integer()>0
ChildSpec = child_spec()
supervisor child_spec
This is the type definition of a child specification:
child_spec() = {Id,StartFunc,Restart,Shutdown,Type,Modules}
Id = term()
StartFunc = {M,F,A}
M = F = atom()
A = [term()]
Restart = permanent | transient | temporary
Shutdown = brutal_kill | int()>0 | infinity
Type = worker | supervisor
Modules = [Module] | dynamic
Module = atom()
So, we should see this returned:
{ok,{{RestartStrategy,MaxR,MaxT},[{Id,StartFunc,Restart,Shutdown,Type,Modules}]}}
So let's break this down:
{ok, { {one_for_one, 10, 10}, [Web]} }.
which is
{ok, { {one_for_one, 10, 10}, [{webmachine_mochiweb,
{webmachine_mochiweb, start, [WebConfig]},
permanent, 5000, worker, [webmachine_mochiweb]}]} }.
which translates to
{ok, // atom
{
{
one_for_one, // restart strategy
10, // MaxR
10 // MaxT
// To prevent a supervisor from getting into an infinite loop of child process terminations and restarts, a maximum restart frequency is defined using two integer values MaxR and MaxT. If more than MaxR restarts occur within MaxT seconds, the supervisor terminates all child processes and then itself.
},
[
{webmachine_mochiweb, // id is a name that is used to identify the child by the supervisor
{webmachine_mochiweb, start, [WebConfig]}, // start function as MFA
permanent, // defines restart strategy
5000, // An integer timeout value means that the supervisor will tell the child process to terminate by calling exit(Child,shutdown) and then wait for an exit signal with reason shutdown back from the child process. If no exit signal is received within the specified number of milliseconds, the child process is unconditionally terminated using exit(Child,kill).
worker, // Type specifies if the child process is a supervisor or a worker.
[webmachine_mochiweb] // Modules is used by the release handler during code replacement to determine which processes are using a certain module. As a rule of thumb Modules should be a list with one element [Module], where Module is the callback module, if the child process is a supervisor, gen_server or gen_fsm. If the child process is an event manager (gen_event) with a dynamic set of callback modules, Modules should be dynamic. See OTP Design Principles for more information about release handling.
}]} }.
TODO