示例#1
0
        private async Task UploadLoop()
        {
            _uploader = new Uploader();
            _analyzer = new Analyzer();
            _monitor  = new Monitor();

            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)));
            Files.AddRange(replays.OrderByDescending(x => x.Created));

            _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)
                        var replay = _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) {
                            _log.Error(ex, "Error saving replay list");
                        }
                        if (ShouldDelete(file, replay))
                        {
                            try {
                                _log.Info($"Deleting replay {file}");
                                file.Deleted = true;
                                File.Delete(file.Filename);
                            } catch (Exception ex) {
                                _log.Error(ex, "Error deleting file");
                            }
                        }
                    }
                    else
                    {
                        await _collectionUpdated.WaitAsync();
                    }
                }
                catch (Exception ex) {
                    _log.Error(ex, "Error in upload loop");
                }
            }
        }