@@ -22,8 +22,8 @@ import mergeStream = require('merge-stream');
2222import { common as p } from 'protobufjs' ;
2323import { Readable , Transform } from 'stream' ;
2424import * as streamEvents from 'stream-events' ;
25- import { grpc } from 'google-gax' ;
26- import { isRetryableInternalError } from './transaction-runner' ;
25+ import { grpc , CallOptions } from 'google-gax' ;
26+ import { DeadlineError , isRetryableInternalError } from './transaction-runner' ;
2727
2828import { codec , JSONOptions , Json , Field , Value } from './codec' ;
2929import { google } from '../protos/protos' ;
@@ -96,6 +96,7 @@ export interface RowOptions {
9696 * };
9797 */
9898 columnsMetadata ?: object ;
99+ gaxOptions ?: CallOptions ;
99100}
100101
101102/**
@@ -491,6 +492,8 @@ export function partialResultStream(
491492 const maxQueued = 10 ;
492493 let lastResumeToken : ResumeToken ;
493494 let lastRequestStream : Readable ;
495+ const startTime = Date . now ( ) ;
496+ const timeout = options ?. gaxOptions ?. timeout ?? Infinity ;
494497
495498 // mergeStream allows multiple streams to be connected into one. This is good;
496499 // if we need to retry a request and pipe more data to the user's stream.
@@ -541,6 +544,17 @@ export function partialResultStream(
541544 } ;
542545
543546 const retry = ( err : grpc . ServiceError ) : void => {
547+ const elapsed = Date . now ( ) - startTime ;
548+ if ( elapsed >= timeout ) {
549+ // The timeout has reached so this will flush any rows the
550+ // checkpoint stream has queued. After that, we will destroy the
551+ // user's stream with the Deadline exceeded error.
552+ setImmediate ( ( ) =>
553+ batchAndSplitOnTokenStream . destroy ( new DeadlineError ( err ) )
554+ ) ;
555+ return ;
556+ }
557+
544558 if (
545559 ! (
546560 err . code &&
0 commit comments