Skip to content

Commit

Permalink
[#206] Support grpc built-in retry header
Browse files Browse the repository at this point in the history
  • Loading branch information
feelform committed Aug 14, 2024
1 parent 4b1ca89 commit 82a6f1c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 8 deletions.
11 changes: 3 additions & 8 deletions lib/client/grpc-data-sender.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,13 @@ const GrpcClientSideStream = require('./grpc-client-side-stream')
const Scheduler = require('../utils/scheduler')
const makeAgentInformationMetadataInterceptor = require('./grpc/make-agent-information-metadata-interceptor')
const socketIdInterceptor = require('./grpc/socketid-interceptor')
const grpcBuiltInRetryHeaderInterceptor = require('./grpc/grpc-built-in-retry-header-interceptor')
const CallArgumentsBuilder = require('./call-arguments-builder')
const OptionsBuilder = require('./grpc/options-builder')

// AgentInfoSender.java
// refresh daily
const DEFAULT_AGENT_INFO_REFRESH_INTERVAL_MS = 24 * 60 * 60 * 1000
// retry every 3 seconds
const DEFAULT_AGENT_INFO_SEND_INTERVAL_MS = 3 * 1000
// retry 3 times per attempt
const DEFAULT_MAX_TRY_COUNT_PER_ATTEMPT = 3

// in GrpcTransportConfig.java
const DEFAULT_METADATA_RETRY_MAX_COUNT = 3
const DEFAULT_METADATA_RETRY_DELAY_MILLIS = 1000

class GrpcDataSender {
constructor(collectorIp, collectorTcpPort, collectorStatPort, collectorSpanPort, agentInfo, config) {
Expand Down Expand Up @@ -70,6 +63,7 @@ class GrpcDataSender {
const agentBuilder = new OptionsBuilder()
.addInterceptor(makeAgentInformationMetadataInterceptor(this.agentInfo))
.addInterceptor(socketIdInterceptor)
.addInterceptor(grpcBuiltInRetryHeaderInterceptor)

if (config && config.grpcServiceConfig && typeof config.grpcServiceConfig.getAgentServiceConfig === 'function') {
agentBuilder.setGrpcServiceConfig(config.grpcServiceConfig.getAgentServiceConfig())
Expand All @@ -80,6 +74,7 @@ class GrpcDataSender {
initializeMetadataClients(collectorIp, collectorTcpPort, config) {
const metadataBuilder = new OptionsBuilder()
.addInterceptor(makeAgentInformationMetadataInterceptor(this.agentInfo))
.addInterceptor(grpcBuiltInRetryHeaderInterceptor)

if (config && config.grpcServiceConfig && typeof config.grpcServiceConfig.getMetadataServiceConfig === 'function') {
metadataBuilder.setGrpcServiceConfig(config.grpcServiceConfig.getMetadataServiceConfig())
Expand Down
21 changes: 21 additions & 0 deletions lib/client/grpc/grpc-built-in-retry-header-interceptor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Pinpoint Node.js Agent
* Copyright 2020-present NAVER Corp.
* Apache License v2.0
*/

'use strict'

const grpc = require('@grpc/grpc-js')
const InterceptingCall = grpc.InterceptingCall

const grpcBuiltInRetryHeaderInterceptor = function (options, nextCall) {
return new InterceptingCall(nextCall(options), {
start: function (metadata, listener, next) {
metadata.add('grpc.built-in.retry', 'true')
next(metadata, listener, next)
},
})
}

module.exports = grpcBuiltInRetryHeaderInterceptor
6 changes: 6 additions & 0 deletions test/client/grpc-unary-rpc.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const SqlUidMetaData = require('../../lib/client/sql-uid-meta-data')
let callCount = 0
let afterCount = 0
let callRequests = []
let callMetadata = []
// https://github.com/agreatfool/grpc_tools_node_protoc_ts/blob/v5.0.0/examples/src/grpcjs/client.ts
const service = (call, callback) => {
const succeedOnRetryAttempt = call.metadata.get('succeed-on-retry-attempt')
Expand All @@ -35,6 +36,7 @@ const service = (call, callback) => {
result.setSuccess(true)
result.setMessage(`succeed-on-retry-attempt: ${succeedOnRetryAttempt[0]}, grpc-previous-rpc-attempts: ${previousAttempts[0]}`)
callRequests.push(call.request)
callMetadata.push(call.metadata)
callback(null, result)
} else {
const statusCode = call.metadata.get('respond-with-status')
Expand All @@ -58,6 +60,7 @@ function beforeSpecificOne(port, one, serviceConfig) {
afterCount = 0
config.clear()
callRequests = []
callMetadata = []
const actualConfig = config.getConfig({ 'grpc.service_config': serviceConfig })
actualConfig.collectorIp = 'localhost'
actualConfig.collectorTcpPort = port
Expand Down Expand Up @@ -241,6 +244,9 @@ test('sendApiMetaInfo retry', (t) => {
t.fail(error)
}
t.true(response.getSuccess(), '1st PResult.success is true')

const metadata = callMetadata[0]
t.deepEqual(metadata.get('grpc.built-in.retry'), ['true'], '1st metadata.get("grpc.built-in.retry") is "true"')
afterOne(t)
}).build()
dataSender.sendApiMetaInfo(actual, callArguments)
Expand Down

0 comments on commit 82a6f1c

Please sign in to comment.