Async version of the Rust standard library
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(3);
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.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::max_by
Stream::min_by_key
Stream::product
as "unstable"Stream::sum
as "unstable"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
.