Reputation: 1041
I've been doing a lot of Sinatra lately and I thought it was time to take it to the next level. Any help would be gladly appreciated guys. So here is what I'm thinking of doing:
App A throws an event to Amazon SQS queue whenever user makes an event. App B does a task (say emails user with a "Hey" message) whenever any event is thrown into the queue. I've never really worked with Cron Jobs other that the below code:
$sum = 1
Thread.new do # trivial example work thread
while true do
sleep 3
$sum += 1
end
end
get '/' do
"Testing background work thread: sum is #{$sum}"
end
Thanks Mark Watson for this (http://markwatson.com/blog/2011-11/ruby-sinatra-web-apps-with-background-work-threads.html)
Here are my doubts:
Upvotes: 1
Views: 836
Reputation: 6357
I would recommend you to have a look at Shoryuken, it's on top of the AWS SDK. And you can easily integrate with Sinatra or any other Ruby app.
get '/' do
MyWorker.perform_async(msg)
end
Upvotes: 1
Reputation: 4193
I would suggest that your split your application into 2 parts. One is regular Sinatra web app and another is some kind of background worker.
This is simple not-for-production working example that you could use.
Create some common boot.rb file where you put your "initialisation" code in:
require 'bundler/setup'
# Use this to load my '.env' that contains AWS credentials
require 'dotenv'; Dotenv.load
# We are using Amazon Ruby SDK
require 'aws-sdk'
# We configure AWS Ruby SDK
AWS.config(
access_key_id: ENV.fetch('AWS_ACCESS_KEY_ID'),
secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY')
)
# We get SQS Web Service
sqs = AWS::SQS.new
QUEUE = sqs.queues[ENV.fetch('AWS_QUEUE_URL')]
Simple Sinatra web app.rb that sends message yo your Amazon SQS if you visit /smoke.
require_relative 'boot'
require 'sinatra'
get '/smoke' do
message = QUEUE.send_message({email: "[email protected]", at: DateTime.now}.to_json.to_s)
"Message was sent to Amazon SQS with id #{message.id}.\n"
end
Create another file - name it worker.rb - that will subscribe to your Amazon SQS queue and pull messages.
require_relative 'boot'
QUEUE.poll do |msg|
object = JSON.load(msg.body) rescue {}
puts "Got your email #{object['email']} at #{object['at']}."
end
My local .env file contains credentials and URL to SQA queue.
AWS_ACCESS_KEY_ID=secret
AWS_SECRET_ACCESS_KEY=secret
AWS_QUEUE_URL=https://sqs.us-west-1.amazonaws.com/...
Then you simply startup your Sinatra app and worker like so
ruby app.rb # in one terminal
ruby worker.rb # in another terminal
If you then visit /smoke
you will see something like this - meaning that job was scheduled.
Message was sent to Amazon SQS with id 788e5e28-8055-4c8f-bb51-c634c327a021.
And in your worker terminal you'll see
Got your email [email protected] at 2014-08-29T15:20:38+02:00.
Now, you don't have to limit yourself to just one worker... You can have as many as you like, one message will be processed only on one worker by default. Another note here is that we are sending JSON as message thats why I've used JSON.load in worker. Amazon SQS sends/receives plain text messages.
Upvotes: 2