Skip to content

Commit d95f924

Browse files
committed
fix: parallel push causing InvalidOperationException (#452)
1 parent 8d81650 commit d95f924

1 file changed

Lines changed: 33 additions & 2 deletions

File tree

src/CommunityToolkit.Datasync.Client/Offline/OperationsQueue/OperationsQueueManager.cs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,13 @@ internal async Task<PushResult> PushAsync(IEnumerable<Type> entityTypes, PushOpt
397397
if (operation.Kind != OperationKind.Delete)
398398
{
399399
_ = response.ContentStream.Seek(0L, SeekOrigin.Begin); // Reset the memory stream to the beginning.
400-
object? newValue = JsonSerializer.Deserialize(response.ContentStream, entityType, DatasyncSerializer.JsonSerializerOptions);
401-
object? oldValue = await this._context.FindAsync(entityType, [operation.ItemId], cancellationToken).ConfigureAwait(false);
400+
object? newValue = await JsonSerializer.DeserializeAsync(
401+
response.ContentStream,
402+
entityType,
403+
DatasyncSerializer.JsonSerializerOptions,
404+
cancellationToken);
405+
406+
object? oldValue = await FindOldValue(operation, entityType, cancellationToken);
402407
ReplaceDatabaseValue(oldValue, newValue);
403408
}
404409

@@ -410,6 +415,32 @@ internal async Task<PushResult> PushAsync(IEnumerable<Type> entityTypes, PushOpt
410415
return null;
411416
}
412417

418+
/// <summary>
419+
/// Internal helper - find the old value for a datasync operation and an entity type.
420+
/// </summary>
421+
/// <param name="operation">The datasync operation.</param>
422+
/// <param name="entityType">The entity type.</param>
423+
/// <param name="cancellationToken">A <see cref="CancellationToken"/> to observe.</param>
424+
/// <returns>The object associated with the datasync operation, or <c>null</c>.</returns>
425+
internal async ValueTask<object?> FindOldValue(DatasyncOperation operation, Type entityType, CancellationToken cancellationToken)
426+
{
427+
this.pushlock.Enter();
428+
try
429+
{
430+
object? oldValue = await this._context
431+
.FindAsync(
432+
entityType,
433+
[operation.ItemId],
434+
cancellationToken)
435+
.ConfigureAwait(false);
436+
return oldValue;
437+
}
438+
finally
439+
{
440+
this.pushlock.Exit();
441+
}
442+
}
443+
413444
/// <summary>
414445
/// Internal helper - replaces an old value of an entity in the database with a new value.
415446
/// </summary>

0 commit comments

Comments
 (0)