@@ -46,34 +46,57 @@ func (c *conn) Address() string {
4646}
4747
4848type conn struct {
49- sync.RWMutex
50- config Config // ro access
51- cc * grpc.ClientConn
52- done chan struct {}
53- endpoint endpoint.Endpoint // ro access
54- closed bool
55- state State
56- usages int32
57- lastUsage time.Time
58- onClose []func (* conn )
49+ mtx sync.RWMutex
50+ config Config // ro access
51+ cc * grpc.ClientConn
52+ done chan struct {}
53+ endpoint endpoint.Endpoint // ro access
54+ closed bool
55+ state State
56+ usages int32
57+ streamUsages int32
58+ lastUsage time.Time
59+ onClose []func (* conn )
5960}
6061
6162func (c * conn ) Release (ctx context.Context ) {
62- if c .decUsages () == 0 {
63- _ = c .Close (ctx )
63+ var (
64+ onDone = trace .DriverOnConnRelease (
65+ c .config .Trace (),
66+ & ctx ,
67+ c .endpoint .Copy (),
68+ )
69+ err error
70+ )
71+ defer func () {
72+ onDone (err )
73+ }()
74+ var issues []error
75+ if c .changeUsages (- 1 ) == 0 {
76+ if usages := atomic .LoadInt32 (& c .streamUsages ); usages > 0 {
77+ issues = append (issues , fmt .Errorf ("conn in stream use: usages=%d" , usages ))
78+ }
79+ if closeErr := c .Close (ctx ); closeErr != nil {
80+ issues = append (issues , closeErr )
81+ }
82+ }
83+ if len (issues ) > 0 {
84+ err = errors .NewWithIssues ("conn released with issues" , issues ... )
6485 }
6586}
6687
6788func (c * conn ) LastUsage () time.Time {
68- c .RLock ()
69- defer c .RUnlock ()
70-
89+ if usages := atomic .LoadInt32 (& c .streamUsages ); usages > 0 {
90+ return time .Now ()
91+ }
92+ c .mtx .RLock ()
93+ defer c .mtx .RUnlock ()
7194 return c .lastUsage
7295}
7396
7497func (c * conn ) IsState (states ... State ) bool {
75- c .RLock ()
76- defer c .RUnlock ()
98+ c .mtx . RLock ()
99+ defer c .mtx . RUnlock ()
77100
78101 for _ , s := range states {
79102 if s == c .state {
@@ -85,8 +108,8 @@ func (c *conn) IsState(states ...State) bool {
85108}
86109
87110func (c * conn ) park (ctx context.Context ) (err error ) {
88- c .Lock ()
89- defer c .Unlock ()
111+ c .mtx . Lock ()
112+ defer c .mtx . Unlock ()
90113
91114 if c .closed {
92115 return nil
@@ -129,8 +152,8 @@ func (c *conn) Endpoint() endpoint.Endpoint {
129152}
130153
131154func (c * conn ) SetState (s State ) State {
132- c .Lock ()
133- defer c .Unlock ()
155+ c .mtx . Lock ()
156+ defer c .mtx . Unlock ()
134157 return c .setState (s )
135158}
136159
@@ -145,8 +168,8 @@ func (c *conn) setState(s State) State {
145168}
146169
147170func (c * conn ) GetState () (s State ) {
148- c .RLock ()
149- defer c .RUnlock ()
171+ c .mtx . RLock ()
172+ defer c .mtx . RUnlock ()
150173 return c .state
151174}
152175
@@ -168,8 +191,8 @@ func (c *conn) take(ctx context.Context) (cc *grpc.ClientConn, err error) {
168191 )
169192 }
170193
171- c .Lock ()
172- defer c .Unlock ()
194+ c .mtx . Lock ()
195+ defer c .mtx . Unlock ()
173196
174197 if ! isBroken (c .cc ) {
175198 return c .cc , nil
@@ -194,30 +217,44 @@ func (c *conn) take(ctx context.Context) (cc *grpc.ClientConn, err error) {
194217 return c .cc , nil
195218}
196219
220+ func (c * conn ) touchLastUsage () {
221+ c .mtx .Lock ()
222+ defer c .mtx .Unlock ()
223+ c .lastUsage = time .Now ()
224+ }
225+
197226func (c * conn ) changeUsages (delta int32 ) int32 {
198- if usages := atomic .AddInt32 (& c .usages , delta ); usages < 0 {
227+ defer c .touchLastUsage ()
228+
229+ usages := atomic .AddInt32 (& c .usages , delta )
230+
231+ if usages < 0 {
199232 panic ("negative usages" + strconv .Itoa (int (usages )))
200- } else {
201- trace .DriverOnConnUsagesChange (
202- c .config .Trace (),
203- c .endpoint .Copy (),
204- int (usages ),
205- )
206- return usages
207233 }
208- }
209234
210- func (c * conn ) incUsages () {
211- c .Lock ()
212- defer c .Unlock ()
213- c .lastUsage = time .Now ()
214- c .changeUsages (1 )
235+ trace .DriverOnConnUsagesChange (
236+ c .config .Trace (),
237+ c .endpoint .Copy (),
238+ int (usages ),
239+ )
240+
241+ return usages
215242}
216243
217- func (c * conn ) decUsages () int32 {
218- c .Lock ()
219- defer c .Unlock ()
220- return c .changeUsages (- 1 )
244+ func (c * conn ) changeStreamUsages (delta int32 ) {
245+ defer c .touchLastUsage ()
246+
247+ usages := atomic .AddInt32 (& c .streamUsages , delta )
248+
249+ if usages < 0 {
250+ panic ("negative stream usages" + strconv .Itoa (int (usages )))
251+ }
252+
253+ trace .DriverOnConnStreamUsagesChange (
254+ c .config .Trace (),
255+ c .endpoint .Copy (),
256+ int (usages ),
257+ )
221258}
222259
223260func isBroken (raw * grpc.ClientConn ) bool {
@@ -240,14 +277,14 @@ func (c *conn) close() (err error) {
240277}
241278
242279func (c * conn ) isClosed () bool {
243- c .RLock ()
244- defer c .RUnlock ()
280+ c .mtx . RLock ()
281+ defer c .mtx . RUnlock ()
245282 return c .closed
246283}
247284
248285func (c * conn ) Close (ctx context.Context ) (err error ) {
249- c .Lock ()
250- defer c .Unlock ()
286+ c .mtx . Lock ()
287+ defer c .mtx . Unlock ()
251288
252289 if c .closed {
253290 return nil
@@ -292,8 +329,17 @@ func (c *conn) invoke(
292329 )
293330 }
294331
295- c .incUsages ()
296- defer c .decUsages ()
332+ ctx , err = c .config .Meta ().Meta (ctx )
333+ if err != nil {
334+ return errors .NewGrpcError (
335+ codes .Unavailable ,
336+ errors .WithMsg ("ydb driver conn apply meta failed" ),
337+ errors .WithErr (err ),
338+ )
339+ }
340+
341+ c .changeUsages (1 )
342+ defer c .changeUsages (- 1 )
297343
298344 return cc .Invoke (ctx , method , req , res , opts ... )
299345}
@@ -370,8 +416,17 @@ func (c *conn) newStream(
370416 )
371417 }
372418
373- c .incUsages ()
374- defer c .decUsages ()
419+ ctx , err = c .config .Meta ().Meta (ctx )
420+ if err != nil {
421+ return nil , errors .NewGrpcError (
422+ codes .Unavailable ,
423+ errors .WithMsg ("ydb driver conn apply meta failed" ),
424+ errors .WithErr (err ),
425+ )
426+ }
427+
428+ c .changeStreamUsages (1 )
429+ defer c .changeStreamUsages (- 1 )
375430
376431 return cc .NewStream (ctx , desc , method , opts ... )
377432}
0 commit comments