aglassman
Proposal: Add `cancel` opt to assign_async and start_async
Problem
The cancel_async function is easily overlooked. Since the results of “outdated” tasks are ignored, it’s easy for developers to assume that the task was killed, even though it will continue to execute. The async_assign documentation does not make a reference to cancel_async, although start_async does.
I think this default is setting up users for issues down the road. Many times, these async functions are used to perform slow, or expensive database queries. Given that each task will checkout its own connection, this puts the LiveView at risk for putting undue pressure on the connection pool.
Suggestions
Suggestion 1
Add mention of cancel_async to the async_assign documentation.
Suggestion 2
assign_async and start_async should provide an opt called cancel, which would effectively do what cancel_async does.
usage: assign_async(socket, :records, fn → … end, cancel: true)
Suggestion 3
Provide a configuration to set the default for the cancel opt. This would allow a sensible default for the workload of the project, yet could still be overridden. This also provides an easy way to not break existing behavior for LiveView projects. The library default can be cancel_async_default: false, and teams can then determine if modifying this value makes sense. This minimizes the amount of code changes needed for an existing project, and removes the need for individuals on a team to remember to add cancel: ... to every usage of async_assign or start_async.
config :phoenix_live_view,
cancel_async_default: true
Most Liked
rhcarvalho
![]()
And perhaps even add to the overall Async Operations too: Phoenix.LiveView — Phoenix LiveView v1.2.5.
I imagine none of the maintainers would oppose to a PR doing just that!
I see a case where you’d want to possibly kill existing tasks started earlier, similar to what is described in the start_async/4 docs. So your intention is to make killing in-flight tasks the default, right?
I think naming the option :cancel is confusing, as reading the code in isolation makes me think of cancelling of the new task I’m about to start.
Suggestion: cancel_existing: true or replace: true.
Idea: if you haven’t already, you can implement this in your project and report on the usage. MyApp.Async.assign_async/4 can replicate the assign_async/4 signature, but additionally understand a replace: true option which makes it call cancel_async/3 before delegating to assign_async/4.
Now that I look at it, I see one thing this option would miss is the ability to pass a custom reason when cancelling the task.
I like that LiveView gives us the primitives. I’m not so sure that replacing in-flight tasks should be the default. If it was, and there was no cancel_async/3, a reasonable ask would be how to keep in-flight tasks.
tfwright
Based on how core teams in the ecosystem have responded to similar proposals, I think this is the most likely response. And although I grumble it makes sense. When Elixir makes it so easy to make such things ergonomic while keeping them explicit and minimizing API surface, probably best to prefer that.
derek-zhou
Function calls with a inline closure and a keyword list are ugly. I suggest to name the new behaviors, sans the option, reassign_async and restart_async and keep the old behaviors to the old functions.
Popular in Proposals: Ideas
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









