[PEAK] Anybody using reactors?
Phillip J. Eby
pje at telecommunity.com
Tue Jan 13 19:54:21 EST 2004
I've just done a partial merge of events.Scheduler and
running.UntwistedReactor. This merge allows the new event-driven "threads"
to use timed events within a reactor-driven program.
In the long term, though, I would like to drop UntwistedReactor altogether,
while refactoring MainLoop to use peak.events, and there are some
transitional issues that would need to be addressed.
Most obvious of these is that if you're using a Twisted reactor, there will
need to be a way to make it continue to run 'iterate()' operations. A
side-effect of this is that the reactor's 'run()' method will never be
called, which means that Twisted startup/shutdown events will not run. Is
anybody relying on those events? Even if you're *not* using a Twisted
reactor, are you relying on the value of 'reactor.running' anywhere? Do
you ever call 'reactor.run()'?
So, the next issue is that the MainLoop will need to stop calling
reactor.run(), and simply perform a scheduler-driven loop instead. As a
consequence, 'reactor.stop()' and 'reactor.crash()' calls will need to be
redirected to the MainLoop. Anybody using these directly? (I can probably
make this backward compatible, but it'd be helpful to know.)
The biggest issue I see at the moment is integrating I/O handling between a
Twisted reactor and 'peak.events'. I don't see an easy way to do this that
wouldn't result in PEAK and Twisted fighting over how much time to run
'select()' for. So, I think there will need to be two 'events.ISelector'
implementations. One, a "native" selector using an events.Thread to run
'select()' operations between timed events, and the other a
"reactor-driven" selector that registers callbacks with a reactor, and
calls 'reactor.iterate(scheduler.time_available())' between timed events.
The latter selector implementation would need to be used whenever one was
depending upon ITwistedReactor. However, this would introduce additional
complexity when configuring such applications, since you'd need to add
something like:
[Component Factories]
peak.events.interfaces.ISelector = events.TwistedSelector
peak.running.interfaces.IBasicReactor = 'peak.running.scheduler.getTwisted'
to your app's .ini file. It would no longer be enough to depend on
ITwistedReactor.
A further issue is that 'IBasicReactor' itself would need to be phased out
in the a4 release cycle. Once PEAK has moved over to the 'peak.events'
model, I don't want to try to continue directly supporting the
reactor-driven paradigm, unless this would cause undue hardship for people
with reactor-driven apps.
However, that last point is only an issue for people who've written
reactor-driven apps based on PEAK's UntwistedReactor, rather than using
Twisted. And in any event, the alpha 3 final release will still include an
UntwistedReactor, it's just that it will be implemented using
'peak.events'. So, it's only in the alpha 4 release cycle that you would
need to migrate from using UntwistedReactor to using 'peak.events' directly.
So... if you're doing event-driven programming in PEAK currently, and have
input or questions on the above issues, please speak up. To reiterate:
Are you directly using reactor.running, reactor.run(), reactor.stop(), or
reactor.crash() in your programs? If yes, you will have issues in alpha 3
if you use Twisted, or alpha 4 if you use only UntwistedReactor. Also, if
you use Twisted, you may have to change your application configuration
somewhat during alpha 3, in order to maintain compatibility. Finally, if
you do not directly use a reactor with PEAK, you should not notice any
changes in either release, since PEAK's internal usage of reactors will be
transparently replaced during the a3 release cycle.
Any questions or problems?
More information about the PEAK
mailing list