Ticket #6290: TimerService.stopService.patch

File TimerService.stopService.patch, 3.3 KB (added by Tom Prince, 7 years ago)
  • twisted/application/internet.py

    diff --git twisted/application/internet.py twisted/application/internet.py
    index a30f418..0c8ce49 100644
    class TimerService(_VolatileDataService): 
    226226    when it stops.
    227227    """
    228228
    229     volatile = ['_loop']
     229    volatile = ['_loop', '_loopFinshed']
    230230
    231231    def __init__(self, step, callable, *args, **kwargs):
    232232        self.step = step
    233233        self.call = (callable, args, kwargs)
     234        self.clock = None
    234235
    235236    def startService(self):
    236237        service.Service.startService(self)
    class TimerService(_VolatileDataService): 
    240241        # LoopingCall were a _VolatileDataService, we wouldn't need to do
    241242        # this.
    242243        self._loop = task.LoopingCall(callable, *args, **kwargs)
    243         self._loop.start(self.step, now=True).addErrback(self._failed)
     244        self._loop.clock = _maybeGlobalReactor(self.clock)
     245        self._loopFinished = self._loop.start(self.step, now=True)
     246        self._loopFinished.addErrback(self._failed)
    244247
    245248    def _failed(self, why):
    246249        # make a note that the LoopingCall is no longer looping, so we don't
    class TimerService(_VolatileDataService): 
    252255    def stopService(self):
    253256        if self._loop.running:
    254257            self._loop.stop()
    255         return service.Service.stopService(self)
     258        self._loopFinished.addCallback(lambda _:
     259                service.Service.stopService(self))
     260        return self._loopFinished
    256261
    257262
    258263
  • twisted/application/test/test_internet.py

    diff --git twisted/application/test/test_internet.py twisted/application/test/test_internet.py
    index 9e058d7..afcdbcf 100644
    from zope.interface.verify import verifyClass 
    1111
    1212from twisted.internet.protocol import Factory
    1313from twisted.trial.unittest import TestCase
    14 from twisted.application.internet import StreamServerEndpointService
     14from twisted.application.internet import StreamServerEndpointService, TimerService
    1515from twisted.internet.interfaces import IStreamServerEndpoint, IListeningPort
    1616from twisted.internet.defer import Deferred, CancelledError
     17from twisted.internet.task import Clock
    1718
    1819class FakeServer(object):
    1920    """
    class TestEndpointService(TestCase): 
    250251        self.assertEqual(len(stoppingErrors), 1)
    251252
    252253
     254
     255class TestTimerService(TestCase):
     256    """
     257    Tests for L{twisted.application.internet.TimerService}.
     258
     259    @ivar timer: service to test
     260    @type timer: L{TimerService}
     261
     262    @ivar clock: source of time
     263    @type clock: L{Clock}
     264
     265    @ivar deferred: deferred returned by L{TestTimerService.call}.
     266    @type deferred: L{Deferred}
     267    """
     268
     269
     270    def setUp(self):
     271        self.timer = TimerService(2, self.call)
     272        self.clock = self.timer.clock = Clock()
     273        self.deferred = Deferred()
     274
     275
     276    def call(self):
     277        return self.deferred
     278
     279
     280    def test_stopServiceWaits(self):
     281        """
     282        When L{TimerService.stopService} is called while a call is in progress.
     283        the L{Deferred} returned doesn't fire until after the call finishes.
     284        """
     285        self.timer.startService()
     286        self.clock.advance(0)
     287        d = self.timer.stopService()
     288        self.assertNoResult(d)
     289        self.deferred.callback(object())
     290        self.assertIs(self.successResultOf(d), None)