Drb::Unknown Problem with backgroundrb
What’s this about ?
Backgroundrb is a nice framework that allows you to run long-running tasks in the background, in another process. It’s not only for Rails, but it’s quite useful there.
The Trac homepage of the project
The Rdoc on Rubyforge
Get to the point already !
Alright. A problem that can be encountered is that you start a new worker with something like:
MiddleMan.new_worker(:class => :infinite_monkeys_class, :job_key => :feeding_time, :args => CollectionOfBananaClassObjects)
And then you get an Exception with a message like “No such method for Drb::Unknown” blabla.
The trick is that somehow backgroundrb can’t transfer non-trivial objects between the processes (Rails on one side, your monkey worker on the other side) without badly mangling them.
The solution (more of a workaround): Serialize the offending arguments and pass the arguments as the serialized String:
</code> bananas = Marshall.dump(CollectionOfBananaClassObjects)
Then use the bananas String as the argument for the worker. Inside your worker, you need to deserialize:
</code> banana_objects = Marshall.load(args)
There’s a pitfall here: You need to explicitly “require” all the files that contain the classes you want to deserialize.
Monkey example aside, I use this in my project, where I pass around large collections of ActiveRecord subclasses to workers:
Dir.glob("#{RAILS_ROOT}/app/models/*.rb") { |file_name| require file_name }
class ImportController < ApplicationController
And BTW, this problem occurs whenever you want to transfer stuff between the Rails and worker processes, so when you use the results worker, for example, you need to serialize/unserialize the results, too.
Inside the monkey worker:
results[:shakespeare] = Marshal.dump(@generated_writings)
Drb::Unknown Problem with backgroundrb
What’s this about ?
Backgroundrb is a nice framework that allows you to run long-running tasks in the background, in another process. It’s not only for Rails, but it’s quite useful there.
The Trac homepage of the project
The Rdoc on Rubyforge
Get to the point already !
Alright. A problem that can be encountered is that you start a new worker with something like:
MiddleMan.new_worker(:class => :infinite_monkeys_class, :job_key => :feeding_time, :args => CollectionOfBananaClassObjects)
And then you get an Exception with a message like “No such method for Drb::Unknown” blabla.
The trick is that somehow backgroundrb can’t transfer non-trivial objects between the processes (Rails on one side, your monkey worker on the other side) without badly mangling them.
The solution (more of a workaround): Serialize the offending arguments and pass the arguments as the serialized String:
</code> bananas = Marshall.dump(CollectionOfBananaClassObjects)
Then use the bananas String as the argument for the worker. Inside your worker, you need to deserialize:
</code> banana_objects = Marshall.load(args)
There’s a pitfall here: You need to explicitly “require” all the files that contain the classes you want to deserialize.
Monkey example aside, I use this in my project, where I pass around large collections of ActiveRecord subclasses to workers:
Dir.glob("#{RAILS_ROOT}/app/models/*.rb") { |file_name| require file_name }
class ImportController < ApplicationController
And BTW, this problem occurs whenever you want to transfer stuff between the Rails and worker processes, so when you use the results worker, for example, you need to serialize/unserialize the results, too.
Inside the monkey worker:
results[:shakespeare] = Marshal.dump(@generated_writings)