submit(boolean shouldQueue);
/**
* Converts the success and failure callbacks into a {@link Result}.
*
This means the {@link #queue(Consumer, Consumer)} failure consumer will never be used.
* Instead, all results will be evaluated into a success consumer which provides an instance of {@link Result}.
*
* {@link Result} will either be {@link Result#isSuccess() successful} or {@link Result#isFailure() failed}.
* This can be useful in combination with {@link #allOf(Collection)} to handle failed requests individually for each
* action.
*
*
Note: You have to handle failures explicitly with this.
* You should use {@link Result#onFailure(Consumer)}, {@link Result#getFailure()}, or {@link Result#expect(Predicate)}!
*
* @return RestAction - Type: {@link Result}
*
* @since 4.2.1
*/
@Nonnull
@CheckReturnValue
default RestAction> mapToResult()
{
return map(Result::success).onErrorMap(Result::failure);
}
/**
* Intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction which will apply
* the map function on successful execution.
*
*
Example
*
{@code
* public RestAction retrieveMemberNickname(Guild guild, String userId) {
* return guild.retrieveMemberById(userId)
* .map(Member::getNickname);
* }
* }
*
* @param map
* The mapping function to apply to the action result
*
* @param
* The target output type
*
* @return RestAction for the mapped type
*
* @since 4.1.1
*/
@Nonnull
@CheckReturnValue
default RestAction map(@Nonnull Function super T, ? extends O> map)
{
Checks.notNull(map, "Function");
return new MapRestAction<>(this, map);
}
/**
* An intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction, which will consume
* the actions result using the given consumer on successful execution.
* The resulting action continues with the previous result.
*
*
Example
*
{@code
* public RestAction retrieveMemberNickname(Guild guild, String userId) {
* return guild.retrieveMemberById(userId)
* .map(Member::getNickname)
* .onSuccess(System.out::println);
* }
* }
*
* Prefer using {@link #queue(Consumer)} instead, if continuation of the action
* chain is not desired.
*
* @param consumer
* The consuming function to apply to the action result, failures are propagated
* into the resulting action
*
* @throws IllegalArgumentException
* If the consumer is null
*
* @return RestAction that consumes the action result
*/
@Nonnull
@CheckReturnValue
default RestAction onSuccess(@Nonnull Consumer super T> consumer)
{
Checks.notNull(consumer, "Consumer");
return map(result -> {
consumer.accept(result);
return result;
});
}
/**
* Supply a fallback value when the RestAction fails for any reason.
*
* This does not modify this instance but returns a new RestAction which will apply
* the map function on failed execution.
*
*
Example
*
{@code
* public RestAction sendMessage(User user, String content) {
* return user.openPrivateChannel() // RestAction
* .flatMap((channel) -> channel.sendMessage(content)) // RestAction
* .map(Message::getContentRaw) // RestAction
* .onErrorMap(Throwable::getMessage); // RestAction (must be the same as above)
* }
* }
*
* @param map
* The mapping function which provides the fallback value to use
*
* @throws IllegalArgumentException
* If the mapping function is null
*
* @return RestAction with fallback handling
*
* @since 4.2.0
*/
@Nonnull
@CheckReturnValue
default RestAction onErrorMap(@Nonnull Function super Throwable, ? extends T> map)
{
return onErrorMap(null, map);
}
/**
* Supply a fallback value when the RestAction fails for a specific reason.
*
* This does not modify this instance but returns a new RestAction which will apply
* the map function on failed execution.
*
*
Example
*
{@code
* public RestAction sendMessage(User user, String content) {
* return user.openPrivateChannel() // RestAction
* .flatMap((channel) -> channel.sendMessage(content)) // RestAction
* .map(Message::getContentRaw) // RestAction
* .onErrorMap(CANNOT_SEND_TO_USER::test, Throwable::getMessage); // RestAction (must be the same as above)
* }
* }
*
* @param condition
* A condition that must return true to apply this fallback
* @param map
* The mapping function which provides the fallback value to use
*
* @throws IllegalArgumentException
* If the mapping function is null
*
* @return RestAction with fallback handling
*
* @see ErrorResponse#test(Throwable)
* @see ErrorResponse#test(ErrorResponse...)
*
* @since 4.2.0
*/
@Nonnull
@CheckReturnValue
default RestAction onErrorMap(@Nullable Predicate super Throwable> condition, @Nonnull Function super Throwable, ? extends T> map)
{
Checks.notNull(map, "Function");
return new MapErrorRestAction<>(this, condition == null ? (x) -> true : condition, map);
}
/**
* Supply a fallback value when the RestAction fails for a any reason.
*
* This does not modify this instance but returns a new RestAction which will apply
* the map function on failed execution.
*
*
Example
*
{@code
* public RestAction sendMessage(User user, TextChannel context, String content) {
* return user.openPrivateChannel() // RestAction
* .flatMap((channel) -> channel.sendMessage(content)) // RestAction
* .onErrorFlatMap(
* (error) -> context.sendMessage("Failed to send direct message to " + user.getAsMention() + " Reason: " + error)
* ); // RestAction (must be the same as above)
* }
* }
*
* @param map
* The mapping function which provides the fallback action to use
*
* @throws IllegalArgumentException
* If the mapping function is null
*
* @return RestAction with fallback handling
*
* @since 4.2.0
*/
@Nonnull
@CheckReturnValue
default RestAction onErrorFlatMap(@Nonnull Function super Throwable, ? extends RestAction extends T>> map)
{
return onErrorFlatMap(null, map);
}
/**
* Supply a fallback value when the RestAction fails for a specific reason.
*
* This does not modify this instance but returns a new RestAction which will apply
* the map function on failed execution.
*
*
Example
*
{@code
* public RestAction sendMessage(User user, TextChannel context, String content) {
* return user.openPrivateChannel() // RestAction
* .flatMap((channel) -> channel.sendMessage(content)) // RestAction
* .onErrorFlatMap(CANNOT_SEND_TO_USER::test,
* (error) -> context.sendMessage("Cannot send direct message to " + user.getAsMention())
* ); // RestAction (must be the same as above)
* }
* }
*
* @param condition
* A condition that must return true to apply this fallback
* @param map
* The mapping function which provides the fallback action to use
*
* @throws IllegalArgumentException
* If the mapping function is null
*
* @return RestAction with fallback handling
*
* @see ErrorResponse#test(Throwable)
* @see ErrorResponse#test(ErrorResponse...)
*
* @since 4.2.0
*/
@Nonnull
@CheckReturnValue
default RestAction onErrorFlatMap(@Nullable Predicate super Throwable> condition, @Nonnull Function super Throwable, ? extends RestAction extends T>> map)
{
Checks.notNull(map, "Function");
return new FlatMapErrorRestAction<>(this, condition == null ? (x) -> true : condition, map);
}
/**
* Intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction which will apply
* the map function on successful execution. This will compute the result of both RestActions.
*
The returned RestAction must not be null!
* To terminate the execution chain on a specific condition you can use {@link #flatMap(Predicate, Function)}.
*
*
Example
*
{@code
* public RestAction initializeGiveaway(Guild guild, String channelName) {
* return guild.createTextChannel(channelName)
* .addPermissionOverride(guild.getPublicRole(), null, EnumSet.of(Permission.MESSAGE_SEND)) // deny write for everyone
* .addPermissionOverride(guild.getSelfMember(), EnumSet.of(Permission.MESSAGE_SEND), null) // allow for self user
* .flatMap((channel) -> channel.sendMessage("React to enter giveaway!")) // send message
* .flatMap((message) -> message.addReaction(REACTION)); // add reaction
* }
* }
*
* @param flatMap
* The mapping function to apply to the action result, must return a RestAction
*
* @param
* The target output type
*
* @return RestAction for the mapped type
*
* @since 4.1.1
*/
@Nonnull
@CheckReturnValue
default RestAction flatMap(@Nonnull Function super T, ? extends RestAction> flatMap)
{
return flatMap(null, flatMap);
}
/**
* Intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction which will apply
* the map function on successful execution. This will compute the result of both RestActions.
*
The provided RestAction must not be null!
*
*
Example
*
{@code
* private static final int MAX_COUNT = 1000;
* public void updateCount(MessageChannel channel, String messageId, int count) {
* channel.retrieveMessageById(messageId) // retrieve message for check
* .map(Message::getContentRaw) // get content of the message
* .map(Integer::parseInt) // convert it to an int
* .flatMap(
* (currentCount) -> currentCount + count <= MAX_COUNT, // Only edit if new count does not exceed maximum
* (currentCount) -> channel.editMessageById(messageId, String.valueOf(currentCount + count)) // edit message
* )
* .map(Message::getContentRaw) // get content of the message
* .map(Integer::parseInt) // convert it to an int
* .queue((newCount) -> System.out.println("Updated count to " + newCount));
* }
* }
*
* @param condition
* A condition predicate that decides whether to apply the flat map operator or not
* @param flatMap
* The mapping function to apply to the action result, must return a RestAction
*
* @param
* The target output type
*
* @return RestAction for the mapped type
*
* @see #flatMap(Function)
* @see #map(Function)
*
* @since 4.1.1
*/
@Nonnull
@CheckReturnValue
default RestAction flatMap(@Nullable Predicate super T> condition, @Nonnull Function super T, ? extends RestAction> flatMap)
{
Checks.notNull(flatMap, "Function");
return new FlatMapRestAction<>(this, condition, flatMap);
}
/**
* Combines this RestAction with the provided action.
*
The result is computed by the provided {@link BiFunction}.
*
* If one of the actions fails, the other will be cancelled.
* To handle failures individually instead of cancelling you can use {@link #mapToResult()}.
*
* @param other
* The action to combine
* @param accumulator
* BiFunction to compute the result
* @param
* The type of the other action
* @param
* The result type after applying the accumulator function
*
* @throws IllegalArgumentException
* If null is provided or you tried to combine an action with itself
*
* @return Combined RestAction
*
* @since 4.2.1
*/
@Nonnull
@CheckReturnValue
default RestAction and(@Nonnull RestAction other, @Nonnull BiFunction super T, ? super U, ? extends O> accumulator)
{
Checks.notNull(other, "RestAction");
Checks.notNull(accumulator, "Accumulator");
return new CombineRestAction<>(this, other, accumulator);
}
/**
* Combines this RestAction with the provided action.
*
* If one of the actions fails, the other will be cancelled.
* To handle failures individually instead of cancelling you can use {@link #mapToResult()}.
*
* @param other
* The action to combine
* @param
* The type of the other action
*
* @throws IllegalArgumentException
* If null is provided or you tried to combine an action with itself
*
* @return Combined RestAction with empty result
*
* @since 4.2.1
*/
@Nonnull
@CheckReturnValue
default RestAction and(@Nonnull RestAction other)
{
return and(other, (a, b) -> null);
}
/**
* Accumulates this RestAction with the provided actions into a {@link List}.
*
* If one of the actions fails, the others will be cancelled.
* To handle failures individually instead of cancelling you can use {@link #mapToResult()}.
*
* @param first
* The first other action to accumulate into the list
* @param other
* The other actions to accumulate into the list
*
* @throws IllegalArgumentException
* If null is provided or you tried to combine an action with itself
*
* @return Combined RestAction with empty result
*
* @see #allOf(RestAction, RestAction[])
* @see #and(RestAction, BiFunction)
*
* @since 4.2.1
*/
@Nonnull
@CheckReturnValue
@SuppressWarnings("unchecked")
default RestAction> zip(@Nonnull RestAction extends T> first, @Nonnull RestAction extends T>... other)
{
Checks.notNull(first, "RestAction");
Checks.noneNull(other, "RestAction");
List> list = new ArrayList<>();
list.add(this);
list.add(first);
Collections.addAll(list, other);
return allOf(list);
}
/**
* Intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction which will delay its result by the provided delay.
*
*
Example
*
{@code
* public RestAction selfDestruct(MessageChannel channel, String content) {
* return channel.sendMessage("The following message will destroy itself in 1 minute!")
* .delay(Duration.ofSeconds(10)) // edit 10 seconds later
* .flatMap((it) -> it.editMessage(content))
* .delay(Duration.ofMinutes(1)) // delete 1 minute later
* .flatMap(Message::delete);
* }
* }
*
* @param duration
* The delay
*
* @return RestAction with delay
*
* @see #queueAfter(long, TimeUnit)
*
* @since 4.1.1
*/
@Nonnull
@CheckReturnValue
default RestAction delay(@Nonnull Duration duration)
{
return delay(duration, null);
}
/**
* Intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction which will delay its result by the provided delay.
*
*
Example
*
{@code
* public RestAction selfDestruct(MessageChannel channel, String content) {
* return channel.sendMessage("The following message will destroy itself in 1 minute!")
* .delay(Duration.ofSeconds(10), scheduler) // edit 10 seconds later
* .flatMap((it) -> it.editMessage(content))
* .delay(Duration.ofMinutes(1), scheduler) // delete 1 minute later
* .flatMap(Message::delete);
* }
* }
*
* @param duration
* The delay
* @param scheduler
* The scheduler to use, null to use {@link JDA#getRateLimitPool()}
*
* @return RestAction with delay
*
* @see #queueAfter(long, TimeUnit, ScheduledExecutorService)
*
* @since 4.1.1
*/
@Nonnull
@CheckReturnValue
default RestAction delay(@Nonnull Duration duration, @Nullable ScheduledExecutorService scheduler)
{
Checks.notNull(duration, "Duration");
return new DelayRestAction<>(this, TimeUnit.MILLISECONDS, duration.toMillis(), scheduler);
}
/**
* Intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction which will delay its result by the provided delay.
*
*
Example
*
{@code
* public RestAction selfDestruct(MessageChannel channel, String content) {
* return channel.sendMessage("The following message will destroy itself in 1 minute!")
* .delay(10, SECONDS) // edit 10 seconds later
* .flatMap((it) -> it.editMessage(content))
* .delay(1, MINUTES) // delete 1 minute later
* .flatMap(Message::delete);
* }
* }
*
* @param delay
* The delay value
* @param unit
* The time unit for the delay value
*
* @return RestAction with delay
*
* @see #queueAfter(long, TimeUnit)
*
* @since 4.1.1
*/
@Nonnull
@CheckReturnValue
default RestAction delay(long delay, @Nonnull TimeUnit unit)
{
return delay(delay, unit, null);
}
/**
* Intermediate operator that returns a modified RestAction.
*
* This does not modify this instance but returns a new RestAction which will delay its result by the provided delay.
*
*
Example
*
{@code
* public RestAction selfDestruct(MessageChannel channel, String content) {
* return channel.sendMessage("The following message will destroy itself in 1 minute!")
* .delay(10, SECONDS, scheduler) // edit 10 seconds later
* .flatMap((it) -> it.editMessage(content))
* .delay(1, MINUTES, scheduler) // delete 1 minute later
* .flatMap(Message::delete);
* }
* }
*
* @param delay
* The delay value
* @param unit
* The time unit for the delay value
* @param scheduler
* The scheduler to use, null to use {@link JDA#getRateLimitPool()}
*
* @return RestAction with delay
*
* @see #queueAfter(long, TimeUnit, ScheduledExecutorService)
*
* @since 4.1.1
*/
@Nonnull
@CheckReturnValue
default RestAction delay(long delay, @Nonnull TimeUnit unit, @Nullable ScheduledExecutorService scheduler)
{
Checks.notNull(unit, "TimeUnit");
return new DelayRestAction<>(this, unit, delay, scheduler);
}
/**
* Schedules a call to {@link #queue()} to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link CompletableFuture CompletableFuture} representing the task.
*
* Similar to {@link #queueAfter(long, TimeUnit)} but does not require callbacks to be passed.
* Continuations of {@link CompletableFuture} can be used instead.
*
*
The global JDA RateLimit {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService}
* is used for this operation.
*
You can provide your own Executor using {@link #submitAfter(long, java.util.concurrent.TimeUnit, java.util.concurrent.ScheduledExecutorService)}!
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit is {@code null}
*
* @return {@link DelayedCompletableFuture DelayedCompletableFuture}
* representing the delayed operation
*/
@Nonnull
@CheckReturnValue
default DelayedCompletableFuture submitAfter(long delay, @Nonnull TimeUnit unit)
{
return submitAfter(delay, unit, null);
}
/**
* Schedules a call to {@link #queue()} to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link CompletableFuture CompletableFuture} representing the task.
*
* Similar to {@link #queueAfter(long, TimeUnit)} but does not require callbacks to be passed.
* Continuations of {@link CompletableFuture} can be used instead.
*
*
The specified {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} is used for this operation.
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
* @param executor
* The {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} that should be used
* to schedule this operation, or null to use the default
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit is {@code null}
*
* @return {@link DelayedCompletableFuture DelayedCompletableFuture}
* representing the delayed operation
*/
@Nonnull
@CheckReturnValue
default DelayedCompletableFuture submitAfter(long delay, @Nonnull TimeUnit unit, @Nullable ScheduledExecutorService executor)
{
Checks.notNull(unit, "TimeUnit");
if (executor == null)
executor = getJDA().getRateLimitPool();
return DelayedCompletableFuture.make(executor, delay, unit,
(task) -> {
final Consumer super Throwable> onFailure;
if (isPassContext())
onFailure = ContextException.here(task::completeExceptionally);
else
onFailure = task::completeExceptionally;
return new ContextRunnable(() -> queue(task::complete, onFailure));
});
}
/**
* Blocks the current Thread for the specified delay and calls {@link #complete()}
* when delay has been reached.
*
If the specified delay is negative this action will execute immediately. (see: {@link TimeUnit#sleep(long)})
*
* @param delay
* The delay after which to execute a call to {@link #complete()}
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} which should be used
* (this will use {@link java.util.concurrent.TimeUnit#sleep(long) unit.sleep(delay)})
*
* @throws java.lang.IllegalArgumentException
* If the specified {@link java.util.concurrent.TimeUnit TimeUnit} is {@code null}
* @throws java.lang.RuntimeException
* If the sleep operation is interrupted
*
* @return The response value
*/
@Blocking
@UnknownNullability
default T completeAfter(long delay, @Nonnull TimeUnit unit)
{
Checks.notNull(unit, "TimeUnit");
try
{
unit.sleep(delay);
return complete();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
/**
* Schedules a call to {@link #queue()} to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link java.util.concurrent.ScheduledFuture ScheduledFuture} representing the task.
*
* This operation gives no access to the response value.
*
Use {@link #queueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer)} to access
* the success consumer for {@link #queue(java.util.function.Consumer)}!
*
*
The global JDA {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} is used for this operation.
*
You can provide your own Executor with {@link #queueAfter(long, java.util.concurrent.TimeUnit, java.util.concurrent.ScheduledExecutorService)}
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit is {@code null}
*
* @return {@link java.util.concurrent.ScheduledFuture ScheduledFuture}
* representing the delayed operation
*/
@Nonnull
default ScheduledFuture> queueAfter(long delay, @Nonnull TimeUnit unit)
{
return queueAfter(delay, unit, null, null, null);
}
/**
* Schedules a call to {@link #queue(java.util.function.Consumer)} to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link java.util.concurrent.ScheduledFuture ScheduledFuture} representing the task.
*
*
This operation gives no access to the failure callback.
*
Use {@link #queueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.function.Consumer)} to access
* the failure consumer for {@link #queue(java.util.function.Consumer, java.util.function.Consumer)}!
*
*
The global JDA {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} is used for this operation.
*
You can provide your own Executor with {@link #queueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.concurrent.ScheduledExecutorService)}
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
* @param success
* The success {@link java.util.function.Consumer Consumer} that should be called
* once the {@link #queue(java.util.function.Consumer)} operation completes successfully.
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit is {@code null}
*
* @return {@link java.util.concurrent.ScheduledFuture ScheduledFuture}
* representing the delayed operation
*/
@Nonnull
default ScheduledFuture> queueAfter(long delay, @Nonnull TimeUnit unit, @Nullable Consumer super T> success)
{
return queueAfter(delay, unit, success, null, null);
}
/**
* Schedules a call to {@link #queue(java.util.function.Consumer, java.util.function.Consumer)}
* to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link java.util.concurrent.ScheduledFuture ScheduledFuture} representing the task.
*
*
The global JDA {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} is used for this operation.
*
You provide your own Executor with {@link #queueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.function.Consumer, java.util.concurrent.ScheduledExecutorService)}
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
* @param success
* The success {@link java.util.function.Consumer Consumer} that should be called
* once the {@link #queue(java.util.function.Consumer, java.util.function.Consumer)} operation completes successfully.
* @param failure
* The failure {@link java.util.function.Consumer Consumer} that should be called
* in case of an error of the {@link #queue(java.util.function.Consumer, java.util.function.Consumer)} operation.
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit is {@code null}
*
* @return {@link java.util.concurrent.ScheduledFuture ScheduledFuture}
* representing the delayed operation
*
* @see net.dv8tion.jda.api.exceptions.ErrorHandler
*/
@Nonnull
default ScheduledFuture> queueAfter(long delay, @Nonnull TimeUnit unit, @Nullable Consumer super T> success, @Nullable Consumer super Throwable> failure)
{
return queueAfter(delay, unit, success, failure, null);
}
/**
* Schedules a call to {@link #queue()} to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link java.util.concurrent.ScheduledFuture ScheduledFuture} representing the task.
*
*
This operation gives no access to the response value.
*
Use {@link #queueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer)} to access
* the success consumer for {@link #queue(java.util.function.Consumer)}!
*
*
The specified {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} is used for this operation.
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
* @param executor
* The Non-null {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} that should be used
* to schedule this operation
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit or ScheduledExecutorService is {@code null}
*
* @return {@link java.util.concurrent.ScheduledFuture ScheduledFuture}
* representing the delayed operation
*/
@Nonnull
default ScheduledFuture> queueAfter(long delay, @Nonnull TimeUnit unit, @Nullable ScheduledExecutorService executor)
{
return queueAfter(delay, unit, null, null, executor);
}
/**
* Schedules a call to {@link #queue(java.util.function.Consumer)} to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link java.util.concurrent.ScheduledFuture ScheduledFuture} representing the task.
*
*
This operation gives no access to the failure callback.
*
Use {@link #queueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.function.Consumer)} to access
* the failure consumer for {@link #queue(java.util.function.Consumer, java.util.function.Consumer)}!
*
*
The specified {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} is used for this operation.
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
* @param success
* The success {@link java.util.function.Consumer Consumer} that should be called
* once the {@link #queue(java.util.function.Consumer)} operation completes successfully.
* @param executor
* The Non-null {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} that should be used
* to schedule this operation
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit or ScheduledExecutorService is {@code null}
*
* @return {@link java.util.concurrent.ScheduledFuture ScheduledFuture}
* representing the delayed operation
*/
@Nonnull
default ScheduledFuture> queueAfter(long delay, @Nonnull TimeUnit unit, @Nullable Consumer super T> success, @Nullable ScheduledExecutorService executor)
{
return queueAfter(delay, unit, success, null, executor);
}
/**
* Schedules a call to {@link #queue(java.util.function.Consumer, java.util.function.Consumer)}
* to be executed after the specified {@code delay}.
*
This is an asynchronous operation that will return a
* {@link java.util.concurrent.ScheduledFuture ScheduledFuture} representing the task.
*
*
The specified {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} is used for this operation.
*
* @param delay
* The delay after which this computation should be executed, negative to execute immediately
* @param unit
* The {@link java.util.concurrent.TimeUnit TimeUnit} to convert the specified {@code delay}
* @param success
* The success {@link java.util.function.Consumer Consumer} that should be called
* once the {@link #queue(java.util.function.Consumer, java.util.function.Consumer)} operation completes successfully.
* @param failure
* The failure {@link java.util.function.Consumer Consumer} that should be called
* in case of an error of the {@link #queue(java.util.function.Consumer, java.util.function.Consumer)} operation.
* @param executor
* The Non-null {@link java.util.concurrent.ScheduledExecutorService ScheduledExecutorService} that should be used
* to schedule this operation
*
* @throws java.lang.IllegalArgumentException
* If the provided TimeUnit or ScheduledExecutorService is {@code null}
*
* @return {@link java.util.concurrent.ScheduledFuture ScheduledFuture}
* representing the delayed operation
*
* @see net.dv8tion.jda.api.exceptions.ErrorHandler
*/
@Nonnull
default ScheduledFuture> queueAfter(long delay, @Nonnull TimeUnit unit, @Nullable Consumer super T> success, @Nullable Consumer super Throwable> failure, @Nullable ScheduledExecutorService executor)
{
Checks.notNull(unit, "TimeUnit");
if (executor == null)
executor = getJDA().getRateLimitPool();
final Consumer super Throwable> onFailure;
if (isPassContext())
onFailure = ContextException.here(failure == null ? getDefaultFailure() : failure);
else
onFailure = failure;
Runnable task = new ContextRunnable(() -> queue(success, onFailure));
return executor.schedule(task, delay, unit);
}
}