Class RestAction<T>
- java.lang.Object
-
- net.dv8tion.jda.core.requests.RestAction<T>
-
- Type Parameters:
T
- The generic response type for this RestAction
- Direct Known Subclasses:
ApplicationAction
,AuditableRestAction
,GuildAction
,MemberAction
,MessageAction
,MessageHistory.MessageRetrieveAction
,OrderAction
,PaginationAction
,RestAction.EmptyRestAction
public abstract class RestAction<T> extends java.lang.Object
A class representing a terminal between the user and the discord API.
This is used to offer users the ability to decide how JDA should limit a Request.Methods that return an instance of RestAction require an additional step to complete the execution. Thus the user needs to append a follow-up method.
A default RestAction is issued with the following operations:
queue()
,queue(Consumer)
,queue(Consumer, Consumer)
The fastest and most simplistic way to execute a RestAction is to queue it.
This method has two optional callback functions, one with the generic type and another with a failure exception.submit()
,submit(boolean)
Provides a Future representing the pending request.
An optional parameter of type boolean can be passed to disable automated rate limit handling. (not recommended)complete()
,complete(boolean)
Blocking execution building up onsubmit()
.
This will simply block the thread and return the Request result, or throw an exception.
An optional parameter of type boolean can be passed to disable automated rate limit handling. (not recommended)
queue()
operations.
These allow users to provide success and failure callbacks which will be called at a convenient time.Planning Execution
To schedule a RestAction we provide bothqueue()
andcomplete()
versions that will be executed by aScheduledExecutorService
after a specified delay:queueAfter(long, TimeUnit)
Schedules a call toqueue()
with default callbackConsumers
to be executed after the specifieddelay
.
TheTimeUnit
is used to convert the provided long into a delay time.
Example:queueAfter(1, TimeUnit.SECONDS);
will callqueue()
1 second later.submitAfter(long, TimeUnit)
This returns aScheduledFuture
which can be joined into the current Thread usingFuture.get()
The blocking call tosubmitAfter(delay, unit).get()
will return the value processed by a call tocomplete()
completeAfter(long, TimeUnit)
This operation simply sleeps for the given delay and will callcomplete()
once finished sleeping.
All of those operations provide overloads for optional parameters such as a custom
ScheduledExecutorService
instead of using the default global JDA executor. SpecificallyqueueAfter(long, TimeUnit)
has overloads to provide a success and/or failure callback due to the returnedScheduledFuture
not being able to provide the response values of thequeue()
callbacks.Using RestActions
The most common way to use a RestAction is not using the returned value.
For instance sending messages usually means you will not require to view the message once it was sent. Thus we can simply use the asynchronousqueue()
operation which will be executed on a rate limit worker thread in the background, without blocking your current thread:MessageChannel
channel = event.getChannel(); RestAction<Message> action = channel.sendMessage("Hello World"); action.queue()
; // Execute the rest action asynchronouslySometimes it is important to access the response value, possibly to modify it later.
Now we have two options to actually access the response value, either using an asynchronous callbackConsumer
or the (not recommended)complete()
which will block the current thread until the response has been processed and joins with the current thread.Example Queue: (recommended)
MessageChannel
channel = event.getChannel(); final long time = System.currentTimeMillis(); RestAction<Message> action = channel.sendMessage("Calculating Response Time...");Consumer
<Message> callback = (message) -> { Message m = message; // ^This is a lambda parameter!^ m.editMessage("Response Time: " + (System.currentTimeMillis() - time) + "ms").queue(); // End with queue() to not block the callback thread! }; // You can also inline this with the queue parameter: action.queue(m -> m.editMessage(...).queue()); action.queue(callback)
;Example Complete:
MessageChannel
channel = event.getChannel(); final long time = System.currentTimeMillis(); RestAction<Message> action = channel.sendMessage("Calculating Response Time..."); Message message = action.complete()
; message.editMessage("Response Time: " + (System.currentTimeMillis() - time) + "ms").queue(); // End withqueue()
to not block the callback thread!Example Planning:
MessageChannel
channel = event.getChannel(); RestAction<Message> action = channel.sendMessage("This message will destroy itself in 5 seconds!"); action.queue((message) -> message.delete().queueAfter(5, TimeUnit.SECONDS)
);Developer Note: It is generally a good practice to use asynchronous logic because blocking threads requires resources which can be avoided by using callbacks over blocking operations:
queue(Consumer)
>complete()
There is a dedicated wiki page for RestActions that can be useful for learning.
- Since:
- 3.0
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static class
RestAction.EmptyRestAction<T>
Specialized form ofRestAction
that is used to provide information that has already been retrieved or generated so that another request does not need to be made to Discord.
-
Field Summary
Fields Modifier and Type Field Description static java.util.function.Consumer<java.lang.Throwable>
DEFAULT_FAILURE
static java.util.function.Consumer
DEFAULT_SUCCESS
static org.slf4j.Logger
LOG
-
Constructor Summary
Constructors Constructor Description RestAction(JDA api, net.dv8tion.jda.core.requests.Route.CompiledRoute route)
Creates a new RestAction instanceRestAction(JDA api, net.dv8tion.jda.core.requests.Route.CompiledRoute route, okhttp3.RequestBody data)
Creates a new RestAction instanceRestAction(JDA api, net.dv8tion.jda.core.requests.Route.CompiledRoute route, org.json.JSONObject data)
Creates a new RestAction instance
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description T
complete()
Blocks the current Thread and awaits the completion of ansubmit()
request.T
complete(boolean shouldQueue)
Blocks the current Thread and awaits the completion of ansubmit()
request.T
completeAfter(long delay, java.util.concurrent.TimeUnit unit)
Blocks the current Thread for the specified delay and callscomplete()
when delay has been reached.JDA
getJDA()
The current JDA instancestatic boolean
isPassContext()
Whether RestActions will useContextException
automatically to keep track of the caller context.void
queue()
Submits a Request for execution.void
queue(java.util.function.Consumer<? super T> success)
Submits a Request for execution.void
queue(java.util.function.Consumer<? super T> success, java.util.function.Consumer<? super java.lang.Throwable> failure)
Submits a Request for execution.java.util.concurrent.ScheduledFuture<?>
queueAfter(long delay, java.util.concurrent.TimeUnit unit)
Schedules a call toqueue()
to be executed after the specifieddelay
.java.util.concurrent.ScheduledFuture<?>
queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call toqueue()
to be executed after the specifieddelay
.java.util.concurrent.ScheduledFuture<?>
queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success)
Schedules a call toqueue(java.util.function.Consumer)
to be executed after the specifieddelay
.java.util.concurrent.ScheduledFuture<?>
queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call toqueue(java.util.function.Consumer)
to be executed after the specifieddelay
.java.util.concurrent.ScheduledFuture<?>
queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success, java.util.function.Consumer<? super java.lang.Throwable> failure)
Schedules a call toqueue(java.util.function.Consumer, java.util.function.Consumer)
to be executed after the specifieddelay
.java.util.concurrent.ScheduledFuture<?>
queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success, java.util.function.Consumer<? super java.lang.Throwable> failure, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call toqueue(java.util.function.Consumer, java.util.function.Consumer)
to be executed after the specifieddelay
.RestAction<T>
setCheck(java.util.function.BooleanSupplier checks)
Sets the last-second checks before finally executing the http request in the queue.static void
setPassContext(boolean enable)
If enabled this will pass aContextException
as root-cause to all failure consumers.RequestFuture<T>
submit()
Submits a Request for execution and provides aRequestFuture
representing its completion task.RequestFuture<T>
submit(boolean shouldQueue)
Submits a Request for execution and provides aRequestFuture
representing its completion task.java.util.concurrent.ScheduledFuture<T>
submitAfter(long delay, java.util.concurrent.TimeUnit unit)
Schedules a call tocomplete()
to be executed after the specifieddelay
.java.util.concurrent.ScheduledFuture<T>
submitAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call tocomplete()
to be executed after the specifieddelay
.
-
-
-
Constructor Detail
-
RestAction
public RestAction(JDA api, net.dv8tion.jda.core.requests.Route.CompiledRoute route)
Creates a new RestAction instance- Parameters:
api
- The current JDA instanceroute
- TheRoute.CompiledRoute
to be used for rate limit handling
-
RestAction
public RestAction(JDA api, net.dv8tion.jda.core.requests.Route.CompiledRoute route, okhttp3.RequestBody data)
Creates a new RestAction instance- Parameters:
api
- The current JDA instanceroute
- TheRoute.CompiledRoute
to be used for rate limit handlingdata
- The data that should be sent to the specified route. (can be null)
-
RestAction
public RestAction(JDA api, net.dv8tion.jda.core.requests.Route.CompiledRoute route, org.json.JSONObject data)
Creates a new RestAction instance- Parameters:
api
- The current JDA instanceroute
- TheRoute.CompiledRoute
to be used for rate limit handlingdata
- The data that should be sent to the specified route. (can be null)
-
-
Method Detail
-
setPassContext
public static void setPassContext(boolean enable)
If enabled this will pass aContextException
as root-cause to all failure consumers. Note that theDEFAULT_FAILURE
does not print a stack-trace at all unless specified!
This might cause performance decrease due to the creation of exceptions for every execution.It is recommended to pass a context consumer as failure manually using
queue(success, ContextException.here(failure))
- Parameters:
enable
- True, if context should be passed to all failure consumers
-
isPassContext
public static boolean isPassContext()
Whether RestActions will useContextException
automatically to keep track of the caller context.
If set totrue
this can cause performance drops due to the creation of stack-traces on execution.- Returns:
- True, if RestActions will keep track of context automatically
- See Also:
setPassContext(boolean)
-
getJDA
public JDA getJDA()
The current JDA instance- Returns:
- The corresponding JDA instance
-
setCheck
public RestAction<T> setCheck(java.util.function.BooleanSupplier checks)
Sets the last-second checks before finally executing the http request in the queue.
If the provided supplier evaluates tofalse
or throws an exception this will not be finished. When an exception is thrown from the supplier it will be provided to the failure callback.- Parameters:
checks
- The checks to run before executing the request, ornull
to run no checks- Returns:
- The current RestAction for chaining convenience
-
queue
public void queue()
Submits a Request for execution.
Using the default callback functions:DEFAULT_SUCCESS
andDEFAULT_FAILURE
This method is asynchronous
-
queue
public void queue(java.util.function.Consumer<? super T> success)
Submits a Request for execution.
Using the default failure callback function.This method is asynchronous
- Parameters:
success
- The success callback that will be called at a convenient time for the API. (can be null)
-
queue
public void queue(java.util.function.Consumer<? super T> success, java.util.function.Consumer<? super java.lang.Throwable> failure)
Submits a Request for execution.This method is asynchronous
- Parameters:
success
- The success callback that will be called at a convenient time for the API. (can be null)failure
- The failure callback that will be called if the Request encounters an exception at its execution point.
-
submit
public RequestFuture<T> submit()
Submits a Request for execution and provides aRequestFuture
representing its completion task.
Cancelling the returned Future will result in the cancellation of the Request!Note: The usage of
CompletionStage.toCompletableFuture()
is not supported.- Returns:
- Never-null
RequestFuture
representing the completion promise
-
submit
public RequestFuture<T> submit(boolean shouldQueue)
Submits a Request for execution and provides aRequestFuture
representing its completion task.
Cancelling the returned Future will result in the cancellation of the Request!Note: The usage of
CompletionStage.toCompletableFuture()
is not supported.- Parameters:
shouldQueue
- Whether the Request should automatically handle rate limitations. (default true)- Returns:
- Never-null
RequestFuture
task representing the completion promise
-
complete
public T complete()
Blocks the current Thread and awaits the completion of ansubmit()
request.
Used for synchronous logic.This might throw
RuntimeExceptions
- Returns:
- The response value
- Throws:
java.lang.IllegalStateException
- If used within aqueue(...)
callback
-
complete
public T complete(boolean shouldQueue) throws RateLimitedException
Blocks the current Thread and awaits the completion of ansubmit()
request.
Used for synchronous logic.- Parameters:
shouldQueue
- Whether this should automatically handle rate limitations (default true)- Returns:
- The response value
- Throws:
java.lang.IllegalStateException
- If used within aqueue(...)
callbackRateLimitedException
- If we were rate limited and theshouldQueue
is false. Usecomplete()
to avoid this Exception.
-
submitAfter
public java.util.concurrent.ScheduledFuture<T> submitAfter(long delay, java.util.concurrent.TimeUnit unit)
Schedules a call tocomplete()
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.The returned Future will provide the return type of a
complete()
operation when received through the blocking call toFuture.get()
!The global JDA
ScheduledExecutorService
is used for this operation.
You can change the core pool size for this Executor throughJDABuilder.setCorePoolSize(int)
or you can provide your own Executor usingsubmitAfter(long, java.util.concurrent.TimeUnit, java.util.concurrent.ScheduledExecutorService)
!- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit isnull
-
submitAfter
public java.util.concurrent.ScheduledFuture<T> submitAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call tocomplete()
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.The returned Future will provide the return type of a
complete()
operation when received through the blocking call toFuture.get()
!The specified
ScheduledExecutorService
is used for this operation.- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
executor
- The Non-nullScheduledExecutorService
that should be used to schedule this operation- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit or ScheduledExecutorService isnull
-
completeAfter
public T completeAfter(long delay, java.util.concurrent.TimeUnit unit)
Blocks the current Thread for the specified delay and callscomplete()
when delay has been reached.
If the specified delay is negative this action will execute immediately. (see:TimeUnit.sleep(long)
)- Parameters:
delay
- The delay after which to execute a call tocomplete()
unit
- TheTimeUnit
which should be used (this will useunit.sleep(delay)
)- Returns:
- The response value
- Throws:
java.lang.IllegalArgumentException
- If the specifiedTimeUnit
isnull
java.lang.RuntimeException
- If the sleep operation is interrupted
-
queueAfter
public java.util.concurrent.ScheduledFuture<?> queueAfter(long delay, java.util.concurrent.TimeUnit unit)
Schedules a call toqueue()
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.This operation gives no access to the response value.
UsequeueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer)
to access the success consumer forqueue(java.util.function.Consumer)
!The global JDA
ScheduledExecutorService
is used for this operation.
You can change the core pool size for this Executor throughJDABuilder.setCorePoolSize(int)
or provide your own Executor withqueueAfter(long, java.util.concurrent.TimeUnit, java.util.concurrent.ScheduledExecutorService)
- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit isnull
-
queueAfter
public java.util.concurrent.ScheduledFuture<?> queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success)
Schedules a call toqueue(java.util.function.Consumer)
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.This operation gives no access to the failure callback.
UsequeueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.function.Consumer)
to access the failure consumer forqueue(java.util.function.Consumer, java.util.function.Consumer)
!The global JDA
ScheduledExecutorService
is used for this operation.
You can change the core pool size for this Executor throughJDABuilder.setCorePoolSize(int)
or provide your own Executor withqueueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.concurrent.ScheduledExecutorService)
- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
success
- The successConsumer
that should be called once thequeue(java.util.function.Consumer)
operation completes successfully.- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit isnull
-
queueAfter
public java.util.concurrent.ScheduledFuture<?> queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success, java.util.function.Consumer<? super java.lang.Throwable> failure)
Schedules a call toqueue(java.util.function.Consumer, java.util.function.Consumer)
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.The global JDA
ScheduledExecutorService
is used for this operation.
You can change the core pool size for this Executor throughJDABuilder.setCorePoolSize(int)
or provide your own Executor withqueueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.function.Consumer, java.util.concurrent.ScheduledExecutorService)
- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
success
- The successConsumer
that should be called once thequeue(java.util.function.Consumer, java.util.function.Consumer)
operation completes successfully.failure
- The failureConsumer
that should be called in case of an error of thequeue(java.util.function.Consumer, java.util.function.Consumer)
operation.- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit isnull
-
queueAfter
public java.util.concurrent.ScheduledFuture<?> queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call toqueue()
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.This operation gives no access to the response value.
UsequeueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer)
to access the success consumer forqueue(java.util.function.Consumer)
!The specified
ScheduledExecutorService
is used for this operation.- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
executor
- The Non-nullScheduledExecutorService
that should be used to schedule this operation- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit or ScheduledExecutorService isnull
-
queueAfter
public java.util.concurrent.ScheduledFuture<?> queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call toqueue(java.util.function.Consumer)
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.This operation gives no access to the failure callback.
UsequeueAfter(long, java.util.concurrent.TimeUnit, java.util.function.Consumer, java.util.function.Consumer)
to access the failure consumer forqueue(java.util.function.Consumer, java.util.function.Consumer)
!The specified
ScheduledExecutorService
is used for this operation.- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
success
- The successConsumer
that should be called once thequeue(java.util.function.Consumer)
operation completes successfully.executor
- The Non-nullScheduledExecutorService
that should be used to schedule this operation- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit or ScheduledExecutorService isnull
-
queueAfter
public java.util.concurrent.ScheduledFuture<?> queueAfter(long delay, java.util.concurrent.TimeUnit unit, java.util.function.Consumer<? super T> success, java.util.function.Consumer<? super java.lang.Throwable> failure, java.util.concurrent.ScheduledExecutorService executor)
Schedules a call toqueue(java.util.function.Consumer, java.util.function.Consumer)
to be executed after the specifieddelay
.
This is an asynchronous operation that will return aScheduledFuture
representing the task.The specified
ScheduledExecutorService
is used for this operation.- Parameters:
delay
- The delay after which this computation should be executed, negative to execute immediatelyunit
- TheTimeUnit
to convert the specifieddelay
success
- The successConsumer
that should be called once thequeue(java.util.function.Consumer, java.util.function.Consumer)
operation completes successfully.failure
- The failureConsumer
that should be called in case of an error of thequeue(java.util.function.Consumer, java.util.function.Consumer)
operation.executor
- The Non-nullScheduledExecutorService
that should be used to schedule this operation- Returns:
ScheduledFuture
representing the delayed operation- Throws:
java.lang.IllegalArgumentException
- If the provided TimeUnit or ScheduledExecutorService isnull
-
-