[Backgroundrb-devel] How does ask_result() work?

Cédric akyrho at gmail.com
Thu Jul 24 10:46:19 EDT 2008


As requested on IRC, here's my code.

The worker :

---
require 'uri'
require 'net/http'
require 'RMagick'
require 'open-uri'
require 'rexml/document'

class ThumbnailerWorker < BackgrounDRb::MetaWorker
  set_worker_name :thumbnailer_worker
  set_no_auto_load true

  def create(args = nil)
    logger.info("[DEBUG] starting a thumbnailer worker (Time: " +
Time.now.to_s + ")")
    generate_thumbnails(args)
  end

  def generate_thumbnails(args = nil) # args = @source.id
    logger.info("[DEBUG] generate_thumbnails(args = " + args.inspect + ")")
    @source_id = eval(args.to_s)
    cache['thumbnailing_for_source_'+ at source_id.to_s] = '0,0,0'

    thumbnails = Thumbnail.find(:all, :conditions => ['medias.source_id=?
AND thumbnails.code=?', @source_id, PROCESSING_STATUS], :order =>
"medias.created_at ASC", :include => { :media => :source })

    @failed = 0
    @success = 0
    @progress = 0
    @total = thumbnails.size unless thumbnails.nil?

    if @total.nil? or @total == 0
      cache['thumbnailing_for_source_'+ at source_id.to_s] =
'-2,'+ at progress.to_s+','+ at total.to_s
    end

    upload_directory = RAILS_ROOT + "/public/medias/"
    no_error_encountered = true

    for thumbnail in thumbnails
      break if !no_error_encountered

      if @progress == 0
        media_id = thumbnail.media_id
        begin
          Dir.mkdir(upload_directory + @source_id.to_s)
        end
      end

      begin
        url = URI.split(thumbnail.original.sub(' ', '%20'))

        resp = Net::HTTP.get_response(url[2], url[5])
        if resp.code.to_s == "200"
          http = Net::HTTP.start(url[2])
          resp = http.get(url[5])
          image_filename = upload_directory + thumbnail.id.to_s + '.tmp.jpg'
          open(image_filename, "w") { |file| file.write(resp.body) }
          pic = Magick::Image.read(image_filename).first
          GC.start
          maxwidth = 100
          maxheight = 100
          aspectratio = 1.0
          imgwidth = pic.columns
          imgheight = pic.rows
          imgratio = imgwidth.to_f / imgheight.to_f
          scaleratio = imgratio > aspectratio ? (maxwidth.to_f / imgwidth) :
(maxheight.to_f / imgheight)
          thumb = pic.thumbnail(scaleratio)
          thumb.write(thumbnail_location = upload_directory +
@source_id.to_s + '/' + thumbnail.id.to_s + '.jpg')
          File.delete(image_filename)
          no_error_encountered = File.exist?(thumbnail_location)
          @success += 1
        else
          logger.info("[WARN] thumbnail for " + thumbnail.original + " not
generated. response = " + resp.code.to_s)
          @failed += 1
        end

        if no_error_encountered
          thumbnail.update_attribute("code", DEFAULT_STATUS)
        end

        sleep 0.5
      rescue Exception => exc
        logger.info("[WARN] exception caught in thumbnailer_worker: " +
exc.inspect)
        logger.info("[WARN] backtrace: " + exc.backtrace.inspect)
        @failed += 1 if resp.code.to_s == "200"
      end
      @progress += 1
      if @progress == @total
        cache['thumbnailing_for_source_'+ at source_id.to_s] =
'9999,'+ at progress.to_s+','+ at total.to_s
      else
        cache['thumbnailing_for_source_'+ at source_id.to_s] =
@progress.to_s+','+ at progress.to_s+','+ at total.to_s
        logger.info("cache['#{'thumbnailing_for_source_'+ at source_id.to_s}']
= #{cache['thumbnailing_for_source_'+ at source_id.to_s].inspect}")
      end
    end

    if no_error_encountered
      Media.update_all("code=#{DEFAULT_STATUS}", ["source_id=?",
@source_id])
      Source.update(@source_id, { "code" => DEFAULT_STATUS })
    else
      cache['thumbnailing_for_source_'+ at source_id.to_s] =
'-1,'+ at progress.to_s+','+ at total.to_s
    end

    return
  end

  def finish_work
    cache['thumbnailing_for_source_'+ at source_id.to_s] = '-9999,0,0'
    exit
  end
end
---

And the controller :

---
def submit
(some code)
                MiddleMan.new_worker(
                  :worker => :thumbnailer_worker,
                  :worker_key => "thumbnailing_for_source_" +
@source.id.to_s,
                  :data => @source.id)
(some more code)
end

def get_loaded_medias
        begin
          worker_status =
MiddleMan.worker(:thumbnailer_worker).ask_result("thumbnailing_for_source_#{params[:id]}").split(',')
          logger.info("[DEBUG] MiddleMan.ask_result =
#{worker_status.inspect}")
          status = worker_status[0].to_i
          progress = worker_status[1].to_i
          total = worker_status[2].to_i
        rescue Exception => exc
          render :update do |page|
            logger.info("[DEBUG] worker a renvoye une exception: " +
exc.message)
            page.replace_html "thumbnailing_progress", ""
          end
          return
        end
(some more code)
end
---

Hope it will help.

On Thu, Jul 24, 2008 at 2:13 PM, Cédric <akyrho at gmail.com> wrote:

> Thank you Kieran, i tried out your solution, but it did not work for me.
>
> I wonder if my syntax is right, could you copy/paste me a piece of your
> code or explain me how to call worker responses correctly? I still retrieve
> a "nil" answer :(
>
> Thanks
>
> On Thu, Jul 24, 2008 at 12:55 PM, Kieran P <kieran776 at gmail.com> wrote:
>
>> Hello,
>>
>> I had this same issue not more than 3 days ago. hemant responded with a
>> clear and effective solution.
>>
>> See:
>>
>> http://rubyforge.org/pipermail/backgroundrb-devel/2008-July/001911.html
>> and
>> http://rubyforge.org/pipermail/backgroundrb-devel/2008-July/001913.html
>>
>> (scroll down on that last link, the thread went off the ML, but forward at
>> the end)
>>
>> Hope this helps.
>>
>> Regards
>> Kieran
>>
>>
>> On Thu, Jul 24, 2008 at 9:46 PM, Cédric <akyrho at gmail.com> wrote:
>>
>>> Hi there,
>>>
>>> I do not really understand how to use ask_result() method. I've got a
>>> thumbnailing process fully managed with backgroundrb, and i would like to
>>> notify the sender of the progress.
>>>
>>> So, in my worker, i register the current status like this :
>>>
>>> cache['thumbnailing_'+id.to_s] = '0,1,2'
>>>
>>> And in my controller, i have this as a periodical call :
>>>
>>> worker_status =
>>> MiddleMan.worker(:thumbnailer_worker).ask_result(''thumbnailing_' +
>>> params[:id].to_s).split(',')
>>>
>>> I expect the return value as 0, 1 and 2 but it seems that ask_result() is
>>> returning a nil value.
>>>
>>> Thanks per advance.
>>>
>>> --
>>> Bousmanne Cédric
>>>
>>
>
>
> --
> Bousmanne Cédric
>
> Jabber / XMPP : akyrho at gmail.com
> Mail : akyrho at gmail.com
> Blog : http://www.parenthese.be/
>



-- 
Bousmanne Cédric

Jabber / XMPP : akyrho at gmail.com
Mail : akyrho at gmail.com
Blog : http://www.parenthese.be/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://rubyforge.org/pipermail/backgroundrb-devel/attachments/20080724/9060420f/attachment-0001.html>


More information about the Backgroundrb-devel mailing list