Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,6 @@ _watcher.EnableRaisingEvents = true;
| Gap | Impact | Status |
|-----|--------|--------|
| No selective folder sync API | Can't sync single folders on demand | Planned: `SyncFolderAsync()`, `SyncFilesAsync()` |
| No pause/resume | Long syncs can't be paused | Planned: `PauseAsync()`, `ResumeAsync()` |
| No incremental change notification | FileSystemWatcher triggers full scan | Planned: `NotifyLocalChangeAsync()` |
| Single-threaded engine | One sync at a time per instance | By design - create separate instances if needed |
| OCIS TUS not implemented | Falls back to generic upload | Planned for v1.0 |
Expand All @@ -304,6 +303,7 @@ _watcher.EnableRaisingEvents = true;
|---------|----------------|
| Bandwidth throttling | `SyncOptions.MaxBytesPerSecond` - limits transfer rate |
| Virtual file awareness | `SyncOptions.VirtualFileCallback` - hook for Windows Cloud Files API integration |
| Pause/Resume sync | `PauseAsync()` / `ResumeAsync()` - gracefully pause and resume long-running syncs |

### Required SharpSync API Additions (v1.0)

Expand All @@ -318,8 +318,7 @@ These APIs are required for v1.0 release to support Nimbus desktop client:
4. OCIS TUS protocol implementation (`WebDavStorage.cs:547` currently falls back)

**Sync Control:**
5. `PauseAsync()` / `ResumeAsync()` - Pause and resume long-running syncs
6. `GetPendingOperationsAsync()` - Inspect sync queue for UI display
5. `GetPendingOperationsAsync()` - Inspect sync queue for UI display

**Progress & History:**
7. Per-file progress events (currently only per-sync-operation)
Expand All @@ -331,6 +330,8 @@ These APIs are required for v1.0 release to support Nimbus desktop client:
- `SyncOptions.CreateVirtualFilePlaceholders` - Enable/disable virtual file placeholder creation
- `VirtualFileState` enum - Track placeholder state (None, Placeholder, Hydrated, Partial)
- `SyncPlanAction.WillCreateVirtualPlaceholder` - Preview which downloads will create placeholders
- `PauseAsync()` / `ResumeAsync()` - Gracefully pause and resume long-running syncs
- `IsPaused` property and `SyncEngineState` enum - Track engine state (Idle, Running, Paused)

### API Readiness Score for Nimbus

Expand All @@ -344,10 +345,10 @@ These APIs are required for v1.0 release to support Nimbus desktop client:
| UI binding (events) | 9/10 | Excellent progress/conflict events |
| Conflict resolution | 9/10 | Rich analysis, extensible callbacks |
| Selective sync | 4/10 | Filter-only, no folder/file API |
| Pause/Resume | 2/10 | Not implemented |
| Desktop integration hooks | 8/10 | Virtual file callback, bandwidth throttling implemented |
| Pause/Resume | 10/10 | Fully implemented with graceful pause points |
| Desktop integration hooks | 9/10 | Virtual file callback, bandwidth throttling, pause/resume |

**Current Overall: 7.25/10** - Solid foundation, key desktop hooks now available
**Current Overall: 8.4/10** - Strong foundation with key desktop features implemented

**Target for v1.0: 9.5/10** - All gaps resolved, ready for Nimbus development

Expand Down Expand Up @@ -501,6 +502,7 @@ The core library is production-ready, but several critical items must be address
- ✅ Bandwidth throttling (`SyncOptions.MaxBytesPerSecond`)
- ✅ Virtual file placeholder support (`SyncOptions.VirtualFileCallback`) for Windows Cloud Files API
- ✅ High-performance logging with `Microsoft.Extensions.Logging.Abstractions`
- ✅ Pause/Resume sync (`PauseAsync()` / `ResumeAsync()`) with graceful pause points

**🚧 Required for v1.0 Release**

Expand All @@ -517,7 +519,7 @@ Desktop Client APIs (for Nimbus):
- [ ] `NotifyLocalChangeAsync(string path, ChangeType type)` - Accept FileSystemWatcher events for incremental sync
- [ ] OCIS TUS protocol implementation (currently falls back to generic upload at `WebDavStorage.cs:547`)
- [x] `SyncOptions.MaxBytesPerSecond` - Built-in bandwidth throttling ✅
- [ ] `PauseAsync()` / `ResumeAsync()` - Pause and resume long-running syncs
- [x] `PauseAsync()` / `ResumeAsync()` - Pause and resume long-running syncs
- [ ] `GetPendingOperationsAsync()` - Inspect sync queue for UI display
- [ ] Per-file progress events (currently only per-sync-operation)
- [x] `SyncOptions.VirtualFileCallback` - Hook for virtual file systems (Windows Cloud Files API) ✅
Expand Down
44 changes: 44 additions & 0 deletions src/SharpSync/Core/ISyncEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ public interface ISyncEngine: IDisposable {
/// </summary>
bool IsSynchronizing { get; }

/// <summary>
/// Gets whether the engine is currently paused
/// </summary>
bool IsPaused { get; }

/// <summary>
/// Gets the current state of the sync engine
/// </summary>
SyncEngineState State { get; }

/// <summary>
/// Synchronizes files between local and remote storage
/// </summary>
Expand Down Expand Up @@ -51,4 +61,38 @@ public interface ISyncEngine: IDisposable {
/// Resets all sync state (forces full rescan)
/// </summary>
Task ResetSyncStateAsync(CancellationToken cancellationToken = default);

/// <summary>
/// Pauses the current synchronization operation
/// </summary>
/// <remarks>
/// <para>
/// The pause is graceful - the engine will complete the current file operation
/// before entering the paused state. This ensures no partial file transfers occur.
/// </para>
/// <para>
/// If no synchronization is in progress, this method returns immediately.
/// </para>
/// <para>
/// While paused, the <see cref="ProgressChanged"/> event will fire with
/// <see cref="SyncOperation.Paused"/> to indicate the paused state.
/// </para>
/// </remarks>
/// <returns>A task that completes when the engine has entered the paused state</returns>
Task PauseAsync();

/// <summary>
/// Resumes a paused synchronization operation
/// </summary>
/// <remarks>
/// <para>
/// If the engine is not paused, this method returns immediately.
/// </para>
/// <para>
/// After resuming, synchronization continues from where it was paused,
/// processing any remaining files in the sync queue.
/// </para>
/// </remarks>
/// <returns>A task that completes when the engine has resumed</returns>
Task ResumeAsync();
}
21 changes: 21 additions & 0 deletions src/SharpSync/Core/SyncEngineState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Oire.SharpSync.Core;

/// <summary>
/// Represents the current state of the sync engine
/// </summary>
public enum SyncEngineState {
/// <summary>
/// The engine is idle and not performing any sync operation
/// </summary>
Idle,

/// <summary>
/// The engine is actively synchronizing files
/// </summary>
Running,

/// <summary>
/// The engine is paused and waiting to be resumed
/// </summary>
Paused
}
7 changes: 6 additions & 1 deletion src/SharpSync/Core/SyncOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,10 @@ public enum SyncOperation {
/// <summary>
/// Resolving a synchronization conflict
/// </summary>
ResolvingConflict
ResolvingConflict,

/// <summary>
/// The sync operation is paused
/// </summary>
Paused
}
5 changes: 5 additions & 0 deletions src/SharpSync/Core/SyncProgress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,9 @@ public record SyncProgress {
/// Gets whether the operation has been cancelled
/// </summary>
public bool IsCancelled { get; init; }

/// <summary>
/// Gets whether the operation is currently paused
/// </summary>
public bool IsPaused { get; init; }
}
24 changes: 24 additions & 0 deletions src/SharpSync/Logging/LogMessages.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,28 @@ internal static partial class LogMessages {
Level = LogLevel.Warning,
Message = "Virtual file callback failed for {FilePath}")]
public static partial void VirtualFileCallbackError(this ILogger logger, Exception ex, string filePath);

[LoggerMessage(
EventId = 7,
Level = LogLevel.Information,
Message = "Sync pause requested, waiting for current operation to complete")]
public static partial void SyncPausing(this ILogger logger);

[LoggerMessage(
EventId = 8,
Level = LogLevel.Information,
Message = "Sync paused")]
public static partial void SyncPaused(this ILogger logger);

[LoggerMessage(
EventId = 9,
Level = LogLevel.Information,
Message = "Sync resume requested")]
public static partial void SyncResuming(this ILogger logger);

[LoggerMessage(
EventId = 10,
Level = LogLevel.Information,
Message = "Sync resumed")]
public static partial void SyncResumed(this ILogger logger);
}
Loading
Loading