From d0edb2c1f3c2dd28d3adcaec163af026e7fa4fcc Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Wed, 2 Apr 2025 12:43:17 -0400 Subject: [PATCH] fix: async handling for events There were issues with async handling in events which can make it difficult to use event handlers to mutate values provided by an emitter. This is not an optimal solution: this will await event listeners in sequence. Ideally, event listeners should be awaited concurrently. --- src/backend/src/ExtensionService.js | 11 ++++++----- src/backend/src/services/EventService.js | 10 +++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/backend/src/ExtensionService.js b/src/backend/src/ExtensionService.js index 76fe37e91..6c0d820d2 100644 --- a/src/backend/src/ExtensionService.js +++ b/src/backend/src/ExtensionService.js @@ -89,15 +89,16 @@ class ExtensionService extends BaseService { // Propagate all events not from extensions to `core.` const svc_event = this.services.get('event'); - svc_event.on_all((key, data, meta = {}) => { + svc_event.on_all(async (key, data, meta = {}) => { meta.from_outside_of_extension = true; - this.state.extension.emit(`core.${key}`, data, meta); + + await this.state.extension.emit(`core.${key}`, data, meta); }); - this.state.extension.on_all((key, data, meta) => { + this.state.extension.on_all(async (key, data, meta) => { if ( meta.from_outside_of_extension ) return; - - svc_event.emit(key, data, meta); + + await svc_event.emit(key, data, meta); }); this.state.extension.kv = (() => { diff --git a/src/backend/src/services/EventService.js b/src/backend/src/services/EventService.js index 1691f48c1..0810854b7 100644 --- a/src/backend/src/services/EventService.js +++ b/src/backend/src/services/EventService.js @@ -32,8 +32,8 @@ class ScopedEventBus { this.scope = scope; } - emit (key, data) { - this.event_bus.emit(this.scope + '.' + key, data); + async emit (key, data) { + await this.event_bus.emit(this.scope + '.' + key, data); } on (key, callback) { @@ -62,7 +62,7 @@ class EventService extends BaseService { this.global_listeners_ = []; } - emit (key, data, meta) { + async emit (key, data, meta) { meta = meta ?? {}; const parts = key.split('.'); for ( let i = 0; i < parts.length; i++ ) { @@ -76,7 +76,7 @@ class EventService extends BaseService { for ( const callback of listeners ) { // IIAFE wrapper to catch errors without blocking // event dispatch. - Context.arun(async () => { + await Context.arun(async () => { try { await callback(key, data, meta); } catch (e) { @@ -103,7 +103,7 @@ class EventService extends BaseService { * @param {Object} [meta={}] - Optional metadata related to the event. * @returns {void} */ - Context.arun(async () => { + await Context.arun(async () => { try { await callback(key, data, meta); } catch (e) {