All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.vertx.core.impl.CompositeFutureImpl Maven / Gradle / Ivy

There is a newer version: 4.5.10
Show newest version
/*
 * Copyright (c) 2011-2013 The original author or authors
 *  ------------------------------------------------------
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  and Apache License v2.0 which accompanies this distribution.
 *
 *      The Eclipse Public License is available at
 *      http://www.eclipse.org/legal/epl-v10.html
 *
 *      The Apache License v2.0 is available at
 *      http://www.opensource.org/licenses/apache2.0.php
 *
 *  You may elect to redistribute this code under either of these licenses.
 */

package io.vertx.core.impl;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Handler;

/**
 * @author Julien Viet
 */
public class CompositeFutureImpl implements CompositeFuture, Handler> {

  public static CompositeFuture all(Future... results) {
    CompositeFutureImpl composite = new CompositeFutureImpl(results);
    for (int i = 0;i < results.length;i++) {
      int index = i;
      results[i].setHandler(ar -> {
        Handler> handler = null;
        if (ar.succeeded()) {
          synchronized (composite) {
            composite.flag |= 1 << index;
            if (!composite.isComplete() && composite.flag == (1 << results.length) - 1) {
              handler = composite.setSucceeded();
            }
          }
        } else {
          synchronized (composite) {
            if (!composite.isComplete()) {
              handler = composite.setFailed(ar.cause());
            }
          }
        }
        if (handler != null) {
          handler.handle(composite);
        }
      });
    }
    return composite;
  }

  public static CompositeFuture any(Future... results) {
    CompositeFutureImpl composite = new CompositeFutureImpl(results);
    for (int i = 0;i < results.length;i++) {
      int index = i;
      results[i].setHandler(ar -> {
        Handler> handler = null;
        if (ar.succeeded()) {
          synchronized (composite) {
            if (!composite.isComplete()) {
              composite.setSucceeded();
            }
          }
        } else {
          synchronized (composite) {
            composite.flag |= 1 << index;
            if (!composite.isComplete() && composite.flag == (1 << results.length) - 1) {
              handler = composite.setFailed(ar.cause());
            }
          }
        }
        if (handler != null) {
          handler.handle(composite);
        }
      });
    }
    return composite;
  }

  private final Future[] results;
  private int flag;
  private boolean completed;
  private Throwable cause;
  private Handler> handler;

  private CompositeFutureImpl(Future... results) {
    this.results = results;
  }

  @Override
  public CompositeFuture setHandler(Handler> handler) {
    boolean call;
    synchronized (this) {
      this.handler = handler;
      call = completed;
    }
    if (call) {
      handler.handle(this);
    }
    return this;
  }

  @Override
  public Throwable cause(int index) {
    return future(index).cause();
  }

  @Override
  public boolean succeeded(int index) {
    return future(index).succeeded();
  }

  @Override
  public boolean failed(int index) {
    return future(index).failed();
  }

  @Override
  public boolean isComplete(int index) {
    return future(index).isComplete();
  }

  @Override
  public  T result(int index) {
    return this.future(index).result();
  }

  private  Future future(int index) {
    if (index < 0 || index > results.length) {
      throw new IndexOutOfBoundsException();
    }
    return (Future) results[index];
  }

  @Override
  public int size() {
    return results.length;
  }

  @Override
  public synchronized boolean isComplete() {
    return completed;
  }

  @Override
  public synchronized boolean succeeded() {
    return completed && cause == null;
  }

  @Override
  public synchronized boolean failed() {
    return completed && cause != null;
  }

  @Override
  public synchronized Throwable cause() {
    return completed && cause != null ? cause : null;
  }

  @Override
  public synchronized CompositeFuture result() {
    return completed && cause == null ? this : null;
  }

  @Override
  public void complete(CompositeFuture result) {
    Handler> handler = setSucceeded();
    if (handler != null) {
      handler.handle(this);
    }
  }

  @Override
  public void complete() {
    complete(null);
  }

  @Override
  public void fail(Throwable throwable) {
    Handler> handler = setFailed(throwable);
    if (handler != null) {
      handler.handle(this);
    }
  }

  @Override
  public void fail(String failureMessage) {
    fail(new NoStackTraceThrowable(failureMessage));
  }

  private Handler> setFailed(Throwable cause) {
    synchronized (this) {
      if (completed) {
        throw new IllegalStateException("Result is already complete: " + (this.cause == null ? "succeeded" : "failed"));
      }
      this.completed = true;
      this.cause = cause;
      return handler;
    }
  }

  private Handler> setSucceeded() {
    synchronized (this) {
      if (completed) {
        throw new IllegalStateException("Result is already complete: " + (this.cause == null ? "succeeded" : "failed"));
      }
      this.completed = true;
      return handler;
    }
  }

  @Override
  public Handler> completer() {
    return this;
  }

  @Override
  public void handle(AsyncResult ar) {
    if (ar.succeeded()) {
      complete(this);
    } else {
      fail(ar.cause());
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy