/**
  * convenience for setting "blocking details" on any task where the current thread is running,
  * while the passed code is executed; often used from groovy as <code>
  *  withBlockingDetails("sleeping 5s") { Thread.sleep(5000); } </code>
  *
  * @deprecated in 0.4.0, use Tasks.withBlockingDetails
  */
 public static Object withBlockingDetails(String description, Callable code) throws Exception {
   return Tasks.withBlockingDetails(description, code);
 }
示例#2
0
  /**
   * attempt to resolve the given value as the given type, waiting on futures, submitting if
   * necessary, and coercing as allowed by TypeCoercions; contextMessage (optional) will be
   * displayed in status reports while it waits (e.g. the name of the config key being looked up)
   */
  @SuppressWarnings({"unchecked", "rawtypes"})
  public static <T> T resolveValue(
      Object v, Class<T> type, ExecutionContext exec, String contextMessage)
      throws ExecutionException, InterruptedException {
    // if the expected type is a closure or map and that's what we have, we're done (or if it's
    // null);
    // but not allowed to return a future or DeferredSupplier as the resolved value
    if (v == null
        || (type.isInstance(v)
            && !Future.class.isInstance(v)
            && !DeferredSupplier.class.isInstance(v))) return (T) v;
    try {
      // if it's a task or a future, we wait for the task to complete
      if (v instanceof Task) {
        // if it's a task, we make sure it is submitted
        // (perhaps could run it here? ... tbd)
        if (!((Task) v).isSubmitted()) {
          exec.submit((Task) v);
        }
      }

      if (v instanceof Future) {
        final Future<?> vfuture = (Future<?>) v;

        // including tasks, above
        if (!vfuture.isDone()) {
          final AtomicReference<Object> vref = new AtomicReference<Object>(v);

          withBlockingDetails(
              "Waiting for " + (contextMessage != null ? contextMessage + ", " : "") + v,
              new Callable<Void>() {
                public Void call() throws Exception {
                  vref.set(vfuture.get());
                  return null;
                }
              });

          v = vref.get();

        } else {
          v = vfuture.get();
        }

      } else if (v instanceof DeferredSupplier<?>) {
        v = ((DeferredSupplier<?>) v).get();

      } else if (v instanceof Map) {
        // and if a map or list we look inside
        Map result = Maps.newLinkedHashMap();
        for (Map.Entry<?, ?> entry : ((Map<?, ?>) v).entrySet()) {
          result.put(
              entry.getKey(),
              resolveValue(
                  entry.getValue(),
                  type,
                  exec,
                  (contextMessage != null ? contextMessage + ", " : "")
                      + "map entry "
                      + entry.getKey()));
        }
        return (T) result;

      } else if (v instanceof List) {
        List result = Lists.newArrayList();
        int count = 0;
        for (Object it : (List) v) {
          result.add(
              resolveValue(
                  it,
                  type,
                  exec,
                  (contextMessage != null ? contextMessage + ", " : "") + "list entry " + count));
          count++;
        }
        return (T) result;

      } else {
        return TypeCoercions.coerce(v, type);
      }

    } catch (Exception e) {
      throw new IllegalArgumentException(
          "Error resolving "
              + (contextMessage != null ? contextMessage + ", " : "")
              + v
              + ", in "
              + exec
              + ": "
              + e,
          e);
    }
    return resolveValue(v, type, exec, contextMessage);
  }