Giter VIP home page Giter VIP logo

semaphore's Introduction

Semaphore

Master Hex.pm Version

Programming in Erlang and Elixir usually allows for no locking since the VM essentially handles it for you when communicating between processes. However, what about the situation when you have thousands of processes attempting to interact with a single resource such as a process? Usually they will overload the process and explode the message queue. ETS is the Swiss Army knife of the Erlang VM and can be applied to this problem. By using :ets.update_counter and :write_concurrency we can achieve a fast low contention semaphore on ETS.

Usage

Add it to mix.exs

defp deps do
  [{:semaphore, "~> 1.3"}]
end

Then just use it like a semaphore in any other language.

if Semaphore.acquire(:test, 1) do
  IO.puts "acquired"
  Semaphore.release(:test)
end

case Semaphore.call(:test, 1, fn -> :ok end) do
  :ok ->
    IO.puts "success"
  {:error, :max} ->
    IO.puts "too many callers"
end

License

Semaphore is released under the MIT License. Check LICENSE file for more information.

semaphore's People

Contributors

daisyzhou avatar jhgg avatar karlseguin avatar likeanocean avatar vishnevskiy avatar ypisetsky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

semaphore's Issues

Behavior of acquire/2 when changing max

๐Ÿ‘‹ Hello!

I am trying to understand what the intended behavior is supposed to be when acquiring a semaphore and changing the max at the same time to a lower number. Here is an example:

# First acquire should work
iex(1)> Semaphore.acquire(:a, 5)
true

iex(2)> Semaphore.count(:a)     
1

# Increasing the max and acquire again
iex(3)> Semaphore.acquire(:a, 7) 
true

iex(4)> Semaphore.count(:a)     
2

# Acquire with the same max
iex(5)> Semaphore.acquire(:a, 7)
true

iex(6)> Semaphore.count(:a)     
3

# Now acquire with a lower max, shouldn't this return false?
iex(7)> Semaphore.acquire(:a, 2)
true

# This count feels a little disingenuous because of the previous statement returning true
iex(8)> Semaphore.count(:a)     
2

What is the behavior supposed to be when lowering the max?

At first my intuition was that the count would be reset to 0, and that's why the iex(7) succeeded, but then when I look at the count I see 2, which is quite confusing. The 2 would make sense if the return value of iex(7) was false (i.e. the semaphore is still full but we now have a lower limit). Another possibility would be that changing the max via the acquire does not alter the count.

Additionally, I am not sure what the use case is for adjusting the max while acquiring at the same time. Would it makes things more clear to have a separate set_max function?

Semaphore.call/3 can leak if a linked process dies.

See this following repro:

{pid, ref} = spawn_monitor fn ->
  Semaphore.call(
    :foo,
    5,
    fn ->
      spawn_link(
        fn ->
          exit(:ded)
        end
      )
      Process.sleep(50)
    end
  )
end
receive do
  {:DOWN, ^ref, :process, ^pid, reason} ->
    count = Semaphore.count(:foo)
    IO.puts("Process down for reason #{inspect reason} - semaphore leaked? #{count}")
end

When ran, it will output:

Process down for reason :ded - semaphore leaked? 1

It should output:

Process down for reason :ded - semaphore leaked? 0

Question with safety of the function call_linksafe

  def call_linksafe(name, max, func) do
    if acquire(name, max) do
      safe_key = {name, self()}
      inserted = ETS.insert_new(@call_safe_table, [safe_key])

What if the process killed before ETS.insert_new(@call_safe_table, [safe_key]) ?
Seems like we still have problem, although time window for this is rather small.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.