/** * Sends a unicast message and - depending on the options - returns a result * * @param msg the message to be sent. The destination needs to be non-null * @param opts the options to be used * @return T the result * @throws Exception If there was problem sending the request, processing it at the receiver, or * processing it at the sender. * @throws TimeoutException If the call didn't succeed within the timeout defined in options (if * set) */ public <T> T sendMessage(Message msg, RequestOptions opts) throws Exception { Address dest = msg.getDest(); if (dest == null) throw new IllegalArgumentException("message destination is null, cannot send message"); if (opts != null) { msg.setFlag(opts.getFlags()).setTransientFlag(opts.getTransientFlags()); if (opts.getScope() > 0) msg.setScope(opts.getScope()); if (opts.getMode() == ResponseMode.GET_NONE) async_unicasts.incrementAndGet(); else sync_unicasts.incrementAndGet(); } UnicastRequest<T> req = new UnicastRequest<T>(msg, corr, dest, opts); req.execute(); if (opts != null && opts.getMode() == ResponseMode.GET_NONE) return null; Rsp<T> rsp = req.getResult(); if (rsp.wasSuspected()) throw new SuspectedException(dest); Throwable exception = rsp.getException(); if (exception != null) { if (exception instanceof Error) throw (Error) exception; else if (exception instanceof RuntimeException) throw (RuntimeException) exception; else if (exception instanceof Exception) throw (Exception) exception; else throw new RuntimeException(exception); } if (rsp.wasUnreachable()) throw new UnreachableException(dest); if (!rsp.wasReceived() && !req.responseReceived()) throw new TimeoutException("timeout sending message to " + dest); return rsp.getValue(); }