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_key
Stream::max_by
Stream::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 Future
Stream::cmp
Stream::ge
Stream::last
Stream::le
Stream::lt
Stream::merge
as “unstable”, replacing stream::join!
Stream::partial_cmp
Stream::take_while
Stream::try_fold
future::IntoFuture
as “unstable”io::BufRead::split
io::Write::write_fmt
print!
, 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::Product
stream::Sum
stream::from_fn
stream::interval
as “unstable”stream::repeat_with
task::spawn_blocking
as “unstable”, replacing task::blocking
task::yield_now
write!
and writeln!
macros as “unstable”future::join!
and future::try_join!
future::timeout
path
task::ready!
BufWriter::into_inner
so it calls flush
before yieldingio::BufWriter
internalsnet::ToSocketAddrs
internalsio::Cursor
io
documentation to match std's io
docstask
documentation to match std's thread
docsstream::join!
in favor of Stream::merge
task::blocking
in favor of task::spawn_blocking
This 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::map
stream::Stream::for_each
stream::Stream::try_for_each
task::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_loop
io
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::enumerate
stream::Stream::fuse
stream::Stream::fold
stream::Stream::scan
stream::Stream::zip
stream::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::repeat
io::Slice
and io::SliceMut
pin
submodule as “unstable”collect
a stream of Result<T, E>
s into a Result<impl FromStream<T>, E>
Send
bound from task::block_on
Unpin
bound from impl<T: futures::stream::Stream> Stream for T
io::timeout
io::BufRead::fill_buf
, an async fn
counterpart to poll_fill_buf
fs::create_dir_all
future::timeout
, a free function to time out futures after a thresholdio::prelude
net::ToSocketAddrs
, a non-blocking version of std's ToSocketAddrs
stream::Stream::all
stream::Stream::filter_map
stream::Stream::find_map
stream::Stream::find
stream::Stream::min_by
stream::Stream::nth
cargo fmt
on all examplesTcpStream::connect_to
futures-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 seek
File
into raw handle