INTEGRITY Dokumentace

Alarmy

Kontext

Alarmy Durable Objects umožňují naplánovat probuzení Durable Object v budoucím čase. Jakmile nastane naplánovaný čas alarmu, alarm() se zavolá metoda handleru. Alarmy se upravují pomocí Storage API, a operace s alarmy se řídí stejnými pravidly jako ostatní operace s úložištěm.

Stojí za zmínku:

Alarms lze použít k vytváření distribuovaných primitiv, jako jsou fronty nebo dávkové zpracování práce nad Durable Objects. Alarms zároveň poskytují mechanismus, který zaručuje dokončení operací uvnitř Durable Object, aniž by bylo nutné spoléhat na příchozí požadavky udržující Durable Object naživu. Kompletní příklad najdete v Použití Alarms API.

Plánování více událostí pomocí jediného alarmu

Ačkoli může mít každý Durable Object nastavený vždy jen jeden alarm, můžete spravovat mnoho naplánovaných a opakujících se událostí tak, že si harmonogram událostí uložíte do úložiště a necháte alarm() handler zpracuje splatné události a poté se naplánuje na další.

import { DurableObject } from "cloudflare:workers";

export class AgentServer extends DurableObject {
  // Schedule a one-time or recurring event
  async scheduleEvent(id, runAt, repeatMs = null) {
    await this.ctx.storage.put(`event:${id}`, { id, runAt, repeatMs });
    const currentAlarm = await this.ctx.storage.getAlarm();
    if (!currentAlarm || runAt < currentAlarm) {
      await this.ctx.storage.setAlarm(runAt);
    }
  }

  async alarm() {
    const now = Date.now();
    const events = await this.ctx.storage.list({ prefix: "event:" });
    let nextAlarm = null;

    for (const [key, event] of events) {
      if (event.runAt <= now) {
        await this.processEvent(event);
        if (event.repeatMs) {
          event.runAt = now + event.repeatMs;
          await this.ctx.storage.put(key, event);
        } else {
          await this.ctx.storage.delete(key);
        }
      }
      // Track the next event time
      if (event.runAt > now && (!nextAlarm || event.runAt < nextAlarm)) {
        nextAlarm = event.runAt;
      }
    }

    if (nextAlarm) await this.ctx.storage.setAlarm(nextAlarm);
  }

  async processEvent(event) {
    // Your event handling logic here
  }
}

Metody úložiště

getAlarm

setAlarm

deleteAlarm

Metody handleru

alarm

Příklad

Tento příklad ukazuje, jak nastavit alarmy pomocí setAlarm(timestamp) metodu a zpracujte alarmy pomocí alarm() handler ve vašem Durable Object.

import { DurableObject } from "cloudflare:workers";

export default {
	async fetch(request, env) {
		return await env.ALARM_EXAMPLE.getByName("foo").fetch(request);
	},
};

const SECONDS = 1000;

export class AlarmExample extends DurableObject {
	constructor(ctx, env) {
		super(ctx, env);
		this.storage = ctx.storage;
	}
	async fetch(request) {
		// If there is no alarm currently set, set one for 10 seconds from now
		let currentAlarm = await this.storage.getAlarm();
		if (currentAlarm == null) {
			this.storage.setAlarm(Date.now() + 10 * SECONDS);
		}
	}
	async alarm() {
		// The alarm handler will be invoked whenever an alarm fires.
		// You can use this to do work, read from the Storage API, make HTTP calls
		// and set future alarms to run using this.storage.setAlarm() from within this handler.
	}
}
import time

from workers import DurableObject, WorkerEntrypoint

class Default(WorkerEntrypoint):
    async def fetch(self, request):
        return await self.env.ALARM_EXAMPLE.getByName("foo").fetch(request)

SECONDS = 1000

class AlarmExample(DurableObject):
    def __init__(self, ctx, env):
        super().__init__(ctx, env)
        self.storage = ctx.storage

    async def fetch(self, request):
        # If there is no alarm currently set, set one for 10 seconds from now
        current_alarm = await self.storage.getAlarm()
        if current_alarm is None:
            self.storage.setAlarm(int(time.time() * 1000) + 10 * SECONDS)

    async def alarm(self):
        # The alarm handler will be invoked whenever an alarm fires.
        # You can use this to do work, read from the Storage API, make HTTP calls
        # and set future alarms to run using self.storage.setAlarm() from within this handler.
        pass

Následující příklad ukazuje, jak použít alarmInfo vlastnost, podle které zjistíte, zda o zpracování dané alarmové události již byl proveden pokus.

class MyDurableObject extends DurableObject {
	async alarm(alarmInfo) {
		if (alarmInfo?.retryCount != 0) {
			console.log(
				"This alarm event has been attempted ${alarmInfo?.retryCount} times before.",
			);
		}
	}
}
class MyDurableObject(DurableObject):
    async def alarm(self, alarm_info):
        if alarm_info and alarm_info.get('retryCount', 0) != 0:
            print(f"This alarm event has been attempted {alarm_info.get('retryCount')} times before.")