Commits

Sergey Shepelev committed 14ce9af

coros: remove Actor which was deprecated in 2010-01

Comments (0)

Files changed (2)

eventlet/coros.py

         return Queue()
     else:
         return Channel(max_size)
-
-
-class Actor(object):
-    """ A free-running coroutine that accepts and processes messages.
-
-    Kind of the equivalent of an Erlang process, really.  It processes
-    a queue of messages in the order that they were sent.  You must
-    subclass this and implement your own version of :meth:`received`.
-
-    The actor's reference count will never drop to zero while the
-    coroutine exists; if you lose all references to the actor object
-    it will never be freed.
-    """
-    def __init__(self, concurrency = 1):
-        """ Constructs an Actor, kicking off a new coroutine to process the messages.
-
-        The concurrency argument specifies how many messages the actor will try
-        to process concurrently.  If it is 1, the actor will process messages
-        serially.
-        """
-        warnings.warn("We're phasing out the Actor class, so as to get rid of"
-                   "the coros module.  If you use Actor, please speak up on "
-                   "eventletdev@lists.secondlife.com, and we'll come up with a "
-                   "transition plan.  If no one speaks up, we'll remove Actor "
-                   "in a future release of Eventlet.",
-                   DeprecationWarning, stacklevel=2)
-
-        self._mailbox = collections.deque()
-        self._event = _event.Event()
-        self._killer = eventlet.spawn(self.run_forever)
-        from eventlet import greenpool
-        self._pool = greenpool.GreenPool(concurrency)
-
-    def run_forever(self):
-        """ Loops forever, continually checking the mailbox. """
-        while True:
-            if not self._mailbox:
-                self._event.wait()
-                self._event = _event.Event()
-            else:
-                # leave the message in the mailbox until after it's
-                # been processed so the event doesn't get triggered
-                # while in the received method
-                self._pool.spawn_n(
-                    self.received, self._mailbox[0])
-                self._mailbox.popleft()
-
-    def cast(self, message):
-        """ Send a message to the actor.
-
-        If the actor is busy, the message will be enqueued for later
-        consumption.  There is no return value.
-
-        >>> a = Actor()
-        >>> a.received = lambda msg: msg
-        >>> a.cast("hello")
-        """
-        self._mailbox.append(message)
-        # if this is the only message, the coro could be waiting
-        if len(self._mailbox) == 1:
-            self._event.send()
-
-    def received(self, message):
-        """ Called to process each incoming message.
-
-        The default implementation just raises an exception, so
-        replace it with something useful!
-
-        >>> class Greeter(Actor):
-        ...     def received(self, (message, evt) ):
-        ...         print "received", message
-        ...         if evt: evt.send()
-        ...
-        >>> a = Greeter()
-
-        This example uses Events to synchronize between the actor and the main
-        coroutine in a predictable manner, but this kinda defeats the point of
-        the :class:`Actor`, so don't do it in a real application.
-
-        >>> from eventlet.event import Event
-        >>> evt = Event()
-        >>> a.cast( ("message 1", evt) )
-        >>> evt.wait()  # force it to run at this exact moment
-        received message 1
-        >>> evt.reset()
-        >>> a.cast( ("message 2", None) )
-        >>> a.cast( ("message 3", evt) )
-        >>> evt.wait()
-        received message 2
-        received message 3
-
-        >>> eventlet.kill(a._killer)   # test cleanup
-        """
-        raise NotImplementedError()

tests/coros_test.py

-from unittest import main
-from tests import LimitedTestCase, silence_warnings
-import eventlet
-from eventlet import coros
-from eventlet import event
-from eventlet import greenthread
-
-class IncrActor(coros.Actor):
-    def received(self, evt):
-        self.value = getattr(self, 'value', 0) + 1
-        if evt: evt.send()
-
-
-class TestActor(LimitedTestCase):
-    mode = 'static'
-
-    @silence_warnings
-    def setUp(self):
-        super(TestActor, self).setUp()
-        self.actor = IncrActor()
-
-    def tearDown(self):
-        super(TestActor, self).tearDown()
-        greenthread.kill(self.actor._killer)
-
-    def test_cast(self):
-        evt = event.Event()
-        self.actor.cast(evt)
-        evt.wait()
-        evt.reset()
-        self.assertEqual(self.actor.value, 1)
-        self.actor.cast(evt)
-        evt.wait()
-        self.assertEqual(self.actor.value, 2)
-
-    def test_cast_multi_1(self):
-        # make sure that both messages make it in there
-        evt = event.Event()
-        evt1 = event.Event()
-        self.actor.cast(evt)
-        self.actor.cast(evt1)
-        evt.wait()
-        evt1.wait()
-        self.assertEqual(self.actor.value, 2)
-
-    def test_cast_multi_2(self):
-        # the actor goes through a slightly different code path if it
-        # is forced to enter its event loop prior to any cast()s
-        eventlet.sleep(0)
-        self.test_cast_multi_1()
-
-    def test_sleeping_during_received(self):
-        # ensure that even if the received method cooperatively
-        # yields, eventually all messages are delivered
-        msgs = []
-        waiters = []
-        def received( (message, evt) ):
-            eventlet.sleep(0)
-            msgs.append(message)
-            evt.send()
-        self.actor.received = received
-
-        waiters.append(event.Event())
-        self.actor.cast( (1, waiters[-1]))
-        eventlet.sleep(0)
-        waiters.append(event.Event())
-        self.actor.cast( (2, waiters[-1]) )
-        waiters.append(event.Event())
-        self.actor.cast( (3, waiters[-1]) )
-        eventlet.sleep(0)
-        waiters.append(event.Event())
-        self.actor.cast( (4, waiters[-1]) )
-        waiters.append(event.Event())
-        self.actor.cast( (5, waiters[-1]) )
-        for evt in waiters:
-            evt.wait()
-        self.assertEqual(msgs, [1,2,3,4,5])
-
-    def test_raising_received(self):
-        msgs = []
-        def received( (message, evt) ):
-            evt.send()
-            if message == 'fail':
-                raise RuntimeError()
-            else:
-                msgs.append(message)
-
-        self.actor.received = received
-
-        evt = event.Event()
-        self.actor.cast( ('fail', evt) )
-        evt.wait()
-        evt.reset()
-        self.actor.cast( ('should_appear', evt) )
-        evt.wait()
-        self.assertEqual(['should_appear'], msgs)
-
-    @silence_warnings
-    def test_multiple(self):
-        self.actor = IncrActor(concurrency=2)
-        total = [0]
-        def received( (func, ev, value) ):
-            func()
-            total[0] += value
-            ev.send()
-        self.actor.received = received
-
-        def onemoment():
-            eventlet.sleep(0.1)
-
-        evt = event.Event()
-        evt1 = event.Event()
-
-        self.actor.cast( (onemoment, evt, 1) )
-        self.actor.cast( (lambda: None, evt1, 2) )
-
-        evt1.wait()
-        self.assertEqual(total[0], 2)
-        eventlet.sleep(0)
-        self.assertEqual(self.actor._pool.free(), 1)
-        evt.wait()
-        self.assertEqual(total[0], 3)
-        eventlet.sleep(0)
-        self.assertEqual(self.actor._pool.free(), 2)
-
-
-if __name__ == '__main__':
-    main()