private static IStateResult configurePushTransitionsForTimeEntries( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, IScheduler scheduler, IStateResult entryPoint, IObservable <Unit> delayCancellation) { var rnd = new Random(); var apiDelay = new RetryDelayService(rnd); var statusDelay = new RetryDelayService(rnd); var push = new PushTimeEntriesState(database.TimeEntries); var pushOne = new PushOneEntityState <IDatabaseTimeEntry>(); var create = new CreateTimeEntryState(api, dataSource.TimeEntries); var update = new UpdateTimeEntryState(api, dataSource.TimeEntries); var delete = new DeleteTimeEntryState(api, database.TimeEntries); var deleteLocal = new DeleteLocalTimeEntryState(database.TimeEntries); var unsyncable = new UnsyncableTimeEntryState(dataSource.TimeEntries); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); return(configurePush(transitions, entryPoint, push, pushOne, create, update, delete, deleteLocal, unsyncable, checkServerStatus, finished)); }
private static void configurePullTransitions( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, ITimeService timeService, StateResult entryPoint) { var fetchAllSince = new FetchAllSinceState(database, api, timeService); var persistWorkspaces = new PersistWorkspacesState(database.Workspaces, database.SinceParameters); var persistWorkspaceFeatures = new PersistWorkspacesFeaturesState(database.WorkspaceFeatures, database.SinceParameters); var persistTags = new PersistTagsState(database.Tags, database.SinceParameters); var persistClients = new PersistClientsState(database.Clients, database.SinceParameters); var persistProjects = new PersistProjectsState(database.Projects, database.SinceParameters); var persistTimeEntries = new PersistTimeEntriesState(dataSource.TimeEntries, database.SinceParameters, timeService); var persistTasks = new PersistTasksState(database.Tasks, database.SinceParameters); transitions.ConfigureTransition(entryPoint, fetchAllSince.Start); transitions.ConfigureTransition(fetchAllSince.FetchStarted, persistWorkspaces.Start); transitions.ConfigureTransition(persistWorkspaces.FinishedPersisting, persistWorkspaceFeatures.Start); transitions.ConfigureTransition(persistWorkspaceFeatures.FinishedPersisting, persistTags.Start); transitions.ConfigureTransition(persistTags.FinishedPersisting, persistClients.Start); transitions.ConfigureTransition(persistClients.FinishedPersisting, persistProjects.Start); transitions.ConfigureTransition(persistProjects.FinishedPersisting, persistTasks.Start); transitions.ConfigureTransition(persistTasks.FinishedPersisting, persistTimeEntries.Start); }
private static IStateResult configureUpdateOnlyPush <T>( TransitionHandlerProvider transitions, IStateResult entryPoint, BasePushState <T> push, PushOneEntityState <T> pushOne, BaseUpdateEntityState <T> update, BaseUnsyncableEntityState <T> markUnsyncable, CheckServerStatusState checkServerStatus, ResetAPIDelayState finished) where T : class, IBaseModel, IDatabaseSyncable { transitions.ConfigureTransition(entryPoint, push.Start); transitions.ConfigureTransition(push.PushEntity, pushOne.Start); transitions.ConfigureTransition(pushOne.UpdateEntity, update.Start); transitions.ConfigureTransition(pushOne.CreateEntity, new InvalidTransitionState($"Creating is not supported for {typeof(T).Name} during Push sync.").Start); transitions.ConfigureTransition(pushOne.DeleteEntity, new InvalidTransitionState($"Deleting is not supported for {typeof(T).Name} during Push sync.").Start); transitions.ConfigureTransition(pushOne.DeleteEntityLocally, new InvalidTransitionState($"Deleting locally is not supported for {typeof(T).Name} during Push sync.").Start); transitions.ConfigureTransition(update.ClientError, markUnsyncable.Start); transitions.ConfigureTransition(update.ServerError, checkServerStatus.Start); transitions.ConfigureTransition(update.UnknownError, checkServerStatus.Start); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus.Start); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, push.Start); transitions.ConfigureTransition(update.UpdatingSucceeded, finished.Start); transitions.ConfigureTransition(finished.PushNext, push.Start); return(push.NothingToPush); }
protected void Reset() { Queue = new SyncStateQueue(); Transitions = new TransitionHandlerProvider(); Scheduler = new TestScheduler(); StateMachine = new StateMachine(Transitions, Scheduler, Substitute.For <ISubject <Unit> >()); EntryPoints = new StateMachineEntryPoints(); Orchestrator = new StateMachineOrchestrator(StateMachine, EntryPoints); SyncManager = new SyncManager(Queue, Orchestrator); }
private static void configurePushTransitions( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, IScheduler scheduler, StateResult entryPoint) { configurePushTransitionsForTimeEntries(transitions, database, api, dataSource, scheduler, entryPoint); }
public static void ConfigureTransitions( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, IScheduler scheduler, ITimeService timeService, StateMachineEntryPoints entryPoints) { configurePullTransitions(transitions, database, api, dataSource, timeService, entryPoints.StartPullSync); configurePushTransitions(transitions, database, api, dataSource, scheduler, entryPoints.StartPushSync); }
private static void configurePullTransitions( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, ITimeService timeService, IScheduler scheduler, StateResult entryPoint, IObservable <Unit> delayCancellation) { var rnd = new Random(); var apiDelay = new RetryDelayService(rnd); var statusDelay = new RetryDelayService(rnd); var fetchAllSince = new FetchAllSinceState(database, api, timeService); var persistWorkspaces = new PersistWorkspacesState(database.Workspaces, database.SinceParameters); var persistWorkspaceFeatures = new PersistWorkspacesFeaturesState(database.WorkspaceFeatures, database.SinceParameters); var persistUser = new PersistUserState(database.User, database.SinceParameters); var persistTags = new PersistTagsState(database.Tags, database.SinceParameters); var persistClients = new PersistClientsState(database.Clients, database.SinceParameters); var persistPreferences = new PersistPreferencesState(dataSource.Preferences, database.SinceParameters); var persistProjects = new PersistProjectsState(database.Projects, database.SinceParameters); var persistTimeEntries = new PersistTimeEntriesState(dataSource.TimeEntries, database.SinceParameters, timeService); var persistTasks = new PersistTasksState(database.Tasks, database.SinceParameters); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); transitions.ConfigureTransition(entryPoint, fetchAllSince.Start); transitions.ConfigureTransition(fetchAllSince.FetchStarted, persistWorkspaces.Start); transitions.ConfigureTransition(persistWorkspaces.FinishedPersisting, persistUser.Start); transitions.ConfigureTransition(persistUser.FinishedPersisting, persistWorkspaceFeatures.Start); transitions.ConfigureTransition(persistWorkspaceFeatures.FinishedPersisting, persistPreferences.Start); transitions.ConfigureTransition(persistPreferences.FinishedPersisting, persistTags.Start); transitions.ConfigureTransition(persistTags.FinishedPersisting, persistClients.Start); transitions.ConfigureTransition(persistClients.FinishedPersisting, persistProjects.Start); transitions.ConfigureTransition(persistProjects.FinishedPersisting, persistTasks.Start); transitions.ConfigureTransition(persistTasks.FinishedPersisting, persistTimeEntries.Start); transitions.ConfigureTransition(persistWorkspaces.Failed, checkServerStatus.Start); transitions.ConfigureTransition(persistWorkspaceFeatures.Failed, checkServerStatus.Start); transitions.ConfigureTransition(persistPreferences.Failed, checkServerStatus.Start); transitions.ConfigureTransition(persistTags.Failed, checkServerStatus.Start); transitions.ConfigureTransition(persistClients.Failed, checkServerStatus.Start); transitions.ConfigureTransition(persistProjects.Failed, checkServerStatus.Start); transitions.ConfigureTransition(persistTasks.Failed, checkServerStatus.Start); transitions.ConfigureTransition(persistTimeEntries.Failed, checkServerStatus.Start); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus.Start); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, finished.Start); transitions.ConfigureTransition(finished.Continue, fetchAllSince.Start); }
private static IStateResult configurePush <T>( TransitionHandlerProvider transitions, IStateResult entryPoint, BasePushState <T> push, PushOneEntityState <T> pushOne, BaseCreateEntityState <T> create, BaseUpdateEntityState <T> update, BaseDeleteEntityState <T> delete, BaseDeleteLocalEntityState <T> deleteLocal, TryResolveClientErrorState <T> tryResolveClientError, BaseUnsyncableEntityState <T> markUnsyncable, CheckServerStatusState checkServerStatus, ResetAPIDelayState finished) where T : class, IBaseModel, IDatabaseSyncable { transitions.ConfigureTransition(entryPoint, push.Start); transitions.ConfigureTransition(push.PushEntity, pushOne.Start); transitions.ConfigureTransition(pushOne.CreateEntity, create.Start); transitions.ConfigureTransition(pushOne.UpdateEntity, update.Start); transitions.ConfigureTransition(pushOne.DeleteEntity, delete.Start); transitions.ConfigureTransition(pushOne.DeleteEntityLocally, deleteLocal.Start); transitions.ConfigureTransition(create.ClientError, tryResolveClientError.Start); transitions.ConfigureTransition(update.ClientError, tryResolveClientError.Start); transitions.ConfigureTransition(delete.ClientError, tryResolveClientError.Start); transitions.ConfigureTransition(create.ServerError, checkServerStatus.Start); transitions.ConfigureTransition(update.ServerError, checkServerStatus.Start); transitions.ConfigureTransition(delete.ServerError, checkServerStatus.Start); transitions.ConfigureTransition(create.UnknownError, checkServerStatus.Start); transitions.ConfigureTransition(update.UnknownError, checkServerStatus.Start); transitions.ConfigureTransition(delete.UnknownError, checkServerStatus.Start); transitions.ConfigureTransition(tryResolveClientError.UnresolvedTooManyRequests, checkServerStatus.Start); transitions.ConfigureTransition(tryResolveClientError.Unresolved, markUnsyncable.Start); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus.Start); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, push.Start); transitions.ConfigureTransition(create.CreatingFinished, finished.Start); transitions.ConfigureTransition(update.UpdatingSucceeded, finished.Start); transitions.ConfigureTransition(delete.DeletingFinished, finished.Start); transitions.ConfigureTransition(deleteLocal.Deleted, finished.Start); transitions.ConfigureTransition(deleteLocal.DeletingFailed, finished.Start); transitions.ConfigureTransition(finished.Continue, push.Start); return(push.NothingToPush); }
private static IStateResult configureCreateOnlyPush <TModel, TDatabase, TThreadsafe>( TransitionHandlerProvider transitions, IStateResult entryPoint, IDataSource <TThreadsafe, TDatabase> dataSource, 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, TThreadsafe>(creatingApi, dataSource, 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.CreatingFinished, finished); transitions.ConfigureTransition(finished.Continue, push); return(push.NothingToPush); }
public static void ConfigureTransitions( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, IRetryDelayService apiDelay, IScheduler scheduler, ITimeService timeService, StateMachineEntryPoints entryPoints, IObservable <Unit> delayCancellation) { configurePullTransitions(transitions, database, api, dataSource, timeService, scheduler, entryPoints.StartPullSync, delayCancellation); configurePushTransitions(transitions, database, api, dataSource, apiDelay, scheduler, entryPoints.StartPushSync, delayCancellation); }
protected void Reset() { var analyticsService = Substitute.For <IAnalyticsService>(); var lastTimeUsageStorage = Substitute.For <ILastTimeUsageStorage>(); var timeService = Substitute.For <ITimeService>(); Queue = new SyncStateQueue(); Transitions = new TransitionHandlerProvider(); Scheduler = new TestScheduler(); StateMachine = new StateMachine(Transitions, Scheduler, Substitute.For <ISubject <Unit> >()); EntryPoints = new StateMachineEntryPoints(); Orchestrator = new StateMachineOrchestrator(StateMachine, EntryPoints); SyncManager = new SyncManager(Queue, Orchestrator, analyticsService, lastTimeUsageStorage, timeService); }
private static void configurePushTransitions( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, IScheduler scheduler, StateResult entryPoint, IObservable <Unit> delayCancellation) { var pushingUsersFinished = configurePushTransitionsForUsers(transitions, database, api, scheduler, entryPoint, delayCancellation); var pushingTagsFinished = configurePushTransitionsForTags(transitions, database, api, scheduler, pushingUsersFinished, delayCancellation); var pushingClientsFinished = configurePushTransitionsForClients(transitions, database, api, scheduler, pushingTagsFinished, delayCancellation); var pushingProjectsFinished = configurePushTransitionsForProjects(transitions, database, api, scheduler, pushingClientsFinished, delayCancellation); configurePushTransitionsForTimeEntries(transitions, database, api, dataSource, scheduler, pushingProjectsFinished, delayCancellation); }
private static void configurePushTransitions( TransitionHandlerProvider transitions, ITogglApi api, ITogglDataSource dataSource, IRetryDelayService apiDelay, IScheduler scheduler, StateResult entryPoint, IObservable <Unit> delayCancellation) { var pushingUsersFinished = configurePushSingleton(transitions, entryPoint, dataSource.User, api.User, User.Clean, User.Unsyncable, api, scheduler, delayCancellation); var pushingPreferencesFinished = configurePushSingleton(transitions, pushingUsersFinished, dataSource.Preferences, api.Preferences, Preferences.Clean, Preferences.Unsyncable, api, scheduler, delayCancellation); var pushingTagsFinished = configureCreateOnlyPush(transitions, pushingPreferencesFinished, dataSource.Tags, api.Tags, Tag.Clean, Tag.Unsyncable, api, scheduler, delayCancellation); var pushingClientsFinished = configureCreateOnlyPush(transitions, pushingTagsFinished, dataSource.Clients, api.Clients, Client.Clean, Client.Unsyncable, api, scheduler, delayCancellation); var pushingProjectsFinished = configureCreateOnlyPush(transitions, pushingClientsFinished, dataSource.Projects, api.Projects, Project.Clean, Project.Unsyncable, api, scheduler, delayCancellation); configurePush(transitions, pushingProjectsFinished, dataSource.TimeEntries, api.TimeEntries, api.TimeEntries, api.TimeEntries, TimeEntry.Clean, TimeEntry.Unsyncable, api, apiDelay, scheduler, delayCancellation); }
public static ISyncManager CreateSyncManager( ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, ITimeService timeService, IScheduler scheduler) { var queue = new SyncStateQueue(); var entryPoints = new StateMachineEntryPoints(); var transitions = new TransitionHandlerProvider(); ConfigureTransitions(transitions, database, api, dataSource, scheduler, timeService, entryPoints); var stateMachine = new StateMachine(transitions, scheduler); var orchestrator = new StateMachineOrchestrator(stateMachine, entryPoints); return(new SyncManager(queue, orchestrator)); }
public static ISyncManager CreateSyncManager( ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, ITimeService timeService, IScheduler scheduler) { var queue = new SyncStateQueue(); var entryPoints = new StateMachineEntryPoints(); var transitions = new TransitionHandlerProvider(); var delayCancellation = new Subject <Unit>(); var delayCancellationObservable = delayCancellation.AsObservable().Replay(); ConfigureTransitions(transitions, database, api, dataSource, scheduler, timeService, entryPoints, delayCancellationObservable); var stateMachine = new StateMachine(transitions, scheduler, delayCancellation); var orchestrator = new StateMachineOrchestrator(stateMachine, entryPoints); return(new SyncManager(queue, orchestrator)); }
public static ISyncManager CreateSyncManager( ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, ITimeService timeService, IAnalyticsService analyticsService, ILastTimeUsageStorage lastTimeUsageStorage, IScheduler scheduler, IAutomaticSyncingService automaticSyncingService) { var queue = new SyncStateQueue(); var entryPoints = new StateMachineEntryPoints(); var transitions = new TransitionHandlerProvider(analyticsService); ConfigureTransitions(transitions, database, api, dataSource, scheduler, timeService, analyticsService, lastTimeUsageStorage, entryPoints, queue); var stateMachine = new StateMachine(transitions, scheduler); var orchestrator = new StateMachineOrchestrator(stateMachine, entryPoints); return(new SyncManager(queue, orchestrator, analyticsService, lastTimeUsageStorage, timeService, automaticSyncingService)); }
private static IStateResult configurePushTransitionsForProjects( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, IScheduler scheduler, IStateResult entryPoint, IObservable <Unit> delayCancellation) { var rnd = new Random(); var apiDelay = new RetryDelayService(rnd); var statusDelay = new RetryDelayService(rnd); var push = new PushProjectsState(database.Projects); var pushOne = new PushOneEntityState <IDatabaseProject>(); var create = new CreateProjectState(api, database.Projects); var unsyncable = new UnsyncableProjectState(database.Projects); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); return(configureCreateOnlyPush(transitions, entryPoint, push, pushOne, create, unsyncable, checkServerStatus, finished)); }
private static IStateResult configurePushTransitionsForUsers( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, IScheduler scheduler, IStateResult entryPoint, IObservable <Unit> delayCancellation) { var rnd = new Random(); var apiDelay = new RetryDelayService(rnd); var statusDelay = new RetryDelayService(rnd); var push = new PushUsersState(database.User); var pushOne = new PushOneEntityState <IDatabaseUser>(); var update = new UpdateUserState(api, database.User); var tryResolveClientError = new TryResolveClientErrorState <IDatabaseUser>(); var unsyncable = new UnsyncableUserState(database.User); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); return(configureUpdateOnlyPush(transitions, entryPoint, push, pushOne, update, tryResolveClientError, unsyncable, checkServerStatus, finished)); }
public static ISyncManager CreateSyncManager( ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, ITimeService timeService, IAnalyticsService analyticsService, ILastTimeUsageStorage lastTimeUsageStorage, TimeSpan?retryLimit, IScheduler scheduler) { var random = new Random(); var queue = new SyncStateQueue(); var entryPoints = new StateMachineEntryPoints(); var transitions = new TransitionHandlerProvider(); var apiDelay = new RetryDelayService(random, retryLimit); var delayCancellation = new Subject <Unit>(); var delayCancellationObservable = delayCancellation.AsObservable().Replay(); ConfigureTransitions(transitions, database, api, dataSource, apiDelay, scheduler, timeService, analyticsService, entryPoints, delayCancellationObservable); var stateMachine = new StateMachine(transitions, scheduler, delayCancellation); var orchestrator = new StateMachineOrchestrator(stateMachine, entryPoints); return(new SyncManager(queue, orchestrator, analyticsService, lastTimeUsageStorage, timeService)); }
private static void configurePullTransitions( TransitionHandlerProvider transitions, ITogglDatabase database, ITogglApi api, ITogglDataSource dataSource, ITimeService timeService, IAnalyticsService analyticsService, IScheduler scheduler, StateResult entryPoint, IObservable <Unit> delayCancellation) { var rnd = new Random(); var apiDelay = new RetryDelayService(rnd); var statusDelay = new RetryDelayService(rnd); var fetchAllSince = new FetchAllSinceState(database, api, timeService); var persistWorkspaces = new PersistListState <IWorkspace, IDatabaseWorkspace, IThreadSafeWorkspace>(dataSource.Workspaces, Workspace.Clean) .UpdateSince <IWorkspace, IDatabaseWorkspace>(database.SinceParameters) .ThrowNoWorkspaceExceptionIfNeeded() .CatchApiExceptions(); var persistWorkspaceFeatures = new PersistListState <IWorkspaceFeatureCollection, IDatabaseWorkspaceFeatureCollection, IThreadSafeWorkspaceFeatureCollection>( dataSource.WorkspaceFeatures, WorkspaceFeatureCollection.From) .CatchApiExceptions(); var persistUser = new PersistSingletonState <IUser, IDatabaseUser, IThreadSafeUser>(dataSource.User, User.Clean) .CatchApiExceptions(); var persistTags = new PersistListState <ITag, IDatabaseTag, IThreadSafeTag>(dataSource.Tags, Tag.Clean) .UpdateSince <ITag, IDatabaseTag>(database.SinceParameters) .CatchApiExceptions(); var persistClients = new PersistListState <IClient, IDatabaseClient, IThreadSafeClient>(dataSource.Clients, Client.Clean) .UpdateSince <IClient, IDatabaseClient>(database.SinceParameters) .CatchApiExceptions(); var persistPreferences = new PersistSingletonState <IPreferences, IDatabasePreferences, IThreadSafePreferences>(dataSource.Preferences, Preferences.Clean) .CatchApiExceptions(); var persistProjects = new PersistListState <IProject, IDatabaseProject, IThreadSafeProject>(dataSource.Projects, Project.Clean) .UpdateSince <IProject, IDatabaseProject>(database.SinceParameters) .CatchApiExceptions(); var createGhostProjects = new CreateGhostProjectsState(dataSource.Projects, analyticsService).CatchApiExceptions(); var persistTimeEntries = new PersistListState <ITimeEntry, IDatabaseTimeEntry, IThreadSafeTimeEntry>(dataSource.TimeEntries, TimeEntry.Clean) .UpdateSince <ITimeEntry, IDatabaseTimeEntry>(database.SinceParameters) .CatchApiExceptions(); var persistTasks = new PersistListState <ITask, IDatabaseTask, IThreadSafeTask>(dataSource.Tasks, Task.Clean) .UpdateSince <ITask, IDatabaseTask>(database.SinceParameters) .CatchApiExceptions(); var refetchInaccessibleProjects = new TryFetchInaccessibleProjectsState(dataSource.Projects, timeService, api.Projects) .CatchApiExceptions(); var checkServerStatus = new CheckServerStatusState(api, scheduler, apiDelay, statusDelay, delayCancellation); var finished = new ResetAPIDelayState(apiDelay); var deleteOlderEntries = new DeleteOldEntriesState(timeService, dataSource.TimeEntries); var deleteNonReferencedGhostProjects = new DeleteNonReferencedProjectGhostsState(dataSource.Projects, dataSource.TimeEntries); transitions.ConfigureTransition(entryPoint, fetchAllSince); transitions.ConfigureTransition(fetchAllSince.FetchStarted, persistWorkspaces); transitions.ConfigureTransition(persistWorkspaces.UnsafeState.FinishedPersisting, persistUser); transitions.ConfigureTransition(persistUser.UnsafeState.FinishedPersisting, persistWorkspaceFeatures); transitions.ConfigureTransition(persistWorkspaceFeatures.UnsafeState.FinishedPersisting, persistPreferences); transitions.ConfigureTransition(persistPreferences.UnsafeState.FinishedPersisting, persistTags); transitions.ConfigureTransition(persistTags.UnsafeState.FinishedPersisting, persistClients); transitions.ConfigureTransition(persistClients.UnsafeState.FinishedPersisting, persistProjects); transitions.ConfigureTransition(persistProjects.UnsafeState.FinishedPersisting, persistTasks); transitions.ConfigureTransition(persistTasks.UnsafeState.FinishedPersisting, createGhostProjects); transitions.ConfigureTransition(createGhostProjects.UnsafeState.FinishedPersisting, persistTimeEntries); transitions.ConfigureTransition(persistTimeEntries.UnsafeState.FinishedPersisting, refetchInaccessibleProjects); transitions.ConfigureTransition(refetchInaccessibleProjects.UnsafeState.FetchNext, refetchInaccessibleProjects); transitions.ConfigureTransition(refetchInaccessibleProjects.UnsafeState.FinishedPersisting, deleteOlderEntries); transitions.ConfigureTransition(deleteOlderEntries.FinishedDeleting, deleteNonReferencedGhostProjects); transitions.ConfigureTransition(persistWorkspaces.Failed, checkServerStatus); transitions.ConfigureTransition(persistUser.Failed, checkServerStatus); transitions.ConfigureTransition(persistWorkspaceFeatures.Failed, checkServerStatus); transitions.ConfigureTransition(persistPreferences.Failed, checkServerStatus); transitions.ConfigureTransition(persistTags.Failed, checkServerStatus); transitions.ConfigureTransition(persistClients.Failed, checkServerStatus); transitions.ConfigureTransition(persistProjects.Failed, checkServerStatus); transitions.ConfigureTransition(persistTasks.Failed, checkServerStatus); transitions.ConfigureTransition(createGhostProjects.Failed, checkServerStatus); transitions.ConfigureTransition(persistTimeEntries.Failed, checkServerStatus); transitions.ConfigureTransition(refetchInaccessibleProjects.Failed, checkServerStatus); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, finished); transitions.ConfigureTransition(finished.Continue, fetchAllSince); }
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.Start); transitions.ConfigureTransition(push.PushEntity, pushOne.Start); transitions.ConfigureTransition(pushOne.CreateEntity, create.Start); transitions.ConfigureTransition(pushOne.UpdateEntity, update.Start); transitions.ConfigureTransition(pushOne.DeleteEntity, delete.Start); transitions.ConfigureTransition(pushOne.DeleteEntityLocally, deleteLocal.Start); transitions.ConfigureTransition(create.ClientError, tryResolveClientError.Start); transitions.ConfigureTransition(update.ClientError, tryResolveClientError.Start); transitions.ConfigureTransition(delete.ClientError, tryResolveClientError.Start); transitions.ConfigureTransition(create.ServerError, checkServerStatus.Start); transitions.ConfigureTransition(update.ServerError, checkServerStatus.Start); transitions.ConfigureTransition(delete.ServerError, checkServerStatus.Start); transitions.ConfigureTransition(create.UnknownError, checkServerStatus.Start); transitions.ConfigureTransition(update.UnknownError, checkServerStatus.Start); transitions.ConfigureTransition(delete.UnknownError, checkServerStatus.Start); transitions.ConfigureTransition(tryResolveClientError.UnresolvedTooManyRequests, checkServerStatus.Start); transitions.ConfigureTransition(tryResolveClientError.Unresolved, unsyncable.Start); transitions.ConfigureTransition(checkServerStatus.Retry, checkServerStatus.Start); transitions.ConfigureTransition(checkServerStatus.ServerIsAvailable, push.Start); transitions.ConfigureTransition(create.CreatingFinished, finished.Start); transitions.ConfigureTransition(update.UpdatingSucceeded, finished.Start); transitions.ConfigureTransition(delete.DeletingFinished, finished.Start); transitions.ConfigureTransition(deleteLocal.Deleted, finished.Start); transitions.ConfigureTransition(deleteLocal.DeletingFailed, finished.Start); transitions.ConfigureTransition(finished.Continue, push.Start); return(push.NothingToPush); }
public ConfigureTransitionMethodTests() { AnalyticsService = Substitute.For <IAnalyticsService>(); Provider = new TransitionHandlerProvider(AnalyticsService); }
public TheGetTransitionHandlerMethod() { analyticsService = Substitute.For <IAnalyticsService>(); provider = new TransitionHandlerProvider(analyticsService); }