Execute a single hook
(&self, hook: &Hook, event: &HookEvent)
| 332 | |
| 333 | /// Execute a single hook |
| 334 | async fn execute_hook(&self, hook: &Hook, event: &HookEvent) -> HookResult { |
| 335 | // Find handler |
| 336 | let handler = { |
| 337 | let handlers = read_or_recover(&self.handlers); |
| 338 | handlers.get(&hook.id).cloned() |
| 339 | }; |
| 340 | |
| 341 | match handler { |
| 342 | Some(h) => { |
| 343 | // Handler found, execute it |
| 344 | let response = if hook.config.async_execution { |
| 345 | // Async execution (fire-and-forget) |
| 346 | let h = h.clone(); |
| 347 | let event = event.clone(); |
| 348 | tokio::spawn(async move { |
| 349 | h.handle(&event); |
| 350 | }); |
| 351 | HookResponse::continue_() |
| 352 | } else { |
| 353 | // Sync execution (with timeout) |
| 354 | let timeout = std::time::Duration::from_millis(hook.config.timeout_ms); |
| 355 | let h = h.clone(); |
| 356 | let event = event.clone(); |
| 357 | |
| 358 | match tokio::time::timeout(timeout, async move { h.handle(&event) }).await { |
| 359 | Ok(response) => response, |
| 360 | Err(_) => { |
| 361 | // Timeout, continue execution |
| 362 | HookResponse::continue_() |
| 363 | } |
| 364 | } |
| 365 | }; |
| 366 | |
| 367 | self.response_to_result(response) |
| 368 | } |
| 369 | None => { |
| 370 | // No handler, continue execution |
| 371 | HookResult::continue_() |
| 372 | } |
| 373 | } |
| 374 | } |
| 375 | |
| 376 | /// Convert HookResponse to HookResult |
| 377 | fn response_to_result(&self, response: HookResponse) -> HookResult { |
no test coverage detected