def run_loadbal(input, output, context=None): context = context or zmq.Context.instance() # Set up a callback so we can be notified when the device connects/binds # its input and output sockets. This resolves issues with attempting to # connect to `inproc:` sockets before they've been bound at the other end. callback = Callback() # Run the load balancer device in a separate thread. This will die once # all its sockets are closed and the context terminated. loadbal = LoadBalancer(input, output, context=context) loadbal_thread = threading.Thread(target=loadbal.run, kwargs={'callback': callback}) loadbal_thread.daemon = True loadbal_thread.start() in_sock, out_sock = callback.wait() client = context.socket(zmq.REQ) client.connect(input) try: yield client finally: client.close() in_sock.close() out_sock.close()
def test_callback_throws_errors(): cb = Callback() def throw_error(callback): callback.throw(SomeError("ABC")) with run_thread(throw_error, cb): assert_raises(SomeError, cb.wait)
def test_callback_returns_values(): cb = Callback() def return_value(callback): callback.send(123) with run_thread(return_value, cb): assert cb.wait() == 123
def test_catch_exceptions_throws_any_unhandled_exceptions_in_waiting_thread(): cb = Callback() def catch_exception(callback): with callback.catch_exceptions(): raise SomeError("ABC") with run_thread(catch_exception, cb): assert_raises(SomeError, cb.wait)
def test_catch_exceptions_without_die_arg_propagates_exceptions_in_both_threads( ): cb = Callback() success = [False] def catch_exception_without_dying(callback): with assert_raises(SomeError): with callback.catch_exceptions(die=False): raise SomeError("ABC") success[0] = True with run_thread(catch_exception_without_dying, cb): assert_raises(SomeError, cb.wait) assert success[0], "Exception wasn't raised within the original thread"
def test_reset_allows_a_callback_to_be_used_again(): cb = Callback() def return_value(callback): callback.send(123) with run_thread(return_value, cb): assert cb.wait() == 123 cb.reset() def return_value2(callback): callback.send(456) with run_thread(return_value2, cb): assert cb.wait() == 456
def multiserver_and_client(address, registry, n_workers): context = zmq.Context.instance() try: cb = Callback() ms = MultiServer(address, registry, context=context) ms_thread = cb.spawn(ms.run, args=(n_workers,), kwargs={'callback': cb}, daemon=True) cb.wait() client = context.socket(zmq.REQ) client.connect(address) try: yield client finally: client.close() finally: context.term()
def server(addr, registry, connect=False, context=None): context = context or zmq.Context.instance() # Set up a server, tell it to run in a separate thread, and pass in a # callback so that we can wait for the server to be bound before connecting # our client. This avoids an issue we were having with inproc:// transport, # wherein if the client connected before the server had bound, it would # raise an error. callback = Callback() server = Server(addr, registry, connect=connect, context=context) server_thread = threading.Thread(target=server.run, kwargs=dict(callback=callback)) server_thread.daemon = True server_thread.start() server_socket = callback.wait() try: yield finally: context.term()