Zero-cost asynchronous programming in Rust

Related tags

async-foundations
Overview

futures-rs

Zero-cost asynchronous programming in Rust

Build Status Crates.io Rustc Version

Documentation | Website

futures-rs is a library providing the foundations for asynchronous programming in Rust. It includes key trait definitions like Stream, as well as utilities like join!, select!, and various futures combinator methods which enable expressive asynchronous control flow.

Usage

Add this to your Cargo.toml:

[dependencies]
futures = "0.3"

Now, you can use futures-rs:

use futures::future::Future;

The current futures-rs requires Rust 1.39 or later.

Feature std

Futures-rs works without the standard library, such as in bare metal environments. However, it has a significantly reduced API surface. To use futures-rs in a #[no_std] environment, use:

[dependencies]
futures = { version = "0.3", default-features = false }

License

This project is licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in futures-rs by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Issues
  • Consider having polling an error represent the final Stream value

    Consider having polling an error represent the final Stream value

    Consider having polling an error represent the final value. In other words, a poll that returns an error means that poll should never be called again. In the case of a Stream, this means that an error indicates the stream has terminated.

    This issue is a placeholder for the associated discussion.

    cc @aturon

    C-feature-request 
    opened by carllerche 57
  • Consider passing the Task that is driving the future to Future::poll and renaming the function

    Consider passing the Task that is driving the future to Future::poll and renaming the function

    Currently Future::poll seems to be expected to call task::park which then fetches the current task from TLS and panics if there is no task in TLS.

    This results in an unintuitive API (it's not clear at first glance that poll()'s expected interface/implementation is related to tasks) and a potential run-time failure that could be checked at compile time.

    So my suggestion is to instead pass the task driving the Future explicitly to Future::poll as an additional function argument, either as a Task reference, a closure calling task::park() (if that's enough), or a similar mechanism, instead of storing it in the TLS variable CURRENT_TASK.

    Also, "poll" is a confusing name, since it creates the expectation that it is a function that anyone can call to get the value of the future if it has already completed, but it is in fact an "internal" function that drives future execution instead and currently even panics if called outside a task.

    Something like "drive", "execute", "run", "run_next_step" or similar would be a better name.

    C-feature-request 
    opened by rjuse 49
  • Task system overhaul

    Task system overhaul

    Updated description

    The primary change made in this PR is to restructure memory management and notifications throughout the "task system" in the futures crate. It is intended that this will have very little impact, if any, on consumers of futures. Implementations of runtimes of futures (e.g. crates like tokio-core) are the target for this series of changes, enabling a suite of possible optimizations that were not previously feasible. One major use case that is now enabled is usage of the task and executor modules in the no_std ecosystem. This means that bare-metal applications of futures should be able to use the same task system that the std-based futures ecosystem uses.

    One of the largest changes being made to support this is an update to the memory management of objects behind Task handles. Previously it was required that Arc<Unpark> instances were passed into the various Spawn::poll_* functions, but new functions Spawn::poll_*_notify were added which operate with a NotifyHandle instead. A NotifyHandle is conceptually very similar to an Arc<Unpark> instance, but it works through an unsafe trait UnsafeNotify to manage memory instead of requiring Arc is used. You can still use Arc safely, however, if you'd like.

    In addition to supporting more forms of memory management, the poll_*_notify functions also take a new id parameter. This parameter is intended to be an opaque bag-of-bits to the futures crate itself but runtimes can use this to identify the future being notified. This is intended to enable situations where the same instance of a NotifyHandle can be used for all futures executed by using the id field to distinguish which future is ready when it gets notified.

    API Additions

    • A FuturesUnordered::push method was added and the FuturesUnordered type itself was completely rewritten to efficiently track a large number of futures.
    • A Task::will_notify_current method was added with a slightly different implementation than Task::is_current but with stronger guarantees and documentation wording about its purpose.

    Compatibility Notes

    As with all 0.1.x releases this PR is intended to be 100% backwards compatible. All code that previously compiled should continue to do so with these changes. As with other changes, though, there are also some updates to be aware of:

    • The task::park function has been renamed to task::current.
    • The Task::unpark function has been renamed to Task::notify, and in general terminology around "unpark" has shifted to terminology around "notify"
    • The Unpark trait has been deprecated in favor of the Notify trait mentioned above.
    • The UnparkEvent structure has been deprecated. It currently should perform the same as it used to, but it's planned that in a future 0.1.x release the performance will regress for crates that have not transitioned away. The primary primitive to replace this is the addition of a push function on the FuturesUnordered type. If this does not help implement your use case though, please let us know!
    • The Task::is_current method is now deprecated, and you likely want to use Task::will_notify_current instead, but let us know if this doesn't suffice!

    Original description

    This PR is a work in progress

    I'm submitting this PR early to hopefully try to illustrate my thoughts and get some early feedback.

    Checklist

    • [x] Land #442
    • [x] Update tokio-core
    • [x] Run sscache tests using new task system
    • [x] Switch Arc<Unpark> to UnparkHandle #432
    • [x] Decide on #312 (leaning towards yes)
    • [x] Allow executors to customize wait behavior #360 (deferring this until later)
    • [x] Fix Task::is_current
    • [x] Remove Notify::is_current, I don't think this is needed anymore.
    • [x] Consider GetNotifyHandle https://github.com/alexcrichton/futures-rs/issues/129
    • [x] Should ref_inc -> ref_dec be moved to UnsafeNotify (@alexcrichton says no).
    • [x] Consider getting rid of poll_*_notify on Stream and Sink. Also, maybe name it poll_notify if it is only for Future.
    • [x] Merge https://github.com/carllerche/futures-rs/pull/4
    • [x] u64 vs. usize

    Overview

    The previous implementation of the task system required a number of allocations per task instance. Each task required a dedicated Arc<Unpark> handle which means that executors require at least two allocations per task.

    Things get worse when using with_unpark_event as nested calls to with_unpark_event result in Vec allocation and cloning during each call to task::park.

    This commit provides an overhaul to the task system to work around these problems. The Unpark trait is changed so that only one instance is required per executor. In order to identify which task is being unparked, Unpark::unpark takes an unpark_id: u64 argument.

    with_unpark_event is removed in favor of UnparkContext which satisfies a similar end goal, but requires only a single allocation per lifetime of the UnparkContext.

    The new Unpark trait

    In general, tasks are driven to completion by executors and executors are able to handle large number of tasks. As such, the Unpark trait has been tweaked to require a single allocation per executor instead of one per task. The idea is that the executor creates one Arc<Unpark> handle and uses the unpark_id: u64 to identify which task is unparked.

    In the case of tokio-core, each task is stored in a slab and the the unpark_id is the slab index. Now, given that an Arc is no longer used, it can be that a slab slot is released and repurposed for a different task while there are still outstanding Task handles referencing the now released task.

    There are two potential ways to deal with this.

    a) Not care. Futures need to be able to handle spurious wake ups already. Spurious wake ups can be reduced by splitting the u64 into 28 bits for the slab offset and use the rest of the u64 as a slot usage counter.

    b) Use Unpark::ref_inc and Unpark::ref_dec to allow the executor implementation to handle its own reference counting.

    Option b) would allow an executor implementation to store a pointer as the unpark_id and the ref_inc and ref_dec allow for atomic reference counting. This could be used in cases where using a slab is not an option.

    UnparkContext

    This is quite similar in spirit to with_unpark_event except it requires significantly less allocations when used in a nested situation.

    It does have some different behavior. Given the following:

    // Currently in task A
    let my_context = UnparkContext::new(my_unpark);
    
    my_context.with(0, || {
        let task = task::park();
    
        thread::spawn(move || {
            thread::sleep(a_few_secs);
            task.unpark();
        });
    });
    
    my_executor.spawn(move || {
        // Currently in task B
    
        my_context.with(0, || {
            // some work here
        });
    });
    

    Task B will be the root task that is notified.

    opened by carllerche 39
  • Add killable future combinator

    Add killable future combinator

    Closes #693

    opened by cramertj 36
  • Can we find a better name for select?

    Can we find a better name for select?

    When the crossbeam-channel RFC was introduced a few months ago, I found it very hard to understand what select meant. I have the same issue in future-rs, where I find the name equally as opaque as in crossbeam. Luckily I have since been pointed in the direction of some Unix history which explains the design and naming behind select, but I feel like we can still do better than requiring a history lesson for a function name to make sense.

    Therefore I would like to propose that select is slightly renamed to make it more clear what it is actually doing, to e.g. select_any or select_any_ready maybe (or any other name that is deemed better). Although the presence of select_ok already makes the naming tough, and not having a pure select breaks somewhat with the precedent for this functionality (since it is named as such in Unix and Go for example), but I think there are many Rust users who are not familiar with these precedents and will hence be confused by the name (myself included). At the same time, by keeping the word "select" in the name, it is still easy to search for, for those that do know the precedent (and if "select" is kept as the first part of the name, anyone just looking to type select in their IDE will also be helped by autocomplete).

    I feel this would be a very rustic improvement to make; it should still be easy for veterans to use, but welcomes newcomers at the same time, by optimizing for readability over familiarity.

    breakage 
    opened by KasMA1990 36
  • Yank futures 0.2?

    Yank futures 0.2?

    Since futures 0.2 is considered just a snapshot that libraries shouldn't expose, most of the ecosystem is still using futures 0.1. It is not expected that 0.2 will see any more development, nor that the ecosystem will move to it. Instead, work is ongoing to try to get futures into libstd.

    However, the version on crates.io is 0.2, and the version that is shown on docs.rs is also 0.2. This leads to a lot of confusion when new users try to get started in the ecosystem, since they don't understand why futures returned by libraries don't implement futures::Future (from v2) (example).

    Could it just be yanked/deprecated/etc, with a 0.1.22 published to get the docs.rs and crates.io listings to suggest 0.1 until the new version is actually ready?

    opened by seanmonstar 36
  • futures-macro (pulled in by futures-util) appears not to compile on musl

    futures-macro (pulled in by futures-util) appears not to compile on musl

    I have a CI pipeline that tests my project on glibc and musl and it appears that when I pull in futures-util as a dependency, this compiles just fine on glibc but does not compile on musl.

    Here is the build log: https://travis-ci.org/github/jbaublitz/neli/jobs/738716295

    This appears to be due to futures-macro exporting all of its procedural macros with #[proc_macro_hack] which is not allowed on musl.

    I know that rust and musl have had problems in the past related to proc macros and I'm wondering if this is the right place to report this or if this should go into the rust repo.

    C-question 
    opened by jbaublitz 30
  • Consider supporting Reactive Streams and Reactive Sockets

    Consider supporting Reactive Streams and Reactive Sockets

    I am one of the developers of https://github.com/akka/akka/ and I just stumbled upon this nice library (I am a Rust lurker mostly). Futures are a very nice building block for asynchronous programs, but eventually one reaches the point where some kind of streaming abstraction is needed. The simplest streaming approach is the RX-style chained Observables, however, as we and others found out, with asynchronous call-chains backpressure becomes an issue as blocking is no longer available to throttle a producer. To solve this issue, the reactive-streams (RS) standard has been created: http://www.reactive-streams.org backed by various companies interested in the JVM landscape. This set of interoperability interfaces was designed by multiple teams together. This standard is also on its way to become part of JDK9. There is also an effort to expose its semantics as a wire-level protocol http://reactivesocket.io which nicely completements the RS standard (which mainly focuses on in-JVM asynchronous, ordered, backpressured communications).

    Since I imagine that eventually the need for asynchronous streams will arise here, I think these standards can be interesting for Rust, too. While RS might not be perfect, it was a result of a long design process and now has mostly consensus about it in the JVM land, so it would be nice to see a Rust implementation that is similar enough to be easily connectable to JVMs, maybe via reactive-socket.

    Sorry for the shameless plug :)

    opened by drewhk 27
  • Shared can interact badly with futures that don't always poll their subfutures

    Shared can interact badly with futures that don't always poll their subfutures

    (I'm opening this issue to continue the discussion from https://github.com/alexcrichton/futures-rs/pull/305.)

    The problem is that Shared, as it is currently designed, can interact poorly with certain futures, such as the ModedFuture sketched below. We should either formalize some reason why ModedFuture is an invalid implementation of Future, or we should redesign Shared to accommodate this kind of situation.

    extern crate futures;
    extern crate tokio_core;
    
    use futures::{Future, Poll};
    use futures::sync::oneshot;
    use std::rc::Rc;
    use std::cell::RefCell;
    
    enum Mode { Left, Right }
    
    struct ModedFutureInner<F> where F: Future {
        mode: Mode,
        left: F,
        right: F,
        task: Option<::futures::task::Task>,
    }
    
    struct ModedFuture<F> where F: Future {
        inner: Rc<RefCell<ModedFutureInner<F>>>,
    }
    
    struct ModedFutureHandle<F> where F: Future {
        inner: Rc<RefCell<ModedFutureInner<F>>>,
    }
    
    impl <F> ModedFuture<F> where F: Future {
        pub fn new(left: F, right: F, mode: Mode) -> (ModedFutureHandle<F>, ModedFuture<F>) {
            let inner = Rc::new(RefCell::new(ModedFutureInner {
                left: left, right: right, mode: mode, task: None,
             }));
            (ModedFutureHandle { inner: inner.clone() }, ModedFuture { inner: inner })
        }
    }
    
    impl <F> ModedFutureHandle<F> where F: Future {
        pub fn switch_mode(&mut self, mode: Mode) {
            self.inner.borrow_mut().mode = mode;
            if let Some(t) = self.inner.borrow_mut().task.take() {
                // The other future may have become ready while we were ignoring it.
                t.unpark();
            }
        }
    }
    
    impl <F> Future for ModedFuture<F> where F: Future {
        type Item = F::Item;
        type Error = F::Error;
        fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
            let ModedFutureInner { ref mut mode, ref mut left, ref mut right, ref mut task } =
                *self.inner.borrow_mut();
            *task = Some(::futures::task::park());
            match *mode {
                Mode::Left => left.poll(),
                Mode::Right => right.poll(),
            }
        }
    }
    
    pub fn main() {
        let mut core = ::tokio_core::reactor::Core::new().unwrap();
        let handle = core.handle();
    
        let (tx, rx) = oneshot::channel::<u32>();
        let f1 = rx.shared();
        let f2 = f1.clone();
    
        let (mut mfh, mf) = ModedFuture::new(
            Box::new(f1.map_err(|_| ()).map(|v| *v)) as Box<Future<Item=u32, Error=()>>,
            Box::new(::futures::future::empty()) as Box<Future<Item=u32, Error=()>>,
            Mode::Left);
    
        let (tx3, rx3) = oneshot::channel::<u32>();
        handle.spawn(f2.map(|x| tx3.complete(*x)).map_err(|_| ()));
    
        core.turn(Some(::std::time::Duration::from_millis(1)));
    
        handle.spawn(mf.map(|_| ()));
    
        core.turn(Some(::std::time::Duration::from_millis(1)));
    
        mfh.switch_mode(Mode::Right);
    
        tx.complete(11); // It seems like this ought to cause f2 and then rx3 to get resolved.
    
        // This hangs forever.
        core.run(rx3).unwrap();
    }
    
    opened by dwrensha 27
  • How can I wait for a future in multiple threads

    How can I wait for a future in multiple threads

    I can't seem to make this work, perhaps I'm being dumb! In any case, I think this should be in the documentation as an example.

    In my case, I have background processes loading data for a given ID. Obviously if a piece of data is already being loaded then I want to join the existing waiters rather than starting a new background process.

    I've implemented this using a Map <Id, Vec <Complete>>>, then the first loader triggers the completion of subsequent loaders when it has completed. This is a lot of boilerplate.

    I've tried all sorts of things to get this to work but somehow I can't get anything else to compile. Waiting for a future consumes it, so I can only do that once. I have tried to replace the future with a new one and wait on that, like I might do in JavaScript, but this also doesn't work.

    If anyone can show me an example then that would be great, if not then I'll probably create an abstraction around my current method and submit this as a pull request for the library.

    opened by jamespharaoh 27
  • futures-util: add `StreamExt::count` method

    futures-util: add `StreamExt::count` method

    Works the same way as its Iterator::count counterpart

    opened by petrosagg 0
  • reexport `alloc::task::Wake`

    reexport `alloc::task::Wake`

    Per #2207.

    opened by ibraheemdev 1
  • Generalize chunks/ready_chunks/try_chunks/etc to collect into T: Extend, not just Vec

    Generalize chunks/ready_chunks/try_chunks/etc to collect into T: Extend, not just Vec

    In particular I would find it really useful to be able to ready_chunks a Stream of Futures into FuturesOrdereds and spawn them on a threadpool to parallelize my computation.

    This would be a breaking change of course.

    C-feature-request A-stream 
    opened by khuey 4
  • Allow to abort & get back values from `JoinAll`

    Allow to abort & get back values from `JoinAll`

    I have a (relatively small) list of futures that need to be polled. But at any time, I may want to abort the operation and get the futures or the value they resolved back. I see that JoinAll uses a list of MaybeDone internally, which is exactly what I'm looking for. So I propose adding an into_inner method (open for bike shedding) that allows me to get the futures back.

    C-feature-request A-future 
    opened by piegamesde 1
  • async `LineWriter` fix #2131

    async `LineWriter` fix #2131

    opened by FelipeLema 2
  • `try_skip_while` and `try_take_while` have inaccurate doc comments (errors are passed through)

    `try_skip_while` and `try_take_while` have inaccurate doc comments (errors are passed through)

    The documentation of try_take_while states:

    This function is similar to StreamExt::take_while but exits early if an error occurs.

    The actual behavior is that errors are passed through. It seems like the wording should be changed to match, e.g. try_filter. try_skip_while has the same problem.

    Alternatively, perhaps all TryStreamExt combinators which return a TryStream should actually not yield more than one error (this is possible, e.g. if selecting between two TryStreams).

    docs A-stream 
    opened by ttttcrngyblflpp 0
  • OptionFuture is_terminated design confusion

    OptionFuture is_terminated design confusion

    OptionFuture's design seems inconsistent to me.

    The docs don't clearly explain what it's for:

    A future representing a value which may or may not be present.

    Which could describe any Future<Output = Option<_>>.

    Given that it's constructed from an Option<Future> though, it seems clear that it's an adapter for Option<Future> that can be awaited, yielding Some(output) when the future is present, and None when it's absent.

    However, it also implements FusedFuture (where F: FusedFuture at least) so that OptionFuture::from(None).is_terminated() == true which seems inconsistent with that interpretation. is_terminated is documented as meaning:

    Returns true if the underlying future should no longer be polled.

    Which sort of means you're not supposed to await it if it's none?

    And practically speaking, FusedFuture affects the behavior of select!, which will skip over futures that are terminated (so it can safely be used in a loop). OptionFuture's current implementation will result in it getting skipped entirely for the None case which is surprising if you're just expecting it to be an adapter that'll produce None.

    One might suggest that this None-skipping behavior is desirable, as a solution for #2270. But for that usecase, why is the result wrapped in a Some()? And why can you create an OptionFuture from a !FusedFuture which doesn't work this way?

    A third option (pun not intended) is suggested by #2457 which is to have none mean terminated and have the inner transition to None after the future completes. Which would make OptionFuture::from(None) very similar to Fuse::terminated(), except polling/awaiting it yields None rather than panicking.

    Personally I think the adapter interpretation is correct, and OptionFuture should not implement FusedFuture. If that's desirable I'd be happy to send a PR. But I admit I haven't personally found a use for OptionFuture in code I've written, so maybe I'm missing the point here?

    opened by ComputerDruid 1
  • Review TryFutureExt combinators

    Review TryFutureExt combinators

    Currently there isn't a complete selection of sync/async and Result/infallible combinators in TryFutureExt.

    -|Result<T,E>|T (auto wrapped into Result) -|-|- sync| none | .map_ok/.map_err async| .and_then/.or_else | none

    For the times when one wants to convert an Ok result into an error depending on its value or vice versa sync combinators that return Result would be nicer than using FutureExt::map and only caring about one of the cases.

    Likewise when one has an async function that is infallible, such as a web handler that in the worst case renders and returns an error page to treat the same as a successful result, infallible async combinators would be very helpful. Instead of declaring returning with Ok around the return and matching the unused Error type to the TryFuture::Error.

    C-feature-request A-future 
    opened by sidju 2
  • Function parameter lifetime in `StreamExt::filter` generic isn't good enough

    Function parameter lifetime in `StreamExt::filter` generic isn't good enough

    I have this following call on a stream, to filter out elements asynchronously (sorry for the ugly encapsulation, async closures aren't a thing yet);

    .filter(move |user_id| Box::pin(async move {!db.users.is_deactivated(user_id).await.unwrap_or(false)}))
    

    The important part here is that .is_deactivated takes a borrowed UserId type, which is taken across await boundaries with the subsequent .await

    However, rust complains about this...

    error: lifetime may not live long enough
       --> src/database/rooms.rs:802:36
        |
    802 |             .filter(move |user_id| Box::pin(async move {!db.users.is_deactivated(user_id).await.unwrap_or(false)}))
        |                           -------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'2`
        |                           |      |
        |                           |      return type of closure `Pin<Box<impl futures::Future>>` contains a lifetime `'2`
        |                           has type `&'1 ruma::UserId`
    

    ...because the filter function signature doesn't explicitly specify the borrow lifetime as OK to be used for a little while longer;

        fn filter<Fut, F>(self, f: F) -> Filter<Self, Fut, F>
        where
            F: FnMut(&Self::Item) -> Fut,
            Fut: Future<Output = bool>,
            Self: Sized,
        {
            assert_stream::<Self::Item, _>(Filter::new(self, f))
        }
    

    I think that altering it to this fixes it, but i'm not sure how that counts with API cleanliness and lifetime soundness;

        fn filter<'a, Fut, F>(self, f: F) -> Filter<Self, Fut, F>
        where
            F: FnMut(&'a Self::Item) -> Fut,
            Fut: Future<Output = bool> + 'a,
            Self::Item: 'a,
            Self: Sized,
        {
            assert_stream::<Self::Item, _>(Filter::new(self, f))
        }
    

    Quickly inserting this seems to pop up a lot of other issues, so i'm only going to report this issue for now here.

    bug A-stream 
    opened by ShadowJonathan 1
  • Give futures::executor::ThreadPool a possibility to wait for completion

    Give futures::executor::ThreadPool a possibility to wait for completion

    Consider the following example for the threadpool, which is close to the example from the documentation:

    https://docs.rs/futures/0.3.15/futures/executor/struct.ThreadPool.html

    use std::thread::sleep;
    use std::time::Duration;
    
    use futures::FutureExt;
    use futures::executor::ThreadPool;
    
    async fn cpu_intensive(i: u64) {
        let mut res: u64 = 0;
        for j in 0..23 {
            for k in 0..256 {
                res += j + i + k;
                res %= 91349;
            }
            // Imagine that here an async API call is required, so we want another future to continue while this future is waiting for the API result 
        }
        println!("{}: {}", i, res)
    }
    
    fn main() {
        let pool = ThreadPool::new().unwrap();
        for i in 0..1000 {
            let fut = cpu_intensive(i);
            pool.spawn_ok(fut)
        }
        // NEEDED: A way to wait for the thread pool to run until completion
        sleep(Duration::from_secs(2));
    }
    

    It would be great if there was a way to block main until all futures of the ThreadPool are completed.

    C-feature-request A-executor 
    opened by TobiasJacob 0
Releases(0.3.17)
  • 0.3.17(Aug 30, 2021)

    • Use FuturesOrdered in join_all (#2412)
    • Add {future, stream}::poll_immediate (#2452)
    • Add stream_select! macro (#2262)
    • Implement Default for OptionFuture (#2471)
    • Add Peekable::{peek_mut, poll_peek_mut} (#2488)
    • Add BufReader::seek_relative (#2489)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.16(Jul 23, 2021)

    • Add TryStreamExt::try_chunks (#2438)
    • Add StreamExt::{all, any} (#2460)
    • Add stream::select_with_strategy (#2450)
    • Update to new io_slice_advance interface (#2454)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.15(May 11, 2021)

    • Use #[proc_macro] at Rust 1.45+ to fix an issue where proc macros don't work with rust-analyzer (#2407)
    • Support targets that do not have atomic CAS on stable Rust (#2400)
    • futures-test: Add async #[test] function attribute (#2409)
    • Add stream::abortable (#2410)
    • Add FuturesUnordered::clear (#2415)
    • Implement IntoIterator for FuturesUnordered (#2423)
    • Implement Send and Sync for FuturesUnordered iterators (#2416)
    • Make FuturesUnordered::iter_pin_ref public (#2423)
    • Add SelectAll::clear (#2430)
    • Add SelectAll::{iter, iter_mut} (#2428)
    • Implement IntoIterator for SelectAll (#2428)
    • Implement Clone for WeakShared (#2396)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.14(Apr 10, 2021)

    • Add future::SelectAll::into_inner (#2363)
    • Allow calling UnboundedReceiver::try_next after None (#2369)
    • Reexport non-Ext traits from the root of futures_util (#2377)
    • Add AsyncSeekExt::stream_position (#2380)
    • Add stream::Peekable::{next_if, next_if_eq} (#2379)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.13(Feb 22, 2021)

    • Mitigated starvation issues in FuturesUnordered (#2333)
    • Fixed race with dropping mpsc::Receiver (#2304)
    • Added Shared::{strong_count, weak_count} (#2346)
    • Added no_std support for task::noop_waker_ref (#2332)
    • Implemented Stream::size_hint for Either (#2325)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.12(Jan 15, 2021)

  • 0.3.11(Jan 14, 2021)

  • 0.3.10(Jan 13, 2021)

  • 0.3.9(Jan 7, 2021)

    • Significantly improved compile time when async-await crate feature is disabled (#2273)
    • Added stream::repeat_with (#2279)
    • Added StreamExt::unzip (#2263)
    • Added sink::unfold (#2268)
    • Added SinkExt::feed (#2155)
    • Implemented FusedFuture for oneshot::Receiver (#2300)
    • Implemented Clone for sink::With (#2290)
    • Re-exported MapOkOrElse, MapInto, OkInto, TryFlatten, WriteAllVectored (#2275)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.8(Nov 9, 2020)

    • Switch proc-macros to use native #[proc_macro] at Rust 1.45+ (#2243)
    • Add WeakShared (#2169)
    • Add TryStreamExt::try_buffered (#2245)
    • Add StreamExt::cycle (#2252)
    • Implemented Clone for stream::{Empty, Pending, Repeat, Iter} (#2248, #2252)
    • Fix panic in some TryStreamExt combinators (#2250)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.7(Oct 23, 2020)

  • 0.3.6(Oct 5, 2020)

    • Fixed UB due to missing 'static on task::waker (#2206)
    • Added AsyncBufReadExt::fill_buf (#2225)
    • Added TryStreamExt::try_take_while (#2212)
    • Added is_connected_to method to mpsc::{Sender, UnboundedSender} (#2179)
    • Added is_connected_to method to oneshot::Sender (#2158)
    • Implement FusedStream for FuturesOrdered (#2205)
    • Fixed documentation links
    • Improved documentation
    • futures-test: Added track_closed method to AsyncWriteTestExt and SinkTestExt (#2159)
    • futures-test: Implemented more traits for InterleavePending (#2208)
    • futures-test: Implemented more traits for AssertUnmoved (#2208)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.5(May 8, 2020)

    • Added StreamExt::flat_map.
    • Added StreamExt::ready_chunks.
    • Added *_unpin methods to SinkExt.
    • Added a cancellation() future to oneshot::Sender.
    • Added reunite method to ReadHalf and WriteHalf.
    • Added Extend implementations for Futures(Un)Ordered and SelectAll.
    • Added support for reexporting the join! and select! macros.
    • Added no_std support for the pending! and poll! macros.
    • Added Send and Sync support for AssertUnmoved.
    • Fixed a bug where Shared wasn't relinquishing control to the executor.
    • Removed the Send bound on the output of RemoteHandle.
    • Relaxed bounds on FuturesUnordered.
    • Reorganized internal tests to work under different --features.
    • Reorganized the bounds on StreamExt::forward.
    • Removed and replaced a large amount of internal unsafe.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.4(Feb 6, 2020)

  • 0.3.3(Feb 4, 2020)

  • 0.3.2(Feb 3, 2020)

    • Improved buffering performance of SplitSink (#1969)
    • Added select_biased! macro (#1976)
    • Added hash_receiver method to mpsc channel (#1962)
    • Added stream::try_unfold (#1977)
    • Fixed bug with zero-size buffers in vectored IO (#1998)
    • AtomicWaker::new() is now const fn (#2007)
    • Fixed bug between threadpool and user park/unparking (#2010)
    • Added stream::Peakable::peek (#2021)
    • Added StreamExt::scan (#2044)
    • Added impl of AsyncRead/Write for BufReader/Writer (#2033)
    • Added impl of Spawn and LocalSpawn for Arc<impl Spawn and Rc<impl Spawn> (#2039)
    • Fixed Sync issues with FuturesUnordered (#2054)
    • Added into_inner method for future::Ready (#2055)
    • Added MappedMutexGuard API (#2056)
    • Mitigated starvation issues in FuturesUnordered (#2049)
    • Added TryFutureExt::map_ok_or_else (#2058)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.1(Nov 7, 2019)

  • 0.3.0(Nov 6, 2019)

    • Stable release along with stable async/await!
    • Added async/await to default features (#1953)
    • Changed Spawn trait and FuturesUnordered::push to take &self (#1950)
    • Moved Spawn and FutureObj out of futures-core and into `futures-task (#1925)
    • Changed case convention for feature names (#1937)
    • Added executor feature (#1949)
    • Moved copy_into/copy_buf_into (#1948)
    • Changed SinkExt::send_all to accept a TryStream (#1946)
    • Removed ThreadPool::run (#1944)
    • Changed to use our own definition of io::Cursor (#1943)
    • Removed BufReader::poll_seek_relative (#1938)
    • Changed skip to take a usize rather than u64 (#1931)
    • Removed Stream impl for VecDeque (#1930)
    • Renamed Peekable::peek to poll_peek (#1928)
    • Added immutable iterators for FuturesUnordered (#1922)
    • Made ThreadPool optional (#1910)
    • Renamed oneshot::Sender::poll_cancel to poll_canceled (#1908)
    • Added some missing Clone implementations
    • Documentation fixes
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-alpha.19(Sep 26, 2019)

    • Stabilized the async-await feature (#1816)
    • Made async-await feature no longer require std feature (#1815)
    • Updated proc-macro2, syn, and quote to 1.0 (#1798)
    • Exposed unstable BiLock (#1827)
    • Renamed "nightly" feature to "unstable" (#1823)
    • Moved to our own io::{Empty, Repeat, Sink} (#1829)
    • Made AsyncRead::initializer API unstable (#1845)
    • Moved the Never type from futures-core to futures-util (#1836)
    • Fixed use-after-free on panic in ArcWake::wake_by_ref (#1797)
    • Added AsyncReadExt::chain (#1810)
    • Added Stream::size_hint (#1853)
    • Added some missing FusedFuture (#1868) and FusedStream implementations (#1831)
    • Added a From impl for Mutex (#1839)
    • Added Mutex::{get_mut, into_inner} (#1839)
    • Re-exported TryConcat and TryFilter (#1814)
    • Lifted Unpin bound and implemented AsyncBufRead for io::Take (#1821)
    • Lifted Unpin bounds on get_pin_mut (#1820)
    • Changed SendAll to flush the Sink when the source Stream is pending (#1877)
    • Set default threadpool size to one if num_cpus::get() returns zero (#1835)
    • Removed dependency on rand by using our own PRNG (#1837)
    • Removed futures-core dependency from futures-sink (#1832)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-alpha.18(Aug 9, 2019)

    • Rewrote join! and try_join! as procedural macros to allow passing expressions (#1783)
    • Banned manual implementation of TryFuture and TryStream for forward compatibility. See #1776 for more details. (#1777)
    • Changed AsyncReadExt::read_to_end to return the total number of bytes read (#1721)
    • Changed ArcWake::into_waker to a free function waker (#1676)
    • Supported trailing commas in macros (#1733)
    • Removed futures-channel dependency from futures-executor (#1735)
    • Supported channel::oneshot in no_std environment (#1749)
    • Added Future bounds to FusedFuture (#1779)
    • Added Stream bounds to FusedStream (#1779)
    • Changed StreamExt::boxed to return BoxStream (#1780)
    • Added StreamExt::boxed_local (#1780)
    • Added AsyncReadExt::read_to_string (#1721)
    • Implemented AsyncWrite for IntoAsyncRead (#1734)
    • Added get_ref, get_mut and into_inner methods to Compat01As03 and Compat01As03Sink (#1705)
    • Added ThreadPool::{spawn_ok, spawn_obj_ok} (#1750)
    • Added TryStreamExt::try_flatten (#1731)
    • Added FutureExt::now_or_never (#1747)
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-alpha.17(Jul 3, 2019)

    • Removed try_ready! macro in favor of ready!(..)?. (#1602)
    • Removed io::Window::{set_start, set_end} in favor of io::Window::set. (#1667)
    • Re-exported pin_utils::pin_mut! macro. (#1686)
    • Made all extension traits unnamed in the prelude. (#1662)
    • Allowed ?Sized types in some methods and structs. (#1647)
    • Added Send + Sync bounds to ArcWake trait to fix unsoundness. (#1654)
    • Changed AsyncReadExt::copy_into to consume self. (#1674)
    • Renamed future::empty to pending. (#1689)
    • Added #[must_use] to some combinators. (#1600)
    • Added AsyncWriteExt::{write, write_vectored}. (#1612)
    • Added AsyncReadExt::read_vectored. (#1612)
    • Added TryFutureExt::try_poll_unpin. (#1613)
    • Added TryFutureExt::try_flatten_stream. (#1618)
    • Added io::BufWriter. (#1608)
    • Added Sender::same_receiver and UnboundedSender::same_receiver. (#1617)
    • Added future::try_select. (#1622)
    • Added TryFutureExt::{inspect_ok, inspect_err}. (#1630)
    • Added Compat::get_ref. (#1648)
    • Added io::Window::set. (#1667)
    • Added AsyncWriteExt::into_sink. (#1675)
    • Added AsyncBufReadExt::copy_buf_into. (#1674)
    • Added stream::pending. (#1689)
    • Implemented std::error::Error for SpawnError. (#1604)
    • Implemented Stream for FlattenSink. (#1651)
    • Implemented Sink for TryFlattenStream. (#1651)
    • Implemented AsyncRead, AsyncWrite, AsyncSeek, AsyncBufRead, FusedFuture and FusedStream for Either. (#1695)
    • Replaced empty enums with Never type, an alias for core::convert::Infallible.
    • Removed the futures-channel dependency from futures-sink and make futures-sink an optional dependency of futures-channel.
    • Renamed Sink::SinkError to Sink::Error.
    • Made a number of dependencies of futures-util optional.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.27(Jun 13, 2019)

  • 0.3.0-alpha.16(May 10, 2019)

    • Updated to new nightly async_await.
    • Changed AsyncRead::poll_vectored_read and AsyncWrite::poll_vectored_write to use
      stabilized std::io::{IoSlice, IoSliceMut} instead of iovec::IoVec, and renamed to
      AsyncRead::poll_read_vectored and AsyncWrite::poll_write_vectored.
    • Added LocalBoxFuture and FutureExt::boxed_local.
    • Added TryStreamExt::{try_filter, inspect_ok, inspect_err}.
    • Added try_future::select_ok.
    • Added AsyncBufReadExt::{read_line, lines}.
    • Added io::BufReader.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-alpha.15(Apr 26, 2019)

    0.3.0-alpha.15 - 2019-4-26

    • Updated to stabilized futures_api.
    • Removed StreamObj, cautioned against usage of FutureObj.
    • Changed StreamExt::select to a function.
    • Added AsyncBufRead and AsyncSeek traits.
    • Expanded trait impls to include more pinned pointers and ?Sized types.
    • Added future::Fuse::terminated constructor.
    • Added never_error combinator.
    • Added StreamExt::enumerate.
    • Re-added TryStreamExt::{and_then, or_else}.
    • Added functions to partially progress a local pool.
    • Changed to use our own Either type rather than the one from the either crate.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-alpha.14(Apr 15, 2019)

    0.3.0-alpha.14 - 2019-4-15

    • Updated to new nightly futures_api.
    • Changed Forward combinator to drop sink after completion, and allow !Unpin Sinks.
    • Added 0.1 <-> 0.3 compatability shim for Sinks.
    • Changed Sink::Item to a generic parameter Sink<Item>, allowing Sinks to accept
      multiple different types, including types containing references.
    • Changed AsyncRead and AsyncWrite to take Pin<&mut Self> rather than &mut self.
    • Added support for no_std + alloc use.
    • Changed join and try_join combinators to functions.
    • Fixed propagation of cfg-target-has-atomic feature.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-alpha.13(Feb 20, 2019)

    • Updated to new nightly with stabilization candidate API.
    • Removed LocalWaker.
    • Added #[must_use] to Stream and Sink traits.
    • Enabled using !Unpin futures in JoinAll.
    • Added the try_join_all combinator.
    • Stopped closing a whole channel upon closing of one sender.
    • Removed TokioDefaultSpawner and tokio-compat.
    • Moved intra-crate dependencies to exact versions.
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0-alpha.12(Jan 14, 2019)

    • Updated to new nightly with a modification to Pin::set.
    • Expose AssertUnmoved and PendingOnce.
    • Prevent double-panic in AssertUnmoved.
    • Support nested invocations of the select! macro.
    • Implement Default for Mutex and SelectAll.
    Source code(tar.gz)
    Source code(zip)
Monad/MonadIO, Handler, Coroutine/doNotation, Functional Programming features for Rust

fpRust Monad, Functional Programming features for Rust Why I love functional programming, Rx-style coding. However it's hard to implement them in Rust

null 74 Sep 8, 2021
rust stackful coroutine library

May May is a high-performant library for programming stackful coroutines with which you can easily develop and maintain massive concurrent programs. I

Xudong Huang 958 Sep 17, 2021
Metal IO library for Rust

Mio – Metal IO Mio is a fast, low-level I/O library for Rust focusing on non-blocking APIs and event notification for building high performance I/O ap

Tokio 4.4k Sep 13, 2021
Coroutine I/O for Rust

Coroutine I/O Coroutine scheduling with work-stealing algorithm. WARN: Possibly crash because of TLS inline, check https://github.com/zonyitoo/coio-rs

ty 444 Aug 18, 2021
[no longer maintained] Scalable, coroutine-based, fibers/green-threads for Rust. (aka MIO COroutines).

Documentation mioco Mioco provides green-threads (aka fibers) like eg. Goroutines in Go, for Rust. Status This repo is a complete re-implementation of

Dawid Ciężarkiewicz 126 Aug 24, 2021
Thread Safe Cache with async loader functions based on tokio-rs

cache-loader-async crates.io The goal of this crate is to provide a thread-safe and easy way to access any data structure which might is stored in a d

ZeroTwo Bot 6 Sep 3, 2021
Robyn is an async Python backend server with a runtime written in Rust, btw.

Robyn is an async Python backend server with a runtime written in Rust, btw.

Sanskar Jethi 140 Sep 16, 2021