Implementation of Chandy-Lamport algorithm for the taking the snapshot of state of a distributed system. == Specific example - There are 3 modules: network, in charge of loading and maintaing a representation of the network basic, containing the basic algorithm (see below) control, for executing and controlling the snapshot - Basic processes are associated with a balance. A process is activated when a basic message (i.e. 'token' or 'go') is received. If message is 'token', then balance is increased by the associated value. After consuming a basic message, the process also sends another token on a random neightbour with a random value (subtracting from the balance). Each process can only be activated a bounded number of times. - The snapshot algorithm is executed by sending a control ('marker') message to one or more basic processes. Once the algorithm terminates, the local snapshots are collected and the sum of local balances and token values inside channels is computed. If the snapshot is consistent, the latter sum should be the same as the sum of the initial local balances (25 by default). There are two versions of the control algorithm: a simpler one working only on FIFO channel, and a more complex one working on non-FIFO channel. == Limitations Current implementation relies on stable networks: messages can only be send along edges of the network, and the latter cannot change during execution of basic processes and control algorithm. Also, edges must always include self-loops at all nodes. == References [http://en.wikipedia.org/wiki/Snapshot_algorithm] From erl prompt: % to compile (only once) c(network), c(basic), c(control), c(basic2), c(control2), c(nonFIFO). % to execute with snapshot after execution network:run(). control:snapshot(). % to execute with snapshot during execution network:run(), control:snapshot(). % to choose between FIFO version and non-FIFO version network:run(basic) network:run(basic2) % to specify a different module and basic process with parameters network:run(basic, process, [3, 5]). % to specify a different network (remember that edges must include self-loops to all nodes) network:run([NodeName1, NodeName2, ...], [{From1, To1}, {From2, To2}, ...]). % for example: network:run(), control:snapshot(). network:run(basic2), control2:snapshot(). network:run(basic2, process, [3,5], [a], [{a,a}]), control2:snapshot().