@Override public byte[] serializeMessage(final BasicRuntime runtime, Message message) throws Exception { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final ObjectOutput out = createObjectOutput(runtime, baos); out.writeByte(message.getMessageType()); out.writeInt(message.getMessageId()); if (message.getReferenceAddress() != null) { final UUID uuid = message.getReferenceAddress().asUUID(); out.writeLong(uuid.getMostSignificantBits()); out.writeLong(uuid.getLeastSignificantBits()); } else { out.writeLong(0); out.writeLong(0); } out.writeInt(message.getInterfaceId()); out.writeInt(message.getMethodId()); out.writeObject(message.getObjectId()); out.writeObject(message.getHeaders()); out.writeObject(message.getFromNode()); out.writeObject(message.getPayload()); return baos.toByteArray(); }
private void logMessage(final Message message, boolean in) long messageId = message.getMessageId(); String from = message.getFromNode() != null ? String.valueOf(message.getFromNode().asUUID().getLeastSignificantBits()) : in ? "IN" : "OUT"; String to = message.getToNode() != null ? String.valueOf(message.getToNode().asUUID().getLeastSignificantBits()) : in ? "OUT" : "IN"; final Object payload = message.getPayload(); if (payload instanceof Object[]) if (message.getInterfaceId() != 0) Class clazz = DefaultClassDictionary.get().getClassById(message.getInterfaceId()); if (clazz != null) final Method method = DefaultDescriptorFactory.get().getInvoker(clazz).getMethod(message.getMethodId()); strTarget = clazz.getSimpleName() + ":" + message.getObjectId() + "." + method.getName();
@Override public Message deserializeMessage(final BasicRuntime runtime, final byte[] payload) throws Exception { final ObjectInput in = createObjectInput(runtime, new ByteArrayInputStream(payload)); final Message message = new Message(); message.setMessageType(in.readByte()); message.setMessageId(in.readInt()); long most = in.readLong(); long least = in.readLong(); message.setReferenceAddress(most != 0 && least != 0 ? new NodeAddressImpl(new UUID(most, least)) : null); message.setInterfaceId(in.readInt()); message.setMethodId(in.readInt()); message.setObjectId(in.readObject()); message.setHeaders((Map) in.readObject()); message.setFromNode((NodeAddress) in.readObject()); message.setPayload(in.readObject()); return message; }
@Override public byte[] serializeMessage(final BasicRuntime runtime, final Message message) throws Exception { ensureInit(runtime); if (message.getPayload() instanceof Throwable && message.getMessageType() == MessageDefinitions.RESPONSE_ERROR) { final StringWriter sw = new StringWriter(); try (PrintWriter pw = new PrintWriter(sw)) { ((Throwable) message.getPayload()).printStackTrace(pw); pw.flush(); } message.withPayload(sw.toString()); } if (message.getHeaders() != null && message.getHeaders().size() == 0) { message.setHeaders(null); } return mapper.writeValueAsBytes(message); }
@Override public byte[] serializeMessage(BasicRuntime basicRuntime, Message message) throws Exception { return outputPool.run(out -> { return kryoPool.run(kryo -> { out.writeByte(message.getMessageType()); out.writeInt(message.getMessageId()); writeNodeAddress(out, message.getReferenceAddress()); out.writeInt(message.getInterfaceId()); out.writeInt(message.getMethodId()); writeObjectId(kryo, out, message); writeHeaders(kryo, out, message.getHeaders()); writeNodeAddress(out, message.getFromNode()); writePayload(kryo, out, message); out.flush(); return out.getByteArrayOutputStream().toByteArray(); }); }, DEFAULT_BUFFER_SIZE); }
@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; } }
return ctx.write(Pair.of(message.getToNode(), messageSerializer.serializeMessage(runtime, message))); final int messageType = message.getMessageType(); if (messageType == MessageDefinitions.REQUEST_MESSAGE || messageType == MessageDefinitions.ONE_WAY_MESSAGE) final Object payload = message.getPayload(); if (messageType == MessageDefinitions.RESPONSE_ERROR && payload instanceof Throwable) message.withMessageType(MessageDefinitions.RESPONSE_ERROR) .withPayload(toSerializationSafeException((Throwable) payload, ex2)); message.withMessageType(MessageDefinitions.RESPONSE_ERROR) .withPayload(ex2); return ctx.write(Pair.of(message.getToNode(), messageSerializer.serializeMessage(runtime, message))); message.withMessageType(MessageDefinitions.RESPONSE_PROTOCOL_ERROR) .withPayload("failed twice sending response"); return ctx.write(Pair.of(message.getToNode(), messageSerializer.serializeMessage(runtime, message)));
public Task<?> writeMessage(HandlerContext ctx, Message message) int messageId = message.getMessageId(); if (messageId != 0) logger.debug("Forwarding message: " + messageId + " to " + message.getToNode().asUUID().getLeastSignificantBits()); message.setMessageId(messageId); if (logger.isTraceEnabled()) if (message.getMessageType() != MessageDefinitions.REQUEST_MESSAGE) message.setMessageId(messageId); ); final boolean oneWay = message.getMessageType() == MessageDefinitions.ONE_WAY_MESSAGE; if (!oneWay)
if (Objects.equals(message.getToNode(), runtime.getLocalAddress())) final Object originalPayload = message.getPayload(); final Object clonedPayload; runtime.bind(); message.setPayload(clonedPayload);
private String getInvokedClassAndMethodName(Message message) { if (message.getInterfaceId() != 0) { final Class clazz = DefaultClassDictionary.get().getClassById(message.getInterfaceId()); if (clazz != null) { final Method method = DefaultDescriptorFactory.get().getInvoker(clazz).getMethod(message.getMethodId()); return clazz.getSimpleName() + "." + method.getName(); } } return null; }
final Object payload = message.getPayload(); if (payload == null) switch (message.getMessageType())
private static void writePayload(Kryo kryo, Output out, Message message) { if (message.getPayload() instanceof Object[]) { out.writeByte(PayloadType.OBJECT_ARRAY.id); kryo.writeObject(out, message.getPayload()); return; } if (message.getPayload() == null) { out.writeByte(PayloadType.NULL.id); return; } out.writeByte(PayloadType.UNKNOWN.id); kryo.writeClassAndObject(out, message.getPayload()); }
@Override public void onRead(final HandlerContext ctx, final Object msg) throws Exception { Message message = (Message) msg; final Class<?> clazz = DefaultClassDictionary.get().getClassById(message.getInterfaceId()); // TODO: check method access, check object access } }
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(); }
@Override public void onRead(HandlerContext ctx, final Object msg) { Pair<NodeAddress, byte[]> message = (Pair<NodeAddress, byte[]>) msg; Message msg1 = null; try { msg1 = messageSerializer.deserializeMessage(runtime, message.getRight()); if (msg1.getFromNode() == null) { msg1.setFromNode(message.getLeft()); } } catch (Throwable e) { logger.error("Error deserializing message", e); logger.error(InternalUtils.hexDump(32, message.getRight(), 0, message.getRight().length)); } if (msg1 != null) { ctx.fireRead(msg1); } }
@Override public String toString() { int count; final StringBuilder builder = new StringBuilder() .append("PendingResponse:").append(hashCode()) .append("[messageId=").append(message.getMessageId()); if (isDone()) { return builder.append((isCompletedExceptionally() ? ",Completed exceptionally]" : ",Completed normally]")).toString(); } if ((count = getNumberOfDependents()) != 0) { return builder.append(",Not completed,").append(count).append(" dependents]").toString(); } return builder.append(",Not completed]").toString(); }
private static void writeObjectId(Kryo kryo, Output out, Message message) { ValueType valueTypeForObjectId = ValueType.getType(message.getObjectId()); out.writeByte(valueTypeForObjectId.id); if (valueTypeForObjectId.equals(ValueType.STRING)) { out.writeString(String.valueOf(message.getObjectId())); } else if (valueTypeForObjectId.equals(ValueType.INT)) { out.writeInt((Integer) message.getObjectId()); } else { kryo.writeClassAndObject(out, message.getObjectId()); } }
@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; } }
@Override public byte[] serializeMessage(final BasicRuntime runtime, final Message message) throws Exception { ensureInit(runtime); if (message.getPayload() instanceof Throwable && message.getMessageType() == MessageDefinitions.RESPONSE_ERROR) { final StringWriter sw = new StringWriter(); try (PrintWriter pw = new PrintWriter(sw)) { ((Throwable) message.getPayload()).printStackTrace(pw); pw.flush(); } message.withPayload(sw.toString()); } if (message.getHeaders() != null && message.getHeaders().size() == 0) { message.setHeaders(null); } return mapper.writeValueAsBytes(message); }
private long getResponseTimeoutMillis(final Message message) { final Class<?> clazz = DefaultClassDictionary.get().getClassById(message.getInterfaceId()); if (clazz != null) { final Method method = DefaultDescriptorFactory.get().getInvoker(clazz).getMethod(message.getMethodId()); final Timeout timeout = timeoutAnnotationCache.getAnnotation(method); if (timeout != null) { return timeout.timeUnit().toMillis(timeout.value()); } } return responseTimeoutMillis; }