Concurrency in production. Real life example - Dmytro Herasymuk | Ruby Meditation 25
Speech of Dmytro Herasymuk, WEB developer at Softermii, at Ruby Meditation #25 Kyiv 08.12.2018
Next conference - http://www.rubymeditation.com/
The modern world demands to be faster and faster. Engineers create more powerful CPUs every day, but our app depends on third party apps too often in the WEB world. So, even the fastest CPU can't cope with I/O delays. On the one hand multithreading could help in such cases, but on the other hand, it seems to be a hard decision of using concurrency in production.
Dmytro would like to share his experience in this field
Announcements and conference materials https://www.fb.me/RubyMeditation
The stream of Ruby conferences (not just ours) https://t.me/RubyMeditation
Why don’t we use it so often?
The Global Interpreter Lock
MRI has a Global Interpreter Lock, often called the GIL, and having a high level
understanding of it is important to understanding how we write multi-threaded code
in Ruby. Basically the GIL prevents multiple Ruby threads from executing at the same
time. This means that no matter how many threads you spawn, and how many cores
you have at your disposal, MRI will literally never be executing Ruby code in multiple
threads concurrently. Note that this is not the case for JRuby or Rubinius which do not
have a GIL and offer true multi-threading.
The existance of the GIL provides some guarantees and removes certain issues around
concurrency within MRI. It’s important to note however that even with the GIL it’s
very possible to write code which isn’t threadsafe in MRI.
So when does using threads make sense?
To ensure all citizens are treated fairly the underlying operating system handles
context switching between threads, i.e. when to pause execution of one thread and
start or resume execution of another thread. We said above that the GIL prevents
multiple Ruby threads within a process from executing concurrently, but a typical
Ruby program will spend a significant amount of time not executing Ruby code,
specifically waiting on blocking I/O. This could be waiting for HTTP requests, database
queries or file system operations to complete. While waiting for these operations to
complete, the GIL will allow another thread to execute. We can take advantage of this
and perform other work, which doesn’t depend on the result, while we wait for the I/O