user4470093
user4470093

Reputation:

Ruby threading/forking with API (Sinatra)

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.

Upvotes: 0

Views: 402

Answers (2)

Vishnu J
Vishnu J

Reputation: 491

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.

Upvotes: 0

unkmas
unkmas

Reputation: 987

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.

Upvotes: 1

Related Questions