예제 #1
0
  @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());
  }
예제 #2
0
  @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()));
  }
예제 #3
0
  @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);
    }
  }
예제 #4
0
 @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();
 }
예제 #5
0
  @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()));
  }
예제 #6
0
  @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());
  }
예제 #7
0
 public Task<Void> stop() {
   try {
     server.stop();
   } catch (Exception e) {
     logger.error("Error stopping jetty", e);
     throw new UncheckedException(e);
   }
   return Task.done();
 }
예제 #8
0
 @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();
 }
예제 #9
0
    @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);
    }
예제 #10
0
  @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());
  }
예제 #11
0
    @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
    }
예제 #12
0
  @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());
  }
예제 #13
0
 @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);
       });
 }
예제 #14
0
  @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());
  }
예제 #15
0
 @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
 }
예제 #16
0
 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();
 }
예제 #17
0
 @Override
 public Task<Void> cleanup() {
   return Task.done();
 }
예제 #18
0
 public Task<Integer> someWork() {
   return Task.fromValue(42);
 }
예제 #19
0
  @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();
  }
예제 #20
0
 @Override
 public Task<Void> addPlayerToMap(SomePlayer player) {
   state().playerMap.put(player.hashCode(), player);
   await(writeState());
   return Task.done();
 }
예제 #21
0
 @Override
 public Task<List<SomePlayer>> getPlayers() {
   return Task.fromValue(state().players);
 }
예제 #22
0
 @Override
 public Task<Map<Integer, SomePlayer>> getPlayers() {
   return Task.fromValue(state().playerMap);
 }
예제 #23
0
 @Override
 public Task<List<String>> getItems() {
   return Task.fromValue(state().items);
 }
예제 #24
0
 @Override
 public Task<String> sayHello(final String greeting) {
   getLogger().info("sayHello: " + greeting);
   return Task.fromValue(greeting);
 }
예제 #25
0
 @Override
 public Task<Integer> getBalance() {
   return Task.fromValue(state().balance);
 }