iT邦幫忙

DAY 19
2

建立API為中心的輕量級網站系列 第 19

redis 應用:resque 的基本使用

比較一下,有用背景工作跟沒有背景工作的差別。
在 RailCasts 的這篇 #271 Resque
是非常簡潔的 resque 影音教學,
本篇也將利用 http://pygments.appspot.com/
來幫忙把程式碼上色,
而利用 sinatra 及 redis 當儲存程式碼的的資料庫。

在 sinatra 來做儲存程式碼的動作及回應:

  post '/noresque' do
    now = Time.now.to_i
    key = "i5:codes:#{now}"
    redis.hmset key,'lang',params[:lang],'codes',params[:codes]
    url = 'http://pygments.appspot.com/'
    http = Curl.post(url,{'lang' => params[:lang], 'code' => codes})
    redis.hset key,'color',http.body_str
    redis.hget key,'codes'
  end

這是利用時間的timestamp做key的一部分,
利用curb也就是curl來把程式碼傳到提供服務所在,
再把程式碼存到redis裡。

用 curl 來當client執行看所要花的時間狀況為:

$ time curl -s -d 'lang=rb&codes=Resque.enqueue(SnippetHighlighter, @snippet.id)' http://i5.tagbible.net/noresque -o /dev/null

real    0m0.177s
user    0m0.003s
sys     0m0.000s

編輯colorCodeJob.rb這檔案,
把要背景工作的動作寫入:

require 'resque'
require 'curb'
require 'redis'

$redis = Redis.new
class ColorCodes
  @queue = :pygment_queue
  def self.perform(key,lang,codes)
    url = 'http://pygments.appspot.com/'
    http = Curl.post(url,{'lang' => lang, 'code' => codes})
    $redis.hset key,'color',http.body_str
  end
end

要把需要的gem包進來,
不然程式不曉得怎麼做這些動作。

編輯一個Rakefile

$LOAD_PATH.unshift File.dirname(__FILE__) unless $LOAD_PATH.include?(File.dirname(__FILE__))
require "resque/tasks"
require 'colorCodeJob'

#以下是舊版的寫法
#rake resque:work QUEUE=*
#task "resque:setup" do
#  ENV['QUEUE'] = '*'
#end

執行前沒有任何worker

執行:

TERM_CHILD=1 QUEUES=* rake resque:work

顯示出有個worker正在等待工作,

並在 sinatra 上加入以下程式碼:

class ColorCodes
  @queue = :pygment_queue
  def self.perform(key,lang,codes)
    url = 'http://pygments.appspot.com/'
    http = Curl.post(url,{'lang' => lang, 'code' => codes})
    redis.hset key,'color',http.body_str
  end
end

  post '/withresque' do
    now = Time.now.to_i
    key = "i5:codes:#{now}"
    redis.hmset key,'lang',params[:lang],'codes',params[:codes]
    Resque.enqueue ColorCodes, key, params[:lang], params[:codes]
    redis.hget key,'codes'
  end

就是要定義好 ColorCodes 的class,
把原來要用curl傳到別的網站的動作及回應,
統統都寫到給 resqueue 來處理,
然後用 Resque.enqueue 把 class 及所需的參數填入,
即可把工作傳到 resqueue 裡,
resqueue 也需要把這 class 的定義,
在執行 rake resqueue:work 也讀入。

用curl執行的結果為:

$ time curl -s -d 'lang=rb&codes=Resque.enqueue(SnippetHighlighter, @snippet.id)' http://i5.tagbible.net/withresque -o /dev/null

real    0m0.134s
user    0m0.003s
sys     0m0.000s

與前面所花的時間少了些,
因為測試的程式碼很簡短,
感覺差別不大,
但貼了較多的程式碼,
就比較會有感了。

顯示已工作過的記錄。

系列文章列表


上一篇
redis 應用:在 sinatra 建立 resque Server
下一篇
redis 多重指令 MULTI 及 ruby 裡的 pipeline 的使用
系列文
建立API為中心的輕量級網站30

1 則留言

我要留言

立即登入留言