/** * Asynchronously runs the Proton {@link Reactor} accepting and sending messages. Any other call * to this method on this {@link AmqpsIotHubConnection} will block until the {@link Reactor} * terminates and this {@link AmqpsIotHubConnection} closes. Normally, this method should only be * called once by the {@link #open()} method until the {@link AmqpsIotHubConnection} has been * closed. * * @throws IOException if the {@link AmqpsIotHubConnectionBaseHandler} has not been initialized. * @throws InterruptedException if there is a problem acquiring the semaphore. */ private synchronized void startReactorAsync() throws IOException, InterruptedException { // Acquire permit to continue execution of this method and spawn a new thread. reactorSemaphore.acquire(); if (this.amqpsHandler != null) { this.reactor = Proton.reactor(this); new Thread( () -> { try { reactor.run(); // Closing here should be okay. The reactor will only stop running if the // connection is remotely // or locally closed. The transport will attempt to receive/send a message and // will get an exception // causing it to create a new AmqpsIoTHubConnection. close(); // Release the semaphore and make permit available allowing for the next reactor // thread to spawn. reactorSemaphore.release(); } catch (Exception e) { close(); reactorSemaphore.release(); } }) .start(); } else { throw new IOException( "The Handler has not been initialized. Ensure that the AmqpsIotHubConnection is in an OPEN state by calling open()."); } }