[Proposal] add Task.completed

100 views
Skip to first unread message

Luke Bakken

unread,
Jun 30, 2021, 6:22:07 PM6/30/21
to elixir-lang-core
## Background

I have an enumerable over which I fold and call Task.async based on the data in the enumerable. I then Task.yield_many over the list of tasks, and use Enum.zip to correlate the original enumerable with the results.

I have a case where, during the fold I find that an entry is invalid for running Task.async. It would be convenient to create an "already completed" Task that contains an error result. For now, I'm still using Task.async to basically return an :error tuple, which of course starts and links a process.

Of course, I could work around this by using maps, etc.

I tried using %Task{} to create a "dummy" but calling Task.yield_many with such an entry always blocks until the timeout.

## Proposal

Add Task.completed/1 that creates an "already completed" Task that can then be awaited / yielded to return the result used when completed/1 was called:

```elixir
task = Task.completed({:error, :boom})
```

Awaiting or yielding on such a task returns the result immediately without invoking a process.

## Other

.NET has the following to achieve this behavior, for instance:



Thanks for your consideration! If approved I would gladly implement this.
Luke

Aaron Ross

unread,
Jun 30, 2021, 6:26:27 PM6/30/21
to elixir-lang-core
+1

I've encountered this in a similar context - I have one overall task that will spawn some number of data fetching tasks, but in some cases I know that the data fetch call will return no results so I stub the task with `Task.async(fn -> {:ok, []} end)`. The proposed `Task.completed/1` would be a great, more semantic replacement and has the benefit of not spawning an unneeded process.

José Valim

unread,
Jul 1, 2021, 3:33:57 AM7/1/21
to elixir-l...@googlegroups.com
It sounds good to me. A small but likely welcome change. A PR to further explore this is welcome!

--
You received this message because you are subscribed to the Google Groups "elixir-lang-core" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-co...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/d12a9c8c-6441-48d7-9ebe-1194abb86f30n%40googlegroups.com.

Aaron Ross

unread,
Jul 1, 2021, 1:50:01 PM7/1/21
to elixir-lang-core
I put together a PR here: https://github.com/superhawk610/elixir/pull/1

I'd love to hear any feedback on the approach and implementation before submitting to the official repo.

Thanks in advance!

José Valim

unread,
Jul 1, 2021, 2:06:21 PM7/1/21
to elixir-l...@googlegroups.com
Instead of creating a new struct, which would require changing many modules, I would build a regular Task and then send a message to myself in the form {ref, result}. :)

Aaron Ross

unread,
Jul 1, 2021, 7:17:52 PM7/1/21
to elixir-lang-core
Reply all
Reply to author
Forward
0 new messages