63 lines
2.0 KiB
TypeScript
63 lines
2.0 KiB
TypeScript
import { Event } from '../Events'
|
|
import { EventBusInterface } from './EventBusInterface'
|
|
import { v4 } from 'uuid'
|
|
|
|
export type RpcEvent<RequestType, ResponseType> = {
|
|
topic: string
|
|
}
|
|
|
|
export class Rpc {
|
|
constructor(private participant: EventBusInterface) {}
|
|
|
|
// tslint:disable-next-line:member-access
|
|
async call<RpcRequest, RpcResponse>(
|
|
event: RpcEvent<RpcRequest, RpcResponse>,
|
|
request: RpcRequest,
|
|
timeout: number = 0
|
|
): Promise<RpcResponse> {
|
|
return new Promise((resolve, reject) => {
|
|
const id = v4()
|
|
|
|
const responseEvent: Event<any> = { topic: `${event.topic}/response/${id}` }
|
|
const requestEvent: Event<any> = { topic: `${event.topic}/request` }
|
|
const callback = (result: { id: string; payload: RpcResponse; error: unknown }) => {
|
|
this.participant.unsubscribe(responseEvent as any, callback)
|
|
if (result.error) {
|
|
reject(result.error)
|
|
} else {
|
|
resolve(result.payload)
|
|
}
|
|
console.log('received', result)
|
|
}
|
|
this.participant.subscribe(responseEvent, callback)
|
|
this.participant.emit(requestEvent, { id, payload: request })
|
|
|
|
if (timeout > 0) {
|
|
setTimeout(() => {
|
|
reject(new Error(`Did not respond to ${event.topic} within ${timeout}ms`))
|
|
this.participant.unsubscribe(responseEvent as any, callback)
|
|
}, 10000)
|
|
}
|
|
})
|
|
}
|
|
|
|
// tslint:disable-next-line:member-access
|
|
async on<RpcRequest, RpcResponse>(
|
|
event: RpcEvent<RpcRequest, RpcResponse>,
|
|
handler: (request: RpcRequest) => Promise<RpcResponse>
|
|
) {
|
|
this.participant.subscribe<RpcRequest>({ topic: `${event.topic}/request` }, async request => {
|
|
let payload
|
|
let error
|
|
try {
|
|
payload = await handler((request as any).payload)
|
|
} catch (e) {
|
|
error = e
|
|
}
|
|
const id = (request as any).id
|
|
console.log(`${event.topic}/response/${id}`, payload, error)
|
|
this.participant.emit({ topic: `${event.topic}/response/${id}` }, { id, payload, error })
|
|
})
|
|
}
|
|
}
|