All notable changes to async-std will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
See 1.6.0-beta.1 and 1.6.0-beta.2.
Clone for UnixStream (#772)wasm, switched underlying Timer implementation to futures-timer. (#776)smol::block_on to handle drop of File, avoiding nested executor panic. (#768)task::spawn_local. (#757)wasm. (#757)JoinHandle::cancel (#757)sync::Condvar (#369)sync::Sender::try_send and sync::Receiver::try_recv (#585)no_std support for task, future and stream (#680)smol. (#757)sync::Barrier to use sync::Condvar like std does. (#581)AtomicUsize for TaskId. (#756)This patch includes various quality of life improvements to async-std. Including improved performance, stability, and the addition of various Clone impls that replace the use of Arc in many cases.
FromStream for Result<T, E> (#643)stream::pending as “unstable” (#615)stream::timeout to document the error flow (#675)Clone for DirEntry (#682)Clone for TcpStream (#689)stream::Interval (#645)stream::FlatMap (#651)1.0.0 (#681)async-task to 1.2.1 (#676)task::block_on now parks after a single poll, improving performance in many cases (#684)take_while instead of scan in impl of Product, Sum and FromStream (#667)TcpStream::connect no longer uses a thread from the threadpool, improving performance (#687)UdpSocket::recv (#648)UdpSocket::send (#671)sync::JoinHandle documentation (#659)std::error::Error::description which failed CI (#661)format_code_in_doc_comments option which failed CI (#685)task::sleep example (#688)This patch adds Future::timeout, providing a method counterpart to the future::timeout free function. And includes several bug fixes around missing APIs. Notably we're not shipping our new executor yet, first announced on our blog.
use async_std::prelude::*; use async_std::future; use std::time::Duration; let fut = future::pending::<()>(); // This future will never resolve. let res = fut.timeout(Duration::from_millis(100)).await; assert!(res.is_err()); // The future timed out, returning an err.
Future::timeout as “unstable” (#600)stream submodule documentation (#621)Write::write_fmt's future is now correctly marked as #[must_use] (#628)io::Bytes export (#633)io::Chain export (#633)io::Take export (#633)This patch introduces Stream::delay, more methods on DoubleEndedStream, and improves compile times. Stream::delay is a new API that's similar to task::sleep, but can be passed as part of as stream, rather than as a separate block. This is useful for examples, or when manually debugging race conditions.
let start = Instant::now(); let mut s = stream::from_iter(vec![0u8, 1]).delay(Duration::from_millis(200)); // The first time will take more than 200ms due to delay. s.next().await; assert!(start.elapsed().as_millis() >= 200); // There will be no delay after the first time. s.next().await; assert!(start.elapsed().as_millis() <= 210);
Stream::delay as “unstable” (#309)DoubleEndedStream::next_back as “unstable” (#562)DoubleEndedStream::nth_back as “unstable” (#562)DoubleEndedStream::rfind as “unstable” (#562)DoubleEndedStream::rfold as “unstable” (#562)DoubleEndedStream::try_rfold as “unstable” (#562)stream::Once now implements DoubleEndedStream (#562)stream::FromIter now implements DoubleEndedStream (#562)async-macros, speeding up compilation (#610)UdpSocket::recv example (#603)task::block_on (#608)task::Builder (#612)futures-preview (#595)<TcpStream as Write>::poll_close now closes the write half of the stream (#618)This patch includes some minor quality-of-life improvements, introduces a new Stream::unzip API, and adds verbose errors to our networking types.
This means if you can‘t connect to a socket, you’ll never have to wonder again which address it was you couldn't connect to, instead of having to go through the motions to debug what the address was.
Unzip a stream of tuples into two collections:
use async_std::prelude::*; use async_std::stream; let s = stream::from_iter(vec![(1,2), (3,4)]); let (left, right): (Vec<_>, Vec<_>) = s.unzip().await; assert_eq!(left, [1, 3]); assert_eq!(right, [2, 4]);
Stream::unzip as “unstable”.Future::join and Future::try_join can now join futures with different output types.Debug output of BufWriter.Stream::throttle that made it consume too much CPU.This patch introduces a faster scheduler algorithm, Stream::throttle, and stabilizes task::yield_now. Additionally we're introducing several more stream APIs, bringing us to almost complete parity with the standard library.
Furthermore our path submodule now returns more context in errors. So if opening a file fails, async-std will tell you which file was failed to open, making it easier to write and debug programs.
let start = Instant::now(); let mut s = stream::interval(Duration::from_millis(5)) .throttle(Duration::from_millis(10)) .take(2); s.next().await; assert!(start.elapsed().as_millis() >= 5); s.next().await; assert!(start.elapsed().as_millis() >= 15); s.next().await; assert!(start.elapsed().as_millis() >= 25);
Stream::throttle as “unstable”.Stream::count as “unstable”.Stream::max as “unstable”.Stream::successors as “unstable”.Stream::by_ref as “unstable”.Stream::partition as “unstable”.path submodule.os::windows::symlink_dir as “unstable”.os::windows::symlink_file as “unstable”.task::yield_now.read calls on File.Stream::max_by_key was returning the wrong result.Stream::min_by_key was returning the wrong result.Unpin bound from stream::Once.pin_mut!.Stream::any and Stream::all's internals.surf example is now enabled again.futures-timer to 2.0.0, improving compilation speed.async-macros to 2.0.0.Stream::merge now uses randomized ordering to reduce overall latency.channel types to link back to the channel function.We were seeing a regression in our fs performance, caused by too many long-running tasks. This patch fixes that regression by being more proactive about closing down idle threads.
task::spawn_blocking.This release marks the 1.0.0 release of async-std; a major milestone for our development. This release itself mostly includes quality of life improvements for all of modules, including more consistent API bounds for a lot of our submodules.
The biggest change is that we're now using the full semver range, major.minor.patch, and any breaking changes to our “stable” APIs will require an update of the major number.
We‘re excited we’ve hit this milestone together with you all. Thank you!
Future::join as “unstable”, replacing future::join!.Future::try_join as “unstable”, replacing future::try_join!.stable and beta channel testing on CI.FromIterator and Extend for PathBuf.FromStream for PathBuf.io::copy on “unstable”.Sync bound to RwLock, resolving a memory safety issue.Stream::take_while where it could continue after it should've ended.attributes Cargo feature wasn't working as intended.Stream::merge, documenting ordering guarantees.future submodule.path submodule.stream submodule.future::join! in favor of Future::join.future::try_join! in favor of Future::try_join.This patch upgrades us to futures 0.3, support for async/await on Rust Stable, performance improvements, and brand new module-level documentation.
Future::flatten as “unstable”.Future::race as “unstable” (replaces future::select!).Future::try_race as “unstable” (replaces future::try_select!).Stderr::lock as “unstable”.Stdin::lock as “unstable”.Stdout::lock as “unstable”.Stream::copied as “unstable”.Stream::eq as “unstable”.Stream::max_by_key as “unstable”.Stream::min as “unstable”.Stream::ne as “unstable”.Stream::position as “unstable”.StreamExt and FutureExt as enumerable in the prelude.TcpListener and TcpStream integration tests.stream::from_iter.sync::WakerSet for internal use.IP v4 and IP v6 connections.default Cargo feature.attributes Cargo feature.std Cargo feature.Stream::merge where sometimes it ended too soon.task module.futures-preview with futures.lazy_static with once_cell.VecDequeue in the examples with stream::from_iter.sync::RwLock using the internal sync::WakerSet type.path submodule documentation to match std.future::select! (replaced by Future::race).future::try_select! (replaced by Future::try_race).This patch introduces async_std::sync::channel, a novel asynchronous port of the ultra-fast Crossbeam channels. This has been one of the most anticipated features for async-std, and we're excited to be providing a first version of this!
In addition to channels, this patch has the regular list of new methods, types, and doc fixes.
Send and receive items from a channel
// Create a bounded channel with a max-size of 1 let (s, r) = channel(1); // This call returns immediately because there is enough space in the channel. s.send(1).await; task::spawn(async move { // This call blocks the current task because the channel is full. // It will be able to complete only after the first message is received. s.send(2).await; }); // Receive items from the channel task::sleep(Duration::from_secs(1)).await; assert_eq!(r.recv().await, Some(1)); assert_eq!(r.recv().await, Some(2));
Future::delay as “unstable”Stream::flat_map as “unstable”Stream::flatten as “unstable”Stream::product as “unstable”Stream::sum as “unstable”Stream::min_by_keyStream::max_byStream::timeout as “unstable”sync::channel as “unstable”.Extend + FromStream for PathBuf.block_on so it works even when nested.cfg_if with our own macros, simplifying the codebase.Cargo.toml to point to async.rs.stream and sync.File operationsNothing was removed in this release.
This patch stabilizes several core concurrency macros, introduces async versions of Path and PathBuf, and adds almost 100 other commits.
Asynchronously read directories from the filesystem
use async_std::fs; use async_std::path::Path; use async_std::prelude::*; let path = Path::new("/laputa"); let mut dir = fs::read_dir(&path).await.unwrap(); while let Some(entry) = dir.next().await { if let Ok(entry) = entry { println!("{:?}", entry.path()); } }
Cooperatively reschedule the current task on the executor
use async_std::prelude::*; use async_std::task; task::spawn(async { let x = fibonnacci(1000); // Do expensive work task::yield_now().await; // Allow other tasks to run x + fibonnacci(100) // Do more work })
Create an interval stream
use async_std::prelude::*; use async_std::stream; use std::time::Duration; let mut interval = stream::interval(Duration::from_secs(4)); while let Some(_) = interval.next().await { println!("prints every four seconds"); }
FutureExt to the prelude, allowing us to extend FutureStream::cmpStream::geStream::lastStream::leStream::ltStream::merge as “unstable”, replacing stream::join!Stream::partial_cmpStream::take_whileStream::try_foldfuture::IntoFuture as “unstable”io::BufRead::splitio::Write::write_fmtprint!, println!, eprint!, eprintln! macros as “unstable”process as “unstable”, re-exporting std types only for nowstd::net re-exports to the net submodulestd::path::PathBuf with all associated methodsstd::path::Path with all associated methodsstream::ExactSizeStream as “unstable”stream::FusedStream as “unstable”stream::Productstream::Sumstream::from_fnstream::interval as “unstable”stream::repeat_withtask::spawn_blocking as “unstable”, replacing task::blockingtask::yield_nowwrite! and writeln! macros as “unstable”future::join! and future::try_join!future::timeoutpathtask::ready!BufWriter::into_inner so it calls flush before yieldingio::BufWriter internalsnet::ToSocketAddrs internalsio::Cursorio documentation to match std's io docstask documentation to match std's thread docsstream::join! in favor of Stream::mergetask::blocking in favor of task::spawn_blockingThis patch upgrades our futures-rs version, allowing us to build on the 1.39 beta. Additionally we‘ve introduced map and for_each to Stream. And we’ve added about a dozen new FromStream implementations for std types, bringing us up to par with std's FromIterator implementations.
And finally we‘ve added a new “unstable” task::blocking function which can be used to convert blocking code into async code using a threadpool. We’ve been using this internally for a while now to async-std to power our fs and net::SocketAddr implementations. With this patch userland code now finally has access to this too.
Create a stream of tuples, and collect into a hashmap
let a = stream::once(1u8); let b = stream::once(0u8); let s = a.zip(b); let map: HashMap<u8, u8> = s.collect().await; assert_eq!(map.get(&1), Some(&0u8));
Spawn a blocking task on a dedicated threadpool
task::blocking(async { println!("long-running task here"); }).await;
stream::Stream::mapstream::Stream::for_eachstream::Stream::try_for_eachtask::blocking as “unstable”FromStream for all std::{option, collections, result, string, sync} types.path submodule as “unstable”.futures-preview to 0.3.0-alpha.19, allowing us to build on rustc 1.39.0-beta.Stream::size_hint to optimize internal allocations.sync::Barrier docs to match std.stream::FromStream docs to match std's FromIterator.io::Read::take method.io::Read::by_ref method.io::Read::chain method.0.3.0-alpha.18, to avoid rustc upgrade problems.broadcast module with std::sync::Mutex, reducing dependencies.future::join macro as “unstable”future::select macro as “unstable”future::try_join macro as “unstable”future::try_select macro as “unstable”io::BufWriter structstream::Extend traitstream::Stream::chain methodstream::Stream::filter methodstream::Stream::inspect methodstream::Stream::skip_while methodstream::Stream::skip methodstream::Stream::step_by methodsync::Arc struct from stdlibsync::Barrier struct as “unstable”sync::Weak struct from stdlibtask::ready macro as “unstable”pin submodule as “unstable” in the docs_loopio traits are now re-exports of futures-rs types, allowing them to be implementedstream traits are now re-exports of futures-rs types, allowing them to be implementedprelude::* now needs to be in scope for functions io and stream traits to workstream::Stream::collect as “unstable”stream::Stream::enumeratestream::Stream::fusestream::Stream::foldstream::Stream::scanstream::Stream::zipstream::join macro as “unstable”stream::DoubleEndedStream as “unstable”stream::FromStream trait as “unstable”stream::IntoStream trait as “unstable”io::Cursor as “unstable”io::BufRead::consume methodio::repeatio::Slice and io::SliceMutpin submodule as “unstable”collect a stream of Result<T, E>s into a Result<impl FromStream<T>, E>Send bound from task::block_onUnpin bound from impl<T: futures::stream::Stream> Stream for Tio::timeoutio::BufRead::fill_buf, an async fn counterpart to poll_fill_buffs::create_dir_allfuture::timeout, a free function to time out futures after a thresholdio::preludenet::ToSocketAddrs, a non-blocking version of std's ToSocketAddrsstream::Stream::allstream::Stream::filter_mapstream::Stream::find_mapstream::Stream::findstream::Stream::min_bystream::Stream::nthcargo fmt on all examplesTcpStream::connect_tofutures-rs crate, improving compilation timesio::Read, io::Write, io::BufRead, and stream::Stream into multiple filesfs::File now flushes more often to prevent flushes during seekFile into raw handle