Need some help on designing scheduled tasks

Hello all

In my application I need to write a scheduled task which iterates every minute, which what code it runs need to be depended on some output last time it runs.

Then I have an ownership problem. No matter it is a piece of data or a channel, seem I need somebody else than the scheduler to hold the ownership so its lifetime can persist through. In a crate clokwerk the way I run a task is passing a closure to the scheduler and it happens cannot let data persists.

Is there any suggestions on how to implement this?

Generally you should try to keep the data owned by one task only. Consider using message passing to communicate with that task if you need some information about the data the task owns.

yes i agree with that. however i have no idea how to pass a channel receiver to such recurring task.

As far as i imagine, if I pass a channel receiver to a task, it will takeover the ownership and dissipate after the task complete. How can I pass the dissipated channel receiver to the next instance of such recurring task?

I would make the task long-lived with a sleep of some kind.

it doesnt sound idiomatic and trivial to me but is a great solution to implement on rust. thanks :stuck_out_tongue:

Here's an example from some software I have been making:

use crossbeam::{channel,Receiver};

pub struct Options
{
  pub dynamic_block_size: bool,
  pub block_size: usize,
  pub probe_max: usize, 
  pub lazy_match: bool
}

pub struct Config
{
  pub options: Options,
  pub pool: scoped_threadpool::Pool
}

impl Config
{
  pub fn new() -> Config
  {
    Config
    { 
      options: Options
      { 
        dynamic_block_size: false, 
        block_size: 0x2000, 
        probe_max: 10, 
        lazy_match: true 
      },
      pool: scoped_threadpool::Pool::new(2)
    }
  }
}


pub fn compress( inp: &[u8], c: &mut Config ) -> Vec<u8>
{
  let mut out = BitStream::new();
  let ( mtx, mrx ) = channel::bounded(1000); // channel for matches
  let ( ctx, crx ) = channel::bounded(1); // channel for checksum

  let opts = &c.options;

  // Execute the match finding, checksum computation and block output in parallel using the scoped thread pool.
  c.pool.scoped( |s| 
  {
    s.execute( || { matcher::find( inp, mtx , &opts ); } );
    s.execute( || { ctx.send( adler32( &inp ) ).unwrap(); } );
    write_blocks( inp, mrx, crx, &mut out, &opts );
  } );

  out.bytes
}

Basically, you can use the rx,tx parts of a channel as parameters to the threads, and then use those to communicate between the threads.

You likely want to use the scoped_threadpool crate, or you run into restrictions.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.