I'm making a Rails 4 app, where I need to keep multiple TCP connections open towards another server. What would be the best way to implement the background threads serving these connections? Or should I use non-blocking sockets?
I have features that require the HTTP serving thread to wait for the response in the background connection, but other times the background threads need to write the DB.
Most libraries handling background threads are pretty much job oriented (e.g. Sidekiq), it seems they could not handle spawning a new thread for each new connection. I tried to make it with the Thread class and mutexes, but strange stuff seems to happen (like background threads stopping for no reason, then reappearing, but that might be a quirk of byebug).
Related
Should i use they with TIdTcpServer, and where they can improve something on my application?
i ask it because maybe they can improve some speed/agility action on TIdTcpServer since i use a Queue.
TIdTCPServer runs a thread for every client that is connected. Those threads are managed by the TIdScheduler that is assigned to the TIdTCPServer.Scheduler property. If you do not assign a scheduler of your own, a default TIdSchedulerOfThreadDefault is created internally for you.
The difference between TIdSchedulerOfThreadDefault and TIdSchedulerOfThreadPool is:
TIdSchedulerOfThreadDefault creates a new thread when a client connects, and then terminates that thread when the client disconnects.
TIdSchedulerOfThreadPool maintains a pool of idle threads. When a client connects, a thread is pulled out of the pool if one is available, otherwise a new thread is created. When the client disconnects, the thread is put back in the pool for reuse if the scheduler's PoolSize will not be exceeded, otherwise the thread is terminated.
From the OS's perspective, creating a new thread is an expensive operation. So in general, using a thread pool is usually preferred for better performance, but at the cost of using memory and resources for idle threads hanging around waiting to be used.
Whichever component you decide to use will not have much effect on how the server performs while processing active clients, only how it performs while handling socket connects/disconnects.
My Rails application has a route that takes a lot of time to process, which makes the entire webpage freeze.
Why does this happen? Is it Rails or third-party gems which are not thread-safe?
Is there any way to work around this? I'm considering using a process pool, just like a thread pool, except it is heavier, it'll take a lot of memory, but it'll be cheaper than halting the whole app.
First thing to notice, your Rails action should not be heavy-weight. When a user requests a page, you should serve the user right away.
Now, there are cases when you need the user to wait for the result, in which case, you can always use websockets, or HTTP streaming.
Now, Ruby and Rails have a problem with threads, which you can read about in "Parallelism is a Myth in Ruby."
A solution you can use in Rails, is to use servers like Unicorn, which forks as many process workers as you want, and each one will be working independent of the others, Puma for creating multi threads, etc.
Now, if you have an action which is a heavy process, you may want to delay the work to a process pool like delayed_job. You can even create a nice UI with JavaScript to fetch the status of the job and show the progress to the user. You can use a pool of tasks to be performed with RabbitMQ, where another process On the background could listen to new messages and act on them, and even give a response, etc.
Have in mind that most webservers have a client timeout, and you don't really want the user to wait for one minute or more without a response, so it's always nice to use a stream response to give some feedback right away while the action is being completed, or answer with some JavaScript code that will continue hitting the server to see how the task is being performed, or even a websocket if required.
Rails uses a mutex lock around the entire request in the middleware stack, so a Rails process only ever takes one request at a time.
However, you can disable this by enabling the config.threadsafe! option AND using a multithreaded server, such as Puma.
Then there is the whole roadblock of using MRI which doesn't really let two threads run at the same time unless they are doing non-blocking I/O.
You would need to use a Ruby implementation that supports real threads, such as Rubinius or Jruby.
I have a windows service which runs a separate background thread. Inside the thread it starts a TCP server which listens to clients using TcpListener.
I'd like to know how I can close the service down gracefully when there is a blocking read like so:
listener.AcceptTcpClient();
I've found that apparently a windows service can abort any other threads as long as they are set-up as background threads, but what if one of the threads is blocking? Does this make a difference and if so, what is the best way to handle this situation?
Best way will be to call listener.Close() on service's stopping event. It will abort blocking call with SocketException.
State of the thread (blocked or running) does not affect the fact that thread is background. So if you call listener.AcceptTcpClient() from a background thread it will still be aborted when service stops,
I have a controller action that aggregates data from multiple sources: web service, database, file lookups, etc... and passes results to the view. So in order to render the page all tasks must have completed. Currently they are performed sequentially but as they are independent I am thinking of running them in parallel as this could improve performance.
So what would be the best approach to achieve this? For each task start a new thread and block the main thread as all tasks are finished? Should I use a thread from the thread pool or spawn a new thread manually? Using threads from the thread pool would limit my web server's capability of serving new requests so this might not be a good idea. Spawning new threads manually could be expensive, so at the end of the day would there be a net gain in performance by paralleling these tasks or just leave them run sequentially?
If it's between spawning your own threads or using the thread pool threads, I'd say use the ones from the thread pool. You can always adjust your server settings to allow for more threads in the pool if you find that you are running out of threads.
The only way to answer your final question would be to actually test it out, as we don't know how complicated the separate aggregation tasks are. If you want to give the illusion of a responsive UI, you could always display the loading page and kick off the aggregation with AJAX. Even non-threaded, this may placate your users sufficiently.
Are there any issues to consider when using DRb for implementing an in-memory message queue and for synchronizing actions between processes? I heard that it could be unreliable, but haven't found anything on the web that confirms this assertion.
In case it's relevant, these would be processes running with a rails app environment that will update models in the database.
DRb is pretty established and widely used. I don't know of anything that would make it unreliable, but I don't use it as a message queue
I'd say you'll have more luck using a message queue as a message queue, instead of rolling your own using DRb. There's a bunch of solutions depending on your needs, memcacheq is pretty easy to interact with, and is in-memory, and is pretty solid.
I personally use DRb running in two separate processes on my web server one to perform minutes-long calculations, allowing the website to poll and check in on the progress, another as a shared captcha server with its own DB connection for various applications on my server. In neither case have I ever had the DRb server fail (except where it was a programming mistake on my part).
Even when the DRb server does fail, you can restart it and the still-running client will reconnect cleanly the next time it needs to communicate.