[Mongrel] Requests that make calls from XMLRPC::Client tie up Mongrel

Thomas Allen thomas.allen at litsoftinc.com
Wed Nov 18 14:50:37 EST 2009


Thanks for suggesting that the problem may be related to threading. At
least on this Debian box, changing RpcTask.run to the following seems
to do the trick:

def run(task, task_params = {})
  Thread.new {
    server = XMLRPC::Client.new2('http://localhost:9192/')
    server.call(task,task_params)
  }.value
end

Thomas

On Wed, Nov 18, 2009 at 2:13 PM, Thomas Allen
<thomas.allen at litsoftinc.com> wrote:
> Hi Jonathan,
>
> I thought that maybe using 'call_async' rather than simply 'call'
> might improve the situation but the behavior is the same with either
> call.
>
> Thomas Allen
>
> On Wed, Nov 18, 2009 at 12:53 PM, Jonathan Rochkind <rochkind at jhu.edu> wrote:
>> Do the RpcTask task methods end up using ruby threads to do their work?
>> That call_async  method definitely sounds suspiciously like it might.
>>
>> I've found that ruby threads under mongrel (although I don't think it's
>> neccesarily an issue specific to mongrel) sometimes block when you don't
>> think they ought to be, or end up in wait state for long periods when it
>> doesn't seem like they ought to be.
>>
>> When I have actual control over my ruby threads, I've found that explicitly
>> setting the thread priority of 'background' threads to be lower than 0
>> generally frees things up.   If RpcTask is creating threads and you don't
>> want to hack it's code to set thread priorities...  is there a synchronous
>> method you can use instead of call_async to make your rpc?
>>
>> Jonathan
>>
>> Thomas Allen wrote:
>>>
>>> Hi Everyone,
>>>
>>> I'm running a Rails site on Mongrel and I can't figure out why a
>>> particular type of request ties up Mongrel easily. The requests that
>>> tie up Mongrel call an XML-RPC server like so:
>>>
>>> # In the controller
>>> def site_start
>>>  if params[:id]
>>>    @site = Site.find(params[:id])
>>>    @site.site_start
>>>    render :json=>{:success=>true}
>>>  end
>>> end
>>>
>>> # In the model
>>> def site_start
>>>  RpcTask.manage(self, 'start')
>>> end
>>>
>>> # In RpcTask
>>> def manage(site, task)
>>>  run('manage_task', {
>>>    :site => site.name,
>>>    :site_id => site.id,
>>>    :task => task
>>>  })
>>> end
>>>
>>> # which calls
>>> def run(task, task_params = {})
>>>  begin
>>>    server = XMLRPC::Client.new2('http://localhost:9192/')
>>>    result = server.call_async(task,task_params)
>>>    return result
>>>  rescue XMLRPC::FaultException => err
>>>    logger = ActiveRecord::Base.logger
>>>    logger.error(err.faultCode)
>>>    logger.error(err.faultString)
>>>    logger.error(result)
>>>  end
>>>  false
>>> end
>>>
>>> If I call the model method directly from the console, the RPC side
>>> responds very quickly:
>>>
>>>
>>>>>
>>>>> start = Time.now; Site.first.site_start; (Time.now - start).to_s
>>>>>
>>>
>>> => "0.493253"
>>>
>>> Removing the body of RpcTask.run results in comparable performance.
>>> Also, by switching from a single mongrel to a four-mongrel cluster, I
>>> was able to get the these actions to perform acceptably but I imagine
>>> that I'm doing something very wrong here to require so much power. Any
>>> ideas?
>>>
>>> Thanks,
>>> Thomas Allen
>>> _______________________________________________
>>> Mongrel-users mailing list
>>> Mongrel-users at rubyforge.org
>>> http://rubyforge.org/mailman/listinfo/mongrel-users
>>>
>>>
>>
>> _______________________________________________
>> Mongrel-users mailing list
>> Mongrel-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/mongrel-users
>>
>


More information about the Mongrel-users mailing list