Generic fn, channel, and thread spawn - closures

I have this code here: (Playground link)
use std::thread;
use std::sync::mpsc::channel;
fn run<T: Send>(task: fn() -> T) -> T {
let (tx, rx) = channel();
thread::spawn(move || {
tx.send(task());
});
rx.recv().unwrap()
}
fn main() {
let task = || 1 + 2;
let result = run(task);
println!("{}", result);
}
But I'm getting a lifetime error I can't figure out.
<anon>:6:5: 6:18 error: the parameter type `T` may not live long enough [E0310]
<anon>:6 thread::spawn(move || {
^~~~~~~~~~~~~
<anon>:6:5: 6:18 help: consider adding an explicit lifetime bound `T: 'static`...
<anon>:6:5: 6:18 note: ...so that captured variable `tx` does not outlive the enclosing closure
<anon>:6 thread::spawn(move || {
^~~~~~~~~~~~~
<anon>:15:22: 15:26 error: mismatched types:
expected `fn() -> _`,
found `[closure <anon>:13:16: 13:24]`
(expected fn pointer,
found closure) [E0308]
<anon>:15 let result = run(task);
^~~~
Any suggestions? Thanks!

The error message suggests adding a 'static bound to the type parameter T. If you do this, it will get rid of the first error:
fn run<T: Send + 'static>(task: fn() -> T) -> T
The 'static bound is needed to guarantee that the value returned by task can outlive the function where task runs. Read more about the 'static lifetime.
The second error is that you are passing a closure, while run expects a function pointer. One way to fix this is by changing task from a closure to a fn:
fn task() -> u32 { 1 + 2 }
Here's the complete working code:
use std::thread;
use std::sync::mpsc::channel;
fn run<T: Send + 'static>(task: fn() -> T) -> T {
let (tx, rx) = channel();
thread::spawn(move || {
tx.send(task());
});
rx.recv().unwrap()
}
fn main() {
fn task() -> u32 { 1 + 2 }
let result = run(task);
println!("{}", result);
}

Related

How can I efficiently extract the first element of a futures::Stream in a blocking manner?

I've got the following method:
pub fn load_names(&self, req: &super::MagicQueryType) -> ::grpcio::Result<::grpcio::ClientSStreamReceiver<String>> {
My goal is to get the very first element of grpcio::ClientSStreamReceiver; I don't care about the other names:
let name: String = load_names(query)?.wait().nth(0)?;
It seems inefficient to call wait() before nth(0) as I believe wait() blocks the stream until it receives all the elements.
How can I write a more efficient solution (i.e., nth(0).wait()) without triggering build errors? Rust's build errors for futures::stream::Stream look extremely confusing to me.
The Rust playground doesn't support grpcio = "0.4.4" so I cannot provide a link.
To extract the first element of a futures::Stream in a blocking manner, you should convert the Stream to an iterator by calling executor::block_on_stream and then call Iterator::next.
use futures::{executor, stream, Stream}; // 0.3.4
use std::iter;
fn example() -> impl Stream<Item = i32> {
stream::iter(iter::repeat(42))
}
fn main() {
let v = executor::block_on_stream(example()).next();
println!("{:?}", v);
}
If you are using Tokio, you can convert the Stream into a Future with StreamExt::into_future and annotate a function with #[tokio::main]:
use futures::{stream, Stream, StreamExt}; // 0.3.4
use std::iter;
use tokio; // 0.2.13
fn example() -> impl Stream<Item = i32> {
stream::iter(iter::repeat(42))
}
#[tokio::main]
async fn just_one() -> Option<i32> {
let (i, _stream) = example().into_future().await;
i
}
fn main() {
println!("{:?}", just_one());
}
See also:
How do I synchronously return a value calculated in an asynchronous Future in stable Rust?
How to select between a future and stream in Rust?

How do I extract messages from an unbounded queue every N seconds and spawn them on to a Tokio handler?

I am trying to extract messages (which are futures themselves) from an unbounded queue every N seconds and spawn them into the Tokio handler.
I’ve tried dozens of variations but I cannot seem to find the right approach. It looks like it should be possible, but I always hit a future type mismatch or end up with borrow issues.
This is the code that shows more or less what I want:
let fut = Interval::new_interval(Duration::from_secs(1))
.for_each(|num| vantage_dequeuer.into_future() )
.for_each(|message:VantageMessage |{
handle.spawn(message);
return Ok(());
})
.map_err(|e| panic!("delay errored; err={:?}", e));
core.run(fut);
Complete code:
extern crate futures; // 0.1.24
extern crate tokio; // 0.1.8
extern crate tokio_core; // 0.1.17
use futures::future::ok;
use futures::sync::mpsc;
use futures::{Future, Stream};
use std::thread;
use std::time::Duration;
use tokio::timer::Interval;
use tokio_core::reactor::Core;
type VantageMessage = Box<Future<Item = (), Error = ()> + Send>;
fn main() {
let (enqueuer, dequeuer) = mpsc::unbounded();
let new_fut: VantageMessage = Box::new(ok(()).and_then(|_| {
println!("Message!");
return Ok(());
}));
enqueuer.unbounded_send(new_fut);
let joinHandle = worker(Some(dequeuer));
joinHandle.join();
}
/*
Every second extract one message from dequeuer (or wait if not available)
and spawn it in the core
*/
fn worker(
mut vantage_dequeuer: Option<mpsc::UnboundedReceiver<VantageMessage>>,
) -> thread::JoinHandle<()> {
let dequeuer = dequeuer.take().unwrap();
let joinHandle = thread::spawn(|| {
let mut core = Core::new().unwrap();
let handle = core.handle();
let fut = Interval::new_interval(Duration::from_secs(1))
.for_each(|num| vantage_dequeuer.into_future())
.for_each(|message: VantageMessage| {
handle.spawn(message);
return Ok(());
})
.map_err(|e| panic!("delay errored; err={:?}", e));
core.run(fut);
println!("Returned!");
});
return joinHandle;
}
Playground
error[E0425]: cannot find value `dequeuer` in this scope
--> src/main.rs:33:20
|
33 | let dequeuer = dequeuer.take().unwrap();
| ^^^^^^^^ not found in this scope
error[E0599]: no method named `into_future` found for type `std::option::Option<futures::sync::mpsc::UnboundedReceiver<std::boxed::Box<(dyn futures::Future<Item=(), Error=()> + std::marker::Send + 'static)>>>` in the current scope
--> src/main.rs:38:46
|
38 | .for_each(|num| vantage_dequeuer.into_future())
| ^^^^^^^^^^^
|
= note: the method `into_future` exists but the following trait bounds were not satisfied:
`&mut std::option::Option<futures::sync::mpsc::UnboundedReceiver<std::boxed::Box<(dyn futures::Future<Item=(), Error=()> + std::marker::Send + 'static)>>> : futures::Stream`
Interval and UnboundedReceiver are both streams, so I'd use Stream::zip to combine them:
The zipped stream waits for both streams to produce an item, and then returns that pair. If an error happens, then that error will be returned immediately. If either stream ends then the zipped stream will also end.
extern crate futures; // 0.1.24
extern crate tokio; // 0.1.8
extern crate tokio_core; // 0.1.17
use futures::{
future::ok,
sync::mpsc,
{Future, Stream},
};
use std::{thread, time::Duration};
use tokio::timer::Interval;
use tokio_core::reactor::Core;
type VantageMessage = Box<Future<Item = (), Error = ()> + Send>;
pub fn main() {
let (tx, rx) = mpsc::unbounded();
let new_fut: VantageMessage = Box::new(ok(()).and_then(|_| {
println!("Message!");
Ok(())
}));
tx.unbounded_send(new_fut).expect("Unable to send");
drop(tx); // Close the sending side
worker(rx).join().expect("Thread had a panic");
}
fn worker(queue: mpsc::UnboundedReceiver<VantageMessage>) -> thread::JoinHandle<()> {
thread::spawn(|| {
let mut core = Core::new().unwrap();
let handle = core.handle();
core.run({
Interval::new_interval(Duration::from_secs(1))
.map_err(|e| panic!("delay errored; err={}", e))
.zip(queue)
.for_each(|(_, message)| {
handle.spawn(message);
Ok(())
})
})
.expect("Unable to run reactor");
println!("Returned!");
})
}
Note that this doesn't actually wait for any of the spawned futures to complete before the reactor shuts down. If you want that, I'd switch to tokio::run and tokio::spawn:
fn worker(queue: mpsc::UnboundedReceiver<VantageMessage>) -> thread::JoinHandle<()> {
thread::spawn(|| {
tokio::run({
Interval::new_interval(Duration::from_secs(1))
.map_err(|e| panic!("delay errored; err={}", e))
.zip(queue)
.for_each(|(_, message)| {
tokio::spawn(message);
Ok(())
})
});
println!("Returned!");
})
}

How can I check if std::io::Cursor has unconsumed data?

I am writing a low-level network app that deals with TCP sockets where I often need to process binary data streams. When some data is available, I read it into u8 array, then wrap into std::io::Cursor<&[u8]> and then pass it to handlers. In a handler, I often need to know if there is some more data in the Cursor or not.
Imagine that the handle function receives data and then processes it in chunks using the handle_chunk function. For simplicity, assume that chunk size is fixed at 10 bytes; if the data size is not divisible by 10, it's an error. This simple logic can be implemented in the following way:
fn handle(mut data: Cursor<&[u8]>) {
while !data.empty() {
if let Err(err) = handle_chunk(&mut data) {
eprintln!("Error while handling data: {}", err);
}
}
}
fn handle_chunk(data: &mut Cursor<&[u8]>) -> Result<(), String> {
// Returns Err("unexpected EOF".to_string()) if chunk is incomplete
// ...
}
However, Cursor does not have an empty() method or any other method capable of telling if there is more data to process. The working solution that I could come up with is:
fn handle(data: Cursor<&[u8]>) {
let data = data.into_inner();
let len = data.len();
let mut data = Cursor::new(data);
while (data.position() as usize) < len - 1 {
if let Err(err) = handle_chunk(&mut data) {
eprintln!("Error while handling data: {}", err);
}
}
}
This looks hacky and inelegant though. Is there a better solution? Maybe there is a different tool in the Rust standard library that fits here better than Cursor?
Your code can be simplified by using Cursor::get_ref to avoid breaking up the input and putting it back together:
fn handle(mut data: Cursor<&[u8]>) {
let len = data.get_ref().len();
while (data.position() as usize) < len - 1 {
if let Err(err) = handle_chunk(&mut data) {
eprintln!("Error while handling data: {}", err);
}
}
}
Now, you haven't shown any code that requires a Cursor. Many times, people think it's needed to convert a &[u8] to something that implements Read, but it's not. Read is implemented for &'a [u8]:
use std::io::Read;
fn handle(mut data: &[u8]) {
while !data.is_empty() {
if let Err(err) = handle_chunk(&mut data) {
eprintln!("Error while handling data: {}", err);
}
}
}
fn handle_chunk<R: Read>(mut data: R) -> Result<(), String> {
let mut b = [0; 10];
data.read_exact(&mut b).unwrap();
println!("Chunk: {:?}", b);
Ok(())
}
fn main() {
let d: Vec<u8> = (0..20).collect();
handle(&d)
}
By having mut data: &[u8] and using &mut data, the code will update the slice variable in place to advance it forward. We can't easily go backward though.
an empty() method
Rust style indicates that an empty method would be a verb — this would remove data (if it were possible). The method you want should be called is_empty, as seen on slices.

Handling streaming iterator as normal iterator by using PhantomData and unsafe

I know the code below is hacky, but could it be called safe and idiomatic Rust? Is there better way for this?
// needs to do 'rustup default nightly' to run under valgrind
// #![feature(alloc_system, global_allocator, allocator_api)]
// extern crate alloc_system;
// use alloc_system::System;
// #[global_allocator]
// static A: System = System;
struct Foo<'a> {
v: Vec<u8>,
pos: usize,
phantom: std::marker::PhantomData<&'a u8>,
}
impl<'a> Iterator for Foo<'a> {
type Item = &'a mut u8;
fn next(&mut self) -> Option<&'a mut u8> {
let r = self.v.get_mut(self.pos);
if r.is_some() {
self.pos += 1;
unsafe { Some(&mut *(r.unwrap() as *mut u8)) }
} else {
None
}
}
}
impl<'a> Foo<'a> {
fn reset(&mut self) {
self.pos = 0;
}
}
fn main() {
let mut x = Foo {
v: (1..10).collect(),
pos: 0,
phantom: std::marker::PhantomData,
};
let vp = x.v.as_ptr();
{
for i in &mut x {
println!("{}", i);
}
}
{
x.reset();
}
{
for i in &mut x {
*i *= *i;
}
}
{
x.reset();
}
{
for i in &mut x {
println!("{}", i);
}
}
assert!(vp == x.v.as_ptr());
}
Write a little bit in the comment, Valgrind told me no leak and the result is as expected under Rust 1.26.0-nightly and 1.25.0.
Related:
How do I write an iterator that returns references to itself?
Iterator returning items by reference, lifetime issue
This code is not safe. The user of the type may choose any lifetime, including 'static:
fn constructor() -> Foo<'static> {
Foo {
v: vec![42; 10],
pos: 0,
phantom: std::marker::PhantomData,
}
}
fn example() -> &'static u8 {
let mut f = constructor();
f.next().unwrap()
}
fn main() {
println!("example: {}", example());
}
Here, example returns a reference to a variable that is no longer in scope, accessing invalid memory and subverting the restrictions you must uphold.
There's an example of how you could write this code with no unsafe whatsoever in another Q&A.

"error: closure may outlive the current function" but it will not outlive it

When I try to compile the following code:
fn main() {
(...)
let mut should_end = false;
let mut input = Input::new(ctx);
input.add_handler(Box::new(|evt| {
match evt {
&Event::Quit{..} => {
should_end = true;
}
_ => {}
}
}));
while !should_end {
input.handle();
}
}
pub struct Input {
handlers: Vec<Box<FnMut(i32)>>,
}
impl Input {
pub fn new() -> Self {
Input {handlers: Vec::new()}
}
pub fn handle(&mut self) {
for a in vec![21,0,3,12,1] {
for handler in &mut self.handlers {
handler(a);
}
}
}
pub fn add_handler(&mut self, handler: Box<FnMut(i32)>) {
self.handlers.push(handler);
}
}
I get this error:
error: closure may outlive the current function, but it borrows `should_end`, which is owned by the current function
I can't simply add move to the closure, because I need to use should_end later in the main loop. I mean, I can, but since bool is Copy, it will only affect the should_end inside the closure, and thus the program loops forever.
As far as I understand, since input is created in the main function, and the closure is stored in input, it couldn't possibly outlive the current function. Is there a way to express to Rust that the closure won't outlive main? Or is there a possibility that I can't see that the closure will outlive main? In the latter case, it there a way to force it to live only as long as main?
Do I need to refactor the way I'm handling input, or is there some way I can make this work. If I need to refactor, where can I look to see a good example of this in Rust?
Here's a playpen of a simplified version. It is possible I made a mistake in it that could crash your browser. I happened to me once, so, beware.
In case it is needed, the rest of my code is available. All the relevant info should be in either main.rs or input.rs.
The problem is not your closure, but the add_handler method. Fully expanded it would look like this:
fn add_handler<'a>(&'a mut self, handler: Box<FnMut(i32) + 'static>)
As you can see, there's an implicit 'static bound on the trait object. Obviously we don't want that, so we introduce a second lifetime 'b:
fn add_handler<'a, 'b: 'a>(&'a mut self, handler: Box<FnMut(i32) + 'b>)
Since you are adding the handler object to the Input::handlers field, that field cannot outlive the scope of the handler object. Thus we also need to limit its lifetime:
pub struct Input<'a> {
handlers: Vec<Box<FnMut(i32) + 'a>>,
}
This again requires the impl to have a lifetime, which we can use in the add_handler method.
impl<'a> Input<'a> {
...
pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
self.handlers.push(handler);
}
}
Now all that's left is using a Cell to control access to your should_end flag.
Here is an example of the fixed code:
use std::cell::Cell;
fn main() {
let should_end = Cell::new(false);
let mut input = Input::new();
input.add_handler(Box::new(|a| {
match a {
1 => {
should_end.set(true);
}
_ => {
println!("{} {}", a, should_end.get())
}
}
}));
let mut fail_safe = 0;
while !should_end.get() {
if fail_safe > 20 {break;}
input.handle();
fail_safe += 1;
}
}
pub struct Input<'a> {
handlers: Vec<Box<FnMut(i32) + 'a>>,
}
impl<'a> Input<'a> {
pub fn new() -> Self {
Input {handlers: Vec::new()}
}
pub fn handle(&mut self) {
for a in vec![21,0,3,12,1,2] {// it will print the 2, but it won't loop again
for handler in &mut self.handlers {
handler(a);
}
}
}
pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
self.handlers.push(handler);
}
}

Resources