/*
* Copyright 2012 LinkedIn, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.linkedin.parseq;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
/**
* This class provides a set of factory methods for create common
* {@link Task}s.
*
* @author Chris Pettitt (cpettitt@linkedin.com)
* @author Chi Chan (ckchan@linkedin.com)
*/
public class Tasks {
private Tasks() {
}
/**
* Creates a new {@link Task} that have a value of type Void. Because the
* returned task has no value, it is typically used to produce side-effects.
*
* @deprecated As of 2.0.0, replaced by {@link Task#action(String, com.linkedin.parseq.function.Action) Task.action}
* @param name a name that describes the action
* @param runnable the action that will be executed when the task is run
* @return the new task
* @see Task#action(String, com.linkedin.parseq.function.Action) Task.action
*/
@Deprecated
public static Task<Void> action(final String name, final Runnable runnable) {
return Task.action(name, runnable::run);
}
/**
* Creates a new {@link Task} that's value will be set to the value returned
* from the supplied callable. This task is useful when doing basic
* computation that does not require asynchrony. It is not appropriate for
* long running or blocking tasks.
*
* @deprecated As of 2.0.0, replaced by {@link Task#callable(String, Callable) Task.callable}
* @param name a name that describes the action
* @param callable the callable to execute when this task is run
* @param <T> the type of the return value for this task
* @return the new task
* @see Task#callable(String, Callable) Task.callable
*/
@Deprecated
public static <T> Task<T> callable(final String name, final Callable<? extends T> callable) {
return Task.callable(name, () -> callable.call());
}
/**
* Creates a new {@link Task} that's value will be set to the value returned
* from the supplied callable. This task is useful when doing basic
* computation that does not require asynchrony. It is not appropriate for
* long running or blocking tasks.
*
* @deprecated As of 2.0.0, replaced by {@link Task#callable(String, Callable) Task.callable}
* @param name a name that describes the action
* @param callable the callable to execute when this task is run
* @param <T> the type of the return value for this task
* @return the new task
* @see Task#callable(String, Callable) Task.callable
*/
@Deprecated
public static <T> Task<T> callable(final String name, final ThrowableCallable<? extends T> callable) {
return new CallableTask<T>(name, callable);
}
/**
* Creates a new task that will run the given tasks sequentially (e.g.
* task1 will be finished before task2 starts). The value of the seq task will
* be the result of the last task in the sequence.
*
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<T> task2) {
return vaseq(task1, task2);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<T> task3) {
return vaseq(task1, task2, task3);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<?> task3, Task<T> task4) {
return vaseq(task1, task2, task3, task4);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<?> task3, Task<?> task4, Task<T> task5) {
return vaseq(task1, task2, task3, task4, task5);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<?> task3, Task<?> task4, Task<?> task5,
Task<T> task6) {
return vaseq(task1, task2, task3, task4, task5, task6);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<?> task3, Task<?> task4, Task<?> task5,
Task<?> task6, Task<T> task7) {
return vaseq(task1, task2, task3, task4, task5, task6, task7);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<?> task3, Task<?> task4, Task<?> task5,
Task<?> task6, Task<?> task7, Task<T> task8) {
return vaseq(task1, task2, task3, task4, task5, task6, task7, task8);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<?> task3, Task<?> task4, Task<?> task5,
Task<?> task6, Task<?> task7, Task<?> task8, Task<T> task9) {
return vaseq(task1, task2, task3, task4, task5, task6, task7, task8, task9);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#map(String, com.linkedin.parseq.function.Function1) Task.map},
* {@link Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap},
* {@link Task#andThen(String, Task) Task.andThen} and other methods in {@link Task}.
* @see Task#map(String, com.linkedin.parseq.function.Function1) Task.map
* @see Task#flatMap(String, com.linkedin.parseq.function.Function1) Task.flatMap
* @see Task#andThen(String, Task) Task.andThen
* @see Task
*/
@Deprecated
public static <T> Task<T> seq(Task<?> task1, Task<?> task2, Task<?> task3, Task<?> task4, Task<?> task5,
Task<?> task6, Task<?> task7, Task<?> task8, Task<?> task9, Task<T> task10) {
return vaseq(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10);
}
/**
* Creates a new task that, when run, will run each of the supplied tasks in
* order. The value of this new task is the value of the last task in the
* sequence. <strong>This method is not type-safe</strong>.
*
* @param tasks the tasks to run sequentially
* @param <T> the result value for the sequence of tasks
* @return a new task that will run the given tasks sequentially
*/
@SuppressWarnings("deprecation")
public static <T> Task<T> seq(final Iterable<? extends Task<?>> tasks) {
return new SeqTask<T>("seq", tasks);
}
/**
* Creates a task that will run another task as a side effect once the primary task
* completes successfully. The side effect will not be run if the primary task fails or
* is canceled. The entire task is marked done once the base task completes, even if
* the side effect has not been run.
*
* @param parent the primary task.
* @param sideEffect the side effect of the primary task.
* @param <T> the result value of the parent task, and the resulting task.
* @return a new task that will be done once parent completes, but has the given side effect.
* @deprecated As of 2.0.0, replaced by {@link Task#withSideEffect(String, com.linkedin.parseq.function.Function1) Task.withSideEffect}
* @see Task#withSideEffect(String, com.linkedin.parseq.function.Function1) Task.withSideEffect
*/
@Deprecated
public static <T> Task<T> withSideEffect(final Task<T> parent, final Task<?> sideEffect) {
return parent.withSideEffect(t -> sideEffect);
}
/**
* Creates a new task that will run the given tasks in parallel (e.g. task1
* can be executed at the same time as task2). When all tasks complete
* successfully, you can use {@link com.linkedin.parseq.ParTask#get()} to
* get a list of the results. If at least one task failed, then this task will
* also be marked as failed. Use {@link com.linkedin.parseq.ParTask#getTasks()}
* or {@link com.linkedin.parseq.ParTask#getSuccessful()} to get results in
* this case.
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2) {
return vapar(task1, task2);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3) {
return vapar(task1, task2, task3);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3,
Task<? extends T> task4) {
return vapar(task1, task2, task3, task4);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3,
Task<? extends T> task4, Task<? extends T> task5) {
return vapar(task1, task2, task3, task4, task5);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3,
Task<? extends T> task4, Task<? extends T> task5, Task<? extends T> task6) {
return vapar(task1, task2, task3, task4, task5, task6);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3,
Task<? extends T> task4, Task<? extends T> task5, Task<? extends T> task6, Task<? extends T> task7) {
return vapar(task1, task2, task3, task4, task5, task6, task7);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3,
Task<? extends T> task4, Task<? extends T> task5, Task<? extends T> task6, Task<? extends T> task7,
Task<? extends T> task8) {
return vapar(task1, task2, task3, task4, task5, task6, task7, task8);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3,
Task<? extends T> task4, Task<? extends T> task5, Task<? extends T> task6, Task<? extends T> task7,
Task<? extends T> task8, Task<? extends T> task9) {
return vapar(task1, task2, task3, task4, task5, task6, task7, task8, task9);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Task, Task) Task.par}
* @see Task#par(Task, Task) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(Task<? extends T> task1, Task<? extends T> task2, Task<? extends T> task3,
Task<? extends T> task4, Task<? extends T> task5, Task<? extends T> task6, Task<? extends T> task7,
Task<? extends T> task8, Task<? extends T> task9, Task<? extends T> task10) {
return vapar(task1, task2, task3, task4, task5, task6, task7, task8, task9, task10);
}
/**
* @deprecated As of 2.0.0, replaced by {@link Task#par(Iterable) Task.par}
* as a safer alternative that does not throw an IllegalArgumentException for
* an empty Iterable of tasks.
* @see Task#par(Iterable) Task.par
*/
@Deprecated
public static <T> ParTask<T> par(final Iterable<? extends Task<? extends T>> tasks) {
return new ParTaskImpl<T>("par", tasks);
}
/**
* Creates a new task that wraps the given task. If the given task finishes
* before the timeout occurs then this task takes on the value of the task.
* If the task does not complete in the given time then this task will
* have a TimeoutException. The wrapped task may be cancelled when a timeout
* occurs.
*
* @param time the time to wait before timing out
* @param unit the units for the time
* @param task the task to wrap
* @param <T> the value type for the task
* @return the new timeout task
* @deprecated As of 2.0.0, replaced by {@link Task#withTimeout(long, TimeUnit) Task.withTimeout}.
* @see Task#withTimeout(long, TimeUnit) Task.withTimeout
*/
@Deprecated
public static <T> Task<T> timeoutWithError(final long time, final TimeUnit unit, final Task<T> task) {
return task.withTimeout(time, unit);
}
/**
* This method is similar to {@link #timeoutWithError(long, java.util.concurrent.TimeUnit, Task)},
* but it also takes a name that will be set on the returned task.
*
* @param name the name of this task
* @param time the time to wait before timing out
* @param unit the units for the time
* @param task the task to wrap
* @param <T> the value type for the task
* @return the new timeout task
* @deprecated As of 2.0.0, replaced by {@link Task#withTimeout(long, TimeUnit) Task.withTimeout}.
* @see Task#withTimeout(long, TimeUnit) Task.withTimeout
*/
@Deprecated
public static <T> Task<T> timeoutWithError(final String name, final long time, final TimeUnit unit,
final Task<T> task) {
return task.withTimeout(time, unit);
}
/**
* Creates a new task that will run the given array of tasks sequentially
* (e.g. tasks[0] will be finished before tasks[1] is run). <strong>This
* method is not type-safe</strong> - prefer one of the {@code seq} options
* when possible. The value of this new task is the value of the last task in
* the sequence.
*
* @param tasks the tasks to run sequentially
* @param <T> the result value for the sequence of tasks
* @return a new task that will run the given tasks sequentially
*/
@SuppressWarnings("deprecation")
private static <T> Task<T> vaseq(final Task<?>... tasks) {
return new SeqTask<T>("seq", Arrays.asList(tasks));
}
/**
* Creates a new task that will run each of the supplied tasks in parallel (e.g.
* tasks[0] can be run at the same time as task2). <strong>This method is not
* type-safe</strong> - prefer one of the {@code par} options when possible.
* <p>
* When all tasks complete successfully, you can use
* {@link com.linkedin.parseq.ParTask#get()} to get a list of the results. If
* at least one task failed, then this task will also be marked as failed. Use
* {@link com.linkedin.parseq.ParTask#getTasks()} or
* {@link com.linkedin.parseq.ParTask#getSuccessful()} to get results in this
* case.
*
* @param tasks the tasks to run in parallel
* @return a new task that will run the given tasks in parallel
*/
private static <T> ParTask<T> vapar(final Task<?>... tasks) {
final List<Task<T>> taskList = new ArrayList<Task<T>>(tasks.length);
for (Task<?> task : tasks) {
@SuppressWarnings("unchecked")
final Task<T> typedTask = (Task<T>) task;
taskList.add(typedTask);
}
return par(taskList);
}
}