Exemplo n.º 1
0
        private async Task LoadStartupDataAsync(CancellationToken cancellationToken)
        {
            logger.Debug("Startup Complete! Loading startup data");

            // There's a race where Syncthing died, and so we kill the API clients and set it to null,
            // but we still end up here, because threading.
            ISyncThingApiClient apiClient;

            lock (this.apiClientsLock)
            {
                cancellationToken.ThrowIfCancellationRequested();
                apiClient = this.apiClient;
                if (apiClient == null)
                {
                    throw new InvalidOperationException("ApiClient must not be null");
                }
            }

            var configTask      = apiClient.FetchConfigAsync();
            var systemTask      = apiClient.FetchSystemInfoAsync();
            var versionTask     = apiClient.FetchVersionAsync();
            var connectionsTask = apiClient.FetchConnectionsAsync();

            cancellationToken.ThrowIfCancellationRequested();
            await Task.WhenAll(configTask, systemTask, versionTask, connectionsTask);

            // We can potentially see duplicate devices (if the user set their config file that way). Ignore them.
            var devices = configTask.Result.Devices.DistinctBy(x => x.DeviceID).Select(device =>
            {
                var deviceObj = new Device(device.DeviceID, device.Name);
                ItemConnectionData connectionData;
                if (connectionsTask.Result.DeviceConnections.TryGetValue(device.DeviceID, out connectionData))
                {
                    deviceObj.SetConnected(connectionData.Address);
                }
                return(deviceObj);
            });

            this.devices = new ConcurrentDictionary <string, Device>(devices.Select(x => new KeyValuePair <string, Device>(x.DeviceId, x)));

            var tilde = systemTask.Result.Tilde;

            // If the folder is invalid for any reason, we'll ignore it.
            // Again, there's the potential for duplicate folder IDs (if the user's been fiddling their config).
            // In this case, there's nothing really sensible we can do. Just pick one of them :)
            var folderConstructionTasks = configTask.Result.Folders
                                          .Where(x => String.IsNullOrWhiteSpace(x.Invalid))
                                          .DistinctBy(x => x.ID)
                                          .Select(async folder =>
            {
                var ignores = await this.FetchFolderIgnoresAsync(folder.ID, cancellationToken);
                var path    = folder.Path;
                if (path.StartsWith("~"))
                {
                    path = Path.Combine(tilde, path.Substring(1).TrimStart(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar));
                }
                return(new Folder(folder.ID, path, new FolderIgnores(ignores.IgnorePatterns, ignores.RegexPatterns)));
            });

            cancellationToken.ThrowIfCancellationRequested();

            var folders = await Task.WhenAll(folderConstructionTasks);

            this.folders = new ConcurrentDictionary <string, Folder>(folders.Select(x => new KeyValuePair <string, Folder>(x.FolderId, x)));

            this.Version = versionTask.Result;

            cancellationToken.ThrowIfCancellationRequested();

            this.StartedTime  = DateTime.UtcNow;
            this.IsDataLoaded = true;
            this.OnDataLoaded();
        }