/** * Installs this observer into this node. * Can called several times the object is registered only once. * * @param iClass hint to the framework about which ActorObserver interface this object represents. * Can be null if there are no ambiguities. * @param observer the object to install * @param <T> The type of reference class returned. * @return a remote reference that can be sent to actors, the runtime will chose one id */ default <T extends com.ea.orbit.actors.ActorObserver> T registerObserver(final Class<T> iClass, final T observer) { return registerObserver(iClass, null, observer); }
/** * Returns an actor reference */ default <T> T getReference(final Class<T> iClass, final Object id) { return getReference(this, null, iClass, id); }
static <DATA> AsyncStream<DATA> getStream(Class<DATA> dataClass, String provider, String streamId) { return BasicRuntime.getRuntime().getStream(provider, dataClass, streamId); } }
/** * Invokes a remote method. * * @param oneWay if the target should send the response back. * @param methodId the target method id * @param params parameters for the method, must all be serializable. * @param <R> generic parameter to make the compiler happy. * @return a task that will contain the returned value, or if one-way a task indicating if the message could be send. */ @SuppressWarnings("unchecked") protected <R> Task<R> invoke(final Method method, final boolean oneWay, final int methodId, final Object[] params) { return (Task<R>) (runtime != null ? runtime : BasicRuntime.getRuntime()).invoke(this, method, oneWay, methodId, params); }
@Override public Message deserializeMessage(final BasicRuntime runtime, final InputStream inputStream) throws Exception { ensureInit(runtime); try { final Message message = mapper.readValue(inputStream, Message.class); // decode payload parameters according to the interface/method if (message.getPayload() != null && (message.getMessageType() == MessageDefinitions.ONE_WAY_MESSAGE || message.getMessageType() == MessageDefinitions.REQUEST_MESSAGE)) { final ObjectInvoker invoker = runtime.getInvoker(message.getInterfaceId()); final Method method = invoker.getMethod(message.getMethodId()); final Object[] args = castArgs(method.getGenericParameterTypes(), message.getPayload()); message.setPayload(args); } return message; } catch (Exception ex) { throw ex; } }
default <T> AsyncStream<T> getStream(final Class<T> dataClass, final String streamId) { return getStream(AsyncStream.DEFAULT_PROVIDER, dataClass, streamId); }
@SuppressWarnings("unchecked") public <T> Task<StreamSubscriptionHandle<T>> subscribe(String provider, Class<T> dataClass, String streamId, AsyncObserver<T> observer) { StreamKey streamKey = new StreamKey(provider, dataClass, streamId); ConcurrentMap<Handle, AsyncObserver> observers = observerMap.get(streamKey); if (observers == null) { observers = InternalUtils.putIfAbsentAndGet(observerMap, streamKey, new ConcurrentHashMap<>()); ServerSideStreamProxy serverSideStreamProxy = runtime.getRemoteObserverReference(null, ServerSideStreamProxy.class, "0"); int dataClassId = DefaultClassDictionary.get().getClassId(dataClass); Task<StreamSubscriptionHandle<Object>> subscriptionHandleTask = serverSideStreamProxy.subscribe(provider, dataClassId, streamId, localReference); await(subscriptionHandleTask); } observers = (observers != null) ? observers : InternalUtils.putIfAbsentAndGet(observerMap, streamKey, new ConcurrentHashMap<>()); Handle handle = new Handle(streamKey, nextId.incrementAndGet()); observers.put(handle, observer); return Task.fromValue(handle); }
@Override public Message deserializeMessage(final BasicRuntime runtime, final InputStream inputStream) throws Exception { ensureInit(runtime); try { final Message message = mapper.readValue(inputStream, Message.class); // decode payload parameters according to the interface/method if (message.getPayload() != null && (message.getMessageType() == MessageDefinitions.ONE_WAY_MESSAGE || message.getMessageType() == MessageDefinitions.REQUEST_MESSAGE)) { final ObjectInvoker invoker = runtime.getInvoker(message.getInterfaceId()); final Method method = invoker.getMethod(message.getMethodId()); final Object[] args = castArgs(method.getGenericParameterTypes(), message.getPayload()); message.setPayload(args); } return message; } catch (Exception ex) { throw ex; } }
private void ensureStream() { if (actualStream == null) { if (runtime == null) { runtime = BasicRuntime.getRuntime(); } if (runtime == null) { throw new IllegalStateException("Can't find the actor runtime"); } AsyncStream<T> stream = runtime.getStream(provider, dataClass, streamId); if (stream instanceof AsyncStreamReference) { actualStream = ((AsyncStreamReference<T>) stream).actualStream; } else { actualStream = stream; } } } }
@Override public Task<?> start() { localReference = runtime.registerObserver(ClientSideStreamProxy.class, null, this); return Task.done(); }
/** * Returns an observer reference to an observer in another node. * <p/> * Should only be used if the application knows for sure that an observer with the given id * indeed exists on that other node. * <p/> * This is a low level use of orbit-actors, recommended only for ActorExtensions. * * @param address the other node address. * @param iClass the IObserverClass * @param id the id, must not be null * @param <T> the ActorObserver sub interface * @return a remote reference to the observer */ default <T extends com.ea.orbit.actors.ActorObserver> T getRemoteObserverReference(NodeAddress address, final Class<T> iClass, final Object id) { return getReference(this, address, iClass, id); }