gRPC之应该注意的地方

记录一下阅读gRPCOC源码时看到的问题

没有暴露设置超时时间的接口

GRPCCompletionQueue.m里面可以看到相关代码,可以看到超时时间是const,外部无法修改,相当于一个默认的超时时间

const int64_t kGRPCCompletionQueueDefaultTimeoutSecs = 60;

同时下面的处理也有点囧

...
gpr_timespec deadline = (timeoutSecs < 0)
          ? gpr_inf_future(GPR_CLOCK_REALTIME)
          : gpr_time_from_seconds(timeoutSecs, GPR_CLOCK_REALTIME);
      while (YES) {
        // The following call blocks until an event is available or the deadline elapses.
        grpc_event event = grpc_completion_queue_next(unmanagedQueue, deadline, NULL);
        GRPCQueueCompletionHandler handler;
        switch (event.type) {
          case GRPC_OP_COMPLETE:
            handler = (__bridge_transfer GRPCQueueCompletionHandler)event.tag;
            handler(event.success);
            break;
          case GRPC_QUEUE_TIMEOUT:
            // Nothing to do here
            break;
          case GRPC_QUEUE_SHUTDOWN:
            grpc_completion_queue_destroy(unmanagedQueue);
            return;
          default:
            [NSException raise:@"Unrecognized completion type" format:@"type=%d", event.type];
        }
...

超时居然不做处理,理应抛个错误什么的吧

网络线程完成后回调在主线程

GRXConcurrentWriteable.m中可以看到,回调时都工作在UI线程

// Designated initializer
- (instancetype)initWithWriteable:(id)writeable {
  if (self = [super init]) {
    _writeableQueue = dispatch_get_main_queue();
    _writeable = writeable;
  }
  return self;
}

- (void)enqueueSuccessfulCompletion {
  dispatch_async(_writeableQueue, ^{
    dispatch_once(&_alreadyFinished, ^{
      // Cancellation is now impossible. None of the other three blocks can run concurrently with
      // this one.
      [self.writeable writesFinishedWithError:nil];
      // Skip any possible message to the wrapped writeable enqueued after this one.
      self.writeable = nil;
    });
  });
}

这种设计模式在AFN中有,在gRPC中也有,但是实际应用中我认为问题很大。我个人认为多线程编程的其中一个最佳实践就是,哪个线程发起异步任务,回调时就工作在哪个线程,这样对于调用方是最安全的。

你可能感兴趣的:(gRPC之应该注意的地方)