Как лучше всего определить момент завершения сеанса RPC с помощью StreamClientInterceptor?

При написании функции StreamClientInterceptor, как лучше всего определить, когда вызывающая сторона завершает работу? ПКР? Это достаточно просто с унарными перехватчиками или на стороне сервера, где вам передается обработчик., который выполняет RPC, но неясно, как лучше всего сделать это на стороне клиента, когда вы возвращаете ClientStream, с которым затем взаимодействует инициатор.

Одним из вариантов использования для этого является инструментирование OpenTracing, где цель состоит в том, чтобы начать и закончить интервал, чтобы отметить начало и конец RPC.

Стратегия, которую я изучаю, заключается в том, чтобы перехватчик потока возвращал оформленный ClientStream. Этот новый ClientStream считает RPC завершенным, если какой-либо из методов интерфейса Header, CloseSend, SendMsg, RecvMsg возвращает ошибку или если Context отменяется. Кроме того, он добавляет эту логику к RecvMsg:

func (cs *DecoratedClientStream) RecvMsg(m interface{}) error {
    err := cs.ClientStream.RecvMsg(m)
    if err == io.EOF {
        // Consider the RPC as complete
        return err
    } else if err != nil {
        // Consider the RPC as complete
        return err
    }
    if !cs.isResponseStreaming {
        // Consider the RPC as complete
    }
    return err
}

Это будет работать в большинстве случаев, но я понимаю, что вызывающая сторона не обязана вызывать Recv, если она знает, что результатом будет io.EOF (см. Вы должны вызывать Recv, пока не получите io.EOF при взаимодействии с grpc.ClientStreams?), поэтому он не будет работать во всех случаях. Есть ли лучший способ сделать это?


person Ryan Burn    schedule 23.03.2017    source источник


Ответы (1)


У меня была очень похожая проблема, когда я хотел отслеживать потоковые вызовы gRPC. Помимо украшения потока, как вы сами упомянули, я не смог найти хороший способ обнаружить конец потоков. То есть, пока я не наткнулся на хуки статистики, предоставляемые grpc-go (https://godoc.org/google.golang.org/grpc/stats). Несмотря на то, что API статистики предназначен для сбора статистики о вызовах RPC, предоставляемые им перехватчики также очень полезны для отслеживания.

Если вы все еще ищете способ трассировки потоковых вызовов, я написал библиотеку для инструментов OpenTracing для gRPC, используя перехватчики статистики: https://github.com/charithe/otgrpc. Однако имейте в виду, что этот подход, вероятно, не подходит для систем, создающих долгоживущие потоки.

person charithe    schedule 14.05.2017