@@ -56,6 +56,7 @@ type conn struct {
5656 closed bool
5757 state atomic.Uint32
5858 lastUsage * lastUsage
59+ childStreams * xcontext.CancelsGuard
5960 onClose []func (* conn )
6061 onTransportErrors []func (ctx context.Context , cc Conn , cause error )
6162}
@@ -392,23 +393,21 @@ func (c *conn) NewStream(
392393 desc * grpc.StreamDesc ,
393394 method string ,
394395 opts ... grpc.CallOption ,
395- ) (_ grpc.ClientStream , err error ) {
396+ ) (_ grpc.ClientStream , finalErr error ) {
396397 var (
397398 onDone = trace .DriverOnConnNewStream (
398399 c .config .Trace (), & ctx ,
399400 stack .FunctionID ("github.com/ydb-platform/ydb-go-sdk/3/internal/conn.(*conn).NewStream" ),
400401 c .endpoint .Copy (), trace .Method (method ),
401402 )
402403 useWrapping = UseWrapping (ctx )
403- cc * grpc.ClientConn
404- s grpc.ClientStream
405404 )
406405
407406 defer func () {
408- onDone (err , c .GetState ())
407+ onDone (finalErr , c .GetState ())
409408 }()
410409
411- cc , err = c .realConn (ctx )
410+ cc , err : = c .realConn (ctx )
412411 if err != nil {
413412 return nil , c .wrapError (err )
414413 }
@@ -423,7 +422,19 @@ func (c *conn) NewStream(
423422
424423 ctx , sentMark := markContext (meta .WithTraceID (ctx , traceID ))
425424
426- s , err = cc .NewStream (ctx , desc , method , opts ... )
425+ ctx , cancel := xcontext .WithCancel (ctx )
426+ defer func () {
427+ if finalErr != nil {
428+ cancel ()
429+ } else {
430+ c .childStreams .Remember (& cancel )
431+ }
432+ }()
433+
434+ s , err := cc .NewStream (ctx , desc , method , append (opts , grpc .OnFinish (func (err error ) {
435+ cancel ()
436+ c .childStreams .Forget (& cancel )
437+ }))... )
427438 if err != nil {
428439 if xerrors .IsContextError (err ) {
429440 return nil , xerrors .WithStackTrace (err )
@@ -490,10 +501,16 @@ func withOnTransportError(onTransportError func(ctx context.Context, cc Conn, ca
490501
491502func newConn (e endpoint.Endpoint , config Config , opts ... option ) * conn {
492503 c := & conn {
493- endpoint : e ,
494- config : config ,
495- done : make (chan struct {}),
496- lastUsage : newLastUsage (nil ),
504+ endpoint : e ,
505+ config : config ,
506+ done : make (chan struct {}),
507+ lastUsage : newLastUsage (nil ),
508+ childStreams : xcontext .NewCancelsGuard (),
509+ onClose : []func (* conn ){
510+ func (c * conn ) {
511+ c .childStreams .Cancel ()
512+ },
513+ },
497514 }
498515 c .state .Store (uint32 (Created ))
499516 for _ , opt := range opts {
0 commit comments