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 kamaelia@googlegroups.com
To unsubscribe from this group, send email to 
kamaelia+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/kamaelia?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to