/** * 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(); }
public <T> NotifyingFuture<T> callRemoteMethodWithFuture( Address dest, MethodCall call, RequestOptions options) throws Throwable { if (log.isTraceEnabled()) log.trace("dest=" + dest + ", method_call=" + call + ", options=" + options); Object buf = req_marshaller != null ? req_marshaller.objectToBuffer(call) : Util.objectToByteBuffer(call); Message msg = new Message(dest, null, null); if (buf instanceof Buffer) msg.setBuffer((Buffer) buf); else msg.setBuffer((byte[]) buf); msg.setFlag(options.getFlags()); if (options.getScope() > 0) msg.setScope(options.getScope()); return super.sendMessageWithFuture(msg, options); }
/** * Invokes a method in all members contained in dests (or all members if dests is null). * * @param dests A list of addresses. If null, the method will be invoked on all cluster members * @param method_call The method (plus args) to be invoked * @param options A collection of call options, e.g. sync versus async, timeout etc * @return RspList A list of return values and flags (suspected, not received) per member * @since 2.9 */ public RspList callRemoteMethods( Collection<Address> dests, MethodCall method_call, RequestOptions options) { if (dests != null && dests.isEmpty()) { // don't send if dest list is empty if (log.isTraceEnabled()) log.trace( new StringBuilder("destination list of ") .append(method_call.getName()) .append("() is empty: no need to send message")); return RspList.EMPTY_RSP_LIST; } if (log.isTraceEnabled()) log.trace( new StringBuilder("dests=") .append(dests) .append(", method_call=") .append(method_call) .append(", options=") .append(options)); Object buf; try { buf = req_marshaller != null ? req_marshaller.objectToBuffer(method_call) : Util.objectToByteBuffer(method_call); } catch (Exception e) { // if(log.isErrorEnabled()) log.error("exception", e); // we will change this in 3.0 to add the exception to the signature // (see http://jira.jboss.com/jira/browse/JGRP-193). The reason for a RTE is that we cannot // change the // signature in 2.3, otherwise 2.3 would be *not* API compatible to prev releases throw new RuntimeException("failure to marshal argument(s)", e); } Message msg = new Message(); if (buf instanceof Buffer) msg.setBuffer((Buffer) buf); else msg.setBuffer((byte[]) buf); msg.setFlag(options.getFlags()); if (options.getScope() > 0) msg.setScope(options.getScope()); RspList retval = super.castMessage(dests, msg, options); if (log.isTraceEnabled()) log.trace("responses: " + retval); return retval; }
public Object callRemoteMethod(Address dest, MethodCall call, RequestOptions options) throws Throwable { if (log.isTraceEnabled()) log.trace("dest=" + dest + ", method_call=" + call + ", options=" + options); Object buf = req_marshaller != null ? req_marshaller.objectToBuffer(call) : Util.objectToByteBuffer(call); Message msg = new Message(dest, null, null); if (buf instanceof Buffer) msg.setBuffer((Buffer) buf); else msg.setBuffer((byte[]) buf); msg.setFlag(options.getFlags()); if (options.getScope() > 0) msg.setScope(options.getScope()); Object retval = super.sendMessage(msg, options); if (log.isTraceEnabled()) log.trace("retval: " + retval); if (retval instanceof Throwable) throw (Throwable) retval; return retval; }
/** * Sends a unicast message to the target defined by msg.getDest() and returns a future * * @param msg The unicast message to be sent. msg.getDest() must not be null * @param options * @param listener A FutureListener which will be registered (if non null) with the future * <em>before</em> the call is invoked * @return NotifyingFuture<T> A future from which the result can be fetched * @throws Exception If there was problem sending the request, processing it at the receiver, or * processing it at the sender. {@link java.util.concurrent.Future#get()} will throw this * exception * @throws TimeoutException If the call didn't succeed within the timeout defined in options (if * set) */ public <T> NotifyingFuture<T> sendMessageWithFuture( Message msg, RequestOptions options, FutureListener<T> listener) throws Exception { Address dest = msg.getDest(); if (dest == null) throw new IllegalArgumentException("message destination is null, cannot send message"); if (options != null) { msg.setFlag(options.getFlags()).setTransientFlag(options.getTransientFlags()); if (options.getScope() > 0) msg.setScope(options.getScope()); if (options.getMode() == ResponseMode.GET_NONE) async_unicasts.incrementAndGet(); else sync_unicasts.incrementAndGet(); } UnicastRequest<T> req = new UnicastRequest<T>(msg, corr, dest, options); if (listener != null) req.setListener(listener); req.setBlockForResults(false); req.execute(); if (options != null && options.getMode() == ResponseMode.GET_NONE) return new NullFuture<T>(null); return req; }
protected <T> GroupRequest<T> cast( final Collection<Address> dests, Message msg, RequestOptions options, boolean block_for_results, FutureListener<RspList<T>> listener) throws Exception { if (msg.getDest() != null && !(msg.getDest() instanceof AnycastAddress)) throw new IllegalArgumentException("message destination is non-null, cannot send message"); if (options != null) { msg.setFlag(options.getFlags()).setTransientFlag(options.getTransientFlags()); if (options.getScope() > 0) msg.setScope(options.getScope()); } List<Address> real_dests; // we need to clone because we don't want to modify the original if (dests != null) { real_dests = new ArrayList<Address>(); for (Address dest : dests) { if (dest instanceof SiteAddress || this.members.contains(dest)) { if (!real_dests.contains(dest)) real_dests.add(dest); } } } else real_dests = new ArrayList<Address>(members); // if local delivery is off, then we should not wait for the message from the local member. // therefore remove it from the membership Channel tmp = channel; if ((tmp != null && tmp.getDiscardOwnMessages()) || msg.isTransientFlagSet(Message.TransientFlag.DONT_LOOPBACK)) { if (local_addr == null) local_addr = tmp != null ? tmp.getAddress() : null; if (local_addr != null) real_dests.remove(local_addr); } if (options != null && options.hasExclusionList()) { Address[] exclusion_list = options.exclusionList(); for (Address excluding : exclusion_list) real_dests.remove(excluding); } // don't even send the message if the destination list is empty if (log.isTraceEnabled()) log.trace("real_dests=" + real_dests); if (real_dests.isEmpty()) { if (log.isTraceEnabled()) log.trace("destination list is empty, won't send message"); return null; } if (options != null) { boolean async = options.getMode() == ResponseMode.GET_NONE; if (options.getAnycasting()) { if (async) async_anycasts.incrementAndGet(); else sync_anycasts.incrementAndGet(); } else { if (async) async_multicasts.incrementAndGet(); else sync_multicasts.incrementAndGet(); } } GroupRequest<T> req = new GroupRequest<T>(msg, corr, real_dests, options); if (listener != null) req.setListener(listener); if (options != null) { req.setResponseFilter(options.getRspFilter()); req.setAnycasting(options.getAnycasting()); } req.setBlockForResults(block_for_results); req.execute(); return req; }