|
1 | 1 | //! The `events` table provides a way to have scheduled events
|
2 |
| -
|
3 |
| -use anyhow::{Result}; |
| 2 | +use anyhow::{Result, Context as _}; |
4 | 3 | use chrono::{DateTime, FixedOffset};
|
5 | 4 | use tokio_postgres::{Client as DbClient};
|
6 | 5 | use uuid::Uuid;
|
| 6 | +use serde::{Deserialize, Serialize}; |
7 | 7 |
|
8 |
| -#[derive(Debug)] |
| 8 | +#[derive(Serialize, Deserialize, Debug)] |
9 | 9 | pub struct Event {
|
10 | 10 | pub event_id: Uuid,
|
11 | 11 | pub event_name: String,
|
12 | 12 | pub expected_event_time: DateTime<FixedOffset>,
|
13 |
| - pub event_metadata: String, |
| 13 | + // pub event_metadata: String, |
14 | 14 | pub executed_at: DateTime<FixedOffset>,
|
15 | 15 | pub failed: Option<String>,
|
16 | 16 | }
|
17 | 17 |
|
18 |
| -pub async fn insert_failed(db: &DbClient) -> Result<()> { |
19 |
| - unimplemented!(); |
| 18 | +pub async fn insert_event(db: &DbClient, event: &Event) -> Result<()> { |
| 19 | + tracing::trace!("insert_event(id={})", event.event_id); |
| 20 | + |
| 21 | + db.execute( |
| 22 | + "INSERT INTO events (event_id, event_name, expected_event_time, event_metadata, executed_at, failed) VALUES ($1, $2, $3, $4, $5, $6) ON CONFLICT DO NOTHING", |
| 23 | + &[&event.event_id, &event.event_name, &event.expected_event_time, &"", &event.executed_at, &event.failed], |
| 24 | + ) |
| 25 | + .await |
| 26 | + .context("inserting event")?; |
| 27 | + |
| 28 | + Ok(()) |
| 29 | +} |
| 30 | + |
| 31 | +pub async fn delete_event(db: &DbClient, event_id: &Uuid) -> Result<()> { |
| 32 | + tracing::trace!("delete_event(id={})", event_id); |
| 33 | + |
| 34 | + db.execute( |
| 35 | + "DELETE FROM events WHERE event_id = $1", |
| 36 | + &[&event_id], |
| 37 | + ) |
| 38 | + .await |
| 39 | + .context("deleting event")?; |
| 40 | + |
| 41 | + Ok(()) |
20 | 42 | }
|
21 | 43 |
|
22 |
| -pub async fn delete_event(db: &DbClient) -> Result<()> { |
23 |
| - unimplemented!(); |
| 44 | +pub async fn update_event_failed_message(db: &DbClient, event_id: &Uuid, message: &String) -> Result<()> { |
| 45 | + tracing::trace!("update_event_failed_message(id={})", event_id); |
| 46 | + |
| 47 | + db.execute( |
| 48 | + "UPDATE events SET failed = $2 WHERE event_id = $1", |
| 49 | + &[&event_id, &message], |
| 50 | + ) |
| 51 | + .await |
| 52 | + .context("updating event failed message")?; |
| 53 | + |
| 54 | + Ok(()) |
24 | 55 | }
|
25 | 56 |
|
26 |
| -pub async fn get_events_to_execute(db: &DbClient) -> Result<Vec<Event>> { |
| 57 | +pub async fn update_event_executed_at(db: &DbClient, event_id: &Uuid) -> Result<()> { |
| 58 | + tracing::trace!("update_event_executed_at(id={})", event_id); |
| 59 | + |
| 60 | + db.execute( |
| 61 | + "UPDATE events SET executed_at = now() WHERE event_id = $1", |
| 62 | + &[&event_id], |
| 63 | + ) |
| 64 | + .await |
| 65 | + .context("updating event executed at")?; |
| 66 | + |
| 67 | + Ok(()) |
| 68 | +} |
| 69 | + |
| 70 | +// Selects all events with: |
| 71 | +// - event_time's in the past |
| 72 | +// - failed is null or executed_at is at least 60 minutes ago (intended to make repeat executions rare enough) |
| 73 | +pub async fn get_events_to_execute(db: &DbClient) -> Result<Vec<Event>> { |
27 | 74 | let events = db
|
28 | 75 | .query(
|
29 | 76 | "
|
30 |
| - SELECT * FROM events", |
| 77 | + SELECT * FROM events WHERE expected_event_time <= now() AND (failed IS NULL OR executed_at <= now() - INTERVAL '60 minutes')", |
31 | 78 | &[],
|
32 | 79 | )
|
33 | 80 | .await
|
34 |
| - .unwrap(); |
| 81 | + .context("Getting events data")?; |
| 82 | + |
| 83 | + let mut data = Vec::with_capacity(events.len()); |
| 84 | + for event in events { |
| 85 | + let event_id: Uuid = event.get(0); |
| 86 | + let event_name: String = event.get(1); |
| 87 | + let expected_event_time: DateTime<FixedOffset> = event.get(2); |
| 88 | + // let event_metadata: String = event.get(3); |
| 89 | + let executed_at: DateTime<FixedOffset> = event.get(4); |
| 90 | + let failed: Option<String> = event.get(5); |
| 91 | + |
| 92 | + data.push(Event { |
| 93 | + event_id, |
| 94 | + event_name, |
| 95 | + expected_event_time, |
| 96 | + // event_metadata, |
| 97 | + executed_at, |
| 98 | + failed |
| 99 | + }); |
| 100 | + } |
35 | 101 |
|
36 |
| - Ok(vec![]) |
| 102 | + Ok(data) |
37 | 103 | }
|
0 commit comments