Configuring Delayed, Periodic, and Synchronous Functions | MuleSoft Documentation
# Configuring Delayed, Periodic, and Synchronous Functions
Use the `Clock` injectable to build a timer to enable delayed, periodic, and synchronous functions. Each policy supports only one timer.
Each timer provides the following async methods:
```
pub async fn next_tick(&self) -> bool;
pub async fn sleep(&self, interval: Duration) -> bool;
```

  * `next_tick`: Sleeps for the minimum amount of time the timer is capable of distinguishing.
  * `sleep`: Sleeps for an amount of ticks where the elapsed time is greater or equal than the provided `Duration`. For example, if you configure the period of the clock to 10 seconds, calling `timer.sleep(Duration::from_secs(1))` sleeps for 10 seconds.


Both functions return `true` when the specified time has passed or `false` if the policy is unapplied or edited during execution.
## Configure the Timer
To inject a timer in your policy, insert a `Clock` into your policy configuration function and define a timer with a time period:
```
#[entrypoint]
async fn configure(
  launcher: Launcher,
  Configuration(bytes): Configuration,
  clock: Clock, // Inject the clock to be able to launch async tasks.
  client: HttpClient,
) -> Result<()> {

  // set the period between ticks of the timer.
  let timer = clock.period(Duration::from_secs(10));
```

After you inject the timer, share a its reference with the `on_request` and `on_response` functions to begin creating delayed functions:
```
  launcher
    .launch(on_request(|rs| request_filter(rs, &timer, &config)))
    .await?;
```

You can now await timer functions in `on_request` and `on_response` functions, for example:
```
  let slept = timer.sleep(duration).await;
  let tick = timer.next_tick().await;
```

To view an example policy project that launches delayed functions, see Spike Policy Example.   
---  
## Release the Clock
To create a new timer with a different tick period, release the `Clock` by using the following method:
```
pub fn release(self) -> Clock;
```

The following code snippet creates a timer and then releases the clock to create a new timer:
```
  // Configure an initial tick period.
  let initial_timer = clock.period(Duration::from_millis(500));
  some_initial_task(&other_timer).await;
  // Configure another tick period.
  let other_timer = initial_timer.release().period(Duration::from_millis(3000);
  some_other_task(&other_timer).await;
  // Get the clock back.
  let clock = other_timer.release();
```

## Launch Asynchronous Tasks
Use the timer to execute tasks independent of the request flow. To execute asynchronous tasks:
  1. Define your task inside an `async` function.
  2. In the policy configuration function, call your function but don’t await the returned future.
  3. In the policy configuration function, call the `launch` function with the `on_request` and `on_response` filter functions but don’t await the returned future.
  4. Use the `join!` macro to await both futures of your task function and `launch` function at the same time.
To use the `join` macro, add the ‘futures’ crate as dependency in your `cargo.toml` file.   
---  


Each worker executes a copy of the task. Configure a loop inside the function to execute periodic tasks. For example, the following code example awaits both functions:
```
let task = my_async_task(&timer, &config);
let launched = launcher.launch(filter);
let joined = join!(launched, task);
```

Adding a loop to the `my_async_task` function creates periodic tasks, for example:
```
async fn my_async_task(timer: &Timer, config: &Config) {
  // While the policy is still running.
  // Wait for the next cycle.
  while timer.next_tick().await {
    // Execute periodic task
  }
}
```

To launch multiple asynchronous tasks, send a reference of the timer to your `async` functions and join them with the `launch` task, for example:
```
let task1 = my_async_task1(&timer, &config);
let task2 = my_async_task2(&timer, &config);
let launched = launcher.launch(filter);
let joined = join!(launched, task1, task2);
```

To view an example policy project that launches asynchronous periodic tasks, see Metrics Policy Example.   
---  
## Sync Asynchronous Tasks between Workers
Use the PDK `LockBuilder` to sync workers. The lock ensures that only one worker is completing a task in a time period. Each policy supports multiple locks.
Locks are useful when a policy consumes an HTTP service that has usage limits. A single worker can fetch data and then share the data with other workers to reduce service requests.
To configure a lock:
  1. Inject the `LockBuilder` into your policy configuration function:
```
#[entrypoint]
async fn configure(
  launcher: Launcher,
  Configuration(bytes): Configuration,
  clock: Clock,    // Inject the clock to be able to launch async tasks.
  lock: LockBuilder,  // Inject the lock to be able to synchronize the workers.
) -> Result<()> {
```

  2. Configure the lock and share a reference of it with your asynchronous function:
```
  let lock = lock
    .new(ID.to_string())
    .expiration(Duration::from_secs(20))
    .build();
  let task = my_async_task(&timer, &lock);
```

If the asynchronous task executes additional `async` function calls inside the task, configure the `expiration` of the lock to a duration longer than the total time needed to complete the nested `async` function calls.
  3. Inside the asynchronous function, acquire the lock before executing the desired task. If no other worker has the lock, the current worker acquires the lock. Otherwise, you must omit the execution of the task and wait for the next task loop, for example:
```
async fn my_async_task(
  timer: &Timer,
  lock: &TryLock,
) {
  while timer.next_tick().await {
   if let Some(acquired) = lock.try_lock() {
    // execute task.
   }
  }
}
```

After obtaining the lock, if you execute code that requires you await a result, you must call the `refresh_lock` function to ensure the lock hasn’t expired. If the lock has expired, the worker is considered unresponsive. Abort the execution of your task because another worker is running the same task execution.


To view an example policy project that synchronizes asynchronous periodic tasks and shares information between workers, see Block Policy Example.   
---  
## See Also
  *