public CreateEntityState( ICreatingApiClient <TModel> api, IBaseDataSource <TThreadsafeModel> dataSource, Func <TModel, TThreadsafeModel> convertToThreadsafeModel) : base(dataSource) { Ensure.Argument.IsNotNull(api, nameof(api)); Ensure.Argument.IsNotNull(convertToThreadsafeModel, nameof(convertToThreadsafeModel)); this.api = api; this.convertToThreadsafeModel = convertToThreadsafeModel; }
private static IStateResult configureCreateOnlyPush <TModel, TDatabase, TThreadsafe>( ITransitionConfigurator transitions, IStateResult entryPoint, IDataSource <TThreadsafe, TDatabase> dataSource, IAnalyticsService analyticsService, ICreatingApiClient <TModel> creatingApi, Func <TModel, TThreadsafe> toClean, Func <TThreadsafe, string, TThreadsafe> toUnsyncable, ITogglApi api, IScheduler scheduler, IObservable <Unit> delayCancellation) where TModel : IIdentifiable, ILastChangedDatable where TDatabase : class, TModel, IDatabaseSyncable where TThreadsafe : class, TDatabase, IThreadSafeModel { var rnd = new Random(); var apiDelay = new RetryDelayService(rnd); var statusDelay = new RetryDelayService(rnd); var push = new PushState <TDatabase, TThreadsafe>(dataSource); var pushOne = new PushOneEntityState <TThreadsafe>(); var create = new CreateEntityState <TModel, TDatabase, TThreadsafe>(creatingApi, dataSource, analyticsService, toClean); var tryResolveClientError = new TryResolveClientErrorState <TThreadsafe>(); var unsyncable = new UnsyncableEntityState <TThreadsafe>(dataSource, toUnsyncable); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); transitions.ConfigureTransition(entryPoint, push); transitions.ConfigureTransition(push.PushEntity, pushOne); transitions.ConfigureTransition(pushOne.CreateEntity, create); transitions.ConfigureTransition(pushOne.UpdateEntity, new InvalidTransitionState($"Updating is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(pushOne.DeleteEntity, new InvalidTransitionState($"Deleting is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(pushOne.DeleteEntityLocally, new InvalidTransitionState($"Deleting locally is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(create.ClientError, tryResolveClientError); transitions.ConfigureTransition(create.ServerError, checkServerStatus); transitions.ConfigureTransition(create.UnknownError, checkServerStatus); transitions.ConfigureTransition(tryResolveClientError.UnresolvedTooManyRequests, checkServerStatus); transitions.ConfigureTransition(tryResolveClientError.Unresolved, unsyncable); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, push); transitions.ConfigureTransition(create.EntityChanged, create); transitions.ConfigureTransition(create.Finished, finished); transitions.ConfigureTransition(finished.Continue, push); return(push.NothingToPush); }
public CreateEntityState( ICreatingApiClient <TModel> api, IDataSource <TThreadsafeModel, TDatabaseModel> dataSource, IAnalyticsService analyticsService, Func <TModel, TThreadsafeModel> convertToThreadsafeModel) : base(analyticsService) { Ensure.Argument.IsNotNull(api, nameof(api)); Ensure.Argument.IsNotNull(convertToThreadsafeModel, nameof(convertToThreadsafeModel)); Ensure.Argument.IsNotNull(analyticsService, nameof(analyticsService)); Ensure.Argument.IsNotNull(dataSource, nameof(dataSource)); this.api = api; this.convertToThreadsafeModel = convertToThreadsafeModel; this.dataSource = dataSource; }
private static LookForChangeToPushState <TDatabase, TThreadsafe> configureCreateOnlyPush <TModel, TDatabase, TThreadsafe>( ITransitionConfigurator transitions, IStateResult entryPoint, IDataSource <TThreadsafe, TDatabase> dataSource, IAnalyticsService analyticsService, ICreatingApiClient <TModel> creatingApi, ILeakyBucket minutesLeakyBucket, IRateLimiter rateLimiter, WaitForAWhileState waitForAWhileState, Func <TModel, TThreadsafe> toClean, Func <TThreadsafe, string, TThreadsafe> toUnsyncable) where TModel : IIdentifiable, ILastChangedDatable where TDatabase : class, TModel, IDatabaseSyncable where TThreadsafe : class, TDatabase, IThreadSafeModel { var lookForChange = new LookForChangeToPushState <TDatabase, TThreadsafe>(dataSource); var chooseOperation = new ChooseSyncOperationState <TThreadsafe>(); var create = new CreateEntityState <TModel, TDatabase, TThreadsafe>(creatingApi, dataSource, analyticsService, minutesLeakyBucket, rateLimiter, toClean); var processClientError = new ProcessClientErrorState <TThreadsafe>(); var unsyncable = new MarkEntityAsUnsyncableState <TThreadsafe>(dataSource, toUnsyncable); transitions.ConfigureTransition(entryPoint, lookForChange); transitions.ConfigureTransition(lookForChange.ChangeFound, chooseOperation); transitions.ConfigureTransition(chooseOperation.CreateEntity, create); transitions.ConfigureTransition(chooseOperation.UpdateEntity, new InvalidTransitionState($"Updating is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(chooseOperation.DeleteEntity, new InvalidTransitionState($"Deleting is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(chooseOperation.DeleteEntityLocally, new InvalidTransitionState($"Deleting locally is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(create.ClientError, processClientError); transitions.ConfigureTransition(create.ServerError, new FailureState()); transitions.ConfigureTransition(create.UnknownError, new FailureState()); transitions.ConfigureTransition(create.PreventOverloadingServer, waitForAWhileState); transitions.ConfigureTransition(processClientError.UnresolvedTooManyRequests, new FailureState()); transitions.ConfigureTransition(processClientError.Unresolved, unsyncable); transitions.ConfigureTransition(create.EntityChanged, new InvalidTransitionState($"Entity cannot have changed since updating is not supported for {typeof(TModel).Name} during Push sync.")); transitions.ConfigureTransition(create.Done, lookForChange); transitions.ConfigureTransition(unsyncable.Done, lookForChange); return(lookForChange); }
public CreateEntityState( ICreatingApiClient <TModel> api, IDataSource <TThreadsafeModel, TDatabaseModel> dataSource, IAnalyticsService analyticsService, ILeakyBucket leakyBucket, IRateLimiter limiter, Func <TModel, TThreadsafeModel> convertToThreadsafeModel) : base(analyticsService) { Ensure.Argument.IsNotNull(api, nameof(api)); Ensure.Argument.IsNotNull(convertToThreadsafeModel, nameof(convertToThreadsafeModel)); Ensure.Argument.IsNotNull(leakyBucket, nameof(leakyBucket)); Ensure.Argument.IsNotNull(limiter, nameof(limiter)); Ensure.Argument.IsNotNull(dataSource, nameof(dataSource)); this.api = api; this.convertToThreadsafeModel = convertToThreadsafeModel; this.dataSource = dataSource; this.leakyBucket = leakyBucket; this.limiter = limiter; }
private CreateEntityStateTests(IBaseDataSource <IThreadSafeTestModel> dataSource) { api = Substitute.For <ICreatingApiClient <ITestModel> >(); this.dataSource = dataSource; }
private static IStateResult configurePush <TModel, TDatabase, TThreadsafe>( TransitionHandlerProvider transitions, IStateResult entryPoint, IDataSource <TThreadsafe, TDatabase> dataSource, ICreatingApiClient <TModel> creatingApi, IUpdatingApiClient <TModel> updatingApi, IDeletingApiClient <TModel> deletingApi, Func <TModel, TThreadsafe> toClean, Func <TThreadsafe, string, TThreadsafe> toUnsyncable, ITogglApi api, IRetryDelayService apiDelay, IScheduler scheduler, IObservable <Unit> delayCancellation) where TModel : class, IIdentifiable, ILastChangedDatable where TDatabase : class, TModel, IDatabaseSyncable where TThreadsafe : class, TDatabase, IThreadSafeModel { var rnd = new Random(); var statusDelay = new RetryDelayService(rnd); var push = new PushState <TDatabase, TThreadsafe>(dataSource); var pushOne = new PushOneEntityState <TThreadsafe>(); var create = new CreateEntityState <TModel, TThreadsafe>(creatingApi, dataSource, toClean); var update = new UpdateEntityState <TModel, TThreadsafe>(updatingApi, dataSource, toClean); var delete = new DeleteEntityState <TModel, TDatabase, TThreadsafe>(deletingApi, dataSource); var deleteLocal = new DeleteLocalEntityState <TDatabase, TThreadsafe>(dataSource); var tryResolveClientError = new TryResolveClientErrorState <TThreadsafe>(); var unsyncable = new UnsyncableEntityState <TThreadsafe>(dataSource, toUnsyncable); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); transitions.ConfigureTransition(entryPoint, push); transitions.ConfigureTransition(push.PushEntity, pushOne); transitions.ConfigureTransition(pushOne.CreateEntity, create); transitions.ConfigureTransition(pushOne.UpdateEntity, update); transitions.ConfigureTransition(pushOne.DeleteEntity, delete); transitions.ConfigureTransition(pushOne.DeleteEntityLocally, deleteLocal); transitions.ConfigureTransition(create.ClientError, tryResolveClientError); transitions.ConfigureTransition(update.ClientError, tryResolveClientError); transitions.ConfigureTransition(delete.ClientError, tryResolveClientError); transitions.ConfigureTransition(create.ServerError, checkServerStatus); transitions.ConfigureTransition(update.ServerError, checkServerStatus); transitions.ConfigureTransition(delete.ServerError, checkServerStatus); transitions.ConfigureTransition(create.UnknownError, checkServerStatus); transitions.ConfigureTransition(update.UnknownError, checkServerStatus); transitions.ConfigureTransition(delete.UnknownError, checkServerStatus); transitions.ConfigureTransition(tryResolveClientError.UnresolvedTooManyRequests, checkServerStatus); transitions.ConfigureTransition(tryResolveClientError.Unresolved, unsyncable); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, push); transitions.ConfigureTransition(create.CreatingFinished, finished); transitions.ConfigureTransition(update.UpdatingSucceeded, finished); transitions.ConfigureTransition(delete.DeletingFinished, finished); transitions.ConfigureTransition(deleteLocal.Deleted, finished); transitions.ConfigureTransition(deleteLocal.DeletingFailed, finished); transitions.ConfigureTransition(finished.Continue, push); return(push.NothingToPush); }