Handlers
A runnable Geblang example.
- Path
gebweb/examples/feature_tour/src/handlers.gb- Category
- Feature Tour
Source
module feature_tour.handlers;
/**
* Consumer-side bits of the tasks app: an event subscriber that
* watches for completed tasks and enqueues a notification email,
* a job handler that wraps the Gebweb mailer for that email,
* and a scheduled cleanup that prunes old completed rows once a
* day. The worker process (`gebweb worker`) ticks both the job
* queue and the scheduler.
*/
import gebweb;
import datetime;
/** Subscribe to the task.completed event. Enqueues a background
* job so the response returns immediately - the mail send goes
* through the worker's retry/backoff. */
export class TaskNotifier {
@On("task.completed")
func onCompleted(gebweb.Event ev): void {
gebweb.enqueue(ev.app, "send-task-notification", ev.payload);
}
}
/** A Mailable for the completion notification. */
export class TaskCompletedMail extends gebweb.Mailable {
string title;
string taskId;
func TaskCompletedMail(string to, string title, string taskId) {
parent();
this.to = to;
this.title = title;
this.taskId = taskId;
}
func subject(): string {
return "Task completed: " + this.title;
}
func template(): string {
return "emails/task-completed.html";
}
func context(): dict<string, any> {
return {"title": this.title, "taskId": this.taskId};
}
}
/** Job handler invoked by the worker. Wraps the mailer so the
* delivery retries on failure under the standard backoff. */
export class TaskNotificationJob {
@Job("send-task-notification")
func send(gebweb.Job job): void {
let payload = job.payload;
let mail = TaskCompletedMail(
payload["ownerEmail"] as string,
payload["title"] as string,
payload["taskId"] as string
);
gebweb.send(job.app, mail);
}
}
/** Daily scheduled cleanup: purge tasks completed more than
* 30 days ago. Runs on the leader worker only. */
export class TaskCleanup {
any repo;
func TaskCleanup(any repo) {
this.repo = repo;
}
@Scheduled("0 3 * * *")
func nightlyPurge(): void {
let cutoff = datetime.nowUnix() - (30 * 24 * 3600);
this.repo.purgeOldCompleted(cutoff);
}
}