2014-08-29 81 views
1

最近我一直在做很多Sinatra,我認爲是時候把它帶到下一個級別。任何幫助將很樂意欣賞球員。所以這就是我正在考慮的:每當Amazon SQS隊列更新時運行Ruby任務

應用程序A在用戶發出事件時將事件引發到Amazon SQS隊列。無論何時將任何事件引入隊列,應用程序B都會執行一項任務(例如,發送帶有「嗨」消息的電子郵件用戶)。我從來沒有真正與Cron作業等工作的下面的代碼:

$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 

感謝馬克沃森這個(http://markwatson.com/blog/2011-11/ruby-sinatra-web-apps-with-background-work-threads.html

這裏是我的疑惑:

  • 就是「做任務在亞馬遜隊列更新「可能嗎?或者我認爲這是錯誤的方式?
  • 如何更新上述代碼,使其每3秒自動刷新一次而不發生「無限循環」錯誤?

回答

2

我建議你把你的應用程序分成兩部分。一個是常規Sinatra網絡應用程序,另一個是某種背景工作者。

示例應用程序

這是簡單不以生產工作的例子,你可以使用。

創建一些常見的boot.rb文件,你把你的「初始化」代碼:

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')] 

簡單西納特拉網絡app.rb,如果你訪問發送消息喲您的Amazon SQS /煙。

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 

創建另一個文件 - 它命名爲worker.rb - 這將訂閱您的Amazon SQS隊列和下拉消息。

require_relative 'boot' 

QUEUE.poll do |msg| 
    object = JSON.load(msg.body) rescue {} 
    puts "Got your email #{object['email']} at #{object['at']}." 
end 

我的地方.ENV文件包含證書和URL給SQA隊列。

AWS_ACCESS_KEY_ID=secret 
AWS_SECRET_ACCESS_KEY=secret 
AWS_QUEUE_URL=https://sqs.us-west-1.amazonaws.com/... 

運行它

然後你只需啓動你的Sinatra應用和工人,像這樣

ruby app.rb # in one terminal 
ruby worker.rb # in another terminal 

如果你再訪問/smoke,你會看到這樣的事情 - 這意味着作業調度。

Message was sent to Amazon SQS with id 788e5e28-8055-4c8f-bb51-c634c327a021. 

而且在你的工人終端你會看到

Got your email [email protected] at 2014-08-29T15:20:38+02:00. 

現在,你不必限制自己只是一個工人......你可以有像你一樣多,一個消息將僅在一個工作人員處理,默認情況下。另一個需要注意的是,我們正在發送JSON作爲消息,這就是爲什麼我在worker中使用了JSON.load。 Amazon SQS發送/接收純文本消息。

1

我建議你看看Shoryuken,它位於AWS SDK之上。您可以輕鬆地與Sinatra或任何其他Ruby應用程序集成。

get '/' do 
    MyWorker.perform_async(msg) 
end