def main(): # Declare the protocol stack used for serialization. # Protocol stacks must match between clients and servers. prot_factory = FProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory()) # Open a NATS connection to send requests nats_client = NATS() options = {"verbose": True, "servers": ["nats://127.0.0.1:4222"]} yield nats_client.connect(**options) # Create a nats transport using the connected client # The transport sends data on the music-service NATS topic nats_transport = FNatsTransport(nats_client, "music-service") try: yield nats_transport.open() except TTransportException as ex: root.error(ex) raise gen.Return() # Using the configured transport and protocol, create a client # to talk to the music store service. store_client = FStoreClient(FServiceProvider(nats_transport, prot_factory), middleware=logging_middleware) album = yield store_client.buyAlbum(FContext(), str(uuid.uuid4()), "ACT-12345") root.info("Bought an album %s\n", album) yield store_client.enterAlbumGiveaway(FContext(), "*****@*****.**", "Kevin") yield nats_transport.close() yield nats_client.close()
def main(): parser = argparse.ArgumentParser(description="Run a python tornado client") parser.add_argument('--port', dest='port', default='9090') parser.add_argument('--protocol', dest='protocol_type', default="binary", choices="binary, compact, json") parser.add_argument('--transport', dest='transport_type', default=NATS_NAME, choices="nats, http") args = parser.parse_args() protocol_factory = get_protocol_factory(args.protocol_type) nats_client = NATS() logging.debug("Connecting to NATS") yield nats_client.connect(**get_nats_options()) transport = None if args.transport_type == NATS_NAME: transport = FNatsTransport(nats_client, "frugal.foo.bar.rpc.{}".format(args.port)) elif args.transport_type == HTTP_NAME: # Set request and response capacity to 1mb max_size = 1048576 transport = FHttpTransport("http://localhost:" + str(args.port), request_capacity=max_size, response_capacity=max_size) else: print("Unknown transport type: {}".format(args.transport_type)) sys.exit(1) try: yield transport.open() except TTransportException as ex: logging.error(ex) raise gen.Return() client = FrugalTestClient(FServiceProvider(transport, protocol_factory), client_middleware) ctx = FContext("test") yield test_rpc(client, ctx, args.transport_type) if transport == NATS_NAME: yield test_pub_sub(nats_client, protocol_factory, args.port) global middleware_called if not middleware_called: print("Client middleware never invoked") exit(1) # Cleanup after tests yield nats_client.close()
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 main(): nc = NATS() # Set pool servers in the cluster and give a name to the client # each with its own auth credentials. options = { "servers": [ "nats://*****:*****@127.0.0.1:4222", "nats://*****:*****@127.0.0.1:4223", "nats://*****:*****@127.0.0.1:4224" ] } # Error callback takes the error type as param. def error_cb(e): print("Error! ", e) def close_cb(): print("Connection was closed!") def disconnected_cb(): print("Disconnected!") def reconnected_cb(): print("Reconnected!") # Set callback to be dispatched whenever we get # protocol error message from the server. options["error_cb"] = error_cb # Called when we are not connected anymore to the NATS cluster. options["closed_cb"] = close_cb # Called whenever we become disconnected from a NATS server. options["disconnected_cb"] = disconnected_cb # Called when we connect to a node in the NATS cluster again. options["reconnected_cb"] = reconnected_cb yield nc.connect(**options) @tornado.gen.coroutine def subscriber(msg): yield nc.publish("pong", "pong:{0}".format(msg.data)) yield nc.subscribe("ping", "", subscriber) for i in range(0, 100): yield nc.publish("ping", "ping:{0}".format(i)) yield tornado.gen.sleep(0.1) yield nc.close() try: yield nc.publish("ping", "ping") except ErrConnectionClosed: print("No longer connected to NATS cluster.")
def go(loop): nc = NATS() try: yield from nc.connect(io_loop=loop) except: pass 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") def request_handler(msg): print("[Request on '{} {}']: {}".format(msg.subject, msg.reply, msg.data.decode())) 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", request_handler) try: # Make a request expecting a single response within 500 ms, # otherwise raising a timeout error. response = 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 main(): nc = NATS() # Set pool servers in the cluster and give a name to the client # each with its own auth credentials. options = { "servers": [ "nats://*****:*****@127.0.0.1:4222", "nats://*****:*****@127.0.0.1:4223", "nats://*****:*****@127.0.0.1:4224" ] } # Error callback takes the error type as param. def error_cb(e): print("Error! ", e) def close_cb(): print("Connection was closed!") def disconnected_cb(): print("Disconnected!") def reconnected_cb(): print("Reconnected!") # Set callback to be dispatched whenever we get # protocol error message from the server. options["error_cb"] = error_cb # Called when we are not connected anymore to the NATS cluster. options["close_cb"] = close_cb # Called whenever we become disconnected from a NATS server. options["disconnected_cb"] = disconnected_cb # Called when we connect to a node in the NATS cluster again. options["reconnected_cb"] = reconnected_cb yield nc.connect(**options) @tornado.gen.coroutine def subscriber(msg): yield nc.publish("pong", "pong:{0}".format(msg.data)) yield nc.subscribe("ping", "", subscriber) for i in range(0, 100): yield nc.publish("ping", "ping:{0}".format(i)) yield tornado.gen.sleep(0.1) yield nc.close() try: yield nc.publish("ping", "ping") except ErrConnectionClosed: print("No longer connected to NATS cluster.")
def main(): nc = NATS() # Establish connection to the server. yield nc.connect("nats://demo.nats.io:4222") @tornado.gen.coroutine def message_handler(msg): subject = msg.subject data = msg.data print("[Received on '{}'] : {}".format(subject, data.decode())) # Simple async subscriber sid = yield nc.subscribe("foo", cb=message_handler) # Stop receiving after 2 messages. yield nc.auto_unsubscribe(sid, 2) yield nc.publish("foo", b'Hello') yield nc.publish("foo", b'World') yield nc.publish("foo", b'!!!!!') # Request/Response @tornado.gen.coroutine def help_request_handler(msg): print("[Received on '{}']: {}".format(msg.subject, msg.data)) yield nc.publish(msg.reply, "OK, I can help!") # Susbcription using distributed queue named 'workers' sid = yield nc.subscribe("help", "workers", help_request_handler) try: # Send a request and expect a single response # and trigger timeout if not faster than 200 ms. msg = yield nc.request("help", b"Hi, need help!", timeout=0.2) print("[Response]: %s" % msg.data) except tornado.gen.TimeoutError: print("Response Timeout!") # Remove interest in subscription. yield nc.unsubscribe(sid) # Terminate connection to NATS. yield nc.close()
def main(): # Declare the protocol stack used for serialization. # Protocol stacks must match between publishers and subscribers. prot_factory = FProtocolFactory(TBinaryProtocol.TBinaryProtocolFactory()) # Open a NATS connection to receive requests nats_client = NATS() options = {"verbose": True, "servers": ["nats://127.0.0.1:4222"]} yield nats_client.connect(**options) # Create a pub sub scope using the configured transport and protocol transport_factory = FNatsPublisherTransportFactory(nats_client) provider = FScopeProvider(transport_factory, None, prot_factory) # Create a publisher publisher = AlbumWinnersPublisher(provider) yield publisher.open() # Publish an album win event album = Album() album.ASIN = str(uuid.uuid4()) album.duration = 12000 album.tracks = [ Track(title="Comme des enfants", artist="Coeur de pirate", publisher="Grosse Boîte", composer="Béatrice Martin", duration=169, pro=PerfRightsOrg.ASCAP) ] yield publisher.publish_Winner(FContext(), album) yield publisher.publish_ContestStart(FContext(), [album, album]) yield publisher.close() yield nats_client.close()
def nats(server, subject, msg): """ NATS client implemented via tornado (NATS py2 approach), see https://github.com/nats-io/nats.py2 """ nc = NATS() try: yield nc.connect(server, max_reconnect_attempts=3) except Exception as exp: print("failed to connect to server: error {}".format(str(exp))) traceback.print_exc() return if isinstance(msg, list): for item in msg: yield nc.publish(subject, item) else: yield nc.publish(subject, msg) # 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) yield nc.close()