88using CommunityToolkit . Datasync . Client . Threading ;
99using Microsoft . EntityFrameworkCore ;
1010using Microsoft . EntityFrameworkCore . ChangeTracking ;
11+ using System . Net ;
1112using System . Reflection ;
1213using System . Text . Json ;
1314
@@ -77,7 +78,7 @@ internal List<EntityEntry> GetChangedEntitiesInScope()
7778 /// </summary>
7879 /// <remarks>
7980 /// An entity is "synchronization ready" if:
80- ///
81+ ///
8182 /// * It is a property on this context
8283 /// * The property is public and a <see cref="DbSet{TEntity}"/>.
8384 /// * The property does not have a <see cref="DoNotSynchronizeAttribute"/> specified.
@@ -215,7 +216,7 @@ internal IEnumerable<Type> GetSynchronizableEntityTypes(IEnumerable<Type> allowe
215216 /// </summary>
216217 /// <remarks>
217218 /// An entity is "synchronization ready" if:
218- ///
219+ ///
219220 /// * It is a property on this context
220221 /// * The property is public and a <see cref="DbSet{TEntity}"/>.
221222 /// * The property does not have a <see cref="DoNotSynchronizeAttribute"/> specified.
@@ -299,30 +300,40 @@ internal async Task<PushResult> PushAsync(IEnumerable<Type> entityTypes, PushOpt
299300 ExecutableOperation op = await ExecutableOperation . CreateAsync ( operation , cancellationToken ) . ConfigureAwait ( false ) ;
300301 ServiceResponse response = await op . ExecuteAsync ( options , cancellationToken ) . ConfigureAwait ( false ) ;
301302
303+ bool isSuccessful = response . IsSuccessful ;
302304 if ( response . IsConflictStatusCode && options . ConflictResolver is not null )
303305 {
304306 object ? serverEntity = JsonSerializer . Deserialize ( response . ContentStream , entityType , DatasyncSerializer . JsonSerializerOptions ) ;
305307 object ? clientEntity = JsonSerializer . Deserialize ( operation . Item , entityType , DatasyncSerializer . JsonSerializerOptions ) ;
306- object ? resolvedEntity = await options . ConflictResolver . ResolveConflictAsync ( clientEntity , serverEntity , cancellationToken ) . ConfigureAwait ( false ) ;
307- if ( resolvedEntity is not null )
308+ ConflictResolution resolution = await options . ConflictResolver . ResolveConflictAsync ( clientEntity , serverEntity , cancellationToken ) . ConfigureAwait ( false ) ;
309+
310+ if ( resolution . Result is ConflictResolutionResult . Client )
311+ {
312+ operation . Item = JsonSerializer . Serialize ( resolution . Entity , entityType , DatasyncSerializer . JsonSerializerOptions ) ;
313+ operation . State = OperationState . Pending ;
314+ operation . LastAttempt = DateTimeOffset . UtcNow ;
315+ operation . HttpStatusCode = response . StatusCode ;
316+ operation . EntityVersion = string . Empty ; // Force the push
317+ operation . Version ++ ;
318+ _ = this . _context . Update ( operation ) ;
319+ ExecutableOperation resolvedOp = await ExecutableOperation . CreateAsync ( operation , cancellationToken ) . ConfigureAwait ( false ) ;
320+ response = await resolvedOp . ExecuteAsync ( options , cancellationToken ) . ConfigureAwait ( false ) ;
321+ isSuccessful = response . IsSuccessful ;
322+ }
323+ else if ( resolution . Result is ConflictResolutionResult . Server )
308324 {
309325 lock ( this . pushlock )
310326 {
311- operation . Item = JsonSerializer . Serialize ( resolvedEntity , entityType , DatasyncSerializer . JsonSerializerOptions ) ;
312- operation . State = OperationState . Pending ;
327+ operation . State = OperationState . Completed ; // Make it successful
313328 operation . LastAttempt = DateTimeOffset . UtcNow ;
314- operation . HttpStatusCode = response . StatusCode ;
315- operation . EntityVersion = string . Empty ; // Force the push
316- operation . Version ++ ;
329+ operation . HttpStatusCode = 200 ;
330+ isSuccessful = true ;
317331 _ = this . _context . Update ( operation ) ;
318332 }
319-
320- ExecutableOperation resolveOperation = await ExecutableOperation . CreateAsync ( operation , cancellationToken ) . ConfigureAwait ( false ) ;
321- response = await resolveOperation . ExecuteAsync ( options , cancellationToken ) . ConfigureAwait ( false ) ;
322333 }
323334 }
324335
325- if ( ! response . IsSuccessful )
336+ if ( ! isSuccessful )
326337 {
327338 lock ( this . pushlock )
328339 {
@@ -338,6 +349,7 @@ internal async Task<PushResult> PushAsync(IEnumerable<Type> entityTypes, PushOpt
338349 // If the operation is a success, then the content may need to be updated.
339350 if ( operation . Kind != OperationKind . Delete )
340351 {
352+ _ = response . ContentStream . Seek ( 0L , SeekOrigin . Begin ) ; // Reset the memory stream to the beginning.
341353 object ? newValue = JsonSerializer . Deserialize ( response . ContentStream , entityType , DatasyncSerializer . JsonSerializerOptions ) ;
342354 object ? oldValue = await this . _context . FindAsync ( entityType , [ operation . ItemId ] , cancellationToken ) . ConfigureAwait ( false ) ;
343355 ReplaceDatabaseValue ( oldValue , newValue ) ;
0 commit comments