def sub(loop): nc = NATS() options = { "io_loop": loop, "closed_cb": closed_cb, "reconnected_cb": reconnected_cb, "servers": NATS_URL } yield from nc.connect(**options) print("Connected to NATS at {}...".format(nc.connected_url.netloc)) def signal_handler(): if nc.is_closed: return print("Disconnecting...") loop.create_task(nc.close()) for sig in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, sig), signal_handler) async def help_request(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data))
def run(loop): nc = NATS() options = { "servers": ["nats://*****:*****@nats-01.cryptoquote.io:4222"], "io_loop": loop, } yield from nc.connect(**options) @asyncio.coroutine def message_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) # "*" matches any token, at any level of the subject. # list to all markets on binance yield from nc.subscribe("hose.*.binance.>", cb=message_handler) # full hose # yield from nc.subscribe("hose.>", cb=message_handler) # listen to BTCUSD system wide yield from nc.subscribe("hose.*.*.btcusd", cb=message_handler)
def test_empty_info_op_uses_defaults(self): @asyncio.coroutine def bad_server(reader, writer): writer.write(b'INFO {}\r\n') yield from writer.drain() data = yield from reader.readline() yield from asyncio.sleep(0.2, loop=self.loop) writer.close() yield from asyncio.start_server(bad_server, '127.0.0.1', 4555, loop=self.loop) disconnected_count = 0 @asyncio.coroutine def disconnected_cb(): nonlocal disconnected_count disconnected_count += 1 nc = NATS() options = { 'servers': [ "nats://127.0.0.1:4555", ], 'disconnected_cb': disconnected_cb, 'io_loop': self.loop } yield from nc.connect(**options) self.assertEqual(nc.max_payload, 1048576) yield from nc.close() self.assertEqual(1, disconnected_count)
def go(loop): nc = NATS() try: yield from nc.connect(io_loop=loop) except: pass @asyncio.coroutine def message_handler(msg): print("[Received on '{}']: {}".format(msg.subject, msg.data.decode())) try: # Interested in receiving 2 messages from the 'discover' subject. sid = yield from nc.subscribe("discover", "", message_handler) yield from nc.auto_unsubscribe(sid, 2) yield from nc.publish("discover", b'hello') yield from nc.publish("discover", b'world') # Following 2 messages won't be received. yield from nc.publish("discover", b'again') yield from nc.publish("discover", b'!!!!!') except ErrConnectionClosed: print("Connection closed prematurely") @asyncio.coroutine def request_handler(msg): print("[Request on '{} {}']: {}".format(msg.subject, msg.reply, msg.data.decode())) yield from nc.publish(msg.reply, b'OK') if nc.is_connected: # Subscription using a 'workers' queue so that only a single subscriber # gets a request at a time. yield from nc.subscribe("help", "workers", cb=request_handler) try: # Make a request expecting a single response within 500 ms, # otherwise raising a timeout error. msg = yield from nc.timed_request("help", b'help please', 0.500) print("[Response]: {}".format(msg.data)) # Make a roundtrip to the server to ensure messages # that sent messages have been processed already. yield from nc.flush(0.500) except ErrTimeout: print("[Error] Timeout!") # Wait a bit for message to be dispatched... yield from asyncio.sleep(1, loop=loop) # Detach from the server. yield from nc.close() if nc.last_error is not None: print("Last Error: {}".format(nc.last_error)) if nc.is_closed: print("Disconnected.")
def pipeline_p4(loop): ##################### # Connection to NATS ##################### nc = NATS() yield from nc.connect("localhost:4222", loop=loop) ##################### # Message Handlers ##################### async def mh_s1(msg): correlation_id = str(uuid.uuid4()) log('info', 'p4', 's0', 'S1 initiated', correlation_id) jrequest = json.loads(msg.data.decode()) # Inject a correlation id into the message to enable analysis across pipeline stages jresponse = {} jresponse['correlation_id'] = correlation_id jresponse['data'] = jrequest data = await async_null_transform(jresponse, test_pauses[0]) # Stage processing await nc.publish("p4.s1", json.dumps(data).encode('utf-8')) log('info', 'p4', 's1', 'S1 completed', correlation_id) async def mh_s2(msg): jrequest = json.loads(msg.data.decode()) data = await async_null_transform(jrequest, test_pauses[1]) # Stage processing log('info', 'p4', 's2', 'S2 completed', data['correlation_id']) await nc.publish("p4.s2", msg.data) async def mh_s3(msg): jrequest = json.loads(msg.data.decode()) data = await async_null_transform(jrequest, test_pauses[1]) # Stage processing log('info', 'p4', 's3', 'S3 completed', data['correlation_id']) await nc.publish("p4.s3", msg.data) async def mh_s4(msg): jrequest = json.loads(msg.data.decode()) data = await async_null_transform(jrequest, test_pauses[1]) # Stage processing log('info', 'p4', 's4', 's4 completed', data['correlation_id']) ###################### # Pipeline Creation ###################### # yield from nc.subscribe("p4.s0", cb=mh_s1) # yield from nc.subscribe("p4.s1", cb=mh_s2) # yield from nc.subscribe("p4.s2", cb=mh_s3) yield from nc.subscribe("p4.s3", cb=mh_s4, queue="p4.s3")
def run(loop): nc = NATS() @asyncio.coroutine def closed_cb(): logging.info("Connection to NATS is closed.") yield from asyncio.sleep(0.1, loop=loop) loop.stop() options = {"servers": [natsURL], "io_loop": loop, "closed_cb": closed_cb} yield from nc.connect(**options) logging.info("Connected to NATS at {}...".format(nc.connected_url.netloc)) @asyncio.coroutine def subscribe_handler(msg): logging.info("Receiving from NATS topic: {}".format(msg.subject)) json_raw = json.loads(msg.data.decode()) timestamp = json_raw['timestamp'] status = json_raw['status'] logging.info("timestamp: {}, status: {}".format(timestamp, status)) yield from nc.subscribe(topic, cb=subscribe_handler) logging.info("Subscribed to topic: {}".format(topic)) def signal_handler(): if nc.is_closed: return logging.info("Disconnecting...") loop.create_task(nc.close()) for sig in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, sig), signal_handler)
def run(): # Use borrowed connection for NATS then mount NATS Streaming # client on top. nc = NATS() nc.connect() # Start session with NATS Streaming cluster. sc = STAN() sc.connect("test-cluster", "client-123", nats=nc) total_messages = 0 #future = asyncio.Future(loop=loop) def queue_cb(msg): #nonlocal future nonlocal total_messages print("Received a message (seq={}): {}".format(msg.seq, msg.data.decode())) total_messages += 1 print(total_messages) r = binary_to_dict(msg.data.decode()) print(r) # if total_messages >= 2: # future.set_result(None) # Subscribe to get all messages since beginning. sub = sc.subscribe("hi", queue="bar", cb=queue_cb)
def run(loop): nc = NATS() yield from nc.connect(io_loop=loop, servers=[nats_connection_string]) @asyncio.coroutine def message_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) sys.stdout.flush() # "*" matches any token, at any level of the subject. # yield from nc.subscribe("vehicle.*", cb=message_handler) # ">" matches any length of the tail of a subject, and can only be the last token # E.g. 'foo.>' will match 'foo.bar', 'foo.bar.baz', 'foo.foo.bar.bax.22' yield from nc.subscribe("*.>", cb=message_handler) yield from asyncio.sleep(3600, loop=loop) yield from nc.close()
def run(loop): nc = NATS() @asyncio.coroutine def closed_cb(): print("Connection to NATS is closed.") yield from asyncio.sleep(0.1, loop=loop) loop.stop() options = {"servers": [natsURL], "io_loop": loop, "closed_cb": closed_cb} yield from nc.connect(**options) print("Connected to NATS at {}...".format(nc.connected_url.netloc)) @asyncio.coroutine def subscribe_handler(msg): datastreamMsg = datastream_pb2.DataStreamMessage() datastreamMsg.ParseFromString(msg.data) print( "Received a message on {data}".format(data=datastreamMsg.payload)) yield from nc.subscribe(topic, cb=subscribe_handler) print("Subscribed to topic: {}".format(topic)) def signal_handler(): if nc.is_closed: return print("Disconnecting...") loop.create_task(nc.close()) for sig in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, sig), signal_handler)
def pipeline_p1(loop): ##################### # Connection to NATS ##################### nc = NATS() logger.info("Attempting to connect to nats server") yield from nc.connect("nats:4222", loop=loop) logger.info('Attached to nats server') ##################### # Message Handlers ##################### async def mh_s1(msg): logger.info('In S1') await nc.publish("p1.s1", msg.data) async def mh_s2(msg): logger.info('In S2') await nc.publish("p1.s2", msg.data) async def mh_s3(msg): logger.info('In S3') await nc.publish("p1.s3", msg.data) ###################### # Pipeline Creation ###################### yield from nc.subscribe("p1.s0", cb=mh_s1) yield from nc.subscribe("p1.s1", cb=mh_s2) yield from nc.subscribe("p1.s2", cb=mh_s3)
def run(self, loop, queue_name): nc = NATS() yield from nc.connect(servers=["nats://SCF_IP:4222"], io_loop=loop) @asyncio.coroutine def message_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print( "Received a message on message_handler'{subject} {reply}': {data}" .format(subject=subject, reply=reply, data=data)) print("\n\ntype of data {}".format(str(type(data)))) #yield from nc.publish(reply, bytes('I can help', 'utf-8')) report = json.loads(data) metadata = dict() metadata.update({'auditor_type': report['auditor_type']}) metadata.update({'cluster': report['cluster']}) post_request_ver2('audit_reports', json.dumps(report), None, metadata) print("************* data saved ************** ") yield from nc.subscribe(queue_name, 'workers', message_handler)
def test_malformed_info_json_response_from_server(self): @asyncio.coroutine def bad_server(reader, writer): writer.write(b'INFO {\r\n') yield from asyncio.sleep(0.2, loop=self.loop) writer.close() yield from asyncio.start_server(bad_server, '127.0.0.1', 4555, loop=self.loop) errors = [] @asyncio.coroutine def error_cb(e): nonlocal errors errors.append(e) nc = NATS() options = { 'servers': [ "nats://127.0.0.1:4555", ], 'error_cb': error_cb, 'io_loop': self.loop, 'allow_reconnect': False, } with self.assertRaises(NatsError): yield from nc.connect(**options) self.assertEqual(1, len(errors)) self.assertEqual(errors[0], nc.last_error) yield from asyncio.sleep(0.5, loop=self.loop)
def run(loop): nc = NATS() @asyncio.coroutine def closed_cb(): logging.info("Connection to NATS is closed.") yield from asyncio.sleep(0.1, loop=loop) loop.stop() options = {"servers": [natsURL], "io_loop": loop, "closed_cb": closed_cb} yield from nc.connect(**options) logging.info("Connected to NATS at {}...".format(nc.connected_url.netloc)) def signal_handler(): if nc.is_closed: return logging.info("Disconnecting...") loop.create_task(nc.close()) for sig in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, sig), signal_handler) while True: msg = str(time.time()) logging.info("Publishing to NATS topic: " + topic) logging.info("Publishing msg: " + msg) yield from nc.publish(topic, msg.encode()) yield from asyncio.sleep(5, loop=loop)
class Notification(object): def __init__(self, nats_host): self._nats = NATS() self._io_loop = asyncio.get_event_loop() asyncio.run_coroutine_threadsafe(self._initialize_nats(nats_host), self._io_loop) async def _initialize_nats(self, nats_host): options = { "servers": nats_host, "io_loop": self._io_loop, "max_reconnect_attemps": 60, "disconnected_cb": self._nats_disconnected_cb, "reconnected_cb": self._nats_reconnected_cb, "error_cb": self._nats_error_cb, "closed_cb": self._nats_closed_cb } try: await self._nats.connect(**options) except ErrNoServers as e: logging.error(str(e)) raise async def _nats_disconnected_cb(self): logging.info("[NATS] disconnected") async def _nats_reconnected_cb(self): logging.info("[NATS] reconnected") async def _nats_error_cb(self, e): logging.error("[NATS] ERROR: {}".format(e)) async def _nats_closed(self): logging.info("[NATS] connection is closed") def cleanup(self): self._nats_client.close() self._io_loop.close() def __del__(self): self.cleanup() def push(self, category, content, timestamp=None): logging.info("Pushing notification: {}: {}".format(category, content)) if timestamp is None: timestamp = time.time() msg = { "timestamp": timestamp, "category": category, "content": content } try: self._nats.publish(CHANNEL_NAME, msg) except ErrConnectionClosed: logging.error("Connection closed prematurely.") raise except ErrTimeout: logging.error("Timeout occurred when publishing" " event: {}".format(event)) raise
async def example(loop): nc = NATS() await nc.connect("nats://127.0.0.1:4222", loop=loop) async def handler(msg): print("[Received] ", msg) await nc.publish(msg.reply, b'I can help') # Can check whether client is in draining state if nc.is_draining: print("Connection is draining") sid = await nc.subscribe("help", "workers", cb=handler) await nc.flush() # Gracefully unsubscribe the subscription await nc.drain(sid) # [end drain_sub] requests = [] for i in range(0, 100): request = nc.request("help", b'help!', timeout=1) requests.append(request) # Wait for all the responses try: responses = [] responses = await asyncio.gather(*requests) except: pass print("Received {} responses".format(len(responses))) await nc.close()
def main(loop): parser = argparse.ArgumentParser() parser.add_argument('-n', '--count', default=DEFAULT_NUM_MSGS, type=int) parser.add_argument('-s', '--size', default=DEFAULT_MSG_SIZE, type=int) parser.add_argument('-S', '--subject', default='test') parser.add_argument('-b', '--batch', default=DEFAULT_BATCH_SIZE, type=int) parser.add_argument('--servers', default=[], action='append') args = parser.parse_args() data = [] for i in range(0, args.size): s = "%01x" % randint(0, 15) data.append(s.encode()) payload = b''.join(data) servers = args.servers if len(args.servers) < 1: servers = ["nats://127.0.0.1:4222"] opts = { "servers": servers, "io_loop": loop } # Make sure we're connected to a server first.. nc = NATS() try: yield from nc.connect(**opts) except Exception as e: sys.stderr.write("ERROR: {0}".format(e)) show_usage_and_die() # Start the benchmark start = time.time() to_send = args.count print("Sending {0} messages of size {1} bytes on [{2}]".format( args.count, args.size, args.subject)) while to_send > 0: for i in range(0, args.batch): to_send -= 1 yield from nc.publish(args.subject, payload) if (to_send % HASH_MODULO) == 0: sys.stdout.write("#") sys.stdout.flush() if to_send == 0: break # Minimal pause in between batches sent to server yield from asyncio.sleep(0.00001, loop=loop) # Additional roundtrip with server to try to ensure everything has been sent already. try: yield from nc.flush(DEFAULT_FLUSH_TIMEOUT) except ErrTimeout: print("Server flush timeout after {0}".format(DEFAULT_FLUSH_TIMEOUT)) elapsed = time.time() - start mbytes = "%.1f" % (((args.size * args.count)/elapsed) / (1024*1024)) print("\nTest completed : {0} msgs/sec ({1}) MB/sec".format( args.count/elapsed, mbytes)) yield from nc.close()
def test_invalid_subscription_type(self): nc = NATS() with self.assertRaises(NatsError): yield from nc.subscribe("hello", cb=None, future=None) with self.assertRaises(NatsError): yield from nc.subscribe_async("hello", cb=None)
def main(loop, subject): nc = NATS() yield from nc.connect(f"{sys.argv[1]}:{sys.argv[2]}", loop=loop) async def mh_s1(msg): await wire_tap(msg) yield from nc.subscribe(subject, cb=wire_tap)
def main(loop): parser = argparse.ArgumentParser() parser.add_argument('-n', '--count', default=DEFAULT_NUM_MSGS, type=int) parser.add_argument('-s', '--size', default=DEFAULT_MSG_SIZE, type=int) parser.add_argument('-S', '--subject', default='test') parser.add_argument('-b', '--batch', default=DEFAULT_BATCH_SIZE, type=int) parser.add_argument('--servers', default=[], action='append') args = parser.parse_args() data = [] for i in range(0, args.size): s = "%01x" % randint(0, 15) data.append(s.encode()) payload = b''.join(data) servers = args.servers if len(args.servers) < 1: servers = ["nats://127.0.0.1:4222"] opts = {"servers": servers, "io_loop": loop} # Make sure we're connected to a server first.. nc = NATS() try: yield from nc.connect(**opts) except Exception as e: sys.stderr.write("ERROR: {0}".format(e)) show_usage_and_die() # Start the benchmark start = time.time() to_send = args.count print("Sending {0} messages of size {1} bytes on [{2}]".format( args.count, args.size, args.subject)) while to_send > 0: for i in range(0, args.batch): to_send -= 1 yield from nc.publish(args.subject, payload) if (to_send % HASH_MODULO) == 0: sys.stdout.write("#") sys.stdout.flush() if to_send == 0: break # Minimal pause in between batches sent to server yield from asyncio.sleep(0.00001, loop=loop) # Additional roundtrip with server to try to ensure everything has been sent already. try: yield from nc.flush(DEFAULT_FLUSH_TIMEOUT) except ErrTimeout: print("Server flush timeout after {0}".format(DEFAULT_FLUSH_TIMEOUT)) elapsed = time.time() - start mbytes = "%.1f" % (((args.size * args.count) / elapsed) / (1024 * 1024)) print("\nTest completed : {0} msgs/sec ({1}) MB/sec".format( args.count / elapsed, mbytes)) yield from nc.close()
def test_flush(self): nc = NATS() yield from nc.connect(io_loop=self.loop) for i in range(0, 10): yield from nc.publish("flush.%d" % i, b'AA') yield from nc.flush() self.assertEqual(10, nc.stats['out_msgs']) self.assertEqual(20, nc.stats['out_bytes']) yield from nc.close()
def __run(self, loop, publisher , data): nc = NATS() print("before connect") yield from nc.connect(servers=["nats://127.0.0.1:4222"], io_loop=loop) print("after connect") yield from nc.publish(publisher, data) #yield from asyncio.sleep(1, loop=loop) yield from nc.close() print("done")
def publishAudit(loop, queue_name, data): nc = NATS() yield from nc.connect(servers=["nats://127.0.0.1:4222"], io_loop=loop) print( "&&&&&&&&&&&&&&&&&&&&&&&&&&& publishAudit &&&&&&&&&&&&&&&&&&&&&&&") response = yield from nc.request(queue_name, bytes(data, 'utf-8'), 2.6) print("****************response*****************", response.data.decode()) yield from nc.close()
def run(loop): parser = argparse.ArgumentParser() # e.g. nats-sub hello -s nats://127.0.0.1:4222 parser.add_argument('subject', default='hello', nargs='?') parser.add_argument('-s', '--servers', default=[], action='append') parser.add_argument('-q', '--queue', default="") args = parser.parse_args() nc = NATS() @asyncio.coroutine def closed_cb(): print("Connection to NATS is closed.") yield from asyncio.sleep(0.1, loop=loop) loop.stop() @asyncio.coroutine def reconnected_cb(): print("Connected to NATS at {}...".format(nc.connected_url.netloc)) @asyncio.coroutine def subscribe_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) options = { "io_loop": loop, "closed_cb": closed_cb, "reconnected_cb": reconnected_cb } try: if len(args.servers) > 0: options['servers'] = args.servers yield from nc.connect(**options) except Exception as e: print(e) show_usage_and_die() print("Connected to NATS at {}...".format(nc.connected_url.netloc)) def signal_handler(): if nc.is_closed: return print("Disconnecting...") loop.create_task(nc.close()) for sig in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, sig), signal_handler) yield from nc.subscribe(args.subject, args.queue, subscribe_handler)
def test_default_connect(self): nc = NATS() yield from nc.connect(io_loop=self.loop) self.assertIn('auth_required', nc._server_info) self.assertIn('max_payload', nc._server_info) self.assertEqual(nc._server_info['max_payload'], nc._max_payload) self.assertTrue(nc.is_connected) yield from nc.close() self.assertTrue(nc.is_closed) self.assertFalse(nc.is_connected)
def test_pending_data_size_tracking(self): nc = NATS() yield from nc.connect(io_loop=self.loop) largest_pending_data_size = 0 for i in range(0, 100): yield from nc.publish("example", b'A' * 100000) if nc.pending_data_size > 0: largest_pending_data_size = nc.pending_data_size self.assertTrue(largest_pending_data_size > 0) yield from nc.close()
def test_pending_data_size_tracking(self): nc = NATS() yield from nc.connect(io_loop=self.loop) largest_pending_data_size = 0 for i in range(0,100): yield from nc.publish("example", b'A' * 100000) if nc.pending_data_size > 0: largest_pending_data_size = nc.pending_data_size self.assertTrue(largest_pending_data_size > 0) yield from nc.close()
def test_pending_data_size_flush_on_close(self): nc = NATS() disconnected_count = 0 reconnected_count = 0 closed_count = 0 err_count = 0 @asyncio.coroutine def disconnected_cb(): nonlocal disconnected_count disconnected_count += 1 @asyncio.coroutine def reconnected_cb(): nonlocal reconnected_count reconnected_count += 1 @asyncio.coroutine def closed_cb(): nonlocal closed_count closed_count += 1 options = { 'dont_randomize': True, 'io_loop': self.loop, 'disconnected_cb': disconnected_cb, 'closed_cb': closed_cb, 'reconnected_cb': reconnected_cb, 'reconnect_time_wait': 0.01 } yield from nc.connect(**options) total_received = 0 future = asyncio.Future(loop=self.loop) @asyncio.coroutine def receiver_cb(msg): nonlocal total_received total_received += 1 if total_received == 200: future.set_result(True) # Extra connection which should be receiving all the messages nc2 = NATS() yield from nc2.connect(**options) yield from nc2.subscribe("example.*", cb=receiver_cb) yield from nc2.flush() for i in range(0, 200): yield from nc.publish("example.{}".format(i), b'A' * 20) # All pending messages should have been emitted to the server # by the first connection at this point. yield from nc.close() # Wait for the server to flush all the messages back to the receiving client yield from asyncio.wait_for(future, 1, loop=self.loop) yield from nc2.close() self.assertEqual(total_received, 200)
def run(loop): nc = NATS() nats_connection_string = "nats://*****:*****@bike.dowhile.se:4222" position_bus = {} position_bus["lat"] = 57.709548 position_bus["lon"] = 11.941056 position_bus["speed"] = 12.5 position_bus["course"] = 45 position_bus["time"] = datetime.datetime.now( datetime.timezone.utc).isoformat() position_bus["vehicle_type"] = "bus" position_bike = {} position_bike["lat"] = 57.709627 position_bike["lon"] = 11.942357 position_bike["speed"] = 14.5 position_bike["course"] = 330 position_bike["time"] = datetime.datetime.now( datetime.timezone.utc).isoformat() position_bike["vehicle_type"] = "bicycle" try: yield from nc.connect(io_loop=loop, servers=[nats_connection_string]) except ErrNoServers as e: print(e) return @asyncio.coroutine def message_sender(position, vehicle_id): subject = "vehicle." + vehicle_id + ".position" yield from nc.publish(subject, json.dumps(position).encode()) @asyncio.coroutine def message_printer(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) sys.stdout.flush() yield from nc.subscribe("*.>", cb=message_printer) yield from message_sender(position_bus, "testBUS1") yield from message_sender(position_bike, "testBIKE1") try: # Flush connection to server, returns when all messages have been processed. # It raises a timeout if roundtrip takes longer than 1 second. yield from nc.flush(1) except ErrTimeout: print("Flush timeout") yield from asyncio.sleep(1, loop=loop) yield from nc.close()
def pub_random(loop): nc = NATS() yield from nc.connect("localhost:4222", loop=loop) if nc.last_error: print("ERROR received from NATS: ", nc.last_error) else: print('Submitting random requests') for i in range(NUM_MESSAGES): jdata = {"i": i} yield from nc.publish('p1.s0', json.dumps(jdata).encode('utf-8'))
async def get_result(): nc = NATS() await nc.connect(uri, loop=loop) try: response = await nc.request(fn_name, request, timeout) return response.data except ErrTimeout: print("Request timed out") raise finally: nc.close()
def main(loop): parser = argparse.ArgumentParser() parser.add_argument('-n', '--count', default=DEFAULT_NUM_MSGS, type=int) parser.add_argument('-S', '--subject', default='test') parser.add_argument('--servers', default=[], action='append') args = parser.parse_args() servers = args.servers if len(args.servers) < 1: servers = ["nats://127.0.0.1:4222"] opts = { "servers": servers, "io_loop": loop, "allow_reconnect": False } # Make sure we're connected to a server first... nc = NATS() try: yield from nc.connect(**opts) except Exception as e: sys.stderr.write("ERROR: {0}".format(e)) show_usage_and_die() received = 0 start = None @asyncio.coroutine def handler(msg): nonlocal received nonlocal start received += 1 # Measure time from when we get the first message. if received == 1: start = time.monotonic() if (received % HASH_MODULO) == 0: sys.stdout.write("*") sys.stdout.flush() yield from nc.subscribe(args.subject, cb=handler) # Additional roundtrip with server to ensure everything has been # processed by the server already. yield from nc.flush() print("Waiting for {} messages on [{}]...".format(args.count, args.subject)) try: while received < args.count: yield from asyncio.sleep(0.1, loop=loop) except ErrTimeout: print("Server flush timeout after {0}".format(DEFAULT_FLUSH_TIMEOUT)) elapsed = time.monotonic() - start print("\nTest completed : {0} msgs/sec sent".format(args.count/elapsed)) print("Received {0} messages ({1} msgs/sec)".format(received, received/elapsed)) yield from nc.close()
def test_connect(self): nc = NATS() yield from nc.connect(io_loop=self.loop, servers=['nats://localhost:4224'], tls=self.ssl_ctx) self.assertEqual(nc._server_info['max_payload'], nc.max_payload) self.assertTrue(nc._server_info['tls_required']) self.assertTrue(nc._server_info['tls_verify']) self.assertTrue(nc.max_payload > 0) self.assertTrue(nc.is_connected) yield from nc.close() self.assertTrue(nc.is_closed) self.assertFalse(nc.is_connected)
def _publish_event(args): nc = NATS() options = { "servers": ["nats://nats:4222"], "io_loop": loop, } yield from nc.connect(**options) payload = args['payload'].encode() yield from nc.publish(args['subject'], payload) yield from nc.close()
def test_timed_request(self): nc = NATS() msgs = [] counter = 0 @asyncio.coroutine def worker_handler(msg): nonlocal counter counter += 1 msgs.append(msg) yield from nc.publish(msg.reply, 'Reply:{}'.format(counter).encode()) @asyncio.coroutine def slow_worker_handler(msg): yield from asyncio.sleep(0.5, loop=self.loop) yield from nc.publish(msg.reply, b'timeout by now...') yield from nc.connect(io_loop=self.loop) yield from nc.subscribe("help", cb=worker_handler) yield from nc.subscribe("slow.help", cb=slow_worker_handler) response = yield from nc.timed_request("help", b'please', timeout=1) self.assertEqual(b'Reply:1', response.data) response = yield from nc.timed_request("help", b'please', timeout=1) self.assertEqual(b'Reply:2', response.data) with self.assertRaises(ErrTimeout): yield from nc.timed_request("slow.help", b'please', timeout=0.1) yield from asyncio.sleep(1, loop=self.loop) yield from nc.close()
def test_connect_with_auth_token(self): nc = NATS() options = { 'servers': [ "nats://[email protected]:4223", ], 'io_loop': self.loop } yield from nc.connect(**options) self.assertIn('auth_required', nc._server_info) self.assertTrue(nc.is_connected) yield from nc.close() self.assertTrue(nc.is_closed) self.assertFalse(nc.is_connected)
def test_subscribe_async_without_coroutine_unsupported(self): nc = NATS() msgs = [] def subscription_handler(msg): if msg.subject == "tests.1": time.sleep(0.5) if msg.subject == "tests.3": time.sleep(0.2) msgs.append(msg) yield from nc.connect(io_loop=self.loop) with self.assertRaises(NatsError): sid = yield from nc.subscribe_async("tests.>", cb=subscription_handler) yield from nc.close()
def run(loop): parser = argparse.ArgumentParser() # e.g. nats-pub hello -d "world" -s nats://127.0.0.1:4222 -s nats://127.0.0.1:4223 parser.add_argument('subject', default='hello', nargs='?') parser.add_argument('-d', '--data', default="hello world") parser.add_argument('-s', '--servers', default=[], action='append') args = parser.parse_args() nc = NATS() @asyncio.coroutine def closed_cb(): print("Connection to NATS is closed.") loop.stop() @asyncio.coroutine def reconnected_cb(): print("Connected to NATS at {}...".format(nc.connected_url.netloc)) @asyncio.coroutine def subscribe_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) options = { "io_loop": loop, "closed_cb": closed_cb, "reconnected_cb": reconnected_cb } try: if len(args.servers) > 0: options['servers'] = args.servers yield from nc.connect(**options) except Exception as e: print(e) show_usage_and_die() print("Connected to NATS at {}...".format(nc.connected_url.netloc)) yield from nc.publish(args.subject, args.data.encode()) yield from nc.flush() yield from nc.close()
def run(loop): nc = Nats() yield from nc.connect(io_loop=loop) # Send a request and expect a single response and trigger timeout if not # faster than 50 ms. try: response = yield from nc.timed_request("conf.host", b'host', 0.050) print("Received response: {message}".format(message=response.data.decode())) except ErrTimeout: print("Request timed out") yield from nc.publish("log.info", b'initializing') yield from nc.publish("log.info", b'scraping item 1') @asyncio.coroutine def help_request(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data ) ) yield from nc.publish(reply, b'I can help') # Use queue named 'workers' for distributing requests among subscribers. yield from nc.subscribe("cmd.help", "workers", help_request) yield from asyncio.sleep(20, loop=loop) yield from nc.close()
def main(loop): parser = argparse.ArgumentParser() parser.add_argument('-n', '--iterations', default=DEFAULT_ITERATIONS, type=int) parser.add_argument('-S', '--subject', default='test') parser.add_argument('--servers', default=[], action='append') args = parser.parse_args() servers = args.servers if len(args.servers) < 1: servers = ["nats://127.0.0.1:4222"] opts = { "servers": servers } # Make sure we're connected to a server first... nc = NATS() try: yield from nc.connect(**opts) except Exception as e: sys.stderr.write("ERROR: {0}".format(e)) show_usage_and_die() @asyncio.coroutine def handler(msg): yield from nc.publish(msg.reply, b'') yield from nc.subscribe(args.subject, cb=handler) # Start the benchmark start = time.monotonic() to_send = args.iterations print("Sending {0} request/responses on [{1}]".format( args.iterations, args.subject)) while to_send > 0: to_send -= 1 if to_send == 0: break yield from nc.timed_request(args.subject, b'') if (to_send % HASH_MODULO) == 0: sys.stdout.write("#") sys.stdout.flush() duration = time.monotonic() - start ms = "%.3f" % ((duration/args.iterations) * 1000) print("\nTest completed : {0} ms avg request/response latency".format(ms)) yield from nc.close()
def run(loop): nc = NATS() ssl_ctx = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH) ssl_ctx.protocol = ssl.PROTOCOL_TLSv1_2 ssl_ctx.load_verify_locations('../tests/certs/ca.pem') ssl_ctx.load_cert_chain(certfile='../tests/certs/client-cert.pem', keyfile='../tests/certs/client-key.pem') yield from nc.connect(io_loop=loop, tls=ssl_ctx) @asyncio.coroutine def message_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) # Simple publisher and async subscriber via coroutine. sid = yield from nc.subscribe("foo", cb=message_handler) # Stop receiving after 2 messages. yield from nc.auto_unsubscribe(sid, 2) yield from nc.publish("foo", b'Hello') yield from nc.publish("foo", b'World') yield from nc.publish("foo", b'!!!!!') @asyncio.coroutine def help_request(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) yield from nc.publish(reply, b'I can help') # Use queue named 'workers' for distributing requests # among subscribers. yield from nc.subscribe("help", "workers", help_request) # Send a request and expect a single response # and trigger timeout if not faster than 50 ms. try: response = yield from nc.timed_request("help", b'help me', 0.050) print("Received response: {message}".format(message=response.data.decode())) except ErrTimeout: print("Request timed out") yield from asyncio.sleep(1, loop=loop) yield from nc.close()
def test_connect_with_bad_auth_token(self): nc = NATS() options = { 'servers': [ "nats://[email protected]:4225", ], 'allow_reconnect': False, 'reconnect_time_wait': 0.1, 'max_reconnect_attempts': 1, 'io_loop': self.loop } # Authorization Violation with self.assertRaises(NatsError): yield from nc.connect(**options) self.assertIn('auth_required', nc._server_info) self.assertFalse(nc.is_connected)
def test_connect_with_auth(self): nc = NATS() options = { 'servers': [ "nats://*****:*****@127.0.0.1:4223", "nats://*****:*****@127.0.0.1:4224" ], 'io_loop': self.loop } yield from nc.connect(**options) self.assertIn('auth_required', nc._server_info) self.assertIn('max_payload', nc._server_info) self.assertEqual(nc._server_info['max_payload'], nc._max_payload) self.assertTrue(nc.is_connected) yield from nc.close() self.assertTrue(nc.is_closed) self.assertFalse(nc.is_connected)
def test_connect_with_failed_auth(self): nc = NATS() options = { 'servers': [ "nats://*****:*****@127.0.0.1:4223", ], 'io_loop': self.loop } with self.assertRaises(ErrNoServers): yield from nc.connect(**options) self.assertIn('auth_required', nc._server_info) self.assertTrue(nc._server_info['auth_required']) self.assertFalse(nc.is_connected) yield from nc.close() self.assertTrue(nc.is_closed) self.assertEqual(ErrNoServers, type(nc.last_error)) self.assertEqual(0, nc.stats['reconnects'])
def run(loop): nc = NATS() @asyncio.coroutine def closed_cb(): print("Connection to NATS is closed.") yield from asyncio.sleep(0.1, loop=loop) loop.stop() options = { "servers": ["nats://127.0.0.1:4222"], "io_loop": loop, "closed_cb": closed_cb } yield from nc.connect(**options) print("Connected to NATS at {}...".format(nc.connected_url.netloc)) @asyncio.coroutine def subscribe_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) # Basic subscription to receive all published messages # which are being sent to a single topic 'discover' yield from nc.subscribe("discover", cb=subscribe_handler) # Subscription on queue named 'workers' so that # one subscriber handles message a request at a time. yield from nc.subscribe("help.*", "workers", subscribe_handler) def signal_handler(): if nc.is_closed: return print("Disconnecting...") loop.create_task(nc.close()) for sig in ('SIGINT', 'SIGTERM'): loop.add_signal_handler(getattr(signal, sig), signal_handler)
def test_invalid_subscribe_error(self): nc = NATS() msgs = [] future_error = asyncio.Future(loop=self.loop) @asyncio.coroutine def subscription_handler(msg): msgs.append(msg) @asyncio.coroutine def closed_cb(): nonlocal future_error future_error.set_result(nc.last_error) yield from nc.connect(io_loop=self.loop, closed_cb=closed_cb) yield from nc.subscribe("foo.", cb=subscription_handler) yield from asyncio.wait_for(future_error, 1.0, loop=self.loop) nats_error = future_error.result() self.assertEqual(type(nats_error), NatsError) self.assertEqual(str(nats_error), "nats: 'Invalid Subject'")
def test_subscribe_sync_call_soon(self): nc = NATS() msgs = [] def subscription_handler(msg): msgs.append(msg) yield from nc.connect(io_loop=self.loop) sid = yield from nc.subscribe("tests.>", cb=subscription_handler) for i in range(0, 5): yield from nc.publish("tests.{}".format(i), b'bar') # Wait a bit for messages to be received. yield from asyncio.sleep(1, loop=self.loop) self.assertEqual(5, len(msgs)) # Check that they were received sequentially. self.assertEqual("tests.1", msgs[1].subject) self.assertEqual("tests.3", msgs[3].subject) yield from nc.close()
def test_close(self): nc = NATS() disconnected_count = 0 reconnected_count = 0 closed_count = 0 err_count = 0 @asyncio.coroutine def disconnected_cb(): nonlocal disconnected_count disconnected_count += 1 @asyncio.coroutine def reconnected_cb(): nonlocal reconnected_count reconnected_count += 1 @asyncio.coroutine def closed_cb(): nonlocal closed_count closed_count += 1 @asyncio.coroutine def err_cb(): nonlocal err_count err_count += 1 options = { 'io_loop': self.loop, 'disconnected_cb': disconnected_cb, 'closed_cb': closed_cb, 'reconnected_cb': reconnected_cb, 'error_cb': err_cb, } yield from nc.connect(**options) yield from nc.close() with self.assertRaises(ErrConnectionClosed): yield from nc.publish("foo", b'A') with self.assertRaises(ErrConnectionClosed): yield from nc.subscribe("bar", "workers") with self.assertRaises(ErrConnectionClosed): yield from nc.publish_request("bar", "inbox", b'B') with self.assertRaises(ErrConnectionClosed): yield from nc.flush() self.assertEqual(1, closed_count) self.assertEqual(1, disconnected_count) self.assertEqual(0, reconnected_count) self.assertEqual(0, err_count)
def run(loop): nc = NATS() yield from nc.connect(io_loop=loop) @asyncio.coroutine def message_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format(subject=subject, reply=reply, data=data)) # "*" matches any token, at any level of the subject. yield from nc.subscribe("foo.*.baz", cb=message_handler) yield from nc.subscribe("foo.bar.*", cb=message_handler) # ">" matches any length of the tail of a subject, and can only be the last token # E.g. 'foo.>' will match 'foo.bar', 'foo.bar.baz', 'foo.foo.bar.bax.22' yield from nc.subscribe("foo.>", cb=message_handler) # Matches all of the above. yield from nc.publish("foo.bar.baz", b"Hello World") yield from asyncio.sleep(1, loop=loop) yield from nc.close()
def run(loop): nc = NATS() yield from nc.connect(io_loop=loop) @asyncio.coroutine def message_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) # Simple publisher and async subscriber via coroutine. sid = yield from nc.subscribe("foo", cb=message_handler) # Stop receiving after 2 messages. yield from nc.auto_unsubscribe(sid, 2) yield from nc.publish("foo", b'Hello') yield from nc.publish("foo", b'World') yield from nc.publish("foo", b'!!!!!') @asyncio.coroutine def help_request(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() print("Received a message on '{subject} {reply}': {data}".format( subject=subject, reply=reply, data=data)) yield from nc.publish(reply, b'I can help') # Use queue named 'workers' for distributing requests # among subscribers. yield from nc.subscribe("help", "workers", help_request) # Send a request and expect a single response # and trigger timeout if not faster than 50 ms. try: response = yield from nc.timed_request("help", b'help me', 0.050) print("Received response: {message}".format(message=response.data.decode())) except ErrTimeout: print("Request timed out") yield from asyncio.sleep(1, loop=loop) yield from nc.close()
def test_subscribe(self): nc = NATS() msgs = [] @asyncio.coroutine def subscription_handler(msg): msgs.append(msg) payload = b'hello world' yield from nc.connect(io_loop=self.loop, servers=['nats://localhost:4224'], tls=self.ssl_ctx) sid = yield from nc.subscribe("foo", cb=subscription_handler) yield from nc.publish("foo", payload) yield from nc.publish("bar", payload) with self.assertRaises(ErrBadSubject): yield from nc.publish("", b'') # Wait a bit for message to be received. yield from asyncio.sleep(0.2, loop=self.loop) self.assertEqual(1, len(msgs)) msg = msgs[0] self.assertEqual('foo', msg.subject) self.assertEqual('', msg.reply) self.assertEqual(payload, msg.data) self.assertEqual(1, nc._subs[sid].received) yield from nc.close()
def test_discover_servers_after_first_connect(self): nc = NATS() options = { 'servers': [ "nats://127.0.0.1:4223", ], 'io_loop': self.loop } yield from nc.connect(**options) # Start rest of cluster members so that we receive them # connect_urls on the first connect. yield from self.loop.run_in_executor(None, self.server_pool[1].start) yield from asyncio.sleep(1, loop=self.loop) yield from self.loop.run_in_executor(None, self.server_pool[2].start) yield from asyncio.sleep(1, loop=self.loop) yield from nc.close() self.assertTrue(nc.is_closed) self.assertEqual(len(nc.servers), 3) self.assertEqual(len(nc.discovered_servers), 2)
def test_empty_info_op_uses_defaults(self): @asyncio.coroutine def bad_server(reader, writer): writer.write(b'INFO {}\r\n') yield from writer.drain() data = yield from reader.readline() yield from asyncio.sleep(0.2, loop=self.loop) writer.close() yield from asyncio.start_server( bad_server, '127.0.0.1', 4555, loop=self.loop ) disconnected_count = 0 @asyncio.coroutine def disconnected_cb(): nonlocal disconnected_count disconnected_count += 1 nc = NATS() options = { 'servers': [ "nats://127.0.0.1:4555", ], 'disconnected_cb': disconnected_cb, 'io_loop': self.loop } yield from nc.connect(**options) self.assertEqual(nc.max_payload, 1048576) yield from nc.close() self.assertEqual(1, disconnected_count)
def test_async_await_subscribe_sync(self): nc = NATS() msgs = [] async def subscription_handler(msg): if msg.subject == "tests.1": await asyncio.sleep(0.5, loop=self.loop) if msg.subject == "tests.3": await asyncio.sleep(0.2, loop=self.loop) msgs.append(msg) yield from nc.connect(io_loop=self.loop) sid = yield from nc.subscribe_async("tests.>", cb=subscription_handler) for i in range(0, 5): yield from nc.publish("tests.{}".format(i), b'bar') # Wait a bit for messages to be received. yield from asyncio.sleep(1, loop=self.loop) self.assertEqual(5, len(msgs)) self.assertEqual("tests.1", msgs[4].subject) self.assertEqual("tests.3", msgs[3].subject) yield from nc.close()