0

I am using Sinatra gem for my API. What I want to do is when request is received process it, return the response and start new long running task.

I am newbie to Ruby, I have read about Threading but not sure what is the best way to accomplish my task.

Here my sinatra endpoint

  post '/items' do
     # Processing data
     # Return response (body ...)
     # Start long running task
  end

I would be grateful for any advice or example.

2 Answers2

1

I believe that better way to do it - is to use background jobs. While your worker executes some long-running tasks, it is unavailable for new requests. With background jobs - they do the work, while your web-worker can work with new request.

You can have a look at most popular backgroung jobs gems for ruby as a starting point: resque, delayed_jobs, sidekiq

UPD: Implementation depends on chosen gem, but general scheme will be like this:

# Controller
post '/items' do
  # Processing data
  MyAwesomeJob.enqueue # here you put your job into queue
  head :ok # or whatever
end

In MyAwesomejob you implement your long-runnning task

Next, about Mongoid and background jobs. You should never use complex objects as job arguments. I don't know what kind of task you are implementing, but there is general answer - use simple objects.

For example, instead of using your User as argument, use user_id and then find it inside your job. If you will do it like that, you can use any DB without problems.

unkmas
  • 977
  • 4
  • 13
  • Thanks for answer, could you please provide example how it would look like in my case, I mean returning response and than adding background job or vice versa ? Thanks –  Dec 26 '16 at 08:21
  • And one more thing, I am using Mongoid to save objects how can I use it or pass the object to the Sidekiq ? –  Dec 26 '16 at 08:46
0

Agree with unkmas.

There are two ways to do this. Threads or a background job gem like sidekiq.

Threads are perfectly fine if the processing times aren't that high and if you don't want to write code for the worker. But there is a strong possibility that you might run up too many threads if you don't use a threadpool or if you're expecting bursty http traffic.

The best way to do it is by using sidekiq or something similar. You could even have a job queue like beanstalkd in between and en-queue the job to it and return the response. You can have a worker reading from the queue and processing it later on.

Vishnu J
  • 501
  • 2
  • 10