def test_periodic_callback(self): period = 0.1 factor = 10 counter = self.counter() timer = CoilThreadingTimer() timer.schedule(period, counter) with timer: time.sleep(period * factor) self.assertAlmostEqual(counter.n_called, factor, delta=factor * 0.5, msg='Should provide 50% accuracy')
class STOMP11(STOMP10): SUPPORTED_VERSIONS = {"1.0", "1.1"} def __init__(self, engine, send_heartbeat_interval=100, receive_heartbeat_interval=100, *args, **kwargs): super(STOMP11, self).__init__(engine) self.last_hb = datetime.datetime.now() self.last_hb_sent = datetime.datetime.now() self.timer = CoilThreadingTimer() # flags to control heartbeating self.send_hb = self.receive_hb = False self.send_heartbeat_interval = datetime.timedelta(milliseconds=send_heartbeat_interval) self.receive_heartbeat_interval = datetime.timedelta(milliseconds=receive_heartbeat_interval) def enable_heartbeat(self, cx, cy, response): if self.send_heartbeat_interval and cy: self.send_heartbeat_interval = max(self.send_heartbeat_interval, datetime.timedelta(milliseconds=cy)) self.timer.schedule( max(self.send_heartbeat_interval, datetime.timedelta(milliseconds=cy)).total_seconds(), self.send_heartbeat, ) if self.receive_heartbeat_interval and cx: self.timer.schedule( max(self.send_heartbeat_interval, datetime.timedelta(milliseconds=cx)).total_seconds(), self.receive_heartbeat, ) self.timer.start() response.headers["heart-beat"] = "{0},{1}".format( int(self.send_heartbeat_interval.microseconds / 1000), int(self.receive_heartbeat_interval.microseconds / 1000), ) def disable_heartbeat(self): self.timer.stop() def send_heartbeat(self): # screw it, just send an error frame self.engine.connection.send_frame(ErrorFrame("heartbeat")) def receive_heartbeat(self): ago = datetime.datetime.now() - self.last_hb if ago > self.receive_heartbeat_interval: self.engine.log.debug("No heartbeat was received for {0} seconds".format(ago.total_seconds())) self.engine.unbind() def connect(self, frame, response=None): connected_frame = Frame(frames.CONNECTED) self._negotiate_protocol(frame, connected_frame) heart_beat = frame.headers.get("heart-beat", "0,0") if heart_beat: self.enable_heartbeat(*map(int, heart_beat.split(",")), response=connected_frame) super(STOMP11, self).connect(frame, response=connected_frame) def nack(self, frame): """ Handles the NACK command: Unacknowledges receipt of a message. For now, this is just a placeholder to implement this version of the protocol """ if not frame.headers.get("message-id"): raise ProtocolError("No message-id specified for NACK command.") if not frame.headers.get("subscription"): raise ProtocolError("No subscription specified for NACK command.") def _negotiate_protocol(self, frame, response): client_versions = frame.headers.get("accept-version") if not client_versions: raise ProtocolError("No version specified") common = set(client_versions.split(",")) & self.SUPPORTED_VERSIONS if not common: versions = ",".join(self.SUPPORTED_VERSIONS) self.engine.connection.send_frame( Frame( frames.ERROR, headers={"version": versions, "content-type": frames.TEXT_PLAIN}, body="Supported protocol versions are {0}".format(versions), ) ) else: response.headers["version"] = max(common) protocol_class = PROTOCOL_MAP[response.headers["version"]] if type(self) is not protocol_class: self.engine.protocol = protocol_class(self.engine) self.engine.protocol.connect(frame, response=response)
class STOMP11(STOMP10): SUPPORTED_VERSIONS = {'1.0', '1.1'} def __init__(self, engine, send_heartbeat_interval=100, receive_heartbeat_interval=100, *args, **kwargs): super(STOMP11, self).__init__(engine) self.last_hb = datetime.datetime.now() self.last_hb_sent = datetime.datetime.now() self.timer = CoilThreadingTimer() # flags to control heartbeating self.send_hb = self.receive_hb = False self.send_heartbeat_interval = datetime.timedelta( milliseconds=send_heartbeat_interval) self.receive_heartbeat_interval = datetime.timedelta( milliseconds=receive_heartbeat_interval) def enable_heartbeat(self, cx, cy, response): if self.send_heartbeat_interval and cy: self.send_heartbeat_interval = max( self.send_heartbeat_interval, datetime.timedelta(milliseconds=cy)) self.timer.schedule( max(self.send_heartbeat_interval, datetime.timedelta(milliseconds=cy)).total_seconds(), self.send_heartbeat) if self.receive_heartbeat_interval and cx: self.timer.schedule( max(self.send_heartbeat_interval, datetime.timedelta(milliseconds=cx)).total_seconds(), self.receive_heartbeat) self.timer.start() response.headers['heart-beat'] = '{0},{1}'.format( int(self.send_heartbeat_interval.microseconds / 1000), int(self.receive_heartbeat_interval.microseconds / 1000)) def disable_heartbeat(self): self.timer.stop() def send_heartbeat(self): # screw it, just send an error frame self.engine.connection.send_frame(ErrorFrame('heartbeat')) def receive_heartbeat(self): ago = datetime.datetime.now() - self.last_hb if ago > self.receive_heartbeat_interval: self.engine.log.debug( "No heartbeat was received for {0} seconds".format( ago.total_seconds())) self.engine.unbind() def connect(self, frame, response=None): connected_frame = Frame(frames.CONNECTED) self._negotiate_protocol(frame, connected_frame) heart_beat = frame.headers.get('heart-beat', '0,0') if heart_beat: self.enable_heartbeat(*map(int, heart_beat.split(',')), response=connected_frame) super(STOMP11, self).connect(frame, response=connected_frame) def nack(self, frame): """ Handles the NACK command: Unacknowledges receipt of a message. For now, this is just a placeholder to implement this version of the protocol """ if not frame.headers.get('message-id'): raise ProtocolError("No message-id specified for NACK command.") if not frame.headers.get('subscription'): raise ProtocolError("No subscription specified for NACK command.") def _negotiate_protocol(self, frame, response): client_versions = frame.headers.get('accept-version') if not client_versions: raise ProtocolError('No version specified') common = set(client_versions.split(',')) & self.SUPPORTED_VERSIONS if not common: versions = ','.join(self.SUPPORTED_VERSIONS) self.engine.connection.send_frame( Frame(frames.ERROR, headers={ 'version': versions, 'content-type': frames.TEXT_PLAIN }, body='Supported protocol versions are {0}'.format( versions))) else: response.headers['version'] = max(common) protocol_class = PROTOCOL_MAP[response.headers['version']] if type(self) is not protocol_class: self.engine.protocol = protocol_class(self.engine) self.engine.protocol.connect(frame, response=response)