Skip to content

proposal for new task API #10614

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thestinger opened this issue Nov 22, 2013 · 6 comments
Closed

proposal for new task API #10614

thestinger opened this issue Nov 22, 2013 · 6 comments

Comments

@thestinger
Copy link
Contributor

fn spawn(proc() -> A) -> Task<A> { ... }
fn spawn_detached(proc()) { ... }

let a = spawn(proc() { ... });
let b = spawn(proc() { ... });
let sum = *a.join() + *b.join();

The Task struct will have a destructor calling join, so there will always be a synchronization point with spawn. If the task fails, the join call will propagate the failure. A try_join method can be added to handle an error.

let mut tasks = ~[];

for i in range(0, n) {
    tasks.push(spawn(proc() { ... });
}

for task in tasks.move_iter() {
    match task.try_join() {
        Err(x) => handle(x), _ => ()
    }
}

A more complex example:

https://github.com/thestinger/rust-core/blob/master/test/thread.rs#L41-L78

Note that since it's using detached threads, it will happily leak the proc and the queue in cases of pathological scheduling. Of course, that's just a case of exiting early without doing more work than required.

@sfackler
Copy link
Member

I can imagine that joining by default will cause a lot of confusion when code that just calls do spawn {...} will mysteriously block.

@alexcrichton
Copy link
Member

I agree that both APIs needs to exist, I'm not sure I'm comfortable with the default being to return a handle.

We already do support both methods today, but the "spawn with handle" is a little more painful than it might need to be.

@huonw
Copy link
Member

huonw commented Nov 23, 2013

cc #8160.

@thestinger
Copy link
Contributor Author

I thought it would be possible to simply detach in the destructor, but that removes the possibility of returning a value to be joined because it will leak.

@brson
Copy link
Contributor

brson commented Dec 5, 2013

I also think that having the default spawn join when a returned handle goes out of scope is surprising, and I'd prefer to use standard synchronization primitives for joining rather than a custom type if possible. If we were to introduce a type called Task then we should think really hard about what it's purpose is, since right now tasks cannot be usefully referenced by user code, so introducing a task type is a big step.

@alexcrichton
Copy link
Member

We discussed this at the triage meeting today, and came to the following conclusions:

  • Silent blocking in a destructor is a behavior that we want to avoid as much as possible
  • It's unclear whether exposing an api like this is vastly more efficient than just using message passing
  • If we have another method of blocking for something (like task.join()), why is it not selectable?
  • The task api today works well with its simplicity. We should perhaps make it easier to spawn for proc() -> A returning Port<A>, but that would be a separate bug tracking that.

For these reasons, we have decided to close this. We are still open to hearing reasons why we should move towards an API such as this, but we would want our concerns above to be addressed to see why this flavor of an API would be a better choice.

flip1995 pushed a commit to flip1995/rust that referenced this issue Apr 11, 2023
Clear with drain

Fixes rust-lang#10572: both the original intent of the issue (extending `clear_with_drain`) and the false negative for `collection_is_never_read` I found in the process are fixed by this PR.

changelog: [`clear_with_drain`]: extend to 5 other types of containers. [`collection_is_never_read`]: fix false negative for `String`s.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants