diff --git a/packages/modules/packages/bridge/packages/module-resolver/src/ProxyModule.ts b/packages/modules/packages/bridge/packages/module-resolver/src/ProxyModule.ts index 8238b22df46..7268923d819 100644 --- a/packages/modules/packages/bridge/packages/module-resolver/src/ProxyModule.ts +++ b/packages/modules/packages/bridge/packages/module-resolver/src/ProxyModule.ts @@ -7,6 +7,7 @@ import { AddressPreviousHashPayload, BaseEmitter, CompositeModuleResolver, + ModuleBusyEventArgs, ModuleConfig, ModuleDescription, ModuleEventData, @@ -36,6 +37,8 @@ export type ProxyModuleParams = ModuleParams< export class ProxyModule extends BaseEmitter implements ModuleInstance { readonly upResolver = new CompositeModuleResolver() + private _busyCount = 0 + constructor(public proxyParams: ProxyModuleParams) { super({ config: proxyParams.bridge.targetConfig(proxyParams.address) }) } @@ -65,29 +68,52 @@ export class ProxyModule extends BaseEmitter impl throw Error('Not Implemented') } - async describe(): Promise { - const description: ModuleDescription = { - address: this.address, - queries: this.queries, + async busy(closure: () => Promise) { + if (this._busyCount <= 0) { + this._busyCount = 0 + const args: ModuleBusyEventArgs = { busy: true, module: this } + await this.emit('moduleBusy', args) } - if (this.config.name) { - description.name = this.config.name + this._busyCount++ + try { + return await closure() + } finally { + this._busyCount-- + if (this._busyCount <= 0) { + this._busyCount = 0 + const args: ModuleBusyEventArgs = { busy: false, module: this } + await this.emit('moduleBusy', args) + } } + } - const discover = await this.discover() + async describe(): Promise { + return await this.busy(async () => { + const description: ModuleDescription = { + address: this.address, + queries: this.queries, + } + if (this.config.name) { + description.name = this.config.name + } + + const discover = await this.discover() - description.children = compact( - discover?.map((payload) => { - const address = payload.schema === AddressSchema ? (payload as AddressPayload).address : undefined - return address != this.address ? address : undefined - }) ?? [], - ) + description.children = compact( + discover?.map((payload) => { + const address = payload.schema === AddressSchema ? (payload as AddressPayload).address : undefined + return address != this.address ? address : undefined + }) ?? [], + ) - return description + return description + }) } - discover(): Promisable { - return this.bridge.targetDiscover() + async discover(): Promise { + return await this.busy(async () => { + return await this.bridge.targetDiscover() + }) } manifest(): Promisable { @@ -104,9 +130,11 @@ export class ProxyModule extends BaseEmitter impl } async query(query: T, payloads?: Payload[]): Promise { - const result = assertEx(await this.bridge.targetQuery(this.address, query, payloads), 'Remote Query Failed') - await this.emit('moduleQueried', { module: this, payloads, query, result }) - return result + return await this.busy(async () => { + const result = assertEx(await this.bridge.targetQuery(this.address, query, payloads), 'Remote Query Failed') + await this.emit('moduleQueried', { module: this, payloads, query, result }) + return result + }) } async queryable(query: QueryBoundWitness, payloads?: Payload[], queryConfig?: ModuleConfig): Promise { @@ -120,10 +148,12 @@ export class ProxyModule extends BaseEmitter impl nameOrAddressOrFilter?: ModuleFilter | string, options?: ModuleFilterOptions, ): Promise { - if (typeof nameOrAddressOrFilter === 'string') { - return await this.bridge.targetResolve(this.address, nameOrAddressOrFilter, options) - } else { - return await this.bridge.targetResolve(this.address, nameOrAddressOrFilter, options) - } + return await this.busy(async () => { + if (typeof nameOrAddressOrFilter === 'string') { + return await this.bridge.targetResolve(this.address, nameOrAddressOrFilter, options) + } else { + return await this.bridge.targetResolve(this.address, nameOrAddressOrFilter, options) + } + }) } }