mirror of
https://github.com/Grace-Solutions/PSMinIO.git
synced 2026-08-07 11:43:11 +00:00
Implement 3-layer progress tracking for multipart uploads
� 3-LAYER PROGRESS TRACKING: ✅ ENHANCED PROGRESS VISIBILITY: • Layer 1: Collection Progress - Overall multipart upload operation • Layer 2: File Progress - Current file being uploaded with parts • Layer 3: Chunk Progress - Individual chunk upload with streaming � STREAMING IMPLEMENTATION: • Created ProgressTrackingStream for real-time chunk upload progress • Replaced ByteArrayContent with StreamContent for better memory usage • Maintains MD5 calculation for data integrity • Progress updates during actual data transfer � PROGRESS HIERARCHY: • Collection Progress (ID: 1) - 'Multipart Upload Collection' • File Progress (ID: 2, Parent: 1) - 'File Upload' with speed/ETA • Chunk Progress (ID: 3, Parent: 2) - 'Uploading Chunk' with bytes transferred ✅ TECHNICAL IMPROVEMENTS: • Real-time progress during HTTP upload (not just after completion) • Proper parent-child progress relationship • Memory-efficient streaming approach • Maintains existing MD5 integrity checking • Compatible with parallel chunk uploads � USER EXPERIENCE: • See overall multipart upload progress • Track current file upload with speed metrics • Watch individual chunks upload in real-time • Better visibility into long-running operations Now multipart uploads show comprehensive 3-layer progress tracking!
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace PSMinIO.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Stream wrapper that tracks read progress and reports it via callback
|
||||
/// </summary>
|
||||
public class ProgressTrackingStream : Stream
|
||||
{
|
||||
private readonly Stream _baseStream;
|
||||
private readonly long _totalBytes;
|
||||
private readonly Action<long, long> _progressCallback;
|
||||
private long _bytesRead = 0;
|
||||
private readonly long _startPosition;
|
||||
|
||||
public ProgressTrackingStream(Stream baseStream, long totalBytes, Action<long, long> progressCallback)
|
||||
{
|
||||
_baseStream = baseStream ?? throw new ArgumentNullException(nameof(baseStream));
|
||||
_totalBytes = totalBytes;
|
||||
_progressCallback = progressCallback ?? throw new ArgumentNullException(nameof(progressCallback));
|
||||
_startPosition = baseStream.Position;
|
||||
}
|
||||
|
||||
public override bool CanRead => _baseStream.CanRead;
|
||||
public override bool CanSeek => _baseStream.CanSeek;
|
||||
public override bool CanWrite => _baseStream.CanWrite;
|
||||
public override long Length => _totalBytes;
|
||||
public override long Position
|
||||
{
|
||||
get => _bytesRead;
|
||||
set => throw new NotSupportedException("Setting position is not supported");
|
||||
}
|
||||
|
||||
public override int Read(byte[] buffer, int offset, int count)
|
||||
{
|
||||
// Limit read to remaining bytes
|
||||
var remainingBytes = _totalBytes - _bytesRead;
|
||||
var bytesToRead = (int)Math.Min(count, remainingBytes);
|
||||
|
||||
if (bytesToRead <= 0)
|
||||
return 0;
|
||||
|
||||
var bytesRead = _baseStream.Read(buffer, offset, bytesToRead);
|
||||
_bytesRead += bytesRead;
|
||||
|
||||
// Report progress
|
||||
_progressCallback(_bytesRead, _totalBytes);
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
public override void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
throw new NotSupportedException("Writing is not supported");
|
||||
}
|
||||
|
||||
public override void Flush()
|
||||
{
|
||||
_baseStream.Flush();
|
||||
}
|
||||
|
||||
public override long Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
throw new NotSupportedException("Seeking is not supported");
|
||||
}
|
||||
|
||||
public override void SetLength(long value)
|
||||
{
|
||||
throw new NotSupportedException("Setting length is not supported");
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
// Don't dispose the base stream - let the caller handle it
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user