예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
 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()
예제 #4
0
  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()
예제 #5
0
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()
예제 #6
0
    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)
예제 #7
0
    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()
예제 #8
0
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.")
예제 #9
0
    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()
예제 #10
0
def run(loop):
    nc = NATS()

    yield from nc.connect(servers=["nats://127.0.0.1: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 '{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()
예제 #11
0
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()
예제 #12
0
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()
예제 #13
0
    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()
예제 #14
0
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()
예제 #15
0
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()
예제 #16
0
 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()
예제 #17
0
 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")
예제 #18
0
 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 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()
예제 #20
0
 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()
예제 #21
0
 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)
예제 #22
0
 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()
예제 #23
0
def run(loop):
    nc = NATS()
    yield from nc.connect(servers=["nats://127.0.0.1:4222"], io_loop=loop)

    yield from nc.publish("foo.thing", b'Hello!')
    message = 'Current date: at {now}'.format(now=datetime.now().isoformat())
    yield from nc.publish("foo.thing", message.encode())

    yield from nc.flush()
    yield from nc.close()
예제 #24
0
 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)
예제 #25
0
    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(e):
            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()
    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()
예제 #27
0
  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)
예제 #28
0
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()
예제 #29
0
 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)
예제 #30
0
 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 test_async_await_messages_delivery_order(self):
        nc = NATS()
        msgs = []
        errors = []

        async def error_handler(e):
            errors.push(e)

        yield from nc.connect(io_loop=self.loop, error_cb=error_handler)

        @asyncio.coroutine
        def handler_foo(msg):
          msgs.append(msg)

          # Should not block other subscriptions from receiving messages.
          yield from asyncio.sleep(0.2, loop=self.loop)
          if msg.reply != "":
            yield from nc.publish(msg.reply, msg.data*2)
        yield from nc.subscribe("foo", cb=handler_foo)

        async def handler_bar(msg):
          msgs.append(msg)
          if msg.reply != "":
            await nc.publish(msg.reply, b'')
        yield from nc.subscribe("bar", cb=handler_bar)

        yield from nc.publish("foo", b'1')
        yield from nc.publish("foo", b'2')
        yield from nc.publish("foo", b'3')

        # Will be processed before the others since no head of line
        # blocking among the subscriptions.
        yield from nc.publish("bar", b'4')

        response = yield from nc.request("foo", b'hello1', 1)
        self.assertEqual(response.data, b'hello1hello1')

        with self.assertRaises(ErrTimeout):
            yield from nc.request("foo", b'hello2', 0.1)

        yield from nc.publish("bar", b'5')
        response = yield from nc.request("foo", b'hello2', 1)
        self.assertEqual(response.data, b'hello2hello2')

        self.assertEqual(msgs[0].data, b'1')
        self.assertEqual(msgs[1].data, b'4')
        self.assertEqual(msgs[2].data, b'2')
        self.assertEqual(msgs[3].data, b'3')
        self.assertEqual(msgs[4].data, b'hello1')
        self.assertEqual(msgs[5].data, b'hello2')
        self.assertEqual(len(errors), 0)
        yield from nc.close()
예제 #32
0
파일: events.py 프로젝트: vtalks/vtalks.net
    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()
예제 #33
0
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_subscription_slow_consumer_pending_bytes_limit(self):
        nc = NATS()
        msgs = []
        errors = []

        async def error_handler(e):
            if type(e) is ErrSlowConsumer:
                errors.append(e)

        yield from nc.connect(io_loop=self.loop, error_cb=error_handler)

        @asyncio.coroutine
        def handler_foo(msg):
            yield from asyncio.sleep(0.2, loop=self.loop)

            msgs.append(msg)
            if msg.reply != "":
                yield from nc.publish(msg.reply, msg.data*2)
        yield from nc.subscribe("foo", cb=handler_foo, pending_bytes_limit=10)

        async def handler_bar(msg):
            msgs.append(msg)
            if msg.reply != "":
                await nc.publish(msg.reply, msg.data*3)
        yield from nc.subscribe("bar", cb=handler_bar)

        for i in range(10):
            yield from nc.publish("foo", "AAA{}".format(i).encode())

        # Will be processed before the others since no head of line
        # blocking among the subscriptions.
        yield from nc.publish("bar", b'14')

        response = yield from nc.request("bar", b'hi1', 2)
        self.assertEqual(response.data, b'hi1hi1hi1')
        self.assertEqual(len(msgs), 2)
        self.assertEqual(msgs[0].data, b'14')
        self.assertEqual(msgs[1].data, b'hi1')

        # Consumed a few messages but the rest were slow consumers.
        self.assertTrue(7 <= len(errors) <= 8)
        for e in errors:
            self.assertEqual(type(e), ErrSlowConsumer)
        self.assertEqual(errors[0].sid, 1)

        # Try again a few seconds later and it should have recovered
        yield from asyncio.sleep(3, loop=self.loop)
        response = yield from nc.request("foo", b'B', 1)
        self.assertEqual(response.data, b'BB')
        yield from nc.close()
def run(loop):
    nc = NATS()

    yield from nc.connect(servers=["nats://127.0.0.1:4222"], io_loop=loop)

    #yield from nc.publish("k8s.events", b'[{"cloudType":"K8s","action":"Item Created", "text":"Event from K8S"}]')
    yield from nc.publish(
        "aws.events",
        b'[{"cloudType":"AWS","action":"Item Created", "text":"Event from AWS"}]'
    )
    #yield from nc.publish("k8s.alarms", b'Alarm from K8S')
    #yield from nc.publish("aws.alarms", b'Alarm from AWS')

    yield from nc.close()
예제 #36
0
파일: tls.py 프로젝트: Gr1N/asyncio-nats
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()
예제 #37
0
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()
예제 #38
0
    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)
예제 #39
0
    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)
예제 #40
0
 def publish_msg(self, subject, msg, loop):
     client = NATS()
     servers = [self.url]
     options = {
         "io_loop": loop,
         "servers": servers,
     }
     try:
         yield from client.connect(**options)
         yield from client.publish(subject, msg)
         yield from client.flush()
         yield from client.close()
     except Exception as e:
         print(e)
         pass
예제 #41
0
파일: test.py 프로젝트: tilient/gotests
def run(loop):
    nc = NATS()
    options = {
        "servers": [
            "nats://tilient.org:44222",
            "nats://wiffel.space:44222",
        ],
        "io_loop": loop,
    }
    yield from nc.connect(**options)
    yield from nc.publish("count", b"33")
    yield from nc.flush(0.500)
    yield from nc.publish("cmd", b"quit")
    yield from nc.flush(0.500)
    yield from nc.close()
예제 #42
0
    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)
        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()

        # After close, the subscription is gone
        with self.assertRaises(KeyError):
            nc._subs[sid]

        self.assertEqual(1, nc.stats['in_msgs'])
        self.assertEqual(11, nc.stats['in_bytes'])
        self.assertEqual(2, nc.stats['out_msgs'])
        self.assertEqual(22, nc.stats['out_bytes'])

        endpoint = '127.0.0.1:{port}'.format(
            port=self.server_pool[0].http_port)
        httpclient = http.client.HTTPConnection(endpoint, timeout=5)
        httpclient.request('GET', '/connz')
        response = httpclient.getresponse()
        connz = json.loads((response.read()).decode())
        self.assertEqual(1, len(connz['connections']))
        self.assertEqual(2, connz['connections'][0]['in_msgs'])
        self.assertEqual(22, connz['connections'][0]['in_bytes'])
        self.assertEqual(1, connz['connections'][0]['out_msgs'])
        self.assertEqual(11, connz['connections'][0]['out_bytes'])
예제 #43
0
    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)
        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()

        # After close, the subscription is gone
        with self.assertRaises(KeyError):
            nc._subs[sid]

        self.assertEqual(1,  nc.stats['in_msgs'])
        self.assertEqual(11, nc.stats['in_bytes'])
        self.assertEqual(2,  nc.stats['out_msgs'])
        self.assertEqual(22, nc.stats['out_bytes'])

        endpoint = '127.0.0.1:{port}'.format(
            port=self.server_pool[0].http_port)
        httpclient = http.client.HTTPConnection(endpoint, timeout=5)
        httpclient.request('GET', '/connz')
        response = httpclient.getresponse()
        connz = json.loads((response.read()).decode())
        self.assertEqual(1, len(connz['connections']))
        self.assertEqual(2,  connz['connections'][0]['in_msgs'])
        self.assertEqual(22, connz['connections'][0]['in_bytes'])
        self.assertEqual(1,  connz['connections'][0]['out_msgs'])
        self.assertEqual(11, connz['connections'][0]['out_bytes'])
예제 #44
0
def run(loop):
    nc = NATS()

    yield from nc.connect("127.0.0.1:4222", 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.
    sid = 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.request("help", b'help me', 0.050)
        print("Received response: {message}".format(
            message=response.data.decode()))
    except ErrTimeout:
        print("Request timed out")

    # Remove interest in subscription.
    yield from nc.unsubscribe(sid)

    yield from nc.close()
예제 #45
0
    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()
예제 #46
0
  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()
예제 #47
0
    def test_unsubscribe(self):
        nc = NATS()
        msgs = []

        @asyncio.coroutine
        def subscription_handler(msg):
            msgs.append(msg)

        yield from nc.connect(io_loop=self.loop)
        sid = yield from nc.subscribe("foo", cb=subscription_handler)
        yield from nc.publish("foo", b'A')
        yield from nc.publish("foo", b'B')

        # Wait a bit to receive the messages
        yield from asyncio.sleep(0.5, loop=self.loop)
        self.assertEqual(2, len(msgs))
        yield from nc.unsubscribe(sid)
        yield from nc.publish("foo", b'C')
        yield from nc.publish("foo", b'D')

        # Ordering should be preserverd in these at least
        self.assertEqual(b'A', msgs[0].data)
        self.assertEqual(b'B', msgs[1].data)

        # Should not exist by now
        with self.assertRaises(KeyError):
            nc._subs[sid].received

        yield from asyncio.sleep(1, loop=self.loop)
        endpoint = '127.0.0.1:{port}'.format(
            port=self.server_pool[0].http_port)
        httpclient = http.client.HTTPConnection(endpoint, timeout=5)
        httpclient.request('GET', '/connz')
        response = httpclient.getresponse()
        connz = json.loads((response.read()).decode())
        self.assertEqual(1, len(connz['connections']))
        self.assertEqual(0, connz['connections'][0]['subscriptions'])
        self.assertEqual(4, connz['connections'][0]['in_msgs'])
        self.assertEqual(4, connz['connections'][0]['in_bytes'])
        self.assertEqual(2, connz['connections'][0]['out_msgs'])
        self.assertEqual(2, connz['connections'][0]['out_bytes'])

        yield from nc.close()
        self.assertEqual(2, nc.stats['in_msgs'])
        self.assertEqual(2, nc.stats['in_bytes'])
        self.assertEqual(4, nc.stats['out_msgs'])
        self.assertEqual(4, nc.stats['out_bytes'])
예제 #48
0
    def test_unsubscribe(self):
        nc = NATS()
        msgs = []

        @asyncio.coroutine
        def subscription_handler(msg):
            msgs.append(msg)

        yield from nc.connect(io_loop=self.loop)
        sid = yield from nc.subscribe("foo", cb=subscription_handler)
        yield from nc.publish("foo", b'A')
        yield from nc.publish("foo", b'B')

        # Wait a bit to receive the messages
        yield from asyncio.sleep(0.5, loop=self.loop)
        self.assertEqual(2, len(msgs))
        yield from nc.unsubscribe(sid)
        yield from nc.publish("foo", b'C')
        yield from nc.publish("foo", b'D')

        # Ordering should be preserverd in these at least
        self.assertEqual(b'A', msgs[0].data)
        self.assertEqual(b'B', msgs[1].data)

        # Should not exist by now
        with self.assertRaises(KeyError):
            nc._subs[sid].received

        yield from asyncio.sleep(1, loop=self.loop)
        endpoint = '127.0.0.1:{port}'.format(
            port=self.server_pool[0].http_port)
        httpclient = http.client.HTTPConnection(endpoint, timeout=5)
        httpclient.request('GET', '/connz')
        response = httpclient.getresponse()
        connz = json.loads((response.read()).decode())
        self.assertEqual(1, len(connz['connections']))
        self.assertEqual(0,  connz['connections'][0]['subscriptions'])
        self.assertEqual(4,  connz['connections'][0]['in_msgs'])
        self.assertEqual(4,  connz['connections'][0]['in_bytes'])
        self.assertEqual(2,  connz['connections'][0]['out_msgs'])
        self.assertEqual(2,  connz['connections'][0]['out_bytes'])

        yield from nc.close()
        self.assertEqual(2, nc.stats['in_msgs'])
        self.assertEqual(2, nc.stats['in_bytes'])
        self.assertEqual(4, nc.stats['out_msgs'])
        self.assertEqual(4, nc.stats['out_bytes'])
예제 #49
0
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()
예제 #50
0
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()
예제 #51
0
파일: basic.py 프로젝트: Gr1N/asyncio-nats
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()
예제 #52
0
  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)
예제 #53
0
  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'])
예제 #54
0
  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()
예제 #55
0
def run(loop):
  nc = NATS()

  try:
    yield from nc.connect(io_loop=loop)
  except ErrNoServers as e:
    print(e)
    return

  @asyncio.coroutine
  def message_handler(msg):
    subject = msg.subject
    reply = msg.reply
    data = msg.data.decode()
    for i in range(0, 20):
      yield from nc.publish(reply, "i={i}".format(i=i).encode())

  yield from nc.subscribe("help.>", cb=message_handler)

  @asyncio.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 from nc.request("help.please", b'help', expected=10, cb=request_handler)

  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()
예제 #56
0
    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)
예제 #57
0
  def test_publish(self):
    nc = NATS()
    yield from nc.connect(io_loop=self.loop)
    for i in range(0, 100):
      yield from nc.publish("hello.%d" % i, b'A')

    with self.assertRaises(ErrBadSubject):
      yield from nc.publish("", b'')

    yield from nc.flush()
    yield from nc.close()
    yield from asyncio.sleep(1, loop=self.loop)
    self.assertEqual(100, nc.stats['out_msgs'])
    self.assertEqual(100, nc.stats['out_bytes'])

    endpoint = '127.0.0.1:{port}'.format(port=self.server_pool[0].http_port)
    httpclient = http.client.HTTPConnection(endpoint, timeout=5)
    httpclient.request('GET', '/varz')
    response = httpclient.getresponse()
    varz = json.loads((response.read()).decode())
    self.assertEqual(100, varz['in_msgs'])
    self.assertEqual(100, varz['in_bytes'])
예제 #58
0
    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()
class Service(pykka.ThreadingActor):
    """
    NATS service implementation.
    :param my_args: dict like {connection, service_q, treatment_callback[, service_name]}
    :param connection_args: dict like {user, password, host[, port, client_properties]}
    """

    def __init__(self, my_args=None, connection_args=None):
        """
        NATS service constructor
        :param my_args: dict like {connection, service_q, treatment_callback[, service_name]}
        :param connection_args: dict like {user, password, host[, port, client_properties]}
        :return: self
        """
        LOGGER.debug("natsd.Service.__init__")
        if my_args is None or connection_args is None:
            raise exceptions.ArianeConfError("service arguments")
        if 'service_q' not in my_args or my_args['service_q'] is None or not my_args['service_q']:
            raise exceptions.ArianeConfError("service_q")
        if 'treatment_callback' not in my_args or my_args['treatment_callback'] is None:
            raise exceptions.ArianeConfError("treatment_callback")
        if 'service_name' not in my_args or my_args['service_name'] is None or not my_args['service_name']:
            LOGGER.warn("natsd.Service.__init__ - service_name is not defined ! Use default : " +
                        self.__class__.__name__)
            my_args['service_name'] = self.__class__.__name__

        Driver.validate_driver_conf(connection_args)

        super(Service, self).__init__()
        self.connection_args = copy.deepcopy(connection_args)
        self.servers = [
            "nats://" + connection_args['user'] + ":" + connection_args['password'] + "@" +
            connection_args['host']+":"+str(connection_args['port'])
        ]
        self.name = self.connection_args['client_properties']['ariane.app'] + "@" + socket.gethostname() + \
            " - service on " + my_args['service_q']
        self.loop = None
        self.options = None
        self.nc = Client()
        self.serviceQ = my_args['service_q']
        self.serviceQS = None
        self.service_name = my_args['service_name']
        self.service = None
        self.cb = my_args['treatment_callback']
        self.is_started = False

    def on_request(self, msg):
        """
        message consumed treatment through provided callback and basic ack
        """
        LOGGER.debug("natsd.Service.on_request - request " + str(msg) + " received")
        try:
            working_response = json.loads(msg.data.decode())
            working_properties = DriverTools.json2properties(working_response['properties'])
            working_body = b''+bytes(working_response['body'], 'utf8') if 'body' in working_response else None
            working_body_decoded = base64.b64decode(working_body) if working_body is not None else \
                bytes(json.dumps({}), 'utf8')
            self.cb(working_properties, working_body_decoded)
        except Exception as e:
            LOGGER.warn("natsd.Service.on_request - Exception raised while treating msg {"+str(msg)+","+str(msg)+"}")
        LOGGER.debug("natsd.Service.on_request - request " + str(msg) + " treated")

    def connect(self):
        LOGGER.debug("natsd.Service.connect")
        try:
            yield from self.nc.connect(**self.options)
            self.serviceQS = yield from self.nc.subscribe(self.serviceQ, cb=self.on_request)
            self.is_started = True
        except ErrNoServers as e:
            print(e)
            return

    def run_event_loop(self):
        LOGGER.debug("natsd.Service.run_event_loop")
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        self.options = {
            "servers": self.servers,
            "name": self.name,
            # "disconnected_cb": self.disconnected_cb,
            # "reconnected_cb": self.reconnected_cb,
            # "error_cb": self.error_cb,
            # "closed_cb": self.closed_cb,
            "io_loop": self.loop,
        }
        self.loop.create_task(self.connect())
        self.loop.run_forever()

    def on_start(self):
        """
        start the service
        """
        LOGGER.debug("natsd.Service.on_start")
        self.service = threading.Thread(target=self.run_event_loop, name=self.serviceQ + " service thread")
        self.service.start()
        while not self.is_started:
            time.sleep(0.01)

    def on_stop(self):
        """
        stop the service
        """
        LOGGER.debug("natsd.Service.on_stop")
        self.is_started = False
        try:
            next(self.nc.unsubscribe(self.serviceQS))
        except StopIteration as e:
            pass
        try:
            next(self.nc.close())
        except StopIteration as e:
            pass
        try:
            for task in asyncio.Task.all_tasks(self.loop):
                task.cancel()
            self.loop.stop()
            while self.loop.is_running():
                time.sleep(1)
            self.loop.close()
        except Exception as e:
            LOGGER.debug("natsd.Service.on_stop - Exception aio clean up : "
                         + traceback.format_exc())

    def on_failure(self, exception_type, exception_value, traceback_):
        LOGGER.error("natsd.Requester.on_failure - " + exception_type.__str__() + "/" + exception_value.__str__())
        LOGGER.error("natsd.Requester.on_failure - " + traceback_.format_exc())
        self.is_started = False
        try:
            next(self.nc.unsubscribe(self.serviceQS))
        except StopIteration as e:
            pass
        try:
            next(self.nc.close())
        except StopIteration as e:
            pass
        try:
            for task in asyncio.Task.all_tasks(self.loop):
                task.cancel()
            self.loop.stop()
            while self.loop.is_running():
                time.sleep(1)
            self.loop.close()
        except Exception as e:
            LOGGER.debug("natsd.Service.on_failure - Exception aio clean up : "
                         + traceback.format_exc())