@Override public Object read(Kryo kryo, Input input, Class type) { ReferenceReplacement replacement = kryo.readObject(input, ReferenceReplacement.class); if (replacement.address != null) { return BasicRuntime.getRuntime().getRemoteObserverReference(replacement.address, (Class<ActorObserver>) replacement.interfaceClass, replacement.id); } return BasicRuntime.getRuntime().getReference(replacement.interfaceClass, replacement.id); } }
/** * 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 ActorObserver> T registerObserver(final Class<T> iClass, final T observer) { return registerObserver(iClass, null, observer); }
public void setRuntime(final BasicRuntime runtime) { this.runtime = runtime; logger = runtime.getLogger(this); }
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 Object read(Kryo kryo, Input input, Class type) { ReferenceReplacement replacement = kryo.readObject(input, ReferenceReplacement.class); return BasicRuntime.getRuntime().getReference(replacement.interfaceClass, replacement.id); } }
@Override public void write(Kryo kryo, Output output, Object object) { ActorObserver objectReference = BasicRuntime.getRuntime().registerObserver(null, (ActorObserver) object); RemoteReference reference = (RemoteReference) objectReference; ReferenceReplacement replacement = new ReferenceReplacement(); replacement.address = reference.address; replacement.interfaceClass = reference._interfaceClass(); replacement.id = reference.id; kryo.writeObject(output, replacement); }
/** * Returns an actor reference */ default <T> T getReference(final Class<T> iClass, final Object id) { return getReference(this, null, iClass, id); }
@SuppressWarnings({ "unchecked", "rawtypes" }) @Override protected Object resolveObject(Object obj) throws IOException { if (obj instanceof ReferenceReplacement) { final ReferenceReplacement replacement = (ReferenceReplacement) obj; if (replacement.address != null) { return runtime.getRemoteObserverReference(replacement.address, (Class) replacement.interfaceClass, replacement.id); } return runtime.getReference((Class) replacement.interfaceClass, replacement.id); } return super.resolveObject(obj); } }
/** * @return the result of the method called */ @SuppressWarnings("unchecked") public Task scheduleLocalInvocation(final LocalObjects.LocalObjectEntry<Object> localObjectEntry, final Invocation invocation) { ObjectInvoker invoker = runtime.getInvoker(RemoteReference.getInterfaceId(invocation.getToReference())); return localObjectEntry.run(target -> performLocalInvocation(invocation, invoker, target) ); }
@Override public <T> T clone(T object) { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ObjectOutput outputStream = createObjectOutput(BasicRuntime.getRuntime(), byteArrayOutputStream); outputStream.writeObject(object); byte[] bytes = byteArrayOutputStream.toByteArray(); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes); ObjectInput inputStream = createObjectInput(BasicRuntime.getRuntime(), byteArrayInputStream); return (T) inputStream.readObject(); } catch (IOException | ClassNotFoundException e) { throw new IllegalArgumentException(e); } } }
default <T> AsyncStream<T> getStream(final Class<T> dataClass, final String streamId) { return getStream(AsyncStream.DEFAULT_PROVIDER, dataClass, streamId); }
public Task cleanup() { // The benchmarks showed that it's faster to iterate over all pending messages // than to keep a priority queue ordered by timeout. // The priority queue forces the application to pay the price of keeping the queue ordered // plus the synchronization cost of adding and removing elements. pendingResponseMap.values() .forEach(top -> { if (top.timeoutAt > runtime.clock().millis()) { // return the message, if there was a concurrent reception the message will be removed on the next cycle. return; } if (!top.isDone()) { final StringBuilder errorMsg = new StringBuilder(); errorMsg.append("Response timeout. "); errorMsg.append(top.message.toString()); top.internalCompleteExceptionally(new TimeoutException(errorMsg.toString())); } pendingResponseMap.remove(top.message.getMessageId()); }); return Task.done(); }
public void bind() { BasicRuntime.setRuntime(cachedRef); } }
@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); }
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 RemoteReference read(Kryo kryo, Input input, Class type) { ReferenceReplacement replacement = kryo.readObject(input, ReferenceReplacement.class); return BasicRuntime.getRuntime().getReference((Class<RemoteReference>) replacement.interfaceClass, replacement.id); } }
/** * 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); }
/** * 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 ActorObserver> T getRemoteObserverReference(NodeAddress address, final Class<T> iClass, final Object id) { return getReference(this, address, iClass, id); }
@Override public Message deserializeMessage(final BasicRuntime runtime, final byte[] payload) throws Exception { ensureInit(runtime); try { final Message message = mapper.readValue(payload, 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; } }