[Rails] Re: Database Concurrency Without a Web Server?

Francis Cianfrocca
Thu, 13 Jul 2006 12:18:05 -0000

Don Stocks wrote:
> Francis Cianfrocca wrote:
>> Don, would it help if we added something like this to the
>> EventMachine...
>>
>> You know how Python''s Twisted has something called a
"deferred"?
>> Basically an operation you kick off and you supply a callback that gets
>
> Guys, a huge "Thank You" for all the help!
>
> Francis, if I understand everything correctly, I think that would do the
> trick!  The db client blocking certainly explains why 100 monitors per
> minute runs like clockwork but 2000 introduces a bunch of delays.
>
> Right now, the only call to the db that I make within EventMachine is to
> save the record.
>
> Here is how it looks:
>
>   EventMachine.add_timer(delay){job.run; job.save}
>
> With the exception of job.save(), all other db activity happens before I
> add the job to EventMachine.  And I don''t think there is any
blocking
> code in job.run.  It simply executes my network connectivity code and
> sets the Job object''s attributes based on the results.
>
> As far as instantiating a bunch of objects, I think that''s working
just
> fine.  I can instantiate 1000 Job objects and add them to EventMachine
> in less than a second.  So I''m very happy there.
>
> If I could get job.save to execute in a thread pool I think I''ll
be
> cooking with gas.  And looking forward, I can think of several instances
> where I may need to leverage blocking code.  For example, I''m
planning
> on writing historical results to RRD (a Round Robin Database) which I
> believe requires file system access. Having the thread pool available
> when needed would be great.
>
> Thanks again for all the help guys.  You''re awesome!  This
beginner
> would be lost without you.
>
>  - Don


Ok, I implemented it. I''ll send you a new EventMachine gem to your
private email, and if it works for you, I''ll cut a new public release
(will be version 0.6.0).

In your particular case you have no code that has to process the result
of job.save, so your callback can be empty. Your new code would look
like this:

EventMachine.add_timer(delay){
    job.run
    EventMachine.defer proc {job.save}
}

If you had had a callback you wanted to execute after job.save
completes, you would have added it as a second proc argument to the
#defer call.