Search in sources :

Example 1 with Action

use of services.moleculer.service.Action in project moleculer-java by moleculer-java.

the class DefaultCircuitBreaker method callWithoutBreaker.

// --- CALL SERVICE WITHOUT BREAKER FUNCTION ---
protected Promise callWithoutBreaker(String name, Tree params, CallOptions.Options opts, int remaining, Context parent) {
    try {
        String targetID = opts == null ? null : opts.nodeID;
        Action action = serviceRegistry.getAction(name, targetID);
        Context ctx = contextFactory.create(name, params, opts, parent);
        if (remaining < 1) {
            return Promise.resolve(action.handler(ctx));
        }
        return Promise.resolve(action.handler(ctx)).catchError(cause -> {
            return retryWithoutBreaker(cause, name, params, opts, remaining, parent);
        });
    } catch (Throwable cause) {
        if (remaining < 1) {
            return Promise.reject(cause);
        }
        return retryWithoutBreaker(cause, name, params, opts, remaining, parent);
    }
}
Also used : Context(services.moleculer.context.Context) Action(services.moleculer.service.Action)

Example 2 with Action

use of services.moleculer.service.Action in project moleculer-java by moleculer-java.

the class Cacher method install.

// --- ADD MIDDLEWARE TO ACTION ---
@Override
public Action install(Action action, Tree config) {
    // Is caching enabled?
    Tree cacheNode = config.get("cache");
    if (cacheNode == null) {
        return null;
    }
    // Get cache keys
    Tree keyNode = cacheNode.get("keys");
    final String[] keys;
    if (keyNode == null) {
        keys = null;
    } else {
        List<String> list = keyNode.asList(String.class);
        if (list.isEmpty()) {
            keys = null;
        } else {
            keys = new String[list.size()];
            list.toArray(keys);
        }
    }
    // Get TTL (0 = use default TTL)
    final int ttl = cacheNode.get("ttl", 0);
    return new Action() {

        @Override
        public Object handler(Context ctx) throws Exception {
            String key = getCacheKey(ctx.name, ctx.params, keys);
            return new Promise(resolver -> {
                get(key).then(in -> {
                    if (in == null || in.isNull()) {
                        new Promise(action.handler(ctx)).then(tree -> {
                            set(key, tree, ttl);
                            resolver.resolve(tree);
                        }).catchError(err -> {
                            resolver.reject(err);
                        });
                    } else {
                        resolver.resolve(in);
                    }
                }).catchError(err -> {
                    resolver.reject(err);
                });
            });
        }
    };
}
Also used : Context(services.moleculer.context.Context) List(java.util.List) Action(services.moleculer.service.Action) Middleware(services.moleculer.service.Middleware) Tree(io.datatree.Tree) Context(services.moleculer.context.Context) Name(services.moleculer.service.Name) Promise(services.moleculer.Promise) Promise(services.moleculer.Promise) Action(services.moleculer.service.Action) Tree(io.datatree.Tree)

Example 3 with Action

use of services.moleculer.service.Action in project moleculer-java by moleculer-java.

the class CircuitBreakerTest method testSimpleCall.

@Test
public void testSimpleCall() throws Exception {
    br.createService(new Service("math") {

        @Name("add")
        public Action add = ctx -> {
            return ctx.params.get("a", 0) + ctx.params.get("b", 0);
        };
    });
    // cb.setEnabled(true);
    long start = System.currentTimeMillis();
    for (int i = 0; i < 50; i++) {
        int rsp = br.call("math.add", "a", i, "b", 1).waitFor().asInteger();
        assertEquals(i + 1, rsp);
    }
    assertTrue(System.currentTimeMillis() - start < 50);
}
Also used : CallOptions(services.moleculer.context.CallOptions) Action(services.moleculer.service.Action) Collection(java.util.Collection) TimeoutException(java.util.concurrent.TimeoutException) Name(services.moleculer.service.Name) Callable(java.util.concurrent.Callable) CompletableFuture(java.util.concurrent.CompletableFuture) Test(org.junit.Test) ServiceBroker(services.moleculer.ServiceBroker) Promise(services.moleculer.Promise) LinkedHashMap(java.util.LinkedHashMap) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) Future(java.util.concurrent.Future) Service(services.moleculer.service.Service) ConstantMonitor(services.moleculer.monitor.ConstantMonitor) Map(java.util.Map) Tree(io.datatree.Tree) TestCase(junit.framework.TestCase) Collections(java.util.Collections) ExecutorService(java.util.concurrent.ExecutorService) DefaultServiceRegistry(services.moleculer.service.DefaultServiceRegistry) Action(services.moleculer.service.Action) Service(services.moleculer.service.Service) ExecutorService(java.util.concurrent.ExecutorService) Name(services.moleculer.service.Name) Test(org.junit.Test)

Example 4 with Action

use of services.moleculer.service.Action in project moleculer-java by moleculer-java.

the class Sample method main.

public static void main(String[] args) throws Exception {
    System.out.println("START");
    try {
        ServiceBrokerConfig cfg = new ServiceBrokerConfig();
        // RedisTransporter t = new RedisTransporter();
        // t.setDebug(false);
        // cfg.setTransporter(t);
        ServiceBroker broker = new ServiceBroker(cfg);
        MathService math = new MathService();
        broker.createService(math);
        broker.start();
        broker.use(new Middleware() {

            @Override
            public Action install(Action action, Tree config) {
                if (config.get("name", "?").equals("v1.math.test")) {
                    return new Action() {

                        @Override
                        public Object handler(Context ctx) throws Exception {
                            Object original = action.handler(ctx);
                            Object replaced = System.currentTimeMillis();
                            broker.getLogger().info("Middleware invoked! Replacing " + original + " to " + replaced);
                            return replaced;
                        }
                    };
                }
                return null;
            }
        });
        broker.waitForServices("v1.math").then(ok -> {
            for (int i = 0; i < 2; i++) {
                broker.call("v1.math.add", "a", 3, "b", 5).then(in -> {
                    broker.getLogger(Sample.class).info("Result: " + in);
                }).catchError(err -> {
                    broker.getLogger(Sample.class).error("Error: " + err);
                });
            }
            System.out.println("FIRST CALL ->3");
            broker.call("service2.test", new Tree(), CallOptions.retryCount(3)).catchError(cause -> {
                cause.printStackTrace();
            });
        });
        ((DefaultContextFactory) broker.getConfig().getContextFactory()).setMaxCallLevel(3);
        Thread.sleep(1000);
        broker.createService(new Service2Service());
        Thread.sleep(1000);
        broker.createService(new Service3Service());
        Thread.sleep(60000);
    } catch (Exception e) {
        e.printStackTrace();
    }
    System.out.println("STOP");
}
Also used : Context(services.moleculer.context.Context) DefaultContextFactory(services.moleculer.context.DefaultContextFactory) CallOptions(services.moleculer.context.CallOptions) Listener(services.moleculer.eventbus.Listener) Cache(services.moleculer.cacher.Cache) Action(services.moleculer.service.Action) Middleware(services.moleculer.service.Middleware) Version(services.moleculer.service.Version) Name(services.moleculer.service.Name) Subscribe(services.moleculer.eventbus.Subscribe) Dependencies(services.moleculer.service.Dependencies) Service(services.moleculer.service.Service) Tree(io.datatree.Tree) Context(services.moleculer.context.Context) ServiceBrokerConfig(services.moleculer.config.ServiceBrokerConfig) Action(services.moleculer.service.Action) ServiceBrokerConfig(services.moleculer.config.ServiceBrokerConfig) Middleware(services.moleculer.service.Middleware) DefaultContextFactory(services.moleculer.context.DefaultContextFactory) Tree(io.datatree.Tree)

Example 5 with Action

use of services.moleculer.service.Action in project moleculer-java by moleculer-java.

the class DefaultCircuitBreaker method callWithBreaker.

// --- CALL SERVICE WITH BREAKER FUNCTION ---
protected Promise callWithBreaker(String name, Tree params, CallOptions.Options opts, int remaining, Context parent) {
    EndpointKey endpointKey = null;
    ErrorCounter errorCounter = null;
    try {
        // Get the first recommended Endpoint and Error Counter
        String targetID = opts == null ? null : opts.nodeID;
        ActionEndpoint action = (ActionEndpoint) serviceRegistry.getAction(name, targetID);
        String nodeID = action.getNodeID();
        endpointKey = new EndpointKey(nodeID, name);
        errorCounter = errorCounters.get(endpointKey);
        // Check availability of the Endpoint (if endpoint isn't targetted)
        if (targetID == null) {
            LinkedHashSet<String> nodeIDs = new LinkedHashSet<>(maxSameNodes * 2);
            int sameNodeCounter = 0;
            long now;
            if (errorCounter == null) {
                now = 0;
            } else {
                now = System.currentTimeMillis();
            }
            for (int i = 0; i < maxTries; i++) {
                if (errorCounter == null || errorCounter.isAvailable(now)) {
                    // Endpoint is available
                    break;
                }
                // Store nodeID
                if (!nodeIDs.add(nodeID)) {
                    sameNodeCounter++;
                    if (sameNodeCounter >= maxSameNodes) {
                        // The "maxSameNodes" limit is reached
                        break;
                    }
                }
                // Try to choose another endpoint
                action = (ActionEndpoint) serviceRegistry.getAction(name, targetID);
                nodeID = action.getNodeID();
                endpointKey = new EndpointKey(nodeID, name);
                errorCounter = errorCounters.get(endpointKey);
            }
        }
        // Create new Context
        Context ctx = contextFactory.create(name, params, opts, parent);
        // Invoke Endpoint
        final ErrorCounter currentCounter = errorCounter;
        final EndpointKey currentKey = endpointKey;
        return Promise.resolve(action.handler(ctx)).then(rsp -> {
            // Reset error counter
            if (currentCounter != null) {
                currentCounter.reset();
            }
            // Return response
            return rsp;
        }).catchError(cause -> {
            // Increment error counter
            increment(currentCounter, currentKey, cause, System.currentTimeMillis());
            // Return with error
            if (remaining < 1) {
                return cause;
            }
            // Retry
            return retryWithBreaker(cause, name, params, opts, remaining, parent);
        });
    } catch (Throwable cause) {
        // Increment error counter
        increment(errorCounter, endpointKey, cause, System.currentTimeMillis());
        // Reject
        if (remaining < 1) {
            return Promise.reject(cause);
        }
        // Retry
        return retryWithBreaker(cause, name, params, opts, remaining, parent);
    }
}
Also used : LinkedHashSet(java.util.LinkedHashSet) Context(services.moleculer.context.Context) CallOptions(services.moleculer.context.CallOptions) Action(services.moleculer.service.Action) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Name(services.moleculer.service.Name) ActionEndpoint(services.moleculer.service.ActionEndpoint) ServiceBroker(services.moleculer.ServiceBroker) Promise(services.moleculer.Promise) HashSet(java.util.HashSet) Objects(java.util.Objects) ServiceRegistry(services.moleculer.service.ServiceRegistry) Tree(io.datatree.Tree) ContextFactory(services.moleculer.context.ContextFactory) Context(services.moleculer.context.Context) ServiceBrokerConfig(services.moleculer.config.ServiceBrokerConfig) LinkedHashSet(java.util.LinkedHashSet) ActionEndpoint(services.moleculer.service.ActionEndpoint) ActionEndpoint(services.moleculer.service.ActionEndpoint)

Aggregations

Action (services.moleculer.service.Action)5 Tree (io.datatree.Tree)4 Context (services.moleculer.context.Context)4 Name (services.moleculer.service.Name)4 Promise (services.moleculer.Promise)3 CallOptions (services.moleculer.context.CallOptions)3 List (java.util.List)2 ServiceBroker (services.moleculer.ServiceBroker)2 ServiceBrokerConfig (services.moleculer.config.ServiceBrokerConfig)2 Middleware (services.moleculer.service.Middleware)2 Service (services.moleculer.service.Service)2 Collection (java.util.Collection)1 Collections (java.util.Collections)1 HashSet (java.util.HashSet)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedHashSet (java.util.LinkedHashSet)1 Map (java.util.Map)1 Objects (java.util.Objects)1 Set (java.util.Set)1 Callable (java.util.concurrent.Callable)1