Skip to content

Commit fb8feb5

Browse files
CopilotCritasWang
andcommitted
Fix client leak when query operations throw exceptions
- When putClientBack=false (query ops), return client if operation fails - Added operationSucceeded flag to track success/failure - Catch all exception types from Reconnect to prevent closed client return - Ensures clients are returned when SessionDataSet isn't created Co-authored-by: CritasWang <19721744+CritasWang@users.noreply.github.com>
1 parent acd1f4e commit fb8feb5

1 file changed

Lines changed: 25 additions & 3 deletions

File tree

src/Apache.IoTDB/SessionPool.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -158,9 +158,11 @@ public async Task<TResult> ExecuteClientOperationAsync<TResult>(AsyncOperation<T
158158
{
159159
Client client = _clients.Take();
160160
bool shouldReturnClient = true;
161+
bool operationSucceeded = false;
161162
try
162163
{
163164
var resp = await operation(client);
165+
operationSucceeded = true;
164166
return resp;
165167
}
166168
catch (TException ex)
@@ -170,14 +172,22 @@ public async Task<TResult> ExecuteClientOperationAsync<TResult>(AsyncOperation<T
170172
try
171173
{
172174
client = await Reconnect(client);
173-
return await operation(client);
175+
var resp = await operation(client);
176+
operationSucceeded = true;
177+
return resp;
174178
}
175179
catch (TException retryEx)
176180
{
177181
// Reconnection failed, client is closed and should not be returned to pool
178182
shouldReturnClient = false;
179183
throw new TException(errMsg, retryEx);
180184
}
185+
catch (Exception retryEx)
186+
{
187+
// Reconnection failed with non-TException, client is closed and should not be returned to pool
188+
shouldReturnClient = false;
189+
throw new TException(errMsg, retryEx);
190+
}
181191
}
182192
else
183193
{
@@ -191,14 +201,22 @@ public async Task<TResult> ExecuteClientOperationAsync<TResult>(AsyncOperation<T
191201
try
192202
{
193203
client = await Reconnect(client);
194-
return await operation(client);
204+
var resp = await operation(client);
205+
operationSucceeded = true;
206+
return resp;
195207
}
196208
catch (TException retryEx)
197209
{
198210
// Reconnection failed, client is closed and should not be returned to pool
199211
shouldReturnClient = false;
200212
throw new TException(errMsg, retryEx);
201213
}
214+
catch (Exception retryEx)
215+
{
216+
// Reconnection failed with non-TException, client is closed and should not be returned to pool
217+
shouldReturnClient = false;
218+
throw new TException(errMsg, retryEx);
219+
}
202220
}
203221
else
204222
{
@@ -207,7 +225,11 @@ public async Task<TResult> ExecuteClientOperationAsync<TResult>(AsyncOperation<T
207225
}
208226
finally
209227
{
210-
if (putClientBack && shouldReturnClient)
228+
// Return client to pool if:
229+
// 1. putClientBack is true (normal operations), OR
230+
// 2. putClientBack is false BUT operation failed (query operations where SessionDataSet wasn't created)
231+
// Do NOT return if reconnection failed (shouldReturnClient is false) because client was closed
232+
if (shouldReturnClient && (putClientBack || !operationSucceeded))
211233
{
212234
_clients.Add(client);
213235
}

0 commit comments

Comments
 (0)