public SyncThingManager( ISyncThingProcessRunner processRunner, ISyncThingApiClientFactory apiClientFactory, ISyncThingEventWatcherFactory eventWatcherFactory, ISyncThingConnectionsWatcherFactory connectionsWatcherFactory, IFreePortFinder freePortFinder) { this.StartedTime = DateTime.MinValue; this.LastConnectivityEventTime = DateTime.MinValue; this.eventDispatcher = new SynchronizedEventDispatcher(this); this.processRunner = processRunner; this.apiClientFactory = apiClientFactory; this.freePortFinder = freePortFinder; this.apiClient = new SynchronizedTransientWrapper <ISyncThingApiClient>(this.apiClientsLock); this.eventWatcher = eventWatcherFactory.CreateEventWatcher(this.apiClient); this.eventWatcher.DeviceConnected += (o, e) => this.OnDeviceConnected(e); this.eventWatcher.DeviceDisconnected += (o, e) => this.OnDeviceDisconnected(e); this.eventWatcher.ConfigSaved += (o, e) => this.ReloadConfigDataAsync(); this.eventWatcher.EventsSkipped += (o, e) => this.ReloadConfigDataAsync(); this.connectionsWatcher = connectionsWatcherFactory.CreateConnectionsWatcher(this.apiClient); this.connectionsWatcher.TotalConnectionStatsChanged += (o, e) => this.OnTotalConnectionStatsChanged(e.TotalConnectionStats); this._folders = new SyncThingFolderManager(this.apiClient, this.eventWatcher, TimeSpan.FromMinutes(10)); this._transferHistory = new SyncThingTransferHistory(this.eventWatcher, this._folders); this.processRunner.ProcessStopped += (o, e) => this.ProcessStopped(e.ExitStatus); this.processRunner.MessageLogged += (o, e) => this.OnMessageLogged(e.LogMessage); this.processRunner.ProcessRestarted += (o, e) => this.ProcessRestarted(); this.processRunner.Starting += (o, e) => this.ProcessStarting(); }
private async Task <Ignores> FetchFolderIgnoresAsync(string folderId, CancellationToken cancellationToken) { // Until startup is complete, these can return a 500. // There's no sensible way to determine when startup *is* complete, so we just have to keep trying... // Again, there's the possibility that we've just abort the API... ISyncThingApiClient apiClient; lock (this.apiClient.LockObject) { cancellationToken.ThrowIfCancellationRequested(); apiClient = this.apiClient.UnsynchronizedValue; if (apiClient == null) { throw new InvalidOperationException("ApiClient must not be null"); } } Ignores ignores = null; // We used to time out after an absolute time here. However, there's the possiblity of going to sleep // halfway through polling, which throws things off. Therefore use a number of iterations var numRetries = this.ignoresFetchTimeout.TotalSeconds; // Each iteration is a second for (var retriesCount = 0; retriesCount < numRetries; retriesCount++) { try { ignores = await apiClient.FetchIgnoresAsync(folderId); // No need to log: ApiClient did that for us break; } catch (ApiException e) { logger.Debug("Attempting to fetch folder {0}, but received status {1}", folderId, e.StatusCode); if (e.StatusCode != HttpStatusCode.InternalServerError) { throw; } } await Task.Delay(1000, cancellationToken); cancellationToken.ThrowIfCancellationRequested(); } if (ignores == null) { throw new SyncThingDidNotStartCorrectlyException($"Unable to fetch ignores for folder {folderId}. Syncthing returned 500 after {this.ignoresFetchTimeout}"); } return(ignores); }
public SyncThingFolderManager( SynchronizedTransientWrapper <ISyncThingApiClient> apiClient, ISyncThingEventWatcher eventWatcher, TimeSpan ignoresFetchTimeout) { this.eventDispatcher = new SynchronizedEventDispatcher(this); this.apiClient = apiClient; this.ignoresFetchTimeout = ignoresFetchTimeout; this.eventWatcher = eventWatcher; this.eventWatcher.SyncStateChanged += (o, e) => this.FolderSyncStateChanged(e); this.eventWatcher.ItemStarted += (o, e) => this.ItemStarted(e.Folder, e.Item); this.eventWatcher.ItemFinished += (o, e) => this.ItemFinished(e.Folder, e.Item); }
public SyncThingConnectionsWatcher(SynchronizedTransientWrapper <ISyncThingApiClient> apiClient) : base(TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10)) { this.apiClientWrapper = apiClient; }
public ISyncThingConnectionsWatcher CreateConnectionsWatcher(SynchronizedTransientWrapper <ISyncThingApiClient> apiClient) { return(new SyncThingConnectionsWatcher(apiClient)); }