sync_primitives for Elixir
Synchronization Primitives for Elixir, such as CyclicBarrier and CountDownLatch.
These primitives allow you to synchronize multiple Elixir processes using higher-level abstractions than messages. I have found them are very useful in testing agent-based and mutli-process Elixir apps.
Installation
sync_primitives is available on Hex. Add sync_primitives to your list of dependencies in mix.exs:
def deps do
[{:sync_primitives, "~> 0.1.0"}]
endDocumentation can be found at https://hexdocs.pm/sync_primitives.
CyclicBarrier Usage
Start a
CyclicBarrierbarrier = SyncPrimitives.CyclicBarrier.start(2, fn -> IO.puts("barrier action") end)Start the processes you wish to synchronize through a CyclicBarrier.
The first process:
spawn_link(fn -> IO.puts("process 1, before wait") SyncPrimitives.CyclicBarrier.await(barrier) IO.puts("process 1, after wait") end)Wait for a little bit to see that
process 1won't reach the "after wait" message.Start the second process:
spawn_link(fn -> IO.puts("process 2, before wait") SyncPrimitives.CyclicBarrier.await(barrier) IO.puts("process 2, after wait") end)
All of above will output:
process 1, before wait process 2, before wait barrier action process 1, after wait process 2, after waitRemember to stop the barrier
SyncPrimitives.CyclicBarrier.stop(barrier)
CountDownLatch Usage
Start a
CountDownLatchlatch = SyncPrimitives.CountDownLatch.start(2, fn -> IO.puts("latch done") end)Start the process you wish to block until the CountDownLatch is released.
spawn_link(fn -> IO.puts("before wait") SyncPrimitives.CountDownLatch.await(latch) IO.puts("after wait") end)Wait for a little bit to see that the process won't reach the "after wait" message.
Countdown enough times for the latch to reach 0.
SyncPrimitives.CountDownLatch.count_down(latch) SyncPrimitives.CountDownLatch.count_down(latch)All of above will output:
latch done after waitRemember to stop the latch!
SyncPrimitives.CountDownLatch.stop(latch)