Esempio n. 1
0
  @Override
  public boolean release(
      List<? extends Resource<?, ?>> resources, List<ResourceConsumer> consumers) {
    checkNotNull(resources);
    checkNotNull(consumers);
    checkArgument(resources.size() == consumers.size());

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    try {
      TransactionalMap<Resource<?, ?>, ResourceConsumer> txMap =
          tx.getTransactionalMap(MAP_NAME, SERIALIZER);
      Iterator<? extends Resource<?, ?>> resourceIte = resources.iterator();
      Iterator<ResourceConsumer> consumerIte = consumers.iterator();

      while (resourceIte.hasNext() && consumerIte.hasNext()) {
        Resource<?, ?> resource = resourceIte.next();
        ResourceConsumer consumer = consumerIte.next();

        // if this single release fails (because the resource is allocated to another consumer,
        // the whole release fails
        if (!txMap.remove(resource, consumer)) {
          tx.abort();
          return false;
        }
      }

      return true;
    } catch (TransactionException e) {
      log.error("Exception thrown, abort the transaction", e);
      tx.abort();
      return false;
    }
  }
Esempio n. 2
0
  @Override
  public boolean release(List<Resource> resources, List<ResourceConsumer> consumers) {
    checkNotNull(resources);
    checkNotNull(consumers);
    checkArgument(resources.size() == consumers.size());

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    TransactionalMap<DiscreteResource, ResourceConsumer> discreteConsumerTxMap =
        tx.getTransactionalMap(DISCRETE_CONSUMER_MAP, SERIALIZER);
    TransactionalMap<ResourceId, ContinuousResourceAllocation> continuousConsumerTxMap =
        tx.getTransactionalMap(CONTINUOUS_CONSUMER_MAP, SERIALIZER);
    Iterator<Resource> resourceIte = resources.iterator();
    Iterator<ResourceConsumer> consumerIte = consumers.iterator();

    while (resourceIte.hasNext() && consumerIte.hasNext()) {
      Resource resource = resourceIte.next();
      ResourceConsumer consumer = consumerIte.next();

      if (resource instanceof DiscreteResource) {
        // if this single release fails (because the resource is allocated to another consumer,
        // the whole release fails
        if (!discreteConsumerTxMap.remove((DiscreteResource) resource, consumer)) {
          return abortTransaction(tx);
        }
      } else if (resource instanceof ContinuousResource) {
        ContinuousResource continuous = (ContinuousResource) resource;
        ContinuousResourceAllocation allocation = continuousConsumerTxMap.get(continuous.id());
        ImmutableList<ResourceAllocation> newAllocations =
            allocation
                .allocations()
                .stream()
                .filter(
                    x ->
                        !(x.consumer().equals(consumer)
                            && ((ContinuousResource) x.resource()).value() == continuous.value()))
                .collect(GuavaCollectors.toImmutableList());

        if (!continuousConsumerTxMap.replace(
            continuous.id(),
            allocation,
            new ContinuousResourceAllocation(allocation.original(), newAllocations))) {
          return abortTransaction(tx);
        }
      }
    }

    return tx.commit();
  }
Esempio n. 3
0
  @Override
  public boolean register(List<Resource> resources) {
    checkNotNull(resources);
    if (log.isTraceEnabled()) {
      resources.forEach(r -> log.trace("registering {}", r));
    }

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    TransactionalMap<DiscreteResource, Set<Resource>> childTxMap =
        tx.getTransactionalMap(CHILD_MAP, SERIALIZER);

    Map<DiscreteResource, List<Resource>> resourceMap =
        resources
            .stream()
            .filter(x -> x.parent().isPresent())
            .collect(Collectors.groupingBy(x -> x.parent().get()));

    for (Map.Entry<DiscreteResource, List<Resource>> entry : resourceMap.entrySet()) {
      Optional<DiscreteResource> child = lookup(childTxMap, entry.getKey());
      if (!child.isPresent()) {
        return abortTransaction(tx);
      }

      if (!appendValues(childTxMap, entry.getKey(), entry.getValue())) {
        return abortTransaction(tx);
      }
    }

    boolean success = tx.commit();
    if (success) {
      List<ResourceEvent> events =
          resources
              .stream()
              .filter(x -> x.parent().isPresent())
              .map(x -> new ResourceEvent(RESOURCE_ADDED, x))
              .collect(Collectors.toList());
      notifyDelegate(events);
    }
    return success;
  }
Esempio n. 4
0
  @Override
  public boolean allocate(List<? extends Resource<?, ?>> resources, ResourceConsumer consumer) {
    checkNotNull(resources);
    checkNotNull(consumer);

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    try {
      TransactionalMap<Resource<?, ?>, ResourceConsumer> txMap =
          tx.getTransactionalMap(MAP_NAME, SERIALIZER);
      for (Resource<?, ?> resource : resources) {
        ResourceConsumer existing = txMap.putIfAbsent(resource, consumer);
        // if the resource is already allocated to another consumer, the whole allocation fails
        if (existing != null) {
          tx.abort();
          return false;
        }
      }
      tx.commit();
      return true;
    } catch (Exception e) {
      log.error("Exception thrown, abort the transaction", e);
      tx.abort();
      return false;
    }
  }
Esempio n. 5
0
  @Override
  public boolean allocate(List<Resource> resources, ResourceConsumer consumer) {
    checkNotNull(resources);
    checkNotNull(consumer);

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    TransactionalMap<DiscreteResource, Set<Resource>> childTxMap =
        tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
    TransactionalMap<DiscreteResource, ResourceConsumer> discreteConsumerTxMap =
        tx.getTransactionalMap(DISCRETE_CONSUMER_MAP, SERIALIZER);
    TransactionalMap<ResourceId, ContinuousResourceAllocation> continuousConsumerTxMap =
        tx.getTransactionalMap(CONTINUOUS_CONSUMER_MAP, SERIALIZER);

    for (Resource resource : resources) {
      if (resource instanceof DiscreteResource) {
        if (!lookup(childTxMap, resource).isPresent()) {
          return abortTransaction(tx);
        }

        ResourceConsumer oldValue =
            discreteConsumerTxMap.put((DiscreteResource) resource, consumer);
        if (oldValue != null) {
          return abortTransaction(tx);
        }
      } else if (resource instanceof ContinuousResource) {
        Optional<ContinuousResource> continuous = lookup(childTxMap, (ContinuousResource) resource);
        if (!continuous.isPresent()) {
          return abortTransaction(tx);
        }

        ContinuousResourceAllocation allocations =
            continuousConsumerTxMap.get(continuous.get().id());
        if (!hasEnoughResource(continuous.get(), (ContinuousResource) resource, allocations)) {
          return abortTransaction(tx);
        }

        boolean success =
            appendValue(
                continuousConsumerTxMap,
                continuous.get(),
                new ResourceAllocation(continuous.get(), consumer));
        if (!success) {
          return abortTransaction(tx);
        }
      }
    }

    return tx.commit();
  }
Esempio n. 6
0
 /**
  * Abort the transaction.
  *
  * @param tx transaction context
  * @return always false
  */
 private boolean abortTransaction(TransactionContext tx) {
   tx.abort();
   return false;
 }
Esempio n. 7
0
  @Override
  public boolean unregister(List<Resource> resources) {
    checkNotNull(resources);

    TransactionContext tx = service.transactionContextBuilder().build();
    tx.begin();

    TransactionalMap<DiscreteResource, Set<Resource>> childTxMap =
        tx.getTransactionalMap(CHILD_MAP, SERIALIZER);
    TransactionalMap<DiscreteResource, ResourceConsumer> discreteConsumerTxMap =
        tx.getTransactionalMap(DISCRETE_CONSUMER_MAP, SERIALIZER);
    TransactionalMap<ResourceId, ContinuousResourceAllocation> continuousConsumerTxMap =
        tx.getTransactionalMap(CONTINUOUS_CONSUMER_MAP, SERIALIZER);

    // Extract Discrete instances from resources
    Map<DiscreteResource, List<Resource>> resourceMap =
        resources
            .stream()
            .filter(x -> x.parent().isPresent())
            .collect(Collectors.groupingBy(x -> x.parent().get()));

    // even if one of the resources is allocated to a consumer,
    // all unregistrations are regarded as failure
    for (Map.Entry<DiscreteResource, List<Resource>> entry : resourceMap.entrySet()) {
      boolean allocated =
          entry
              .getValue()
              .stream()
              .anyMatch(
                  x -> {
                    if (x instanceof DiscreteResource) {
                      return discreteConsumerTxMap.get((DiscreteResource) x) != null;
                    } else if (x instanceof ContinuousResource) {
                      ContinuousResourceAllocation allocations =
                          continuousConsumerTxMap.get(x.id());
                      return allocations != null && !allocations.allocations().isEmpty();
                    } else {
                      return false;
                    }
                  });
      if (allocated) {
        return abortTransaction(tx);
      }

      if (!removeValues(childTxMap, entry.getKey(), entry.getValue())) {
        return abortTransaction(tx);
      }
    }

    boolean success = tx.commit();
    if (success) {
      List<ResourceEvent> events =
          resources
              .stream()
              .filter(x -> x.parent().isPresent())
              .map(x -> new ResourceEvent(RESOURCE_REMOVED, x))
              .collect(Collectors.toList());
      notifyDelegate(events);
    }
    return success;
  }