DEV Community

x1957
x1957

Posted on

1 1

stop async-std task

I have a situation:

connect to a websocket & send ping message via rest.(It's ridiculous, but the biggest cryptocurrency exchange Binance's websocket api require this).

fn main() {
    task::block_on(async {
        loop { // loop for handle reconnect
            connect to websocket
            task::spawn(async move {
                loop {
                    // delay 30 minutes
                    // rest put
                }
            }); // send rest ping/pong
            read the push message
            // when websocket disconnect finish this iteration
        }
    });
}

The problem is: when iteration finished, the spawn task will run forever.

We can use async-std channel here to recv the stop message and break the loop.

The new problem: When we delay this task, how to get notice that out loop iteration finished?

futures::select solved this problem.

use async_std::sync::{channel, Receiver};
use async_std::task;
use futures::future::{Fuse, FusedFuture, FutureExt};
use futures::select;
use std::time::Duration;

fn main() {
    task::block_on(async move {
        let mut idx: i32 = 0;
        loop {
            idx = idx + 1;
            let (_s, r) = channel::<i32>(1);
            let h = task::spawn(async move {
                loop {
                    let fut = async {
                        task::sleep(Duration::from_secs(2)).await;
                        println!("{} do something!", idx);
                    }.fuse();
                    let mut fut = Box::pin(fut);
                    let mut stop = Box::pin(r.recv().fuse());
                    select! {
                        _ = fut=> {},
                        _ = stop => break,
                    }
                }
            });

            task::sleep(Duration::from_secs(5)).await;
            println!("{} exit", idx);
        }
    });
}

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more