[Twisted-Python] Multiple main loops

David Pratt fairwinds at eastlink.ca
Tue May 2 11:00:53 EDT 2006


Hi. I am hoping you can clarify for me whether it is possible to run 
multiple independent main loops in Twisted. It is my understanding that 
this would mean separate independent reactors.

Googling, I found this patch but after looking into the repository, it 
was never committed. I would appreciate any comments on the patch or 
attempts people have made on the integration of a second twisted loop.

At the present time I am using twisted with wxpython with wxpython as 
main loop and also running a selectreactor instance. Here there are two 
separate loops, interoperating and operating independently, however they 
are not both twisted loops.

Zope currently runs using a reactor instance for each zope instance but 
I would like to consider a separate independent loop for each client to 
synchronize to a server without paying a penalty. Zope's ZEO (basically 
a synchronization server) currently uses a simple zrpc protocol and runs 
independently but interoperates with a separate ansyncore main loop. The 
current system works well for the exception that it would be great to 
simplify this as well as improve security using twisted's built in 
capabilities. Many thanks.


Regards
David


Index: twisted/internet/default.py
===================================================================
RCS file: /cvs/Twisted/twisted/internet/default.py,v
retrieving revision 1.79
diff -u -r1.79 default.py
--- twisted/internet/default.py    10 May 2003 12:52:37 -0000    1.79
+++ twisted/internet/default.py    11 May 2003 23:11:26 -0000
@@ -367,8 +367,6 @@


  # global state for selector
-reads = {}
-writes = {}


  def win32select(r, w, e, timeout=None):
@@ -403,13 +401,18 @@

      __implements__ = (PosixReactorBase.__implements__, IReactorFDSet)

+    def __init__(self):
+        PosixReactorBase.__init__(self)
+        self.reads = {}
+        self.writes = {}
+
      def _preenDescriptors(self):
          log.msg("Malformed file descriptor found.  Preening lists.")
-        readers = reads.keys()
-        writers = writes.keys()
-        reads.clear()
-        writes.clear()
-        for selDict, selList in ((reads, readers), (writes, writers)):
+        readers = self.reads.keys()
+        writers = self.writes.keys()
+        self.reads.clear()
+        self.writes.clear()
+        for selDict, selList in ((self.reads, readers), (self.writes, 
writers)):
              for selectable in selList:
                  try:
                      select.select([selectable], [selectable], 
[selectable], 0)
@@ -419,19 +422,19 @@
                      selDict[selectable] = 1


-    def doSelect(self, timeout,
-                 # Since this loop should really be as fast as possible,
-                 # I'm caching these global attributes so the interpreter
-                 # will hit them in the local namespace.
-                 reads=reads,
-                 writes=writes,
-                 rhk=reads.has_key,
-                 whk=writes.has_key):
+    def doSelect(self, timeout):
          """Run one iteration of the I/O monitor loop.

          This will run all selectables who had input or output readiness
          waiting for them.
          """
+        # Since this loop should really be as fast as possible,
+        # I'm caching these global attributes so the interpreter
+        # will hit them in the local namespace.
+        reads=self.reads
+        writes=self.writes
+        rhk=reads.has_key
+        whk=writes.has_key
          while 1:
              try:
                  r, w, ignored = _select(reads.keys(),
@@ -502,33 +505,33 @@
      def addReader(self, reader):
          """Add a FileDescriptor for notification of data available to 
read.
          """
-        reads[reader] = 1
+        self.reads[reader] = 1

      def addWriter(self, writer):
          """Add a FileDescriptor for notification of data available to 
write.
          """
-        writes[writer] = 1
+        self.writes[writer] = 1

      def removeReader(self, reader):
          """Remove a Selectable for notification of data available to read.
          """
-        if reads.has_key(reader):
-            del reads[reader]
+        if self.reads.has_key(reader):
+            del self.reads[reader]

      def removeWriter(self, writer):
          """Remove a Selectable for notification of data available to 
write.
          """
-        if writes.has_key(writer):
-            del writes[writer]
+        if self.writes.has_key(writer):
+            del self.writes[writer]

      def removeAll(self):
          """Remove all readers and writers, and return list of 
Selectables."""
-        readers = reads.keys()
+        readers = self.reads.keys()
          for reader in readers:
-            if reads.has_key(reader):
-                del reads[reader]
-            if writes.has_key(reader):
-                del writes[reader]
+            if self.reads.has_key(reader):
+                del self.reads[reader]
+            if self.writes.has_key(reader):
+                del self.writes[reader]
          return readers




More information about the Twisted-Python mailing list