簡體   English   中英

在另一個輪詢中輪詢上下文

[英]Polling a context inside another poll

我有一個輪詢 function,它將永遠輪詢並始終掛起。 在輪詢 function poll_event_loop中,我想控制再次輪詢上下文的時間,並根據某些條件在x秒內再次調用 function。 我可以使用另一個調用waker.wake_by_ref function 的線程來做到這一點。但這感覺像是作弊。 如果沒有其他線程,我怎么能做到這一點。

poll_fn(|cx| self.poll_event_loop(cx)).await
// function will never be  Ready, always pending, polling sould be fast so not just sleeping x seconds inside
fn poll_event_loop(&mut self, cx: &mut Context) -> Poll<anyhow::Result<()>> {
    while some_codeandfunc() { /*....*/ }

    // guarantee another poll_fn in 1 sec
    if condition {
        context_callback(cx, 1000);
    }

    // guarantee another poll_fn in 2 sec
    if condition {
        context_callback(cx, 2000);
    }

    Poll::Pending
}

fn context_callback(context: &mut Context, millisec: u64) {
    let mut future = Box::pin(tokio::time::sleep(Durationtk::from_millis(millisec)));
    //let cb = future.as_mut().poll(context);
    future.poll_unpin(context);
}

//  ugly way to auto poll the function every x seconds
fn spawn_qeueu_thread(waker: &Waker, rx: &Receiver<String>) -> Option<JoinHandle<()>> {
    debug!("doing spawning thread");
    //self.thread_spawned = true;
    let waker = waker.clone();
    let rx2 = rx.clone();
    let spawn = tokio::spawn(async move {
        loop {
            tokio::time::sleep(Durationtk::from_millis(WAKEUPINTERVAL)).await;
            debug!("doing other thread wakebyref");
            waker.wake_by_ref();
            let try_result = rx2.try_recv();
            match try_result {
                Err(_) => {}
                Ok(_msg) => break,
            }
        }
        debug!("ending spawned thread");
    });
    return Some(spawn);
    //self.threadhandle = Some(spawn);
}

經過一些試驗,我找到了一個可行的解決方案,可以讓您在多個所需時間調用輪詢 function,工作示例:

use chrono::Utc;
use futures::FutureExt;
use futures::future::poll_fn;
use tokio::time::Sleep;
use std::pin::Pin;
use std::task::Context;
use std::task::Poll;
use tokio::time::Duration as Durationtk;

pub struct ControllerModule {
    vec: Vec<Pin<Box<Sleep>>>,
    i: i64,
}

impl ControllerModule {
    fn new() -> Self {
        let vec = vec![];
        let i = 0;

        Self { vec, i }
    }
    async fn start(&mut self) {
        poll_fn(|cx| self.poll_event_loop(cx)).await;
        print!("worked");
    }

    fn poll_event_loop(&mut self, context: &mut Context) -> Poll<anyhow::Result<()>> {

        self.i += 1;

        if self.i % 3 == 0 {
            let mut sleep = Box::pin(tokio::time::sleep(Durationtk::from_millis(5000)));
            sleep.poll_unpin(context);
            self.vec.push(sleep);
        } else if self.i % 3 == 1 {
            let mut sleep = Box::pin(tokio::time::sleep(Durationtk::from_millis(4000)));
            sleep.poll_unpin(context);
            self.vec.push(sleep);
        } else {
            context.waker().wake_by_ref();
        }

        self.vec.retain(|e| !e.is_elapsed());

        Poll::Pending
    }
}

#[tokio::main]
async fn main() {
    let mut i = ControllerModule::new();
    i.start().await
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM