@SuppressWarnings("deprecation")
  protected void afterEnd(Map flags, Task<?> task) {
    activeTaskCount.decrementAndGet();
    incompleteTaskCount.decrementAndGet();

    if (log.isTraceEnabled()) log.trace(this + " afterEnd, task: " + task);
    ExecutionUtils.invoke(flags.get("newTaskEndCallback"), task);
    List l = (List) flags.get("tagLinkedPreprocessors");
    Collections.reverse(l);
    for (Object li : l) {
      TaskPreprocessor t = (TaskPreprocessor) li;
      t.onEnd(flags, task);
    }

    PerThreadCurrentTaskHolder.perThreadCurrentTask.remove();
    ((BasicTask) task).endTimeUtc = System.currentTimeMillis();
    // clear thread _after_ endTime set, so we won't get a null thread when there is no end-time
    if (RENAME_THREADS) {
      String newThreadName = "brooklyn-" + LanguageUtils.newUid();
      ((BasicTask) task).thread.setName(newThreadName);
    }
    ((BasicTask) task).thread = null;
    synchronized (task) {
      task.notifyAll();
    }

    ExpirationPolicy expirationPolicy = (ExpirationPolicy) flags.get("expirationPolicy");
    if (expirationPolicy == null) expirationPolicy = ExpirationPolicy.IMMEDIATE;
    if (expirationPolicy == ExpirationPolicy.IMMEDIATE) {
      for (Object t : ((BasicTask) task).tags) {
        getMutableTasksWithTag(t).remove(task);
      }
    }
  }
Example #2
0
 public ConfigKey<V> subKey() {
   String subName = LanguageUtils.newUid();
   return new SubElementConfigKey<V>(
       this,
       subType,
       getName() + "." + subName,
       "element of " + getName() + ", uid " + subName,
       null);
 }
  /**
   * This implementation handles the following flags, in addition to those described in the {@link
   * SubscriptionManager} interface:
   *
   * <ul>
   *   <li>subscriberExecutionManagerTag - a tag to pass to execution manager (without setting any
   *       execution semantics / TaskPreprocessor); if not supplied and there is a subscriber, this
   *       will be inferred from the subscriber and set up with SingleThreadedScheduler (supply this
   *       flag with value null to prevent any task preprocessor from being set)
   *   <li>eventFilter - a Predicate&lt;SensorEvent&gt; instance to filter what events are delivered
   * </ul>
   *
   * @see SubscriptionManager#subscribe(Map, Entity, Sensor, SensorEventListener)
   */
  public synchronized <T> SubscriptionHandle subscribe(
      Map<String, Object> flags,
      Entity producer,
      Sensor<T> sensor,
      SensorEventListener<? super T> listener) {
    Subscription s = new Subscription(producer, sensor, listener);
    s.subscriber = flags.containsKey("subscriber") ? flags.remove("subscriber") : listener;
    if (flags.containsKey("subscriberExecutionManagerTag")) {
      s.subscriberExecutionManagerTag = flags.remove("subscriberExecutionManagerTag");
      s.subscriberExecutionManagerTagSupplied = true;
    } else {
      s.subscriberExecutionManagerTag =
          s.subscriber instanceof Entity
              ? "subscription-delivery-entity-"
                  + ((Entity) s.subscriber).getId()
                  + "["
                  + s.subscriber
                  + "]"
              : s.subscriber instanceof String
                  ? "subscription-delivery-string[" + s.subscriber + "]"
                  : s != null ? "subscription-delivery-object[" + s.subscriber + "]" : null;
      s.subscriberExecutionManagerTagSupplied = false;
    }
    s.eventFilter = (Predicate) flags.remove("eventFilter");
    s.flags = flags;

    if (LOG.isDebugEnabled())
      LOG.debug(
          "Creating subscription {} for {} on {} {} in {}",
          new Object[] {s, s.subscriber, producer, sensor, this});
    allSubscriptions.put(s.id, s);
    LanguageUtils.addToMapOfSets(
        subscriptionsByToken, makeEntitySensorToken(s.producer, s.sensor), s);
    if (s.subscriber != null) {
      LanguageUtils.addToMapOfSets(subscriptionsBySubscriber, s.subscriber, s);
    }
    if (!s.subscriberExecutionManagerTagSupplied && s.subscriberExecutionManagerTag != null) {
      ((BasicExecutionManager) em)
          .setTaskSchedulerForTag(s.subscriberExecutionManagerTag, SingleThreadedScheduler.class);
    }
    return s;
  }
  /**
   * Unsubscribe the given subscription id.
   *
   * @see #subscribe(Map, Entity, Sensor, SensorEventListener)
   */
  public synchronized boolean unsubscribe(SubscriptionHandle sh) {
    if (!(sh instanceof Subscription))
      throw new IllegalArgumentException(
          "Only subscription handles of type Subscription supported: sh="
              + sh
              + "; type="
              + (sh != null ? sh.getClass().getCanonicalName() : null));
    Subscription s = (Subscription) sh;
    boolean b1 = allSubscriptions.remove(s.id) != null;
    boolean b2 =
        LanguageUtils.removeFromMapOfCollections(
            subscriptionsByToken, makeEntitySensorToken(s.producer, s.sensor), s);
    assert b1 == b2;
    if (s.subscriber != null) {
      boolean b3 =
          LanguageUtils.removeFromMapOfCollections(subscriptionsBySubscriber, s.subscriber, s);
      assert b3 == b2;
    }

    // TODO Requires code review: why did we previously do exactly same check twice in a row (with
    // no synchronization in between)?
    if ((subscriptionsBySubscriber.size() == 0
            || !groovyTruth(subscriptionsBySubscriber.get(s.subscriber)))
        && !s.subscriberExecutionManagerTagSupplied
        && s.subscriberExecutionManagerTag != null) {
      // if subscriber has gone away forget about his task; but check in synch block to ensure
      // setTaskPreprocessor call above will win in any race
      if ((subscriptionsBySubscriber.size() == 0
          || !groovyTruth(subscriptionsBySubscriber.get(s.subscriber))))
        ((BasicExecutionManager) em).clearTaskPreprocessorForTag(s.subscriberExecutionManagerTag);
    }

    // FIXME ALEX - this seems wrong
    ((BasicExecutionManager) em)
        .setTaskSchedulerForTag(s.subscriberExecutionManagerTag, SingleThreadedScheduler.class);
    return b1;
  }