sync_primitives for Elixir

Apache LicenseHex.pmDocumentationBuild StatusCoverage Status

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"}]
end

Documentation can be found at https://hexdocs.pm/sync_primitives.

CyclicBarrier Usage

  1. Start a CyclicBarrier

     barrier = SyncPrimitives.CyclicBarrier.start(2, fn -> IO.puts("barrier action") end)
  2. Start the processes you wish to synchronize through a CyclicBarrier.

    1. The first process:

       spawn_link(fn ->
         IO.puts("process 1, before wait")
         SyncPrimitives.CyclicBarrier.await(barrier)
         IO.puts("process 1, after wait")
       end)
    2. Wait for a little bit to see that process 1 won't reach the "after wait" message.

    3. Start the second process:

       spawn_link(fn ->
         IO.puts("process 2, before wait")
         SyncPrimitives.CyclicBarrier.await(barrier)
         IO.puts("process 2, after wait")
       end)
  3. All of above will output:

     process 1, before wait
     process 2, before wait
     barrier action
     process 1, after wait
     process 2, after wait
  4. Remember to stop the barrier

     SyncPrimitives.CyclicBarrier.stop(barrier)

CountDownLatch Usage

  1. Start a CountDownLatch

     latch = SyncPrimitives.CountDownLatch.start(2, fn -> IO.puts("latch done") end)
  2. 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)
  3. Wait for a little bit to see that the process won't reach the "after wait" message.

  4. Countdown enough times for the latch to reach 0.

     SyncPrimitives.CountDownLatch.count_down(latch)
     SyncPrimitives.CountDownLatch.count_down(latch)
  5. All of above will output:

     latch done
     after wait
  6. Remember to stop the latch!

     SyncPrimitives.CountDownLatch.stop(latch)