commit 2db321edc71ab9c5963e40d7ba63787dafbd8eb1
parent 8907b64eb82ad5ac0f85eb625914c72d6f4bc5f0
Author: triesap <137732411+triesap@users.noreply.github.com>
Date: Sat, 12 Apr 2025 20:30:32 +0000
Refactor job request events subscriber adding error handling and NIP-90 job feedback events.
Diffstat:
4 files changed, 70 insertions(+), 2 deletions(-)
diff --git a/src/events/job_request.rs b/src/events/job_request.rs
@@ -1,10 +1,18 @@
use anyhow::Result;
+use nostr::event::Event;
use nostr::{event::Kind, filter::Filter, key::Keys, types::Timestamp};
use nostr_sdk::Client;
use nostr_sdk::RelayPoolNotification;
-use tracing::info;
+use tracing::{info, warn};
use crate::KIND_JOB_REQUEST;
+use crate::utils::nostr::nostr_event_job_request_feedback;
+
+#[derive(thiserror::Error, Debug)]
+pub enum JobRequestError {
+ #[error("Failure to process request.")]
+ Failure,
+}
pub async fn subscriber(keys: Keys, relays: Vec<String>) -> Result<()> {
info!("Starting subscriber for kind {}", KIND_JOB_REQUEST);
@@ -26,7 +34,17 @@ pub async fn subscriber(keys: Keys, relays: Vec<String>) -> Result<()> {
while let Ok(n) = notifications.recv().await {
if let RelayPoolNotification::Event { event, .. } = n {
if event.kind == Kind::Custom(KIND_JOB_REQUEST) {
- info!("Receieved job request event: {:?}", { event.clone() });
+ let event = (*event).clone();
+ let keys = keys.clone();
+ let client = client.clone();
+
+ tokio::spawn(async move {
+ if let Err(err) =
+ handle_event(event.clone(), keys.clone(), client.clone()).await
+ {
+ let _ = handle_error(err, event, keys, client).await;
+ }
+ });
}
}
}
@@ -35,3 +53,31 @@ pub async fn subscriber(keys: Keys, relays: Vec<String>) -> Result<()> {
Ok(())
}
+
+async fn handle_error(
+ error: JobRequestError,
+ event: Event,
+ keys: Keys,
+ client: Client,
+) -> Result<()> {
+ warn!("job_request handle_error {}", error);
+
+ let builder = nostr_event_job_request_feedback(&event, error, "error", None)?;
+ let event_id = client.send_event_builder(builder).await?;
+
+ warn!("job_request handle_error sent feedback {:?}", {
+ event_id.clone()
+ });
+ Ok(())
+}
+
+async fn handle_event(event: Event, keys: Keys, client: Client) -> Result<(), JobRequestError> {
+ let t = std::time::Instant::now();
+ if t.elapsed().as_nanos() % 2 == 0 {
+ info!("job_request handle_event {:?}", { event.clone() });
+ } else {
+ return Err(JobRequestError::Failure);
+ }
+
+ Ok(())
+}
diff --git a/src/lib.rs b/src/lib.rs
@@ -1,6 +1,7 @@
pub mod config;
pub mod events;
pub mod keys;
+pub mod utils;
pub const KIND_JOB_REQUEST: u16 = 5300;
pub const KIND_JOB_RESPONSE: u16 = 6300;
diff --git a/src/utils/mod.rs b/src/utils/mod.rs
@@ -0,0 +1 @@
+pub mod nostr;
diff --git a/src/utils/nostr.rs b/src/utils/nostr.rs
@@ -0,0 +1,20 @@
+use nostr::{
+ event::{Event, EventBuilder, Tag},
+ nips::nip90::{DataVendingMachineStatus, JobFeedbackData},
+};
+
+use crate::events::job_request::JobRequestError;
+
+pub fn nostr_event_job_request_feedback(
+ event: &Event,
+ error: JobRequestError,
+ status: &str,
+ tags: Option<Vec<Tag>>,
+) -> anyhow::Result<EventBuilder> {
+ let status = status
+ .parse::<DataVendingMachineStatus>()
+ .unwrap_or(DataVendingMachineStatus::Error);
+ let feedback_data = JobFeedbackData::new(&event, status).extra_info(error.to_string());
+ let builder = EventBuilder::job_feedback(feedback_data).tags(tags.unwrap_or_default());
+ Ok(builder)
+}