@@ -13,13 +13,17 @@ import (
1313 "github.com/ydb-platform/ydb-go-sdk/v3/discovery"
1414 "github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/single"
1515 "github.com/ydb-platform/ydb-go-sdk/v3/internal/conn"
16+ internalCoordination "github.com/ydb-platform/ydb-go-sdk/v3/internal/coordination"
1617 coordinationConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/coordination/config"
1718 "github.com/ydb-platform/ydb-go-sdk/v3/internal/database"
1819 discoveryConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/discovery/config"
19- "github.com/ydb-platform/ydb-go-sdk/v3/internal/lazy "
20+ internalRatelimiter "github.com/ydb-platform/ydb-go-sdk/v3/internal/ratelimiter "
2021 ratelimiterConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/ratelimiter/config"
22+ internalScheme "github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme"
2123 schemeConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme/config"
24+ internalScripting "github.com/ydb-platform/ydb-go-sdk/v3/internal/scripting"
2225 scriptingConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/scripting/config"
26+ internalTable "github.com/ydb-platform/ydb-go-sdk/v3/internal/table"
2327 tableConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/table/config"
2428 "github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
2529 "github.com/ydb-platform/ydb-go-sdk/v3/log"
@@ -61,27 +65,33 @@ type Connection interface {
6165 With (ctx context.Context , opts ... Option ) (Connection , error )
6266}
6367
68+ // nolint: maligned
6469type connection struct {
6570 opts []Option
6671
6772 config config.Config
6873 options []config.Option
6974
70- table table.Client
75+ tableOnce sync.Once
76+ table * internalTable.Client
7177 tableOptions []tableConfig.Option
7278
73- scripting scripting.Client
79+ scriptingOnce sync.Once
80+ scripting * internalScripting.Client
7481 scriptingOptions []scriptingConfig.Option
7582
76- scheme scheme.Client
83+ schemeOnce sync.Once
84+ scheme * internalScheme.Client
7785 schemeOptions []schemeConfig.Option
7886
7987 discoveryOptions []discoveryConfig.Option
8088
81- coordination coordination.Client
89+ coordinationOnce sync.Once
90+ coordination * internalCoordination.Client
8291 coordinationOptions []coordinationConfig.Option
8392
84- ratelimiter ratelimiter.Client
93+ ratelimiterOnce sync.Once
94+ ratelimiter * internalRatelimiter.Client
8595 ratelimiterOptions []ratelimiterConfig.Option
8696
8797 pool conn.Pool
@@ -107,7 +117,7 @@ func (c *connection) Close(ctx context.Context) error {
107117 }()
108118
109119 c .childrenMtx .Lock ()
110- closers := make ([]func (context.Context ) error , 0 , len ( c . children ) + 7 )
120+ closers := make ([]func (context.Context ) error , 0 )
111121 for _ , child := range c .children {
112122 closers = append (closers , child .Close )
113123 }
@@ -116,11 +126,41 @@ func (c *connection) Close(ctx context.Context) error {
116126
117127 closers = append (
118128 closers ,
119- c .ratelimiter .Close ,
120- c .coordination .Close ,
121- c .scheme .Close ,
122- c .table .Close ,
123- c .scripting .Close ,
129+ func (ctx context.Context ) error {
130+ c .ratelimiterOnce .Do (func () {})
131+ if c .ratelimiter == nil {
132+ return nil
133+ }
134+ return c .ratelimiter .Close (ctx )
135+ },
136+ func (ctx context.Context ) error {
137+ c .coordinationOnce .Do (func () {})
138+ if c .coordination == nil {
139+ return nil
140+ }
141+ return c .coordination .Close (ctx )
142+ },
143+ func (ctx context.Context ) error {
144+ c .schemeOnce .Do (func () {})
145+ if c .scheme == nil {
146+ return nil
147+ }
148+ return c .scheme .Close (ctx )
149+ },
150+ func (ctx context.Context ) error {
151+ c .scriptingOnce .Do (func () {})
152+ if c .scripting == nil {
153+ return nil
154+ }
155+ return c .scripting .Close (ctx )
156+ },
157+ func (ctx context.Context ) error {
158+ c .tableOnce .Do (func () {})
159+ if c .table == nil {
160+ return nil
161+ }
162+ return c .table .Close (ctx )
163+ },
124164 c .db .Close ,
125165 c .pool .Release ,
126166 )
@@ -182,18 +222,78 @@ func (c *connection) Secure() bool {
182222}
183223
184224func (c * connection ) Table () table.Client {
225+ c .tableOnce .Do (func () {
226+ c .table = internalTable .New (
227+ c .db ,
228+ tableConfig .New (
229+ append (
230+ // prepend common params from root config
231+ []tableConfig.Option {
232+ tableConfig .With (c .config .Common ),
233+ },
234+ c .tableOptions ... ,
235+ )... ,
236+ ),
237+ )
238+ })
239+ // may be nil if driver closed early
185240 return c .table
186241}
187242
188243func (c * connection ) Scheme () scheme.Client {
244+ c .schemeOnce .Do (func () {
245+ c .scheme = internalScheme .New (
246+ c .db ,
247+ schemeConfig .New (
248+ append (
249+ // prepend common params from root config
250+ []schemeConfig.Option {
251+ schemeConfig .With (c .config .Common ),
252+ },
253+ c .schemeOptions ... ,
254+ )... ,
255+ ),
256+ )
257+ })
258+ // may be nil if driver closed early
189259 return c .scheme
190260}
191261
192262func (c * connection ) Coordination () coordination.Client {
263+ c .coordinationOnce .Do (func () {
264+ c .coordination = internalCoordination .New (
265+ c .db ,
266+ coordinationConfig .New (
267+ append (
268+ // prepend common params from root config
269+ []coordinationConfig.Option {
270+ coordinationConfig .With (c .config .Common ),
271+ },
272+ c .coordinationOptions ... ,
273+ )... ,
274+ ),
275+ )
276+ })
277+ // may be nil if driver closed early
193278 return c .coordination
194279}
195280
196281func (c * connection ) Ratelimiter () ratelimiter.Client {
282+ c .ratelimiterOnce .Do (func () {
283+ c .ratelimiter = internalRatelimiter .New (
284+ c .db ,
285+ ratelimiterConfig .New (
286+ append (
287+ // prepend common params from root config
288+ []ratelimiterConfig.Option {
289+ ratelimiterConfig .With (c .config .Common ),
290+ },
291+ c .ratelimiterOptions ... ,
292+ )... ,
293+ ),
294+ )
295+ })
296+ // may be nil if driver closed early
197297 return c .ratelimiter
198298}
199299
@@ -202,6 +302,21 @@ func (c *connection) Discovery() discovery.Client {
202302}
203303
204304func (c * connection ) Scripting () scripting.Client {
305+ c .scriptingOnce .Do (func () {
306+ c .scripting = internalScripting .New (
307+ c ,
308+ scriptingConfig .New (
309+ append (
310+ // prepend common params from root config
311+ []scriptingConfig.Option {
312+ scriptingConfig .With (c .config .Common ),
313+ },
314+ c .scriptingOptions ... ,
315+ )... ,
316+ ),
317+ )
318+ })
319+ // may be nil if driver closed early
205320 return c .scripting
206321}
207322
@@ -301,60 +416,5 @@ func open(ctx context.Context, opts ...Option) (_ Connection, err error) {
301416 return nil , xerrors .WithStackTrace (err )
302417 }
303418
304- c .table = lazy .Table (
305- c .db ,
306- append (
307- // prepend common params from root config
308- []tableConfig.Option {
309- tableConfig .With (c .config .Common ),
310- },
311- c .tableOptions ... ,
312- ),
313- )
314-
315- c .scheme = lazy .Scheme (
316- c .db ,
317- append (
318- // prepend common params from root config
319- []schemeConfig.Option {
320- schemeConfig .With (c .config .Common ),
321- },
322- c .schemeOptions ... ,
323- ),
324- )
325-
326- c .scripting = lazy .Scripting (
327- c .db ,
328- append (
329- // prepend common params from root config
330- []scriptingConfig.Option {
331- scriptingConfig .With (c .config .Common ),
332- },
333- c .scriptingOptions ... ,
334- ),
335- )
336-
337- c .coordination = lazy .Coordination (
338- c .db ,
339- append (
340- // prepend common params from root config
341- []coordinationConfig.Option {
342- coordinationConfig .With (c .config .Common ),
343- },
344- c .coordinationOptions ... ,
345- ),
346- )
347-
348- c .ratelimiter = lazy .Ratelimiter (
349- c .db ,
350- append (
351- // prepend common params from root config
352- []ratelimiterConfig.Option {
353- ratelimiterConfig .With (c .config .Common ),
354- },
355- c .ratelimiterOptions ... ,
356- ),
357- )
358-
359419 return c , nil
360420}
0 commit comments