views:

366

answers:

1

I'm using DRb within a Rails application to offload an expensive task outside the Rails process. Before initializing the client stub with DRbObject.new it is necessary to initialize the DRb service with DRb.start_service.

Doing this in model or controller appears to leave threads in an uncertain state. When I exit mongrel it says:

Reaping 1 threads for slow workers because of 'shutdown' Waiting for 1 requests to finish, could take 60 seconds.

Initializing the service in environment.rb seems to work fine with a big caveat: I'm also using backgroundrb with some rails workers. When they initialize they run environment.rb and again lead to issues due to double-initialization.

Where is the correct place to call DRb.start_service in the client? Or, is there a way to test for initialization so I can avoid doing it twice for the same process?

+2  A: 

The following code will check if a primary server is already active to avoid double initialization. The mongrel hang on exit can be avoided by moving the DRb thread to a ThreadGroup different from the one mongrel is using.

    # start DRb service if it hasn't been started before
    begin
        DRb.current_server
    rescue DRb::DRbServerNotFound
        DRb.start_service
        # move to different ThreadGroup to avoid mongrel hang on exit
        ThreadGroup.new.add DRb.thread
    end

Running this before the class is used (rather than in environment.rb) yielded the best results and seems to work fine with backgroundrb.

Max Caceres