diff --git a/server/python/rpc.py b/server/python/rpc.py index 0c51626c8..24cf05ae6 100644 --- a/server/python/rpc.py +++ b/server/python/rpc.py @@ -1,4 +1,6 @@ import inspect +import random +import string import traceback from asyncio.futures import Future from typing import Any, Callable, Dict, List, Mapping @@ -497,13 +499,15 @@ class RpcPeer: print("unhandled rpc error", self.peerName, e) pass + randomDigits = random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits) + async def createPendingResult(self, cb: Callable[[str, Callable[[Exception], None]], None]): future = Future() if self.killed: future.set_exception(RPCResultError(None, 'RpcPeer has been killed (createPendingResult)')) return future - id = str(self.idCounter) + id = ''.join(random.choices(RpcPeer.randomDigits, k=8)) self.idCounter = self.idCounter + 1 self.pendingResults[id] = future await cb(id, lambda e: future.set_exception(RPCResultError(e, None))) diff --git a/server/src/rpc.ts b/server/src/rpc.ts index a034951fa..9a7723dac 100644 --- a/server/src/rpc.ts +++ b/server/src/rpc.ts @@ -303,7 +303,6 @@ interface ErrorType { } export class RpcPeer { - idCounter = 1; params: { [name: string]: any } = {}; pendingResults: { [id: string]: Deferred } = {}; proxyCounter = 1; @@ -390,6 +389,7 @@ export class RpcPeer { return props; } + static readonly RANDOM_DIGITS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; static readonly RPC_RESULT_ERROR_NAME = 'RPCResultError'; static readonly PROPERTY_PROXY_ID = '__proxy_id'; static readonly PROPERTY_PROXY_ONEWAY_METHODS = '__proxy_oneway_methods'; @@ -422,12 +422,16 @@ export class RpcPeer { return !value || (!value[RpcPeer.PROPERTY_JSON_DISABLE_SERIALIZATION] && this.transportSafeArgumentTypes.has(value.constructor?.name)); } + generateId() { + return Array(8).map(() => RpcPeer.RANDOM_DIGITS.charAt(Math.floor(Math.random() * RpcPeer.RANDOM_DIGITS.length))).join(''); + } + createPendingResult(method: string, cb: (id: string, reject: (e: Error) => void) => void): Promise { if (Object.isFrozen(this.pendingResults)) return Promise.reject(new RPCResultError(this, 'RpcPeer has been killed (createPendingResult)')); const promise = new Promise((resolve, reject) => { - const id = (this.idCounter++).toString(); + const id = this.generateId(); this.pendingResults[id] = { resolve, reject, method }; cb(id, e => reject(new RPCResultError(this, e.message, e)));