documentation/topics/advanced/timeouts.md
You have a few options.
You can specify a timeout when you call an action. This takes the highest precedence.
Ash.read!(query, timeout: :timer.seconds(30))
You can specify one using Ash.Changeset.timeout/2 or Ash.Query.timeout/2. This can be useful if you want to conditionally set a timeout based on the details of the request. For example, you might do something like this:
# in your resource
defmodule MyApp.SetReportTimeout do
use Ash.Resource.Preparation
def prepare(query, _, _) do
if Ash.Query.get_argument(query, :full_report) do
Ash.Query.timeout(query, :timer.minutes(3))
else
Ash.Query.timeout(query, :timer.minutes(1))
end
end
end
actions do
read :report_items do
argument :full_report, :boolean, default: false
prepare MyApp.SetReportTimeout
end
end
You can also specify a default timeout on your domain modules.
execution do
timeout :timer.seconds(30) # the default is `:infinity`
end
Keep in mind, you can't specify timeouts in a before_action or after_action hook, because at that point you are already "within" the code that should have a timeout applied.
timeouts use processes {: .warning}
Timeouts are implemented using processes. This means that potentially large query results will be copied across processes. Because of this, specifying timeouts globally or for things that you don't suspect would ever exceed that timeout is not recommended.
Timeouts in Ash work a bit differently than other tools. The following considerations must be taken into account:
touches_resources is already in a transaction then the timeout is ignored, as the outer transaction is handling the timeout.