diff options
| author | Sergey Shepelev <temotor@gmail.com> | 2013-10-09 22:30:22 +0400 |
|---|---|---|
| committer | Sergey Shepelev <temotor@gmail.com> | 2013-12-03 22:30:02 +0400 |
| commit | 76c1fcf3e5587db5c831bd825c2ba4bdf46a28c7 (patch) | |
| tree | 5c7182d54f4f059f046f0150448c5971dd63f83e | |
| parent | be8ddd5a893655f8d898b952cdb342af04e827c9 (diff) | |
| download | eventlet-76c1fcf3e5587db5c831bd825c2ba4bdf46a28c7.tar.gz | |
coros: remove Actor which was deprecated in 2010-01
| -rw-r--r-- | eventlet/coros.py | 94 | ||||
| -rw-r--r-- | tests/coros_test.py | 128 |
2 files changed, 0 insertions, 222 deletions
diff --git a/eventlet/coros.py b/eventlet/coros.py index 5d3d82e..37205e3 100644 --- a/eventlet/coros.py +++ b/eventlet/coros.py @@ -305,97 +305,3 @@ def queue(max_size=None): 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() diff --git a/tests/coros_test.py b/tests/coros_test.py deleted file mode 100644 index eb6bca9..0000000 --- a/tests/coros_test.py +++ /dev/null @@ -1,128 +0,0 @@ -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() |
