private static async Task <IEnumerable <string> > PrepareUploadSegmentsAsync(SessionRecordingData recording, string targetDirectoryPath, IProgress <int> progress, CancellationToken cancellationToken) { string uploadFileName = Path.Combine(targetDirectoryPath, "data.zip"); var segments = await Task.Run(() => ZipHelper.Pack(uploadFileName, recording.Path, 2 * 1024 * 1024, progress, cancellationToken)); return(segments.Select(segment => Path.Combine(targetDirectoryPath, segment)).ToList()); }
public bool TryEnqueue(SessionRecordingData recording) { if (_queue.Any(u => u.Recording.Path.Equals(recording.Path)) == false) { var upload = new Upload(recording.Clone()); _queue.Enqueue(upload); UploadsChanged?.Invoke(this, CollectionChangedEventArgs <Upload> .CreateForAddedItem(upload)); return(true); } return(false); }
private async Task <bool> UploadSegmentAsync(string segmentPath, SessionRecordingData recording, IProgress <int> progress, CancellationToken cancellationToken) { try { using (var file = File.OpenRead(segmentPath)) { bool uploaded = await _uxrClient.UploadSessionRecordingFileAsync(_uxrNode.NodeId, recording.StartTime, file, progress, cancellationToken); return(uploaded); } } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex); } return(false); }
private async Task UploadRecordingDataAsync(SessionRecordingData recording, IProgress <UploadStatus> progress, CancellationToken cancellationToken) { CompositeProgress <UploadStatus, int> progressStatus = new CompositeProgress <UploadStatus, int>(progress, UploadStatus.CreatePreparing(), (i, p) => p.Update(i)); string uploadSegmentsDirectoryPath = PrepareDirectoryForUploadSegments(recording); var segments = await PrepareUploadSegmentsAsync(recording, uploadSegmentsDirectoryPath, progressStatus, cancellationToken); if (segments.Any()) { //segments = await FilterAlreadyUploadedSegmentsAsync(segments, recording); // upload all segments progressStatus.Report(UploadStatus.CreateUploading()); bool uploaded = await UploadMultipleSegmentsAsync(segments, recording, progressStatus, cancellationToken); if (uploaded) { // verify if all segments are uploaded progressStatus.Report(UploadStatus.CreateVerifying()); bool verified = await VerifyAllSegmentsAreUploadedAsync(segments, recording); if (verified) { // if all segments are uploaded // commit the upload progressStatus.Report(UploadStatus.CreateCompleting()); bool saved = await _uxrClient.SaveSessionRecordingAsync(_uxrNode.NodeId, recording.StartTime, recording.SessionId); if (saved) { progressStatus.Report(UploadStatus.CreateCompleted()); // delete upload files Directory.Delete(uploadSegmentsDirectoryPath, true); //if (recording.DeleteData) //{ // // TODO Uploader: delete recording data? // // Directory.Delete(recording.Path, true); //} } } } } }
private static string PrepareDirectoryForUploadSegments(SessionRecordingData recording) { string sessionIdentifier = Path.GetFileName(recording.Path); //string sessionIdentifier = $"{recording.StartTime.ToString(SESSION_FOLDER_TIMESTAMP_FORMAT)} {recording.SessionName}"; string sessionDirectoryName = FilenameHelper.ReplaceInvalidFileNameChars(sessionIdentifier); string sessionDirectory = Path.Combine(Directories.UploadFolderPath, sessionDirectoryName); if (Directory.Exists(sessionDirectory)) { Directory.Delete(sessionDirectory, true); } Directories.EnsureDirectoryExists(sessionDirectory); return(sessionDirectory); }
// do not use, we do not know any checksum or filesize, so the files may be incomplete //private async Task<IEnumerable<string>> FilterAlreadyUploadedSegmentsAsync(IEnumerable<string> segments, SessionRecordingData recording) //{ // var uploadedFiles = await _uxrClient.GetUploadedSessionRecordingFilesAsync(_uxrNode.NodeId, recording.StartTime); // return segments.Where(s => uploadedFiles.Contains(Path.GetFileName(s)) == false).ToList(); //} private async Task <bool> VerifyAllSegmentsAreUploadedAsync(IEnumerable <string> segments, SessionRecordingData recording) { var uploadedFiles = await _uxrClient.GetUploadedSessionRecordingFilesAsync(_uxrNode.NodeId, recording.StartTime); return(uploadedFiles.All(upload => segments.Any(s => s.EndsWith(upload)))); }
private async Task <bool> UploadMultipleSegmentsAsync(IEnumerable <string> segments, SessionRecordingData recording, IProgress <int> progress, CancellationToken cancellationToken) { Queue <string> segmentsToUpload = new Queue <string>(segments); bool canUploadSegment = true; double segmentProgressPart = (100d / segmentsToUpload.Count); double finishedProgress = 0d; while (segmentsToUpload.Any() && canUploadSegment && cancellationToken.IsCancellationRequested == false) { int attempts = 0; bool uploaded = false; string segment = segmentsToUpload.Peek(); var segmentProgress = new Progress <int>(i => progress.Report((int)Math.Min(100, finishedProgress + (i / 100d) * segmentProgressPart))); while (uploaded == false && attempts < 3 && cancellationToken.IsCancellationRequested == false) { attempts += 1; uploaded = await UploadSegmentAsync(segment, recording, segmentProgress, cancellationToken); } if (uploaded) { segmentsToUpload.Dequeue(); } canUploadSegment = uploaded; finishedProgress += segmentProgressPart; } return(segmentsToUpload.Any() == false); }
public Upload(SessionRecordingData recording) { Recording = recording.Clone(); Status = UploadStatus.CreateScheduled(); }