BinChengZhao / delay-timer

Time-manager of delayed tasks. Like crontab, but synchronous asynchronous tasks are possible scheduling, and dynamic add/cancel/remove is supported.
Apache License 2.0
309 stars 23 forks source link

task parameter error #18

Closed bingryan closed 3 years ago

bingryan commented 3 years ago

Describe the bug add parameters to task function will get error of lifetime.

run example s demo.r,

error[E0621]: explicit lifetime required in the type of `url`
  --> examples/demo.rs:81:10
   |
81 |         .spawn(body)
   |          ^^^^^ lifetime `'static` required

error[E0621]: explicit lifetime required in the type of `url`
  --> examples/demo.rs:68:16
   |
68 |       let body = create_async_fn_body!({
   |  ________________^
69 | |         if let Ok(mut res) = surf::get(url).await {
70 | |             dbg!(res.body_string().await.unwrap_or_default());
71 | |
...  |
74 | |         }
75 | |     });
   | |______^ lifetime `'static` required
   |
   = note: this error originates in the macro `create_async_fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)
bingryan commented 3 years ago

Here are some question:

q1: How to enter multiple parameters(task function)?

q2: How to enter dynamic parameters(task function)?

q3: How to enter input generic (data) parameters(task function)?

BinChengZhao commented 3 years ago

Describe the bug add parameters to task function will get error of lifetime.

run example s demo.r,

error[E0621]: explicit lifetime required in the type of `url`
  --> examples/demo.rs:81:10
   |
81 |         .spawn(body)
   |          ^^^^^ lifetime `'static` required

error[E0621]: explicit lifetime required in the type of `url`
  --> examples/demo.rs:68:16
   |
68 |       let body = create_async_fn_body!({
   |  ________________^
69 | |         if let Ok(mut res) = surf::get(url).await {
70 | |             dbg!(res.body_string().await.unwrap_or_default());
71 | |
...  |
74 | |         }
75 | |     });
   | |______^ lifetime `'static` required
   |
   = note: this error originates in the macro `create_async_fn_body` (in Nightly builds, run with -Z macro-backtrace for more info)

The correct way to write it is right here.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=b9cb92dbaa578e0b960230843d8263ed

BinChengZhao commented 3 years ago

Here are some question:

q1: How to enter multiple parameters(task function)?

q2: How to enter dynamic parameters(task function)?

q3: How to enter input generic (data) parameters(task function)?

Hi friend, I'm here to answer your questions.

1 . the task input multiple environment variables can be achieved by another way of writing macros, the documentation can be found in this section of -README: Capture the specified environment information and build the closure & task.

2.Because task is a metadata, it will continue to generate task instances in the run, the running task instances are Future state machine can not update variables, but can update Task task itself through DelayTimer::update_task, task-id consistent can be.

  1. generic (data) parameters are the same way.

Why does Rust require your data to be static-lived? Because the underlying task scheduler is an asynchronous runtime, and the runtime of each task is uncertain. The compiler must give the user the assurance that all variables are static for the program to execute safely.

bingryan commented 3 years ago

great~ But there are still some questions about q3.

trait Animal {
    fn call(&self);
}

struct Dog;

struct Cat;

impl Animal for Dog {
    fn call(&self) {
        println!("this is Dog");
    }
}

impl Animal for Cat {
    fn call(&self) {
        println!("this is Cat");
    }
}

// Generic Data Types(this is static dispatch)
// TODO: if Animal is parameter
fn generic_animal_call<T: Animal>(animal: T) {
    animal.call();
}

// dynamic dispatch
fn dynamic_animal_call(animal: &dyn Animal) {
    animal.call();
}
BinChengZhao commented 3 years ago

great~ But there are still some questions about q3.

trait Animal {
    fn call(&self);
}

struct Dog;

struct Cat;

impl Animal for Dog {
    fn call(&self) {
        println!("this is Dog");
    }
}

impl Animal for Cat {
    fn call(&self) {
        println!("this is Cat");
    }
}

// Generic Data Types(this is static dispatch)
// TODO: if Animal is parameter
fn generic_animal_call<T: Animal>(animal: T) {
    animal.call();
}

// dynamic dispatch
fn dynamic_animal_call(animal: &dyn Animal) {
    animal.call();
}

Here is the case with the generic type, you can do anything with thread safety.

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=5b01993a79feb15d374da92e95e26464

bingryan commented 3 years ago

nice job !