Concurrency in Ruby
Topalov Alex @sharkzp 2014
Concurrency types
- Threads(Java). Threads sharedin memory. Live long
- New process per request(PHP). No Deadlocks and threadsafe. Die fast
- Actor Model(Erlang, Scala). Messaging between actors
Global Interpreter Lock
GIL is a locking mechanism that is meant to protect your data integrity(CRuby, CPython) It force to run only one thread at a time even on a multicore processor
Why?
- Some C extensation aren't Threadsafe
- Deadlocks
- Data integrity
Example
$ ruby pushing_nil.rb
5000
$ jruby pushing_nil.rb
4446
$ rbx pushing_nil.rb
3088
array = []
5.times.map do
Thread.new do
1000.times do
array << nil
end
end
end.each(&:join)
puts array.size
Implementation
VALUE
rb_ary_push(VALUE ary, VALUE item)
{
long idx = RARRAY_LEN(ary);
ary_ensure_room_for_push(ary, 1);
RARRAY_ASET(ary, idx, item);
ARY_SET_LEN(ary, idx + 1);
return ary;
}
Is it so bad?
In web each thread spend quite a lot of time in IOs which won’t block the thread scheduler. So if you receive two quasi-concurrent requests you might not even be affected by the GIL
Yehuda Katz
Multiple Process/Froking
- Passanger
- Unicorn
- Resque
It allow to fork as many process as need and control them in case of hanging or memory leaks
Actors/Fibers
- Actors implementations like Celluloid(sidekiq)
- Fibers
Non blocking IO/ Reactor pattern
- Goliath
- Thin
- Twisted
- EvenMachine
- Node.js(http://howtonode.org/control-flow-part-ii/file-write.js)
Reactor Pattern
If DB query(I/O) blocking other requests then wrap it in a fiber, trigger an async call and pause the fiber so another request can get processed. Once the DB query comes back, it wakes up the fiber it was trigger from, which then sends the response back to the client.
The Dining Philosophers Problem
Lets write some code! Finally!
Credits:
1. https://www.youtube.com/watch?v=eHPp-tpCAZ0
2. http://en.wikipedia.org/wiki/Global_Interpreter_Lock
3. http://tonyarcieri.com/2012-the-year-rubyists-learned-to-stop-worrying-and-love-the-threads
4. https://practicingruby.com/articles/gentle-intro-to-actor-based-concurrency
5. https://github.com/celluloid/celluloid/wiki/Gotchas
6. http://merbist.com/2011/02/22/concurrency-in-ruby-explained/
7. https://en.wikipedia.org/wiki/Actor_model
8. http://www.jstorimer.com/products/working-with-ruby-threads
Concurrency in Ruby
By Alex Topalov
Concurrency in Ruby
- 1,893