Flex Gateway新着情報
Governance新着情報
Monitoring API Manager遅延、周期、および同期関数を有効にするために Clock を挿入してタイマーを作成します。各ポリシーでサポートされるタイマーは 1 つのみです。
各タイマーには、次の非同期メソッドがあります。
pub async fn next_tick(&self) -> bool;
pub async fn sleep(&self, interval: Duration) -> bool;
next_tick: タイマーが識別できる最小時間スリープします。
sleep: 目盛量スリープします。この場合、経過時間は指定した Duration 以上となります。たとえば、クロックの期間を 10 秒に設定した場合、timer.sleep(Duration::from_secs(1)) をコールすると 10 秒間スリープします。
どちらの関数も、指定した時間が経過すると true を返し、実行中にポリシーが適用解除または編集されると false を返します。
タイマーをポリシーに挿入するには、ポリシー設定関数に Clock を挿入し、期間を指定してタイマーを定義します。
#[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));
タイマーを挿入した後、その参照を on_request 関数と on_response 関数と共有して遅延関数の作成を開始します。
launcher
.launch(on_request(|rs| request_filter(rs, &timer, &config)))
.await?;
これで、次に示すように、on_request 関数と on_response 関数でタイマー関数を待機できます。
let slept = timer.sleep(duration).await;
let tick = timer.next_tick().await;
| 遅延関数を起動するポリシープロジェクトの例については、 スパイクポリシーの例を参照してください。 |
異なるティック周期で新しいタイマーを作成するには、次のメソッドを使用してクロックをリリースします。
pub fn release(self) -> Clock;
次のコードスニペットでは、タイマーを作成してからクロックをリリースし、新しいタイマーを作成します。
// 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();
タイマーを使用して、要求フローとは関係なくタスクを実行します。非同期タスクを実行する手順は、次のとおりです。
async 関数内でタスクを定義します。
ポリシー設定関数で、関数をコールします。ただし、返される将来は待機しません。
ポリシー設定関数で、on_request および on_response filter 関数を使用して launch 関数をコールします。ただし、返される将来は待機しません。
join! マクロを使用して、タスク関数と launch 関数の両方の将来を同時に待機します。
join マクロを使用するには、cargo.toml ファイルに連動関係として 'futures' クレートを追加します。
|
各ワーカーは、タスクのコピーを実行します。関数内にループを設定して、周期タスクを実行します。たとえば、次のコード例は両方の関数を待機します。
let task = my_async_task(&timer, &config);
let launched = launcher.launch(filter);
let joined = join!(launched, task);
次に示すように、my_async_task 関数にループを追加すると周期タスクが作成されます。
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
}
}
複数の非同期タスクを起動するには、次に示すようにタイマーの参照を async 関数に送信し、それらを launch タスクと結合します。
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);
| 非同期の周期タスクを起動するポリシープロジェクトの例については、 メトリクスポリシーの例 を参照してください。 |
PDK LockBuilder を使用してワーカーを同期します。ロックを使用すると、1 つの期間にタスクを完了するワーカーは 1 つのみになります。各ポリシーは、複数のロックをサポートします。
ロックは、ポリシーが使用制限のある HTTP サービスをコンシュームする場合に便利です。1 つのワーカーがデータをフェッチし、そのデータを他のワーカーと共有して、サービス要求を減らすことができます。
ロックを設定する手順は、次のとおりです。
LockBuilder をポリシー設定関数に挿入します。
#[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<()> {
ロックを設定し、その参照を非同期関数と共有します。
let lock = lock
.new(ID.to_string())
.expiration(Duration::from_secs(20))
.build();
let task = my_async_task(&timer, &lock);
非同期タスクがタスク内で追加の async 関数コールを実行する場合は、ロックの expiration を、ネストされた async 関数コールを完了するために必要な合計時間よりも長く設定します。
非同期関数内で、目的のタスクを実行する前にロックを取得します。他のワーカーにロックが設定されていない場合、現在のワーカーがロックを取得します。それ以外の場合は、次に示すようにタスクの実行を省略し、次のタスクループを待機する必要があります。
async fn my_async_task(
timer: &Timer,
lock: &TryLock,
) {
while timer.next_tick().await {
if let Some(acquired) = lock.try_lock() {
// execute task.
}
}
}
ロックを取得した後、結果を待機する必要があるコードを実行する場合は、refresh_lock 関数をコールして、ロックの有効期限が切れていないことを確認する必要があります。ロックの有効期限が切れている場合、ワーカーは無応答と見なされます。別のワーカーが同じタスク実行を実行しているため、タスクの実行を中止します。
| 非同期の周期タスクを同期し、ワーカー間で情報を共有するポリシープロジェクトの例については、 ブロックポリシーの例を参照してください。 |