Esempio n. 1
0
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()
Esempio n. 2
0
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()
Esempio n. 3
0
     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")
Esempio n. 4
0
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.")
Esempio n. 5
0
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.")
Esempio n. 6
0
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.")
Esempio n. 7
0
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()
Esempio n. 8
0
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()
Esempio n. 9
0
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()