@@ -25,6 +25,7 @@ var grpc = require('grpc');
2525var is = require ( 'is' ) ;
2626var nodeutil = require ( 'util' ) ;
2727var path = require ( 'path' ) ;
28+ var retryRequest = require ( 'retry-request' ) ;
2829
2930/**
3031 * @type {module:common/service }
@@ -241,19 +242,47 @@ GrpcService.prototype.request = function(protoOpts, reqOpts, callback) {
241242 grpcOpts . deadline = new Date ( Date . now ( ) + protoOpts . timeout ) ;
242243 }
243244
244- service [ protoOpts . method ] ( reqOpts , function ( err , resp ) {
245- if ( err ) {
246- if ( HTTP_ERROR_CODE_MAP [ err . code ] ) {
247- var httpError = HTTP_ERROR_CODE_MAP [ err . code ] ;
248- err . code = httpError . code ;
249- }
250-
251- callback ( err ) ;
252- return ;
245+ // Retains a reference to an error from the response. If the final callback is
246+ // executed with this as the "response", we return it to the user as an error.
247+ var respError ;
248+
249+ retryRequest ( null , {
250+ shouldRetryFn : function ( resp ) {
251+ return [ 429 , 500 , 502 , 503 ] . indexOf ( resp . code ) > - 1 ;
252+ } ,
253+
254+ // retry-request determines if it should retry from the incoming HTTP
255+ // response status. gRPC always returns an error proto message. We pass that
256+ // "error" into retry-request to act as the HTTP response, so it can use the
257+ // status code to determine if it should retry.
258+ request : function ( _ , onResponse ) {
259+ respError = null ;
260+
261+ service [ protoOpts . method ] ( reqOpts , function ( err , resp ) {
262+ if ( err ) {
263+ if ( HTTP_ERROR_CODE_MAP [ err . code ] ) {
264+ respError = err ;
265+ var httpError = HTTP_ERROR_CODE_MAP [ err . code ] ;
266+ respError . code = httpError . code ;
267+ onResponse ( null , respError ) ;
268+ return ;
269+ }
270+
271+ onResponse ( err ) ;
272+ return ;
273+ }
274+
275+ onResponse ( null , resp ) ;
276+ } , null , grpcOpts ) ;
277+ }
278+ } , function ( err , resp ) {
279+ if ( ! err && resp === respError ) {
280+ err = respError ;
281+ resp = null ;
253282 }
254283
255- callback ( null , resp ) ;
256- } , null , grpcOpts ) ;
284+ callback ( err , resp ) ;
285+ } ) ;
257286} ;
258287
259288/**
0 commit comments