Everybody always explicitly mentions that next_tick will be executed in the Main Thread.
But what about Timers and callbacks/errbacks? Are they guaranteed to run in the Main Thread as well?
Regardless of Ruby version, EM runs everything except the EM.defer code block inside the reactor thread (EM.defer result and on error blocks are in the reactor too), so yes,
timers, callbacks and errbacks are guaranteed to run in the reactor (main) thread
Assuming you're using MRI Ruby, then there is only 1 'real/native' thread, which is the main/reactor thread, and all code is executed by this reactor thread. All timers and callbacks will be picked up on the reactor thread.
Eventmachine is not designed to use multiple threads as part of its standard operation, however, Eventmachine does have a 'EM::defer' method, which will execute the block on a different 'ruby' thread, and I believe that if you are running a multithread capable ruby such as jruby or rubinious, then this will be run on a 'native' OS thread. "Defer" should be used if you are going to be executing any 'blocking' code.
Related
When using MRI Ruby 2.1.2 with Puma (say 1 worker with 8 threads), when is the GC run? Is it run by the parent worker process when all those threads become idle, or would it be run by the parent process as needed, even when those threads are busy processing requests?
And how would this behaviour be different in Ruby 2.0 (without deferred GC).
Also asked here.
Its been answered on the Github issue.
It runs whenever the VM decides to run it. Puma does nothing to control that nor can it really.
As I understand, Ruby 1.9 uses OS threads but only one thread will still actually be running concurrently (though one thread may be doing blocking IO while another thread is doing processing). The threading examples I've seen just use Thread.new to launch a new thread. Coming from a Java background, I typically use thread pools as to not launch to many new threads since they are "heavyweight."
Is there a thread pool construct built into ruby? I didn't see one in the default language libraries. Or are there is a standard gem that is typically used? Since OS level threading is a newer feature of ruby, I don't know how mature the libraries are for it.
You are correct in that the default C Ruby interpreter only executes one thread at a time (other C based dynamic languages such as Python have similar restrictions). Because of this restriction, threading is not really that common in Ruby and as a result there is no default threadpool library. If there are tasks to be done in parallel, people typically uses processes since processes can scale over multiple servers.
If you do need to use threads, I would recommend you use https://github.com/meh/ruby-threadpool on the JRuby platform, which is a Ruby interpreter running on the JVM. That should be right up your alley, and because it is running on the virtual machine it will have true threading.
The accepted answer is correct, But, there are many tasks in which threads are fine. after all there are some reasons why it is there. even though it can only run a thread at a time. it is still can be considered parallel in many real life situations.
for example when we have 100 long running process in which each takes approximate 10 minutes to complete. by using threads in ruby, even with all those restrictions, if we define a threadpool of 10 tasks at time, it will run much faster than 100*10 minutes when running without threads. examples include, live capturing of file changes, sending large number of web requests (such as status check)
You can understand how pooling works by reading https://blog.codeship.com/understanding-fundamental-ruby-abstraction-concurrency/ . in production code use https://github.com/meh/ruby-thread#pool
I have searched the Internet but failed to find a satisfactory answer. What is the threading model present in an OSGi container? Does it simply spawn a new thread to each registered bundle e.g.? Any reference regarding the threading model would be great.
You have not found anything because there is no such thing as an "OSGi threading model". Bundles simply exist and don't "have threads" unless they start them.
The OSGi framework follows a synchronous model, ie. everything happens in a strict order. Bundles are not executed in threads (but they have their own classloader instances). There are some exceptions, though. For example, when an event is raised via the postEvent method, the delivery of the event is done asynchronously, usually implemented in many framework implementations as a thread.
When you start a bundle, code in activator is executed in one thread, similar to the 'main' thread. When the main thread completes its execution, bundle is changed from the 'Starting' state to 'Active' state. So it is better to execute time consuming code in another thread and starting another thread from the main thread.
When service method gets called from service consumer. At that time, the code written in the service method get executed in service consumer's thread.
I didn't find any difference between static variables and local variable in the service method.
Besides some special cases (Events/Listeners) the application threads are neighter managed nor restricted. You can use threading freely. You do need to be aware that some operations in the bundle lifecylce must be (therefore) thread safe and you need to be very carefull to tear down threads cleanly. You also need to be carefull not to block OSGi operations needlessly long.
I have a small HTTP server script I've written using eventmachine which needs to call external scripts/commands and does so via backticks (``). When serving up requests which don't run backticked code, everything is fine, however, as soon as my EM code executes any backticked external script, it stops serving requests and stops executing in general.
I noticed eventmachine seems to be sensitive to sub-processes and/or threads, and appears to have the popen method for this purpose, but EM's source warns that this method doesn't work under Windows. Many of the machines running this script are running Windows, so I can't use popen.
Am I out of luck here? Is there a safe way to run an external command from an eventmachine script under Windows? Is there any way I could fire off some commands to be run externally without blocking EM's execution?
edit: the culprit that seems to be screwing up EM the most is my usage of the Windows start command, as in: start java myclass. The reason I'm using start is because I want those external scripts to start running and keep running after the EM request is served
The ruby documentation states that the backtick operator "Returns the standard output of running cmd in a subshell"
So if your command i.e. start java myclass is continuing to run then ruby is waiting for it to finish to pass back it's output to your program.
Try win32-open3 (and if it needs to be cross-platform not windows-only, also have a look at POpen4)
EventMachine has a thread pool. You can EM.defer your backticks like this
EM.defer { `start java myclass` }
By default the thread pool has 20 threads, and you can change its size by assiging EM.threadpool_size a value.
Important to note, that EM.defer can be passed operation, which is executed in deferred thread, callback, which is executed in reactor thread, and error callback which is run in reactor thread when the operation raises the exception.
If you use Java, you may consider using jruby, which has real threads support, and you could probably reuse your Java code from within jruby.
I'm writing a project at the moment that involves running two parallel threads to pull data from different sources at regular intervals. I am using the Threads functionality in ruby 1.9 to do this but am unfortunately running up against deadlock problems. Also I have a feeling that the Thread.join method is causing the threads to queue rather than run in parallel.
I'm new to multithreading programming and any advice would be greatly appreciated
Cheers
Patrick
EDIT: The shared resource that both these threads are accessing is a mysql database which could be the problem. The deadlock arrises after a few iterations of these threads being run.
You can use synchronization mechanisms such as Mutex, Monitor, Queue, SizedQueue from standart library. Or problem in using them?
It's very difficult to diagnose what could be going wrong without more details but deadlock is (obviously) caused by multiple threads trying to acquire resources held by others. That really means that you must have at least two mutexes and two threads. Could that be happening in your code?
Thread.join doesn't have anything to do with parallel executiion - it's a synchronization method to enable one (usually the master) thread to wait for one or more threads to complete.
Which Ruby 1.9 implementation are you using? YARV cannot run Ruby Threads in parallel. At the moment, there is no production-ready implementation of Ruby 1.9 which can run threads in parallel. JRuby can threads in parallel, but its Ruby 1.9 implementation is not quite complete yet. (Although it is stable, so if all the features you need are there, you can use it.)