class NatsUtils(object): def __init__(self, servers, subject, handle): self.__nc__ = Client() self.__servers__ = servers self.__subject__ = subject self.__handle__ = handle @tornado.gen.coroutine def main(self): yield self.__nc__.connect(self.__servers__) for i in range(0, len(self.__subject__)): yield self.__nc__.subscribe(self.__subject__[i], cb=self.__handle__[i]) def startNats(self): self.main() tornado.ioloop.IOLoop.instance().start() @tornado.gen.coroutine def publish(self, subject, data): yield self.__nc__.publish(subject, data) yield self.__nc__.flush() def isConnect(self): return self.__nc__.is_connected
def main(): nc = NATS() # Establish connection to the server. options = {"verbose": True, "servers": ["nats://127.0.0.1:4222"]} yield nc.connect(**options) def discover(msg=None): channel_message = message_pb2.ChannelMessage() channel_message.ParseFromString(msg.data) print("[Received]: %s" % channel_message) send_message = message_pb2.ChannelMessage() send_message.chan_num = 5 #send_message.from = "python" send_message.message = "Hello, World!" sid = yield nc.subscribe("world.channel_message", "", discover) yield nc.publish("world.channel_message", send_message.SerializeToString()) loop = tornado.ioloop.IOLoop.instance() yield tornado.gen.Task(loop.add_timeout, time.time() + 20) try: start = datetime.now() # Make roundtrip to the server and timeout after 1 second yield nc.flush(1) end = datetime.now() print("Latency: %d µs" % (end.microsecond - start.microsecond)) except tornado.gen.TimeoutError, e: print("Timeout! Roundtrip too slow...")
def test_publish_request(self): nc = Client() yield nc.connect(io_loop=self.io_loop) self.assertEqual(Client.CONNECTED, nc._status) info_keys = nc._server_info.keys() self.assertTrue(len(info_keys) > 0) inbox = new_inbox() yield nc.publish_request("help.1", inbox, "hello") yield nc.publish_request("help.2", inbox, "world") yield nc.flush() yield tornado.gen.sleep(1.0) http = tornado.httpclient.AsyncHTTPClient() response = yield http.fetch('http://127.0.0.1:%d/varz' % self.server_pool[0].http_port) varz = json.loads(response.body) self.assertEqual(10, varz['in_bytes']) self.assertEqual(0, varz['out_bytes']) self.assertEqual(2, varz['in_msgs']) self.assertEqual(0, varz['out_msgs']) self.assertEqual(0, nc.stats['in_bytes']) self.assertEqual(10, nc.stats['out_bytes']) self.assertEqual(0, nc.stats['in_msgs']) self.assertEqual(2, nc.stats['out_msgs'])
def test_unsubscribe_only_if_max_reached(self): nc = Client() options = { "io_loop": self.io_loop } yield nc.connect(**options) log = Log() sid = yield nc.subscribe("foo", cb=log.persist) yield nc.publish("foo", b'A') yield nc.publish("foo", b'B') yield nc.publish("foo", b'C') yield tornado.gen.sleep(1) self.assertEqual(3, len(log.records["foo"])) yield nc.unsubscribe(sid, 3) yield nc.publish("foo", b'D') yield nc.flush() self.assertEqual(3, len(log.records["foo"])) self.assertEqual(b'A', log.records["foo"][0].data) self.assertEqual(b'B', log.records["foo"][1].data) self.assertEqual(b'C', log.records["foo"][2].data) # Should not exist by now yield tornado.gen.sleep(1) with self.assertRaises(KeyError): nc._subs[sid].received http = tornado.httpclient.AsyncHTTPClient() response = yield http.fetch('http://127.0.0.1:%d/connz' % self.server_pool[0].http_port) result = json.loads(response.body) connz = result['connections'][0] self.assertEqual(0, connz['subscriptions'])
def test_close_connection(self): nc = Client() options = { "dont_randomize": True, "servers": [ "nats://*****:*****@127.0.0.1:4223", "nats://*****:*****@127.0.0.1:4224" ], "io_loop": self.io_loop } yield nc.connect(**options) self.assertEqual(True, nc._server_info["auth_required"]) log = Log() sid_1 = yield nc.subscribe("foo", "", log.persist) self.assertEqual(sid_1, 1) sid_2 = yield nc.subscribe("bar", "", log.persist) self.assertEqual(sid_2, 2) sid_3 = yield nc.subscribe("quux", "", log.persist) self.assertEqual(sid_3, 3) yield nc.publish("foo", "hello") yield tornado.gen.sleep(1.0) # Done yield nc.close() orig_gnatsd = self.server_pool.pop(0) orig_gnatsd.finish() try: a = nc._current_server # Wait and assert that we don't reconnect. yield tornado.gen.sleep(3) finally: b = nc._current_server self.assertEqual(a.uri, b.uri) self.assertFalse(nc.is_connected) self.assertFalse(nc.is_reconnecting) self.assertTrue(nc.is_closed) with(self.assertRaises(ErrConnectionClosed)): yield nc.publish("hello", "world") with(self.assertRaises(ErrConnectionClosed)): yield nc.flush() with(self.assertRaises(ErrConnectionClosed)): yield nc.subscribe("hello", "worker") with(self.assertRaises(ErrConnectionClosed)): yield nc.publish_request("hello", "inbox", "world") with(self.assertRaises(ErrConnectionClosed)): yield nc.request("hello", "world") with(self.assertRaises(ErrConnectionClosed)): yield nc.timed_request("hello", "world")
def test(): client = Client() options = {"servers": ["nats://%s:%d" % (NATS_HOST, NATS_PORT)]} yield client.connect(**options) msg = "0" * size for i in range(0, COUNT): yield client.publish(TOPIC, msg) yield client.publish(TOPIC, "quit") yield client.flush()
def main(): nc = NATS() # Set pool servers in the cluster and give a name to the client. options = { "name": "worker", "servers": [ "nats://*****:*****@127.0.0.1:4222", "nats://*****:*****@127.0.0.1:4223", "nats://*****:*****@127.0.0.1:4224" ] } # Explicitly set loop to use for the reactor. options["io_loop"] = tornado.ioloop.IOLoop.instance() yield nc.connect(**options) @tornado.gen.coroutine def subscriber(msg): yield nc.publish("discover", "pong") yield nc.subscribe("discover", "", subscriber) @tornado.gen.coroutine def async_subscriber(msg): # First request takes longer, while others are still processed. if msg.subject == "requests.1": yield tornado.gen.sleep(0.5) print("Processed request [{0}]: {1}".format(msg.subject, msg)) # Create asynchronous subscription and make roundtrip to server # to ensure that subscriptions have been processed. yield nc.subscribe_async("requests.*", cb=async_subscriber) yield nc.flush() for i in range(1, 10): yield nc.publish("requests.{0}".format(i), "example") yield tornado.gen.sleep(1) while True: # Confirm stats to implement basic throttling logic. sent = nc.stats["out_msgs"] received = nc.stats["in_msgs"] delta = sent - received if delta > 2000: print("Waiting... Sent: {0}, Received: {1}, Delta: {2}".format( sent, received, delta)) yield tornado.gen.sleep(1) if nc.stats["reconnects"] > 10: print("[WARN] Reconnected over 10 times!") for i in range(1000): yield nc.publish("discover", "ping")
def main(): nc = NATS() # Set pool servers in the cluster and give a name to the client. options = { "name": "worker", "servers": [ "nats://*****:*****@127.0.0.1:4222", "nats://*****:*****@127.0.0.1:4223", "nats://*****:*****@127.0.0.1:4224" ] } # Explicitly set loop to use for the reactor. options["io_loop"] = tornado.ioloop.IOLoop.instance() yield nc.connect(**options) @tornado.gen.coroutine def subscriber(msg): yield nc.publish("discover", "pong") yield nc.subscribe("discover", "", subscriber) @tornado.gen.coroutine def async_subscriber(msg): # First request takes longer, while others are still processed. if msg.subject == "requests.1": yield tornado.gen.sleep(0.5) print("Processed request [{0}]: {1}".format(msg.subject, msg)) # Create asynchronous subscription and make roundtrip to server # to ensure that subscriptions have been processed. yield nc.subscribe_async("requests.*", cb=async_subscriber) yield nc.flush() for i in range(1, 10): yield nc.publish("requests.{0}".format(i), "example") yield tornado.gen.sleep(1) while True: # Confirm stats to implement basic throttling logic. sent = nc.stats["out_msgs"] received = nc.stats["in_msgs"] delta = sent - received if delta > 2000: print("Waiting... Sent: {0}, Received: {1}, Delta: {2}".format(sent, received, delta)) yield tornado.gen.sleep(1) if nc.stats["reconnects"] > 10: print("[WARN] Reconnected over 10 times!") for i in range(1000): yield nc.publish("discover", "ping")
def notify_new_user(user, config): client = Nats() server = 'nats://{}:{}'.format(config['host'], config['port']) opts = {"servers": [server]} yield client.connect(**opts) notif = { 'message': 'created', 'user_name': '{0}'.format(user.name), 'user_id': '{0}'.format(user.user_id) } yield client.publish('userAction', json.dumps(notif)) yield client.flush() log.info("New user notification sent on NATS for {0}".format(user.user_id))
def main(): nc = NATS() try: # Setting explicit list of servers in a cluster and # max reconnect retries. servers = [ "nats://127.0.0.1:4222", "nats://127.0.0.1:4223", "nats://127.0.0.1:4224" ] yield nc.connect(max_reconnect_attempts=2, servers=servers) except ErrNoServers: print("No servers available!") return @tornado.gen.coroutine def message_handler(msg): subject = msg.subject reply = msg.reply data = msg.data.decode() for i in range(0, 20): yield nc.publish(reply, "i={i}".format(i=i).encode()) yield nc.subscribe("help.>", cb=message_handler) @tornado.gen.coroutine def request_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)) # Signal the server to stop sending messages after we got 10 already. yield nc.request("help.please", b'help', expected=10, cb=request_handler) # Flush connection to server, returns when all messages have been processed. # It raises a timeout if roundtrip takes longer than 1 second. yield nc.flush() # Drain gracefully closes the connection, allowing all subscribers to # handle any pending messages inflight that the server may have sent. yield nc.drain() # Drain works async in the background. yield tornado.gen.sleep(1)
def test_flush_timeout(self): class Parser(): def __init__(self, nc, t): self.nc = nc self.t = t @tornado.gen.coroutine def parse(self, data=''): self.t.assertEqual(1, self.nc._pings_outstanding) yield tornado.gen.sleep(2.0) yield self.nc._process_pong() nc = Client() nc._ps = Parser(nc, self) yield nc.connect(io_loop=self.io_loop) with self.assertRaises(tornado.gen.TimeoutError): yield nc.flush(timeout=1) self.assertEqual(1, len(nc._pongs)) self.assertEqual(1, nc._pings_outstanding)