", "
{% endverbatim %}", [global]).
103 |
--------------------------------------------------------------------------------
/notes-20151112-chicago-erlang/README.md:
--------------------------------------------------------------------------------
1 | # Mailboxes - Messaging
2 |
3 | Ideas of message buses. Simple constructs related to messaging,
4 | mailboxes. Ability to signal.
5 |
6 | Familiarity of the constructs from experience with OS constructs.
7 |
8 | # Congruence with System Coordination
9 |
10 | Semantics didn't work against instinct of messaging / signal bases systems.
11 |
12 | # Fault Tolerance via Fault -> Death -> Restart
13 |
14 | The central premise of Erlang's fault tolerance.
15 |
16 | # Discoverability of root causes
17 |
18 | Uncertainty of "let it crash" and "restart" as a correct solution for
19 | all cases demands a facility to discover root causes in support of
20 | "correct software".
21 |
22 | # Ability to ignore errors freeing
23 |
24 | Like not having to spend days on tracking down a bug that may never
25 | occur again, or is hard to reproduce.
26 |
27 | # Learning from Experience
28 |
29 | How to put code into production that isn't "done" or 100% tested,
30 | correct, etc. and learn from real world experience without killing
31 | your app.
32 |
33 | "The perfect being the enemy of the good."
34 |
35 | # Syntax Different
36 |
37 | Different from more familiar languages.
38 |
39 | # Spatial Relationships in Erlang
40 |
41 | Who's calling what and where? What's going on?
42 |
43 | # Incongruence between code structure and runtime behavior
44 |
45 | Looking for some cues in the code - the modules, files, functions,
46 | etc. to understand what happens at runtime. Consider classes, which
47 | isolate state and functions, which corresponds to the runtime
48 | behavior.
49 |
50 | # Records are too thin as an abstraction
51 |
52 | "The compiler should be helping me more."
53 |
54 | # What is the standard way of doing this?
55 |
56 | Uncertainty and nervousness about an approach that works but may not
57 | be "the right way" in Erlang.
58 |
59 | # Process abstraction as finite state machine
60 |
61 | Use case is a "debouncer". A process allows a focus on input and
62 | output with isolated logic for maintaining associated state.
63 |
64 | Simplifies signal processing.
65 |
66 | # Natural application of processes to experience
67 |
68 | Comparable to "classes" and objects.
69 |
70 | # Strict vs Flexible
71 |
72 | This is related to message passing and handling. The decoupling of
73 | "calls" by way of messages passed via queues, allows for a more
74 | flexible communication scheme.
75 |
76 | Being flexible in how you handle messages allows for lose coupling
77 | and, possibly, more resilient behavior.
78 |
--------------------------------------------------------------------------------
/patterns/Makefile:
--------------------------------------------------------------------------------
1 | gen:
2 | cd ..; make gen
3 |
--------------------------------------------------------------------------------
/patterns/abstract-execution.md:
--------------------------------------------------------------------------------
1 | Name: Abstract Execution Scope: Principle Summary: Describe impure logic as abstract data representing that logic, to be executed separately.
2 |
3 | Sometimes a function needs to perform side-effectful or otherwise complicated logic (making network requests, reading / writing to a database, manipulating the filesystem, caching, batching, etc). This can make the function difficult to reason about by conflating its purpose with its implementation. For example, while caching and batching may make a function more efficient, they may not be required in order for the function to be correct.
4 |
5 | Instead, write the function as two separate functions:
6 | 1) A function that returns a high-level, declarative description of the desired logic
7 | 2) A function that interprets that description and executes it
8 |
9 | It then becomes possible to separately reason about the high-level goals of a program and the mechanism by which those goals are achieved. Moreover, it becomes possible to test both concerns in isolation, and to increase the complexity of the interpreter without increasing the complexity of the functions which make use of it.
10 |
11 | Examples:
12 | - `Ecto.Multi` - https://hexdocs.pm/ecto/Ecto.Multi.html
13 | - `Haxl` - https://github.com/facebook/Haxl
14 |
--------------------------------------------------------------------------------
/patterns/acceptor-pool.md:
--------------------------------------------------------------------------------
1 | Name: Acceptor Pool
2 | Scope: Application Level Facility
3 | Summary: A pool of acceptors can be used to reduce the latency of
4 | inbound connections.
5 |
6 | Given a collection of workers, usually started as part of the socket listening module:
7 |
8 | ```erlang
9 | -record(state, {workers}).
10 |
11 | init([NumWorkers]) ->
12 | {ok, #state{workers = make_workers(queue:new(), NumWorkers)}}.
13 |
14 | make_workers(Queue, NumWorkers) ->
15 | make_workers(Queue, NumWorkers, 1).
16 | make_workers(Queue, NumWorkers, N) ->
17 | case N < NumWorkers of
18 | true ->
19 | {ok, WorkerPid} = ?WORKER:start_link([]),
20 | make_workers(queue:in(WorkerPid, Queue), NumWorkers, N + 1);
21 | false ->
22 | Queue
23 | end.
24 | ```
25 |
26 | The function that handles inbound packets may delegate to a worker:
27 |
28 | ```erlang
29 | handle_request(Socket, Host, Port, Bin, State) ->
30 | case queue:out(State#state.workers) of
31 | {{value, Worker}, Queue} ->
32 | gen_server:cast(Worker, {udp_query, Socket, Host, Port, Bin}),
33 | {noreply, State#state{workers = queue:in(Worker, Queue)}};
34 | {empty, _Queue} ->
35 | % Drop the packet
36 | {noreply, State}
37 | end.
38 | ```
39 |
--------------------------------------------------------------------------------
/patterns/accumulator.md:
--------------------------------------------------------------------------------
1 | Name: Accumulator
2 | Scope: Function Type
3 | Summary: A recursive function can be used to build a list.
4 |
5 | Creating a list is one of the more common functions in a program. The
6 | _accumulator_ pattern uses a recursive function to build a list by
7 | adding items to the head of a list. It's common to reverse the list as
8 | a final step in the process.
9 |
10 | Here's an example that creates a sequential list of integers.
11 |
12 | ```erlang
13 | {% example file="accumulator.erl" lines="5-10" %}
14 | ```
15 |
16 | The _accumulator_ has an exit condition that indicates when the
17 | accumulation is finished. In this case, the list is finished when
18 | `Start` is greater than or equal to `Finish`.
19 |
--------------------------------------------------------------------------------
/patterns/behavior.md:
--------------------------------------------------------------------------------
1 | Name: Behavior
2 | Scope: Erlang/OTP Construct
3 | Summary: Generic process behavior can be customized with callback functions.
4 |
--------------------------------------------------------------------------------
/patterns/broker.md:
--------------------------------------------------------------------------------
1 | Name: Broker
2 | Scope: Application Level Facility
3 | Summary: A process can broker the sending of messages from publishers
4 | to subscribers.
5 |
--------------------------------------------------------------------------------
/patterns/case-expression.md:
--------------------------------------------------------------------------------
1 | Name: Case Expression
2 | Scope: Erlang/OTP Construct
3 | Summary: Use a case expression to define a conditional value based on
4 | a term.
5 |
6 | A case expression evaluates an expression against a series of patterns and optional guard sequences. The body of the first pattern/guard sequence that matches is evaluated and is the result of the case expression.
7 |
8 | In the following example, if Dir is a directory, the return from the function will be the count of its files. Otherwise, the return will be 0.
9 |
10 | ```
11 | count_files(Dir) ->
12 | case filelib:is_dir(Dir) of
13 | true ->
14 | {ok, Files} = file:list_dir(Dir),
15 | length(Files);
16 | false ->
17 | 0
18 | end.
19 | ```
20 |
--------------------------------------------------------------------------------
/patterns/chain.md:
--------------------------------------------------------------------------------
1 | Name: Chain
2 | Scope: Function/Wrapper
3 | Summary: Connect a bunch of functions passing the returned value of each
4 | function to the next one. The last function's return value is
5 | the chain's return value.
6 |
7 | There are different possible ways of breaking from the chain:
8 |
9 | * Throw an exception.
10 |
11 | * Shortcut by returning some special value. For example, return
12 | ```{ok, Value}``` or ```{error, Error}``` in each function inside
13 | the chain.
14 |
15 | * Just let any values pass through and let the code crash if some
16 | garbage gets into a function.
17 |
18 | Examples:
19 |
20 | ```
21 | -module(chain).
22 |
23 | -export([naive/2, error_monad/2]).
24 |
25 | naive([], Arg) ->
26 | Arg;
27 | naive([Fun | Funs], Arg) ->
28 | naive(Funs, Fun(Arg)).
29 |
30 | error_monad([], Arg) ->
31 | Arg;
32 | error_monad([Fun | Funs], Arg) ->
33 | case Fun(Arg) of
34 | {ok, V} ->
35 | error_monad(Funs, V);
36 | {error, E} ->
37 | {error, E}
38 | end.
39 | ```
40 |
--------------------------------------------------------------------------------
/patterns/circuit_breaker.md:
--------------------------------------------------------------------------------
1 | Name: Circuit Breaker
2 | Scope: Application Level Facility
3 | Summary: A mechanism to prevent queue overflow and allow the system to fail fast. Circuit breaker is used to detect failures and encapsulates logic of preventing a failure to reoccur constantly (during maintenance, temporary external system failure or unexpected system difficulties). This pattern can be useful for graceful degradation of a service.
4 |
5 | A circuit breaker usually has a 3 values (but could be more advanced).
6 | A number of retries before melting the fuse. A time period to reset
7 | the number of retries and a cooldown period to reset the fuse.
8 |
9 | For examples see the https://github.com/jlouis/fuse library.
10 |
11 |
--------------------------------------------------------------------------------
/patterns/clarifying-variable.md:
--------------------------------------------------------------------------------
1 | Name: Clarifying Variable
2 | Scope: Not Sure
3 | Summary: Use a variable to order sequential code from top-to-bottom
4 | and name the result of an operation.
5 |
--------------------------------------------------------------------------------
/patterns/cleanup-crew.md:
--------------------------------------------------------------------------------
1 | Name: Cleanup Crew
2 | Scope: Application Level Facility
3 | Summary: Use a separate process to cleanup up after other processes,
4 | freeing those processes from those additional duties.
5 |
--------------------------------------------------------------------------------
/patterns/connection-pool.md:
--------------------------------------------------------------------------------
1 | Name: Connection Pool
2 | Scope: Application Level Facility
3 | Summary: Manage access to a network resource using a controlled pool of
4 | connection.
5 |
--------------------------------------------------------------------------------
/patterns/crash-by-default.md:
--------------------------------------------------------------------------------
1 | Name: Crash by Default
2 | Scope: Principle
3 | Summary: Avoid complicating error handling logic by default and allow
4 | a process to crash, relying on Erlang's process isolation to
5 | protect the integrity of the system as a whole.
6 |
--------------------------------------------------------------------------------
/patterns/data-service.md:
--------------------------------------------------------------------------------
1 | Name: Data Service
2 | Scope: Application Level Facility
3 | Summary: Provide access to a data using service.
4 |
--------------------------------------------------------------------------------
/patterns/department.md:
--------------------------------------------------------------------------------
1 | Name: Department
2 | Scope: Application Level Facility
3 | Summary: A common setup for supervisor, worker that allows proper escalation of failures.
4 |
5 | The department pattern consists of a supervisor for the department (subsystem) with a one for all strategy (AND tree). Under this department supervisor are two children a manager process responsible for orchestrating what happens in the department and a worker supervisor which can have either a one for one (OR tree) or a one for all (AND tree) strategy. The manager asks its sibling process (the worker supervisor) to spawn new workers as needed and potentially to restart them automatically should something fail.
6 |
7 | This pattern supports Agile software development because it defers implementation of monitoring in the manager process. It also ensures the failures are properly escalated.
8 |
9 | In order to select the initial intensity (MaxR) and period (MaxT) values for the supervisors. It is a good idea to manually crash the processes and observe the behavior and to tweak the values accordingly.
10 |
11 |
--------------------------------------------------------------------------------
/patterns/dispatch.md:
--------------------------------------------------------------------------------
1 | Name: Dispatch
2 | Scope: Function Type
3 | Summary: Use a function to dispatch a to other functions according
4 | to its arguments.
5 |
--------------------------------------------------------------------------------
/patterns/explicit-text-encoding.md:
--------------------------------------------------------------------------------
1 | Name: Explicit Text Encoding
2 | Scope: Not Sure
3 | Summary: TODO - From Fred's observation about dealing with text during
4 | Mostly Erlang podcast.
5 |
--------------------------------------------------------------------------------
/patterns/finite-state-machine.md:
--------------------------------------------------------------------------------
1 | Name: Finite State Machine
2 | Scope: Process/Behavior Type
3 | Summary: Use a process to implement a finite state machine, where process
4 | state is modified in response to events.
5 |
--------------------------------------------------------------------------------
/patterns/function.md:
--------------------------------------------------------------------------------
1 | Name: Function
2 | Scope: Erlang/OTP Construct
3 | Summary: A function does the work in Erlang. It can be used to implement
4 | behavior and things.
5 |
--------------------------------------------------------------------------------
/patterns/getopt-arguments.md:
--------------------------------------------------------------------------------
1 | Name: Getopt Arguments
2 | Scope: Not Sure
3 | Summary: Simplify function arguments using the getopt pattern of separating
4 | arguments into a minimal set of required arguments and a set of
5 | optional arguments, representing the optional arguments with an
6 | Erlang property list.
7 |
--------------------------------------------------------------------------------
/patterns/group-leader.md:
--------------------------------------------------------------------------------
1 | Name: Group Leader
2 | Scope: ????
3 | Summary: Represent IO generically and let the facility deal with distribution of it across nodes/processes
4 |
--------------------------------------------------------------------------------
/patterns/higher-order-function.md:
--------------------------------------------------------------------------------
1 | Name: Higher Order Function
2 | Scope: Not Sure
3 | Summary: Implement generic algorithms using higher order functions, which
4 | accept function arguments that implement functionality used
5 | by the algorithm.
6 |
--------------------------------------------------------------------------------
/patterns/hunt-gather.md:
--------------------------------------------------------------------------------
1 | Name: Hunt Gather
2 | Scope: Vanilla Erlang
3 | Summary: Use them cores. Parallelizing a list of work with the goal
4 | of avoiding sequentiality.
5 |
6 | This pattern parallelizes work which can save time and utilize
7 | hardware. Wherever there is work to be done which has no restriction
8 | for the order of operations, the hunt-gather pattern can be employed.
9 |
10 | ```
11 | -module(foo).
12 |
13 | -export([start/0]).
14 |
15 | start() ->
16 | Work = lists:seq(1, 999), % proxy for a list of actual data
17 | Cnt = length(Work),
18 | hunt(Work),
19 | gather(Cnt, []).
20 |
21 | hunt(L) ->
22 | Parent = self(),
23 | Fn = fun faux_expensive_routine/2,
24 | [ spawn(fun() -> Fn(Parent, X) end) || X <- L ].
25 |
26 | gather(0, Acc) -> Acc;
27 | gather(K, Acc) ->
28 | receive
29 | {bounty, R} -> gather(K - 1, [R|Acc])
30 | end.
31 |
32 | faux_expensive_routine(Parent, _X) ->
33 | timer:sleep(3000),
34 | R = gathered, % usually do something with _X
35 | Parent ! {bounty, R}.
36 | ```
37 |
--------------------------------------------------------------------------------
/patterns/if-expression.md:
--------------------------------------------------------------------------------
1 | Name: If Expression
2 | Scope: Erlang/OTP Construct
3 | Summary: Use an if expression to define a condition value based on
4 | Erlang guards.
5 |
--------------------------------------------------------------------------------
/patterns/iolist.md:
--------------------------------------------------------------------------------
1 | Name: IO List
2 | Scope: Erlang/OTP Construct
3 | Summary: Use deeply nested lists of integers and binaries to represent IO data
4 | to avoid copying when concatenating strings or binaries.
5 |
6 | IO lists are typically used to build output to a port e.g. a file or network
7 | socket.
8 |
9 | ```
10 | file:write_file("myfile.txt", ["Hi " [<<"there">>], $\n]).
11 | ```
12 |
13 | They are efficient even when combining large amounts of data. For
14 | example combining two fifty kilobyte binaries using binary syntax
15 | `<This is the second generic interior page. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ante ante, viverra a ornare sed, convallis sed est. Proin felis sapien, adipiscing quis eleifend vel, sodales vitae sapien. Donec vel lacus leo, eu convallis metus. Cras egestas feugiat tortor, vitae interdum augue aliquam a. Sed nec augue id orci egestas commodo in eget magna. Nunc eleifend diam non odio laoreet placerat gravida nulla bibendum. Phasellus tempus imperdiet suscipit.
55 |Mauris risus nulla, pulvinar vitae sagittis a, pharetra nec tellus. Suspendisse varius enim ac felis mattis aliquam. Aenean et justo quis ipsum gravida lacinia. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lacinia bibendum cursus. Nullam nec pellentesque lacus. In porta erat in tortor rhoncus quis accumsan magna pretium. Nulla posuere magna eget mauris lacinia in mollis sem fermentum. Donec mollis adipiscing mauris, ut posuere enim rhoncus ut. Nunc commodo vestibulum orci vel placerat. Cras sed risus libero. Donec ac lacus vitae lectus mattis commodo id vitae libero. Etiam lorem odio, volutpat nec pulvinar sit amet, tincidunt ut lacus. Pellentesque consequat arcu vel nisi lobortis in pellentesque orci sollicitudin. Cras gravida lacus turpis, consectetur porttitor lectus. Cras malesuada tortor id neque porta ut semper quam iaculis.
56 |Nulla ut tortor quam, a luctus nunc. Nulla condimentum diam porttitor arcu placerat tincidunt. Nunc non augue ipsum. Nulla facilisi. Phasellus feugiat augue in ipsum egestas semper. Suspendisse blandit, nisl ullamcorper blandit sollicitudin, sem leo auctor lectus, et volutpat mauris elit et odio. Ut elementum risus in metus mollis tristique vulputate nulla interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vitae orci dui, ut facilisis dui.
57 |Scope: {{ pattern.scope }}
10 |{{ pattern.summary }}
11 |Duis neque sed nisi, dapibus sed mattis rutrum accumsan sed. 68 | Suspendisse eu varius amet nibh. Suspendisse vitae magna eget odio amet 69 | mollis justo facilisis quis. Sed sagittis mauris amet tellus gravida 70 | lorem ipsum dolor consequat blandit tempus ipsum dolor lorem sit amet.
71 |Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ante ante, viverra a ornare sed, convallis sed est. Proin felis sapien, adipiscing quis eleifend vel, sodales vitae sapien. Donec vel lacus leo, eu convallis metus. Cras egestas feugiat tortor, vitae interdum augue aliquam a. Sed nec augue id orci egestas commodo in eget magna. Nunc eleifend diam non odio laoreet placerat gravida nulla bibendum. Phasellus tempus imperdiet suscipit.
79 |Mauris risus nulla, pulvinar vitae sagittis a, pharetra nec tellus. Suspendisse varius enim ac felis mattis aliquam. Aenean et justo quis ipsum gravida lacinia. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lacinia bibendum cursus. Nullam nec pellentesque lacus. In porta erat in tortor rhoncus quis accumsan magna pretium. Nulla posuere magna eget mauris lacinia in mollis sem fermentum. Donec mollis adipiscing mauris, ut posuere enim rhoncus ut. Nunc commodo vestibulum orci vel placerat. Cras sed risus libero. Donec ac lacus vitae lectus mattis commodo id vitae libero. Etiam lorem odio, volutpat nec pulvinar sit amet, tincidunt ut lacus. Pellentesque consequat arcu vel nisi lobortis in pellentesque orci sollicitudin. Cras gravida lacus turpis, consectetur porttitor lectus. Cras malesuada tortor id neque porta ut semper quam iaculis.
80 |Nulla ut tortor quam, a luctus nunc. Nulla condimentum diam porttitor arcu placerat tincidunt. Nunc non augue ipsum. Nulla facilisi. Phasellus feugiat augue in ipsum egestas semper. Suspendisse blandit, nisl ullamcorper blandit sollicitudin, sem leo auctor lectus, et volutpat mauris elit et odio. Ut elementum risus in metus mollis tristique vulputate nulla interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vitae orci dui, ut facilisis dui.
81 |Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ante ante, viverra a ornare sed, convallis sed est. Proin felis sapien, adipiscing quis eleifend vel, sodales vitae sapien. Donec vel lacus leo, eu convallis metus. Cras egestas feugiat tortor, vitae interdum augue aliquam a. Sed nec augue id orci egestas commodo in eget magna. Nunc eleifend diam non odio laoreet placerat gravida nulla bibendum. Phasellus tempus imperdiet suscipit.
55 |Mauris risus nulla, pulvinar vitae sagittis a, pharetra nec tellus. Suspendisse varius enim ac felis mattis aliquam. Aenean et justo quis ipsum gravida lacinia. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lacinia bibendum cursus. Nullam nec pellentesque lacus. In porta erat in tortor rhoncus quis accumsan magna pretium. Nulla posuere magna eget mauris lacinia in mollis sem fermentum. Donec mollis adipiscing mauris, ut posuere enim rhoncus ut. Nunc commodo vestibulum orci vel placerat. Cras sed risus libero. Donec ac lacus vitae lectus mattis commodo id vitae libero. Etiam lorem odio, volutpat nec pulvinar sit amet, tincidunt ut lacus. Pellentesque consequat arcu vel nisi lobortis in pellentesque orci sollicitudin. Cras gravida lacus turpis, consectetur porttitor lectus. Cras malesuada tortor id neque porta ut semper quam iaculis.
56 |Nulla ut tortor quam, a luctus nunc. Nulla condimentum diam porttitor arcu placerat tincidunt. Nunc non augue ipsum. Nulla facilisi. Phasellus feugiat augue in ipsum egestas semper. Suspendisse blandit, nisl ullamcorper blandit sollicitudin, sem leo auctor lectus, et volutpat mauris elit et odio. Ut elementum risus in metus mollis tristique vulputate nulla interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vitae orci dui, ut facilisis dui.
57 |Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ante ante, viverra a ornare sed, convallis sed est. Proin felis sapien, adipiscing quis eleifend vel, sodales vitae sapien. Donec vel lacus leo, eu convallis metus. Cras egestas feugiat tortor, vitae interdum augue aliquam a. Sed nec augue id orci egestas commodo in eget magna. Nunc eleifend diam non odio laoreet placerat gravida nulla bibendum. Phasellus tempus imperdiet suscipit.
100 |Mauris risus nulla, pulvinar vitae sagittis a, pharetra nec tellus. Suspendisse varius enim ac felis mattis aliquam. Aenean et justo quis ipsum gravida lacinia. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec lacinia bibendum cursus. Nullam nec pellentesque lacus. In porta erat in tortor rhoncus quis accumsan magna pretium. Nulla posuere magna eget mauris lacinia in mollis sem fermentum. Donec mollis adipiscing mauris, ut posuere enim rhoncus ut. Nunc commodo vestibulum orci vel placerat. Cras sed risus libero. Donec ac lacus vitae lectus mattis commodo id vitae libero. Etiam lorem odio, volutpat nec pulvinar sit amet, tincidunt ut lacus. Pellentesque consequat arcu vel nisi lobortis in pellentesque orci sollicitudin. Cras gravida lacus turpis, consectetur porttitor lectus. Cras malesuada tortor id neque porta ut semper quam iaculis.
101 |Nulla ut tortor quam, a luctus nunc. Nulla condimentum diam porttitor arcu placerat tincidunt. Nunc non augue ipsum. Nulla facilisi. Phasellus feugiat augue in ipsum egestas semper. Suspendisse blandit, nisl ullamcorper blandit sollicitudin, sem leo auctor lectus, et volutpat mauris elit et odio. Ut elementum risus in metus mollis tristique vulputate nulla interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis vitae orci dui, ut facilisis dui.
102 |