@@ -35,6 +35,7 @@ import (
3535 "github.com/ydb-platform/ydb-go-sdk/v3/internal/value"
3636 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xcontext"
3737 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
38+ "github.com/ydb-platform/ydb-go-sdk/v3/internal/xsync"
3839 "github.com/ydb-platform/ydb-go-sdk/v3/retry"
3940 "github.com/ydb-platform/ydb-go-sdk/v3/table"
4041 "github.com/ydb-platform/ydb-go-sdk/v3/table/options"
@@ -248,7 +249,7 @@ var (
248249// Note that after session is no longer needed it should be destroyed by
249250// Close() call.
250251type Session struct {
251- onClose [] func (s * Session ) error
252+ closeOnce func (ctx context. Context ) error
252253 id string
253254 client Ydb_Table_V1.TableServiceClient
254255 status table.SessionStatus
@@ -329,7 +330,7 @@ func newSession(ctx context.Context, cc grpc.ClientConnInterface, config *config
329330 return newTableSession (ctx , cc , config )
330331}
331332
332- func newTableSession ( //nolint:funlen
333+ func newTableSession (
333334 ctx context.Context , cc grpc.ClientConnInterface , config * config.Config ,
334335) (* Session , error ) {
335336 response , err := Ydb_Table_V1 .NewTableServiceClient (cc ).CreateSession (ctx ,
@@ -355,25 +356,6 @@ func newTableSession( //nolint:funlen
355356 id : result .GetSessionId (),
356357 config : config ,
357358 status : table .SessionReady ,
358- onClose : []func (s * Session ) error {
359- func (s * Session ) error {
360- _ , err = s .client .DeleteSession (ctx ,
361- & Ydb_Table.DeleteSessionRequest {
362- SessionId : s .id ,
363- OperationParams : operation .Params (ctx ,
364- s .config .OperationTimeout (),
365- s .config .OperationCancelAfter (),
366- operation .ModeSync ,
367- ),
368- },
369- )
370- if err != nil {
371- return xerrors .WithStackTrace (err )
372- }
373-
374- return nil
375- },
376- },
377359 }
378360
379361 s .lastUsage .Store (time .Now ().Unix ())
@@ -387,6 +369,7 @@ func newTableSession( //nolint:funlen
387369 },
388370 ),
389371 )
372+ s .closeOnce = xsync .OnceFunc (closeTableSession (s .client , s .config , s .id ))
390373 s .dataQuery = tableClientExecutor {
391374 client : s .client ,
392375 ignoreTruncated : s .config .IgnoreTruncated (),
@@ -395,7 +378,37 @@ func newTableSession( //nolint:funlen
395378 return s , nil
396379}
397380
398- func newQuerySession ( //nolint:funlen
381+ func closeTableSession (c Ydb_Table_V1.TableServiceClient , cfg * config.Config , id string ) func (context.Context ) error {
382+ return func (ctx context.Context ) error {
383+ if err := ctx .Err (); err != nil {
384+ return xerrors .WithStackTrace (err )
385+ }
386+
387+ if t := cfg .DeleteTimeout (); t > 0 {
388+ var cancel context.CancelFunc
389+ ctx , cancel = xcontext .WithTimeout (ctx , t )
390+ defer cancel ()
391+ }
392+
393+ _ , err := c .DeleteSession (ctx ,
394+ & Ydb_Table.DeleteSessionRequest {
395+ SessionId : id ,
396+ OperationParams : operation .Params (ctx ,
397+ cfg .OperationTimeout (),
398+ cfg .OperationCancelAfter (),
399+ operation .ModeSync ,
400+ ),
401+ },
402+ )
403+ if err != nil {
404+ return xerrors .WithStackTrace (err )
405+ }
406+
407+ return nil
408+ }
409+ }
410+
411+ func newQuerySession (
399412 ctx context.Context , cc grpc.ClientConnInterface , config * config.Config ,
400413) (* Session , error ) {
401414 s := & Session {
@@ -438,16 +451,7 @@ func newQuerySession( //nolint:funlen
438451 },
439452 ),
440453 )
441- s .onClose = []func (s * Session ) error {
442- func (s * Session ) error {
443- err := core .Close (ctx )
444- if err != nil {
445- return xerrors .WithStackTrace (err )
446- }
447-
448- return nil
449- },
450- }
454+ s .closeOnce = xsync .OnceFunc (closeQuerySession (core ))
451455 if config .ExecuteDataQueryOverQueryService () {
452456 s .dataQuery = queryClientExecutor {
453457 core : core ,
@@ -463,6 +467,17 @@ func newQuerySession( //nolint:funlen
463467 return s , nil
464468}
465469
470+ func closeQuerySession (core query.Core ) func (context.Context ) error {
471+ return func (ctx context.Context ) error {
472+ err := core .Close (ctx )
473+ if err != nil {
474+ return xerrors .WithStackTrace (err )
475+ }
476+
477+ return nil
478+ }
479+ }
480+
466481func (s * Session ) ID () string {
467482 if s == nil {
468483 return ""
@@ -471,18 +486,18 @@ func (s *Session) ID() string {
471486 return s .id
472487}
473488
474- func (s * Session ) Close (ctx context.Context ) (err error ) {
489+ func (s * Session ) Close (ctx context.Context ) (finalErr error ) {
475490 onDone := trace .TableOnSessionDelete (s .config .Trace (), & ctx ,
476491 stack .FunctionID ("github.com/ydb-platform/ydb-go-sdk/v3/internal/table.(*Session).Close" ),
477492 s ,
478493 )
479494 defer func () {
480- onDone (err )
495+ onDone (finalErr )
481496 s .SetStatus (table .SessionClosed )
482497 }()
483498
484- for _ , onClose := range s . onClose {
485- err := onClose ( s )
499+ if s . closeOnce != nil {
500+ err := s . closeOnce ( ctx )
486501 if err != nil {
487502 return xerrors .WithStackTrace (err )
488503 }
0 commit comments