Hi,
self.pause() in generator components has the follow effects:
* It schedules a request with the schedule to pause the generator. cf:
self.scheduler.pauseThread(self)
This actually adds a pauseRequest for the microprocess on a threadsafe
queue. That queue is periodically processed, and the microprocesse is marked
as "_GOINGTOSLEEP". This precludes it being added to the run queue (ie being
given a timeslice).
In practice it gets unpaused by a callback in Component & Box resulting in an
unpause request undoing this.
The upshot is that pause() tells the scheduler "please don't call me again
unless there's a new message in an inbox OR a message is taken from an
outbox".
For threaded components it means the same thing. However, since a threaded
component can genuinely sleep, if it doesn't ever bother checking its inboxes
for messages, it will sleep for ever. As a result, for threaded components,
it adds an optional timeout argument to say "sleep for this long". Whilst
this was added for practicality reasons, it does mean that self.pause() has a
different meaning for generator components from threaded ones.
Now there's two ways that self.pause(timeout=delay) could gain the same
meaning for generator components. One is to change the scheduler to become
time aware. The other is for it to wrap up a call to "PausingService" that
will awaken you after a minimum of delay has passed.
Personally I prefer the latter, but this raises two issues:
* By changing the scheduler we change Axon/Kamaelia in a more fundamental
way. Not necessarily the correct way. Certainly in a way that makes it
harder to hack on and modify.
* The latter approach would mean that we're either using a component
*inside Axon* itself. This goes against Axon's spirit to an extent, but
is the simpler, and probably more robust solution.
I would also suggest that the return value of self.pause() be something that
is yieldable.
For a practical, real world usecase where this would be useful, it would allow
this:
while not self.safeConnect(sock,(self.host, self.port)):
if self.shutdown():
return
if ( time.time() - startConnect ) > self.connect_timeout:
self.howDied = "timeout"
raise Finality
yield 1
To become this:
while not self.safeConnect(sock,(self.host, self.port)):
if self.shutdown():
return
if ( time.time() - startConnect ) > self.connect_timeout:
self.howDied = "timeout"
raise Finality
# Retry in a millisecond. Release CPU.
yield self.pause(timeout=0.001)
This would release the CPU significantly for this particular usecase. It would
also be useful in other components, but this one is topical :)
Michael.
--
http://yeoldeclue.com/blog
http://twitter.com/kamaelian
http://www.kamaelia.org/Home
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"kamaelia" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/kamaelia?hl=en
-~----------~----~----~----~------~----~------~--~---