Search in sources :

Example 6 with NodeDescriptor

use of services.moleculer.transporter.tcp.NodeDescriptor in project moleculer-java by moleculer-java.

the class ClusterTest method run.

public void run() {
    System.out.println("START");
    try {
        // Load Sigar DLLs
        String nativeDir = "./native";
        System.setProperty("java.library.path", nativeDir);
        ExecutorService executor = Executors.newFixedThreadPool(Math.min(NODES, 100));
        ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(Math.min(NODES, 100));
        String[] urls = new String[NODES];
        for (int i = 0; i < NODES; i++) {
            int port = 6000 + i;
            urls[i] = "tcp://127.0.0.1:" + port + "/node-" + i;
        }
        ServiceBroker[] brokers = new ServiceBroker[NODES];
        for (int i = 0; i < NODES; i++) {
            // urls
            TcpTransporter transporter = new TcpTransporter();
            transporter.setGossipPeriod(3);
            transporter.setDebug(false);
            transporter.setOfflineTimeout(0);
            ServiceBrokerConfig settings = new ServiceBrokerConfig();
            settings.setShutDownThreadPools(false);
            settings.setExecutor(executor);
            settings.setScheduler(scheduler);
            settings.setTransporter(transporter);
            settings.setNodeID("node-" + i);
            ServiceBroker broker = new ServiceBroker(settings);
            brokers[i] = broker;
        }
        for (int i = 0; i < NODES; i++) {
            brokers[i].start();
            System.out.println("node-" + i + " started.");
        }
        boolean turnOn = true;
        HashMap<String, Long> maxSeqs = new HashMap<>();
        ServiceBroker broker;
        TcpTransporter transporter;
        int counter = 0;
        while (true) {
            Thread.sleep(1000);
            counter++;
            if (counter % 70 == 0) {
                if (turnOn) {
                    for (int n = 0; n < NODES / 3; n++) {
                        int i = rnd.nextInt(NODES);
                        broker = brokers[i];
                        transporter = (TcpTransporter) broker.getConfig().getTransporter();
                        if (transporter.writer == null) {
                            transporter.connect();
                        }
                    }
                }
                int i = rnd.nextInt(NODES);
                broker = brokers[i];
                transporter = (TcpTransporter) broker.getConfig().getTransporter();
                if (transporter.writer != null) {
                    transporter.nodes.clear();
                    transporter.disconnect();
                }
            }
            maxSeqs.clear();
            for (int i = 0; i < NODES; i++) {
                broker = brokers[i];
                transporter = (TcpTransporter) broker.getConfig().getTransporter();
                maxSeqs.put(broker.getNodeID(), transporter.getDescriptor().cpuSeq);
            }
            for (int i = 0; i < NODES; i++) {
                broker = brokers[i];
                transporter = (TcpTransporter) broker.getConfig().getTransporter();
                for (int n = 0; n < NODES; n++) {
                    NodeDescriptor d = transporter.nodes.get("node-" + n);
                    boolean online = transporter.isOnline("node-" + n);
                    Color color;
                    Long seq = null;
                    if (online) {
                        if (d != null) {
                            long cpuSeq = d.cpuSeq;
                            long maxSeq = maxSeqs.get("node-" + n);
                            if (maxSeq > 0) {
                                if (maxSeq < cpuSeq) {
                                    maxSeq = cpuSeq;
                                    maxSeqs.put("node-" + n, maxSeq);
                                }
                                long c = Math.max(0, 255 - 20 * (maxSeq - cpuSeq));
                                color = new Color(0, (int) c, 0);
                            } else {
                                color = Color.WHITE;
                            }
                            seq = d.seq;
                        } else {
                            color = Color.YELLOW;
                        }
                    } else {
                        color = Color.RED;
                        if (d != null) {
                            seq = d.seq;
                        }
                    }
                    image.draw(n, i, color, seq);
                }
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("STOP");
    System.exit(0);
}
Also used : ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) HashMap(java.util.HashMap) Color(java.awt.Color) NodeDescriptor(services.moleculer.transporter.tcp.NodeDescriptor) ServiceBrokerConfig(services.moleculer.config.ServiceBrokerConfig) ServiceBroker(services.moleculer.ServiceBroker) ScheduledExecutorService(java.util.concurrent.ScheduledExecutorService) ExecutorService(java.util.concurrent.ExecutorService)

Example 7 with NodeDescriptor

use of services.moleculer.transporter.tcp.NodeDescriptor in project moleculer-java by moleculer-java.

the class TcpTransporterTest method createOnlineDescriptorWithoutInfo.

protected NodeDescriptor createOnlineDescriptorWithoutInfo(boolean local, String nodeID) {
    Tree info = new Tree();
    info.put("seq", 1);
    info.put("port", 1);
    info.put("hostname", nodeID);
    return new NodeDescriptor(nodeID, true, local, info);
}
Also used : NodeDescriptor(services.moleculer.transporter.tcp.NodeDescriptor) Tree(io.datatree.Tree)

Example 8 with NodeDescriptor

use of services.moleculer.transporter.tcp.NodeDescriptor in project moleculer-java by moleculer-java.

the class TcpTransporterTest method testProcessGossipRequest.

// --- GOSSIP REQUEST PROCESSING ---
@Test
public void testProcessGossipRequest() throws Exception {
    // Add "node2" (hidden)
    tr.nodes.put("node2", createOfflineDescriptor(false, "node2"));
    // Simple request
    Tree req = createGossipRequest("node3", 1, 2, 3);
    Tree rsp = tr.processGossipRequest(req);
    assertEquals(1, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertEquals(1, rsp.get("online.node1").size());
    assertNotNull(rsp.get("online.node1[0].hostname"));
    assertTrue(rsp.get("online.node1[0].port", 0) > 0);
    assertTrue(rsp.get("online.node1[0].seq", 0) > 0);
    assertTrue(rsp.get("online.node1[0].services").size() > 0);
    // Update local CPU
    tr.getDescriptor().updateCpu(4);
    rsp = tr.processGossipRequest(req);
    assertEquals(3, rsp.get("online.node1").size());
    assertEquals(1, rsp.get("online.node1[1]", 0));
    assertEquals(4, rsp.get("online.node1[2]", 0));
    tr.getDescriptor().updateCpu(5);
    rsp = tr.processGossipRequest(req);
    assertEquals(2, rsp.get("online.node1[1]", 0));
    assertEquals(5, rsp.get("online.node1[2]", 0));
    tr.getDescriptor().updateCpu(0);
    rsp = tr.processGossipRequest(req);
    assertEquals(3, rsp.get("online.node1[1]", 0));
    assertEquals(0, rsp.get("online.node1[2]", 0));
    // Add offline node
    // Node4 -> offline & hidden
    tr.registerAsNewNode("node3", "host3", 1003);
    rsp = tr.processGossipRequest(req);
    assertEquals(1, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertEquals(3, rsp.get("online.node1").size());
    // Node5 -> online
    NodeDescriptor node4 = createOnlineDescriptorWithInfo(false, "node4");
    node4.info.put("seq", "3");
    node4.seq = 3;
    tr.nodes.put("node4", node4);
    rsp = tr.processGossipRequest(req);
    assertEquals(2, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertEquals(3, rsp.get("online.node1").size());
    assertEquals(1, rsp.get("online.node4").size());
    assertEquals(1, rsp.get("online.node4[0].port", 0));
    assertEquals(3, rsp.get("online.node4[0].seq", 0));
    assertEquals("node4", rsp.get("online.node4[0].hostname", "?"));
    // Add "node4" to request (low seq)
    req.get("online").putList("node4").add(1).add(1).add(0);
    rsp = tr.processGossipRequest(req);
    assertEquals(2, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertEquals(3, rsp.get("online.node1").size());
    assertEquals(3, rsp.get("online.node1[1]", 0));
    assertEquals(0, rsp.get("online.node1[2]", 0));
    // Add "node4" to request (correct seq)
    req.get("online").get("node4").clear().add(3).add(1).add(0);
    rsp = tr.processGossipRequest(req);
    assertEquals(1, rsp.get("online").size());
    assertEquals(3, rsp.get("online.node1").size());
    // Add "node4" to request (high seq)
    req.get("online").get("node4").clear().add(4).add(1).add(0);
    rsp = tr.processGossipRequest(req);
    assertEquals(1, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertEquals(3, rsp.get("online.node1").size());
    // Add "node4" to request (higher CPU seq)
    req.get("online").get("node4").clear().add(3).add(2).add(1);
    rsp = tr.processGossipRequest(req);
    assertEquals(1, rsp.get("online").size());
    assertEquals(1, tr.getCpuUsage("node4"));
    // Add "node4" to request (lower CPU seq)
    req.get("online").get("node4").clear().add(3).add(1).add(2);
    rsp = tr.processGossipRequest(req);
    assertEquals(2, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertEquals(2, rsp.get("online.node4").size());
    assertEquals(2, rsp.get("online.node4[0]", 0));
    assertEquals(1, rsp.get("online.node4[1]", 0));
    assertEquals(1, tr.getCpuUsage("node4"));
    // Add "node4" to request (same CPU seq)
    req.get("online").get("node4").clear().add(3).add(2).add(2);
    rsp = tr.processGossipRequest(req);
    assertEquals(1, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertNull(rsp.get("online.node4"));
    assertEquals(1, tr.getCpuUsage("node4"));
    // Add "node4" to request (higher CPU seq)
    req.get("online").get("node4").clear().add(3).add(3).add(5);
    rsp = tr.processGossipRequest(req);
    assertEquals(1, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertNull(rsp.get("online.node4"));
    assertEquals(5, tr.getCpuUsage("node4"));
    // Add "node4" to request (lower CPU seq)
    req.get("online").get("node4").clear().add(3).add(1).add(2);
    rsp = tr.processGossipRequest(req);
    assertEquals(2, rsp.get("online").size());
    assertNull(rsp.get("offline"));
    assertEquals(2, rsp.get("online.node4").size());
    assertEquals(3, rsp.get("online.node4[0]", 0));
    assertEquals(5, rsp.get("online.node4[1]", 0));
    assertEquals(5, tr.getCpuUsage("node4"));
    assertEquals(1, tr.getDescriptor().seq);
}
Also used : NodeDescriptor(services.moleculer.transporter.tcp.NodeDescriptor) Tree(io.datatree.Tree) Test(org.junit.Test)

Example 9 with NodeDescriptor

use of services.moleculer.transporter.tcp.NodeDescriptor in project moleculer-java by moleculer-java.

the class TcpTransporterTest method createOfflineDescriptor.

protected NodeDescriptor createOfflineDescriptor(boolean local, String nodeID) {
    Tree info = new Tree();
    info.put("seq", 0);
    info.put("port", 1);
    info.put("hostname", nodeID);
    NodeDescriptor nd = new NodeDescriptor(nodeID, true, local, info);
    nd.offlineSince = 1;
    return nd;
}
Also used : NodeDescriptor(services.moleculer.transporter.tcp.NodeDescriptor) Tree(io.datatree.Tree)

Example 10 with NodeDescriptor

use of services.moleculer.transporter.tcp.NodeDescriptor in project moleculer-java by moleculer-java.

the class TcpTransporter method unableToSend.

// --- CONNECTION ERROR ---
public void unableToSend(String nodeID, LinkedList<byte[]> packets, Throwable cause) {
    if (nodeID != null) {
        executor.execute(() -> {
            // Debug
            if (debug) {
                logger.warn("Unable to send message to \"" + nodeID + "\".", cause);
            }
            // Mark endpoint as offline
            NodeDescriptor node = nodes.get(nodeID);
            boolean disconnected = false;
            if (node != null) {
                node.writeLock.lock();
                try {
                    if (node != null && node.markAsOffline()) {
                        // Remove actions and listeners
                        registry.removeActions(nodeID);
                        eventbus.removeListeners(nodeID);
                        writer.close(node.nodeID);
                        disconnected = true;
                    }
                } catch (Exception error) {
                    logger.warn("Unable to turn off node!", error);
                } finally {
                    node.writeLock.unlock();
                }
            }
            if (node != null && disconnected) {
                // Notify listeners (unexpected disconnection)
                logger.info("Node \"" + nodeID + "\" disconnected.");
                broadcastNodeDisconnected(node.info, true);
            }
            // Send error back to the source
            if (packets != null) {
                FastBuildTree errorMap = null;
                if (cause != null) {
                    errorMap = new FastBuildTree(2);
                    // Add message
                    errorMap.putUnsafe("message", cause.getMessage());
                    // Add trace
                    StringWriter sw = new StringWriter(128);
                    PrintWriter pw = new PrintWriter(sw);
                    cause.printStackTrace(pw);
                    errorMap.putUnsafe("trace", sw.toString());
                }
                for (byte[] packet : packets) {
                    try {
                        // Remove header
                        if (packet != null && packet.length > 6) {
                            byte[] copy = new byte[packet.length - 6];
                            System.arraycopy(packet, 6, copy, 0, copy.length);
                            // Deserialize packet
                            Tree message = serializer.read(copy);
                            // Get request's unique ID
                            String id = message.get("id", (String) null);
                            if (id == null || id.isEmpty()) {
                                // Not a request
                                return;
                            }
                            // Create response message
                            FastBuildTree response = new FastBuildTree(6);
                            response.putUnsafe("id", id);
                            response.putUnsafe("ver", ServiceBroker.PROTOCOL_VERSION);
                            response.putUnsafe("sender", nodeID);
                            response.putUnsafe("success", false);
                            response.putUnsafe("data", (String) null);
                            if (errorMap != null) {
                                response.putUnsafe("error", errorMap);
                            }
                            registry.receiveResponse(response);
                        }
                    } catch (Exception error) {
                        logger.warn("Unable to handle error!", error);
                    }
                }
            }
        });
    }
}
Also used : StringWriter(java.io.StringWriter) FastBuildTree(services.moleculer.util.FastBuildTree) NodeDescriptor(services.moleculer.transporter.tcp.NodeDescriptor) CommonUtils.readTree(services.moleculer.util.CommonUtils.readTree) FastBuildTree(services.moleculer.util.FastBuildTree) Tree(io.datatree.Tree) PrintWriter(java.io.PrintWriter)

Aggregations

NodeDescriptor (services.moleculer.transporter.tcp.NodeDescriptor)17 Tree (io.datatree.Tree)12 FastBuildTree (services.moleculer.util.FastBuildTree)9 CommonUtils.readTree (services.moleculer.util.CommonUtils.readTree)5 ArrayList (java.util.ArrayList)2 LinkedList (java.util.LinkedList)2 Color (java.awt.Color)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 HashMap (java.util.HashMap)1 ExecutorService (java.util.concurrent.ExecutorService)1 ScheduledExecutorService (java.util.concurrent.ScheduledExecutorService)1 Test (org.junit.Test)1 ServiceBroker (services.moleculer.ServiceBroker)1 ServiceBrokerConfig (services.moleculer.config.ServiceBrokerConfig)1 RemoteAddress (services.moleculer.transporter.tcp.RemoteAddress)1 TcpReader (services.moleculer.transporter.tcp.TcpReader)1 TcpWriter (services.moleculer.transporter.tcp.TcpWriter)1 UDPLocator (services.moleculer.transporter.tcp.UDPLocator)1