def blockWriteSuccess(self, ign, datagram): """The write was successful, respond with ACK for current block number If this is the last chunk (received data length < block size), the protocol will keep running until the end of current timeout period, so we can respond to any duplicates. @type datagram: L{DATADatagram} """ bytes = ACKDatagram(datagram.blocknum).to_wire() if len(datagram.data) < self.block_size: self._clock.callLater(0, self.sendData, bytes) self.timeout_watchdog = SequentialCall.run(self.timeout[:-1], callable=lambda: None, on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=False, _clock=self._clock ) self.completed = True self.writer.finish() # TODO: If self.tsize is not None, compare it with the actual # count of bytes written. Log if there's a mismatch. Should it # also emit an error datagram? else: self.timeout_watchdog = SequentialCall.run(self.timeout[:-1], callable=self.sendData, callable_args=[bytes, ], on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock )
def test_empty_now(self): SequentialCall.run((), self.f, on_timeout=self.t, run_now=True, _clock=self.clock) self.clock.pump((1, )) self.assertEqual(self.f.call_num, 1) self.assertEqual(self.t.call_num, 1)
def test_cancel_immediately(self): c = SequentialCall.run((1, 3, 5), lambda: c.cancel(), run_now=True, on_timeout=self.t, _clock=self.clock) self.clock.pump((1,)*2) self.assertRaises(Cancelled, c.cancel) self.assertEqual(self.t.call_num, 0) self.assertRaises(Cancelled, c.reschedule)
def test_cancel(self): c = SequentialCall.run((1, 3, 5), self.f, on_timeout=self.t, _clock=self.clock) self.clock.pump((1,)*2) self.assertEqual(self.f.call_num, 1) c.cancel() self.assertRaises(Cancelled, c.cancel) self.assertEqual(self.t.call_num, 0) self.assertRaises(Cancelled, c.reschedule)
def test_cancel_immediately(self): c = SequentialCall.run((1, 3, 5), lambda: c.cancel(), run_now=True, on_timeout=self.t, _clock=self.clock) self.clock.pump((1, ) * 2) self.assertRaises(Cancelled, c.cancel) self.assertEqual(self.t.call_num, 0) self.assertRaises(Cancelled, c.reschedule)
def test_cancel(self): c = SequentialCall.run((1, 3, 5), self.f, on_timeout=self.t, _clock=self.clock) self.clock.pump((1, ) * 2) self.assertEqual(self.f.call_num, 1) c.cancel() self.assertRaises(Cancelled, c.cancel) self.assertEqual(self.t.call_num, 0) self.assertRaises(Cancelled, c.reschedule)
def dataFromReader(self, data): """Got data from the reader. Send it to the network and start the timeout cycle. """ if len(data) < self.block_size: self.completed = True bytes = DATADatagram(self.blocknum, data).to_wire() self.timeout_watchdog = SequentialCall.run(self.timeout[:-1], callable=self.sendData, callable_args=[bytes, ], on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock )
def blockWriteSuccess(self, ign, datagram): """The write was successful, respond with ACK for current block number If this is the last chunk (received data length < block size), the protocol will keep running until the end of current timeout period, so we can respond to any duplicates. @type datagram: L{DATADatagram} """ bytes = ACKDatagram(datagram.blocknum).to_wire() if len(datagram.data) < self.block_size: self._clock.callLater(0, self.sendData, bytes) self.timeout_watchdog = SequentialCall.run( self.timeout[:-1], callable=lambda: None, on_timeout=lambda: self._clock.callLater( self.timeout[-1], self.timedOut), run_now=False, _clock=self._clock) self.completed = True self.writer.finish() # TODO: If self.tsize is not None, compare it with the actual # count of bytes written. Log if there's a mismatch. Should it # also emit an error datagram? else: self.timeout_watchdog = SequentialCall.run( self.timeout[:-1], callable=self.sendData, callable_args=[ bytes, ], on_timeout=lambda: self._clock.callLater( self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock)
def test_non_empty(self): c = SequentialCall.run((1, 3, 5), self.f, run_now=True, on_timeout=self.t, _clock=self.clock) self.clock.advance(0.1) self.failUnless(c.active()) self.assertEqual(self.f.call_num, 1) self.clock.pump((1,)*2) self.failUnless(c.active()) self.assertEqual(self.f.call_num, 2) self.clock.pump((1,)*3) self.failUnless(c.active()) self.assertEqual(self.f.call_num, 3) self.clock.pump((1,)*5) self.failIf(c.active()) self.assertEqual(self.f.call_num, 4) self.assertEqual(self.t.call_num, 1) self.assertRaises(Spent, c.reschedule) self.assertRaises(Spent, c.cancel)
def dataFromReader(self, data): """Got data from the reader. Send it to the network and start the timeout cycle. """ # reached maximum number of blocks. Rolling over if self.blocknum == 65536: self.blocknum = 0 if len(data) < self.block_size: self.completed = True bytes = DATADatagram(self.blocknum, data).to_wire() self.timeout_watchdog = SequentialCall.run(self.timeout[:-1], callable=self.sendData, callable_args=[bytes, ], on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock )
def startProtocol(self): """Connect the transport, respond with an initial ACK or OACK (depending on if we were initialized with options or not). """ self.transport.connect(*self.remote) if self.options: self.resultant_options = self.processOptions(self.options) bytes = OACKDatagram(self.resultant_options).to_wire() else: bytes = ACKDatagram(0).to_wire() self.timeout_watchdog = SequentialCall.run( self.timeout[:-1], callable=self.transport.write, callable_args=[bytes, ], on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock )
def blockWriteSuccess(self, ign, datagram): """The write was successful, respond with ACK for current block number If this is the last chunk (received data length < block size), the protocol will keep running until the end of current timeout period, so we can respond to any duplicates. @type datagram: L{DATADatagram} """ bytes = ACKDatagram(datagram.blocknum).to_wire() self.timeout_watchdog = SequentialCall.run(self.timeout[:-1], callable=self.sendData, callable_args=[bytes, ], on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock ) if len(datagram.data) < self.block_size: self.completed = True self.writer.finish()
def startProtocol(self): """Start sending an OACK datagram if we were initialized with options or start the L{ReadSession} immediately. """ self.transport.connect(*self.remote) if self.options: self.resultant_options = self.processOptions(self.options) bytes = OACKDatagram(self.resultant_options).to_wire() self.timeout_watchdog = SequentialCall.run( self.timeout[:-1], callable=self.transport.write, callable_args=[bytes, ], on_timeout=lambda: self._clock.callLater(self.timeout[-1], self.timedOut), run_now=True, _clock=self._clock ) else: self.session.transport = self.transport self.session.startProtocol() return self.session.nextBlock()
def test_non_empty(self): c = SequentialCall.run((1, 3, 5), self.f, run_now=True, on_timeout=self.t, _clock=self.clock) self.clock.advance(0.1) self.assertTrue(c.active()) self.assertEqual(self.f.call_num, 1) self.clock.pump((1, ) * 2) self.assertTrue(c.active()) self.assertEqual(self.f.call_num, 2) self.clock.pump((1, ) * 3) self.assertTrue(c.active()) self.assertEqual(self.f.call_num, 3) self.clock.pump((1, ) * 5) self.assertFalse(c.active()) self.assertEqual(self.f.call_num, 4) self.assertEqual(self.t.call_num, 1) self.assertRaises(Spent, c.reschedule) self.assertRaises(Spent, c.cancel)
def test_empty_now(self): SequentialCall.run((), self.f, on_timeout=self.t, run_now=True, _clock=self.clock) self.clock.pump((1,)) self.assertEqual(self.f.call_num, 1) self.assertEqual(self.t.call_num, 1)