@Test public void twoMutexes() { class Experiment { int x; Task doIt(Object mutex1, Object mutex2, int a) { synchronized (mutex1) { mutex1.notify(); synchronized (mutex2) { x = 1; mutex1.notify(); mutex2.notify(); await(getBlockedTask()); mutex1.notify(); mutex2.notify(); } mutex1.notify(); } return fromValue(x + a); } } final Task res = new Experiment().doIt("a", "b", 1); completeFutures(); assertEquals(2, res.join()); }
@Test public void synchronizedMethod() { class SynchronizedMethodExperiment { int x; synchronized Task doIt(int a) { x = 1; this.notify(); await(getBlockedTask()); this.notify(); return fromValue(x); } } final Task res = new SynchronizedMethodExperiment().doIt(0); Method asyncMethod = Stream.of(SynchronizedMethodExperiment.class.getDeclaredMethods()) .filter(m -> m.getName().startsWith("async$")) .findFirst() .orElse(null); completeFutures(); assertEquals(1, res.join()); // it must be false since the async method is static assertFalse(Modifier.isSynchronized(asyncMethod.getModifiers())); assertTrue(Modifier.isStatic(asyncMethod.getModifiers())); }
@SuppressWarnings("unchecked") protected Task<Object> performInvocation( HandlerContext ctx, final Invocation invocation, final LocalObjects.LocalObjectEntry entry, final LocalObjects.LocalObjectEntry target) { if (logger.isDebugEnabled()) { logger.debug("Invoking {} ", invocation); } try { if (target == null || target.isDeactivated()) { // if the entry is deactivated, forward the message back to the net. ctx.write(invocation); return Task.fromValue(null); } if (target.getObject() == null) { if (target instanceof ObserverEntry) { return Task.fromException(new ObserverNotFound()); } ctx.write(invocation); return Task.fromValue(null); } final ObjectInvoker invoker = DefaultDescriptorFactory.get().getInvoker(target.getObject().getClass()); final ActorTaskContext context = ActorTaskContext.current(); if (invocation.getHeaders() != null && invocation.getHeaders().size() > 0 && runtime.getStickyHeaders() != null) { for (Map.Entry e : invocation.getHeaders().entrySet()) { if (runtime.getStickyHeaders().contains(e.getKey())) { context.setProperty(String.valueOf(e.getKey()), e.getValue()); } } } // todo: it would be nice to separate this last part into another handler (InvocationHandler) // to be able intercept the invocation right before it actually happens, good for logging and // metrics if (context != null) { context.setRuntime(runtime); } else { runtime.bind(); } final Task result = invoker.safeInvoke(target.getObject(), invocation.getMethodId(), invocation.getParams()); if (invocation.getCompletion() != null) { InternalUtils.linkFutures(result, invocation.getCompletion()); } return result; } catch (Throwable exception) { if (logger.isDebugEnabled()) { logger.debug("Unknown application error. ", exception); } if (invocation.getCompletion() != null) { invocation.getCompletion().completeExceptionally(exception); } return Task.fromException(exception); } }
@Override public Task<Void> callRandomB() { if (Math.random() > 0.5d) return Task.done(); // some variance to the calls String id = Integer.toString((int) (Math.random() * 10)); ExampleB b = Actor.getReference(ExampleB.class, id); b.someWork().join(); return Task.done(); }
@Test public void staticSynchronizedMethod() { final Task res = StaticSynchronizedMethod_Experiment.doIt(getBlockedTask(), 1); Method asyncMethod = Stream.of(StaticSynchronizedMethod_Experiment.class.getDeclaredMethods()) .filter(m -> m.getName().startsWith("async$")) .findFirst() .orElse(null); completeFutures(); assertEquals(1, res.join()); // this is not strictly necessary assertTrue(Modifier.isSynchronized(asyncMethod.getModifiers())); }
@Test public void outOfTheWay() { class Experiment { int x; Task doIt(Object mutex, int a) { synchronized (mutex) { x = 1; mutex.notify(); } await(getBlockedTask()); return fromValue(x + a); } } final Task res = new Experiment().doIt(new Object(), 1); completeFutures(); assertEquals(2, res.join()); }
public Task<Void> stop() { try { server.stop(); } catch (Exception e) { logger.error("Error stopping jetty", e); throw new UncheckedException(e); } return Task.done(); }
@Override public Task write(final HandlerContext ctx, final Object msg) throws Exception { if (!(msg instanceof Pair)) { return ctx.write(msg); } Pair<NodeAddress, byte[]> message = (Pair<NodeAddress, byte[]>) msg; clusterPeer.sendMessage(message.getLeft(), message.getRight()); return Task.done(); }
@Override public Task<String> giveItem(String itemName) { if (!"ok".equals(fakeSync.get("proceed").join())) { throw new IllegalArgumentException("Something went wrong: " + itemName); } String item = itemName + ":" + IdUtils.urlSafeString(128); state().addItem(item); return Task.fromValue(item); }
@Test public void usingThis() { class Experiment { int x; Task doIt(int a) { synchronized (this) { x = 1; this.notify(); await(getBlockedTask()); this.notify(); } return fromValue(x + a); } } final Task res = new Experiment().doIt(0); completeFutures(); assertEquals(1, res.join()); }
@Override public Task<Integer> remote(int i1, Disjunct other, int i2) { // Start Transaction await( transaction( () -> { state().incrementBalance(i1); if (i1 < 0) { // the nested transaction was completed // this will force the parent to cancel the nested throw new IllegalArgumentException("i1: " + i1); } return Task.done(); })); final int r1 = await(other.singleLevel(i2)); return Task.fromValue(state().balance + r1); // End Transaction }
@Test public void mixed() { class MixedExperiment { int x; synchronized Task doIt(String mutex1, String mutex2, int a) { String mutex3 = "c"; x = 1; this.notify(); await(getBlockedTask()); this.notify(); synchronized (mutex1) { await(getBlockedTask()); this.notify(); mutex1.notify(); } synchronized (mutex2) { await(getBlockedTask()); this.notify(); mutex2.notify(); } synchronized (mutex1) { synchronized (mutex2) { synchronized (mutex3) { await(getBlockedTask()); this.notify(); mutex1.notify(); mutex2.notify(); mutex3.notify(); } } } this.notify(); await(getBlockedTask()); this.notify(); return fromValue(x); } } final Task res = new MixedExperiment().doIt("a", "b", 0); completeFutures(); assertEquals(1, res.join()); }
@Override public Task<Integer> singleLevel(int i) { return transaction( () -> { state().incrementBalance(i); if (i < 0) { throw new IllegalArgumentException("i: " + i); } return Task.fromValue(state().balance); }); }
@Test public void synchronizedMethodWithExtraSync() { class SynchronizedMethodWithExtraSyncExperiment { int x; synchronized Task doIt(int a) { x = 1; this.notify(); await(getBlockedTask()); synchronized (this) { await(getBlockedTask()); this.notify(); } this.notify(); await(getBlockedTask()); this.notify(); return fromValue(x); } } final Task res = new SynchronizedMethodWithExtraSyncExperiment().doIt(0); completeFutures(); assertEquals(1, res.join()); }
@Override public Task<Integer> local(int i1, int i2) { // Start Transaction await( transaction( () -> { state().incrementBalance(i1); if (i1 < 0) { throw new IllegalArgumentException("i1: " + i1); } return Task.done(); })); await( transaction( () -> { state().incrementBalance(i2); if (i2 < 0) { throw new IllegalArgumentException("i2: " + i2); } return Task.done(); })); return Task.fromValue(state().balance); // End Transaction }
private Task<Void> onActivate(HandlerContext ctx, final Invocation invocation) { // this must run serialized by the remote reference key. LocalObjects.LocalObjectEntry<Object> entry = objects.findLocalObjectByReference(invocation.getToReference()); if (entry == null) { objects.registerLocalObject(invocation.getToReference(), null); entry = objects.findLocalObjectByReference(invocation.getToReference()); } // queues the invocation final LocalObjects.LocalObjectEntry<Object> theEntry = entry; final Task result = entry.run(target -> performInvocation(ctx, invocation, theEntry, target)); if (invocation.getCompletion() != null) { InternalUtils.linkFuturesOnError(result, invocation.getCompletion()); } // yielding since we blocked the entry before running on activate (serialized execution) return Task.done(); }
@Override public Task<Void> cleanup() { return Task.done(); }
public Task<Integer> someWork() { return Task.fromValue(42); }
@SuppressWarnings({"unchecked", "rawtypes"}) public Task<Void> start() { // Ensuring that jersey will use singletons from the orbit container. ServiceLocator locator = Injections.createLocator(); DynamicConfigurationService dcs = locator.getService(DynamicConfigurationService.class); DynamicConfiguration dc = dcs.createDynamicConfiguration(); final List<Class<?>> classes = new ArrayList<>(providers); if (container != null) { classes.addAll(container.getClasses()); for (final Class<?> c : container.getClasses()) { if (c.isAnnotationPresent(Singleton.class)) { Injections.addBinding( Injections.newFactoryBinder( new Factory() { @Override public Object provide() { return container.get(c); } @Override public void dispose(final Object instance) {} }) .to(c), dc); } } } dc.commit(); final ResourceConfig resourceConfig = new ResourceConfig(); // installing jax-rs classes known by the orbit container. for (final Class c : classes) { if (c.isAnnotationPresent(javax.ws.rs.Path.class) || c.isAnnotationPresent(javax.ws.rs.ext.Provider.class)) { resourceConfig.register(c); } } final WebAppContext webAppContext = new WebAppContext(); final ProtectionDomain protectionDomain = EmbeddedHttpServer.class.getProtectionDomain(); final URL location = protectionDomain.getCodeSource().getLocation(); logger.info(location.toExternalForm()); webAppContext.setInitParameter("useFileMappedBuffer", "false"); webAppContext.setWar(location.toExternalForm()); // this sets the default service locator to one that bridges to the orbit container. webAppContext.getServletContext().setAttribute(ServletProperties.SERVICE_LOCATOR, locator); webAppContext.setContextPath("/*"); webAppContext.addServlet(new ServletHolder(new ServletContainer(resourceConfig)), "/*"); final ContextHandler resourceContext = new ContextHandler(); ResourceHandler resourceHandler = new ResourceHandler(); resourceHandler.setDirectoriesListed(true); resourceHandler.setWelcomeFiles(new String[] {"index.html"}); resourceHandler.setBaseResource(Resource.newClassPathResource("/web")); resourceContext.setHandler(resourceHandler); resourceContext.setInitParameter("useFileMappedBuffer", "false"); final ContextHandlerCollection contexts = new ContextHandlerCollection(); contexts.setHandlers( new Handler[] { wrapHandlerWithMetrics(resourceContext, "resourceContext"), wrapHandlerWithMetrics(webAppContext, "webAppContext") }); server = new Server(port); server.setHandler(contexts); try { /// Initialize javax.websocket layer final ServerContainer serverContainer = WebSocketServerContainerInitializer.configureContext(webAppContext); for (Class c : classes) { if (c.isAnnotationPresent(ServerEndpoint.class)) { final ServerEndpoint annotation = (ServerEndpoint) c.getAnnotation(ServerEndpoint.class); final ServerEndpointConfig serverEndpointConfig = ServerEndpointConfig.Builder.create(c, annotation.value()) .configurator( new ServerEndpointConfig.Configurator() { @Override public <T> T getEndpointInstance(final Class<T> endpointClass) throws InstantiationException { return container.get(endpointClass); } }) .build(); serverContainer.addEndpoint(serverEndpointConfig); } } } catch (Exception e) { logger.error("Error starting jetty", e); throw new UncheckedException(e); } try { server.start(); } catch (Exception e) { logger.error("Error starting jetty", e); throw new UncheckedException(e); } return Task.done(); }
@Override public Task<Void> addPlayerToMap(SomePlayer player) { state().playerMap.put(player.hashCode(), player); await(writeState()); return Task.done(); }
@Override public Task<List<SomePlayer>> getPlayers() { return Task.fromValue(state().players); }
@Override public Task<Map<Integer, SomePlayer>> getPlayers() { return Task.fromValue(state().playerMap); }
@Override public Task<List<String>> getItems() { return Task.fromValue(state().items); }
@Override public Task<String> sayHello(final String greeting) { getLogger().info("sayHello: " + greeting); return Task.fromValue(greeting); }
@Override public Task<Integer> getBalance() { return Task.fromValue(state().balance); }