Skip to content

Commit b155938

Browse files
authored
chore: edge cases from cursor bugbot review (#210)
Adds fix for a dispose race condition and exception from start (unlikely given current code, but defensive against future changes). Ignore whitespace is your friend for this PR. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > <sup>[Cursor Bugbot](https://cursor.com/dashboard?tab=bugbot) is generating a summary for commit 6de3936. Configure [here](https://cursor.com/dashboard?tab=bugbot).</sup> <!-- /CURSOR_SUMMARY -->
1 parent 42abb30 commit b155938

File tree

1 file changed

+40
-22
lines changed

1 file changed

+40
-22
lines changed

pkgs/sdk/server/src/Internal/DataSources/CompositeDataSource/CompositeSource.cs

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -247,34 +247,52 @@ public Task<bool> StartCurrent()
247247

248248
EnqueueAction(() =>
249249
{
250-
IDataSource dataSourceToStart;
251-
lock (_lock)
252-
{
253-
TryFindNextUnderLock();
254-
dataSourceToStart = _currentDataSource;
255-
}
256-
257-
if (dataSourceToStart is null)
250+
try
258251
{
259-
// No sources available.
260-
tcs.SetResult(false);
261-
return;
262-
}
252+
IDataSource dataSourceToStart;
253+
bool disposed;
254+
lock (_lock)
255+
{
256+
TryFindNextUnderLock();
257+
dataSourceToStart = _currentDataSource;
258+
disposed = _disposed;
259+
}
263260

264-
// Start the source asynchronously and complete the task when it finishes.
265-
// We do this outside the lock to avoid blocking the queue.
266-
_ = Task.Run(async () =>
267-
{
268-
try
261+
if (disposed)
269262
{
270-
var result = await dataSourceToStart.Start().ConfigureAwait(false);
271-
tcs.TrySetResult(result);
263+
// Disposed while getting the data source.
264+
tcs.SetResult(false);
265+
return;
272266
}
273-
catch (Exception ex)
267+
268+
if (dataSourceToStart is null)
274269
{
275-
tcs.TrySetException(ex);
270+
// No sources available.
271+
tcs.SetResult(false);
272+
return;
276273
}
277-
});
274+
275+
// Start the source asynchronously and complete the task when it finishes.
276+
// We do this outside the lock to avoid blocking the queue.
277+
_ = Task.Run(async () =>
278+
{
279+
try
280+
{
281+
var result = await dataSourceToStart.Start().ConfigureAwait(false);
282+
tcs.TrySetResult(result);
283+
}
284+
catch (Exception ex)
285+
{
286+
tcs.TrySetException(ex);
287+
}
288+
});
289+
}
290+
catch (Exception ex)
291+
{
292+
// If an exception occurs while finding or setting up the data source,
293+
// ensure the task is completed so callers don't wait indefinitely.
294+
tcs.TrySetException(ex);
295+
}
278296
});
279297

280298
return tcs.Task;

0 commit comments

Comments
 (0)