Search in sources :

Example 11 with FastBuildTree

use of services.moleculer.util.FastBuildTree in project moleculer-java by moleculer-java.

the class TcpTransporter method sendGossipRequest.

/**
 * Create and send a Gossip request packet.
 */
protected Tree sendGossipRequest() {
    try {
        // Update CPU
        NodeDescriptor descriptor = getDescriptor();
        int cpu = monitor.getTotalCpuPercent();
        descriptor.writeLock.lock();
        try {
            descriptor.updateCpu(cpu);
        } finally {
            descriptor.writeLock.unlock();
        }
        // Are we alone?
        if (nodes.isEmpty()) {
            return null;
        }
        // Add "online" and "offline" blocks
        Collection<NodeDescriptor> descriptors = nodes.values();
        int size = nodes.size() + 32;
        FastBuildTree online = new FastBuildTree(size);
        FastBuildTree offline = new FastBuildTree(size);
        // Add current node
        descriptor.readLock.lock();
        try {
            ArrayList<Object> array = new ArrayList<>(3);
            array.add(descriptor.seq);
            array.add(descriptor.cpuSeq);
            array.add(descriptor.cpu);
            online.putUnsafe(nodeID, array);
        } finally {
            descriptor.readLock.unlock();
        }
        // Separate online and offline nodes
        String[] liveEndpoints = new String[size];
        String[] unreachableEndpoints = new String[size];
        int liveEndpointCount = 0;
        int unreachableEndpointCount = 0;
        // Loop on registered nodes
        for (NodeDescriptor node : descriptors) {
            node.readLock.lock();
            try {
                if (node.offlineSince > 0) {
                    // Offline
                    if (unreachableEndpointCount < unreachableEndpoints.length) {
                        unreachableEndpoints[unreachableEndpointCount++] = node.nodeID;
                    }
                    if (node.seq > 0) {
                        offline.put(node.nodeID, node.seq);
                    }
                } else {
                    if (!node.local) {
                        // Online
                        if (liveEndpointCount < liveEndpoints.length) {
                            liveEndpoints[liveEndpointCount++] = node.nodeID;
                        }
                        if (node.seq > 0) {
                            ArrayList<Object> array = new ArrayList<>(3);
                            array.add(node.seq);
                            array.add(node.cpuSeq);
                            array.add(node.cpu);
                            online.putUnsafe(node.nodeID, array);
                        }
                    }
                }
            } finally {
                node.readLock.unlock();
            }
        }
        // Create gossip request
        FastBuildTree root = new FastBuildTree(4);
        root.putUnsafe("ver", ServiceBroker.PROTOCOL_VERSION);
        root.putUnsafe("sender", nodeID);
        root.putUnsafe("online", online.asObject());
        if (!offline.isEmpty()) {
            root.putUnsafe("offline", offline.asObject());
        }
        // Serialize gossip packet (JSON, MessagePack, etc.)
        byte[] packet = serialize(PACKET_GOSSIP_REQ_ID, root);
        // Do gossiping with a live endpoint
        if (liveEndpointCount > 0) {
            sendGossipToRandomEndpoint(liveEndpoints, liveEndpointCount, packet, root);
        }
        // Do gossiping with a unreachable endpoint
        if (unreachableEndpointCount > 0) {
            // 10 nodes:
            // 1 offline / (9 online + 1) = 0.10
            // 3 offline / (7 online + 1) = 0.37
            // 5 offline / (5 online + 1) = 0.83
            // 9 offline / (1 online + 1) = 4.50
            double ratio = (double) unreachableEndpointCount / ((double) liveEndpointCount + 1);
            // Random number between 0.0 and 1.0
            double random = rnd.nextDouble();
            if (random < ratio) {
                sendGossipToRandomEndpoint(unreachableEndpoints, unreachableEndpointCount, packet, root);
            }
        }
        // For unit testing
        return root;
    } catch (Exception cause) {
        logger.error("Unable to send gossip message to peer!", cause);
    }
    return null;
}
Also used : FastBuildTree(services.moleculer.util.FastBuildTree) NodeDescriptor(services.moleculer.transporter.tcp.NodeDescriptor) ArrayList(java.util.ArrayList)

Example 12 with FastBuildTree

use of services.moleculer.util.FastBuildTree in project moleculer-java by moleculer-java.

the class DefaultServiceRegistry method throwableToTree.

// --- CONVERT THROWABLE TO RESPONSE MESSAGE ---
protected Tree throwableToTree(String id, String sender, Throwable error) {
    FastBuildTree msg = new FastBuildTree(6);
    msg.putUnsafe("id", id);
    msg.putUnsafe("ver", ServiceBroker.PROTOCOL_VERSION);
    msg.putUnsafe("sender", sender);
    msg.putUnsafe("success", false);
    msg.putUnsafe("data", null);
    if (error != null) {
        // Add message
        FastBuildTree errorMap = new FastBuildTree(2);
        msg.putUnsafe("error", errorMap);
        errorMap.putUnsafe("message", error.getMessage());
        // Add trace
        StringWriter sw = new StringWriter(128);
        PrintWriter pw = new PrintWriter(sw);
        error.printStackTrace(pw);
        errorMap.putUnsafe("trace", sw.toString());
    }
    return msg;
}
Also used : StringWriter(java.io.StringWriter) FastBuildTree(services.moleculer.util.FastBuildTree) PrintWriter(java.io.PrintWriter)

Example 13 with FastBuildTree

use of services.moleculer.util.FastBuildTree in project moleculer-java by moleculer-java.

the class DefaultServiceRegistry method receiveRequest.

// --- RECEIVE REQUEST FROM REMOTE SERVICE ---
@Override
public void receiveRequest(Tree message) {
    // Verify protocol version
    if (checkVersion) {
        String ver = message.get("ver", "unknown");
        if (!ServiceBroker.PROTOCOL_VERSION.equals(ver)) {
            logger.warn("Invalid protocol version (" + ver + ")!");
            return;
        }
    }
    // Get action property
    String action = message.get("action", (String) null);
    if (action == null || action.isEmpty()) {
        logger.warn("Missing \"action\" property!");
        return;
    }
    // Get strategy (action endpoint array) by action name
    Strategy<ActionEndpoint> strategy;
    readLock.lock();
    try {
        strategy = strategies.get(action);
    } finally {
        readLock.unlock();
    }
    if (strategy == null) {
        logger.warn("Invalid action name (" + action + ")!");
        return;
    }
    // Get local action endpoint (with cache handling)
    ActionEndpoint endpoint = strategy.getEndpoint(nodeID);
    if (endpoint == null) {
        logger.warn("Not a local action (" + action + ")!");
        return;
    }
    // Get request's unique ID
    String id = message.get("id", (String) null);
    if (id == null || id.isEmpty()) {
        logger.warn("Missing \"id\" property!");
        return;
    }
    // Get sender's nodeID
    String sender = message.get("sender", (String) null);
    if (sender == null || sender.isEmpty()) {
        logger.warn("Missing \"sender\" property!");
        return;
    }
    // Create CallOptions
    int timeout = message.get("timeout", 0);
    Tree params = message.get("params");
    // TODO Process other properties:
    // Tree meta = message.get("meta");
    // int level = message.get("level", 1);
    // boolean metrics = message.get("metrics", false);
    // String parentID = message.get("parentID", (String) null);
    // String requestID = message.get("requestID", (String) null);
    CallOptions.Options opts = CallOptions.nodeID(nodeID).timeout(timeout);
    Context ctx = contextFactory.create(action, params, opts, null);
    // Invoke action
    try {
        new Promise(endpoint.handler(ctx)).then(data -> {
            // Send response
            FastBuildTree msg = new FastBuildTree(5);
            msg.putUnsafe("sender", nodeID);
            msg.putUnsafe("id", id);
            msg.putUnsafe("ver", ServiceBroker.PROTOCOL_VERSION);
            msg.putUnsafe("success", true);
            msg.putUnsafe("data", data);
            transporter.publish(Transporter.PACKET_RESPONSE, sender, msg);
        }).catchError(error -> {
            // Send error
            transporter.publish(Transporter.PACKET_RESPONSE, sender, throwableToTree(id, sender, error));
        });
    } catch (Throwable error) {
        // Send error
        transporter.publish(Transporter.PACKET_RESPONSE, sender, throwableToTree(id, sender, error));
    }
}
Also used : Context(services.moleculer.context.Context) CallOptions(services.moleculer.context.CallOptions) Arrays(java.util.Arrays) ScheduledFuture(java.util.concurrent.ScheduledFuture) Enumeration(java.util.Enumeration) FastBuildTree(services.moleculer.util.FastBuildTree) CommonUtils.convertAnnotations(services.moleculer.util.CommonUtils.convertAnnotations) TimeoutException(java.util.concurrent.TimeoutException) HashMap(java.util.HashMap) ReentrantReadWriteLock(java.util.concurrent.locks.ReentrantReadWriteLock) AtomicReference(java.util.concurrent.atomic.AtomicReference) ServiceBroker(services.moleculer.ServiceBroker) InetAddress(java.net.InetAddress) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ContextFactory(services.moleculer.context.ContextFactory) LinkedList(java.util.LinkedList) NoSuchElementException(java.util.NoSuchElementException) ServiceBrokerConfig(services.moleculer.config.ServiceBrokerConfig) CommonUtils.getHostName(services.moleculer.util.CommonUtils.getHostName) LinkedHashSet(java.util.LinkedHashSet) PrintWriter(java.io.PrintWriter) Eventbus(services.moleculer.eventbus.Eventbus) Iterator(java.util.Iterator) StringWriter(java.io.StringWriter) Collection(java.util.Collection) NetworkInterface(java.net.NetworkInterface) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) UIDGenerator(services.moleculer.uid.UIDGenerator) Field(java.lang.reflect.Field) RemoteException(java.rmi.RemoteException) Promise(services.moleculer.Promise) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) AtomicLong(java.util.concurrent.atomic.AtomicLong) List(java.util.List) Lock(java.util.concurrent.locks.Lock) Strategy(services.moleculer.strategy.Strategy) Tree(io.datatree.Tree) Transporter(services.moleculer.transporter.Transporter) Annotation(java.lang.annotation.Annotation) Context(services.moleculer.context.Context) StrategyFactory(services.moleculer.strategy.StrategyFactory) CommonUtils.nameOf(services.moleculer.util.CommonUtils.nameOf) Collections(java.util.Collections) Promise(services.moleculer.Promise) FastBuildTree(services.moleculer.util.FastBuildTree) FastBuildTree(services.moleculer.util.FastBuildTree) Tree(io.datatree.Tree) CallOptions(services.moleculer.context.CallOptions)

Example 14 with FastBuildTree

use of services.moleculer.util.FastBuildTree in project moleculer-java by moleculer-java.

the class Transporter method sendDisconnectPacket.

protected void sendDisconnectPacket() {
    FastBuildTree msg = new FastBuildTree(1);
    msg.putUnsafe("sender", nodeID);
    publish(disconnectChannel, msg);
}
Also used : FastBuildTree(services.moleculer.util.FastBuildTree)

Example 15 with FastBuildTree

use of services.moleculer.util.FastBuildTree in project moleculer-java by moleculer-java.

the class Transporter method sendHeartbeatPacket.

protected void sendHeartbeatPacket() {
    FastBuildTree msg = new FastBuildTree(3);
    msg.putUnsafe("ver", PROTOCOL_VERSION);
    msg.putUnsafe("sender", nodeID);
    msg.putUnsafe("cpu", monitor.getTotalCpuPercent());
    publish(heartbeatChannel, msg);
}
Also used : FastBuildTree(services.moleculer.util.FastBuildTree)

Aggregations

FastBuildTree (services.moleculer.util.FastBuildTree)15 Tree (io.datatree.Tree)5 PrintWriter (java.io.PrintWriter)3 StringWriter (java.io.StringWriter)3 NodeDescriptor (services.moleculer.transporter.tcp.NodeDescriptor)3 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 CommonUtils.readTree (services.moleculer.util.CommonUtils.readTree)2 Annotation (java.lang.annotation.Annotation)1 Field (java.lang.reflect.Field)1 InetAddress (java.net.InetAddress)1 NetworkInterface (java.net.NetworkInterface)1 RemoteException (java.rmi.RemoteException)1 Arrays (java.util.Arrays)1 Collection (java.util.Collection)1 Collections (java.util.Collections)1 Enumeration (java.util.Enumeration)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Iterator (java.util.Iterator)1