private async Task UploadLoop()
        {
            var uploader = new Uploader();
            var analyzer = new Analyzer();
            var monitor  = new Monitor();

            var replays   = _storage.Load().ToList();
            var filenames = new HashSet <string>(replays.Select(x => x.Filename));

            replays.AddRange(monitor.ScanReplays().Where(x => !filenames.Contains(x)).Select(x => new ReplayFile(x)));
            replays.OrderByDescending(x => x.Created).Map(x => Files.Add(x));

            monitor.ReplayAdded += async(_, e) => {
                await EnsureFileAvailable(e.Data, 3000);

                Files.Insert(0, new ReplayFile(e.Data));
            };
            monitor.Start();
            Files.CollectionChanged += (_, __) => _collectionUpdated.Set();

            analyzer.MinimumBuild = await uploader.GetMinimumBuild();

            while (true)
            {
                try {
                    // take files one by one, in case newer replays are added to the top of the list while we upload older ones
                    // upload in a single thread to prevent load spikes on server
                    var file = Files.Where(f => f.UploadStatus == UploadStatus.None).FirstOrDefault();
                    if (file != null)
                    {
                        file.UploadStatus = UploadStatus.InProgress;

                        // test if replay is eligible for upload (not AI, PTR, Custom, etc)
                        analyzer.Analyze(file);
                        if (file.UploadStatus == UploadStatus.InProgress)
                        {
                            // if it is, upload it
                            await uploader.Upload(file);
                        }
                        try {
                            // save only replays with fixed status. Will retry failed ones on next launch.
                            _storage.Save(Files.Where(x => !new[] { UploadStatus.None, UploadStatus.UploadError, UploadStatus.InProgress }.Contains(x.UploadStatus)));
                        }
                        catch (Exception ex) {
                            // we can still continue uploading
                            _log.Error(ex, "Error saving replay list");
                        }
                    }
                    else
                    {
                        await _collectionUpdated.WaitAsync();
                    }
                }
                catch (Exception ex) {
                    _log.Error(ex, "Error in upload loop");
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// Load replay cache and merge it with folder scan results
        /// </summary>
        private List <ReplayFile> ScanReplays()
        {
            var replays  = new List <ReplayFile>(_storage.Load());
            var lookup   = new HashSet <ReplayFile>(replays);
            var comparer = new ReplayFile.ReplayFileComparer();

            replays.AddRange(_monitor.ScanReplays().Select(x => new ReplayFile(x)).Where(x => !lookup.Contains(x, comparer)));
            return(replays.OrderByDescending(x => x.Created).ToList());
        }