Как безопасно добавить значения в grp c ServerStream в перехватчике - PullRequest
0 голосов
/ 02 апреля 2020

У меня есть перехватчик ведения журнала для моего сервера grp c, и я хочу добавить значение к метаданным (я хочу отслеживать запрос в течение всего времени его существования):

func (m *middleware) loggingInterceptor(srv interface{},
    ss grpc.ServerStream,
    info *grpc.StreamServerInfo,
    handler grpc.StreamHandler) 

    md, ok := metadata.FromIncomingContext(ss.Context())
    if !ok {
        return errors.New("could not get metadata from incoming stream context")
    }

    // add the transaction id to the metadata so that business logic can track it
    md.Append("trans-id", "some-transaction-id")

    // call the handler func
    return handler(srv, ss)
}

, но документы для FromIncomingContext утверждают, что:

// FromIncomingContext returns the incoming metadata in ctx if it exists.  The
// returned MD should not be modified. Writing to it may cause races.
// Modification should be made to copies of the returned MD.

Хорошо, поэтому я смотрю на функцию копирования и копирую метаданные:

mdCopy := md.Copy()
mdCopy.Append("trans-id", "some-transaction-id")

и думаю, «как мне прикрепить эти метаданные обратно к ServerStream context? ", И я проверяю, есть ли какой-нибудь ss.SetContext(newCtx), но я не вижу ничего подобного. Я думаю об этом с неправильной точки зрения, или я что-то упускаю?

1 Ответ

0 голосов
/ 08 апреля 2020

Вам нужно будет использовать NewIncomingContext для создания копии текущего контекста в потоке.

Затем вам нужно будет создать тип wrappedStream, который переопределяет метод Context в ServerStream чтобы вернуть измененный context. Вам нужно будет передать это wrappedStream на handler, которое вы получили в вашем перехватчике.

Пример этого вы можете увидеть здесь (здесь он переопределяет другие методы, но идея та же): https://github.com/grpc/grpc-go/blob/master/examples/features/interceptor/server/main.go#L106 -L124

Надеюсь, это поможет.

...