cluster-client icon indicating copy to clipboard operation
cluster-client copied to clipboard

clusterClient leader invoke结果回调了2次

Open ClarkMiaguo opened this issue 3 years ago • 0 comments

代码

class MongoDataClient extends Base {
    constructor(args) {
        super(args);
        this.ready(true);
    }

    async find(collectionName, ...rest) {
        rest.pop(); //需要手动去掉callback
        const db = await mongoClient;
        return db.collection(collectionName).find(...rest).toArray();
    }
}

结合leader代码

invoke(methodName, args, callback) {
    let method = this._realClient[methodName];
    // compatible with generatorFunction
    if (is.generatorFunction(method)) {
      method = co.wrap(method);
    }
    args.push(callback);
    const ret = method.apply(this._realClient, args);
    if (callback && is.promise(ret)) {
      ret.then(result => callback(null, result), err => callback(err))
        // to avoid uncaught exception in callback function, then cause unhandledRejection
        .catch(err => { this._errorHandler(err); });
    }
  }

假设在clusterClient方式,且被invoke函数是async函数, Leader在执行follower程序,即调用invoke时候, 会被callback 次,一次在method.apply(this._realClient, args); 另外一次在 ret.then(result => callback(null, result), err => callback(err))

导致的结果是发送了2次,第一次没数据,第二次真实数据

 cluster-client#leader [Leader:MongoDataClient] send method:find result to follower, result: undefined +11ms
  cluster-client#leader [Leader:MongoDataClient] send method:find result to follower, result: [...

ClarkMiaguo avatar Apr 25 '21 08:04 ClarkMiaguo