Skip to content

Commit 1193e4b

Browse files
authored
chore: rework mutagen controller, add polling (#65)
- Use locks during operations for daemon process consistency - Use a state model for UI rendering - Use events to signal state changes - Fix some tooltip problems that arise from polling
1 parent 9b1aaa5 commit 1193e4b

13 files changed

+544
-343
lines changed

Diff for: App/App.xaml.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ protected override void OnLaunched(LaunchActivatedEventArgs args)
120120
// Initialize file sync.
121121
var syncSessionCts = new CancellationTokenSource(TimeSpan.FromSeconds(10));
122122
var syncSessionController = _services.GetRequiredService<ISyncSessionController>();
123-
_ = syncSessionController.Initialize(syncSessionCts.Token).ContinueWith(t =>
123+
_ = syncSessionController.RefreshState(syncSessionCts.Token).ContinueWith(t =>
124124
{
125125
// TODO: log
126126
#if DEBUG

Diff for: App/Models/RpcModel.cs

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Collections.Generic;
2-
using System.Linq;
32
using Coder.Desktop.Vpn.Proto;
43

54
namespace Coder.Desktop.App.Models;
@@ -26,18 +25,18 @@ public class RpcModel
2625

2726
public VpnLifecycle VpnLifecycle { get; set; } = VpnLifecycle.Unknown;
2827

29-
public List<Workspace> Workspaces { get; set; } = [];
28+
public IReadOnlyList<Workspace> Workspaces { get; set; } = [];
3029

31-
public List<Agent> Agents { get; set; } = [];
30+
public IReadOnlyList<Agent> Agents { get; set; } = [];
3231

3332
public RpcModel Clone()
3433
{
3534
return new RpcModel
3635
{
3736
RpcLifecycle = RpcLifecycle,
3837
VpnLifecycle = VpnLifecycle,
39-
Workspaces = Workspaces.ToList(),
40-
Agents = Agents.ToList(),
38+
Workspaces = Workspaces,
39+
Agents = Agents,
4140
};
4241
}
4342
}

Diff for: App/Models/SyncSessionControllerStateModel.cs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Collections.Generic;
2+
3+
namespace Coder.Desktop.App.Models;
4+
5+
public enum SyncSessionControllerLifecycle
6+
{
7+
// Uninitialized means that the daemon has not been started yet. This can
8+
// be resolved by calling RefreshState (or any other RPC method
9+
// successfully).
10+
Uninitialized,
11+
12+
// Stopped means that the daemon is not running. This could be because:
13+
// - It was never started (pre-Initialize)
14+
// - It was stopped due to no sync sessions (post-Initialize, post-operation)
15+
// - The last start attempt failed (DaemonError will be set)
16+
// - The last daemon process crashed (DaemonError will be set)
17+
Stopped,
18+
19+
// Running is the normal state where the daemon is running and managing
20+
// sync sessions. This is only set after a successful start (including
21+
// being able to connect to the daemon).
22+
Running,
23+
}
24+
25+
public class SyncSessionControllerStateModel
26+
{
27+
public SyncSessionControllerLifecycle Lifecycle { get; init; } = SyncSessionControllerLifecycle.Stopped;
28+
29+
/// <summary>
30+
/// May be set when Lifecycle is Stopped to signify that the daemon failed
31+
/// to start or unexpectedly crashed.
32+
/// </summary>
33+
public string? DaemonError { get; init; }
34+
35+
public required string DaemonLogFilePath { get; init; }
36+
37+
/// <summary>
38+
/// This contains the last known state of all sync sessions. Sync sessions
39+
/// are periodically refreshed if the daemon is running. This list is
40+
/// sorted by creation time.
41+
/// </summary>
42+
public IReadOnlyList<SyncSessionModel> SyncSessions { get; init; } = [];
43+
}

Diff for: App/Models/SyncSessionModel.cs

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ public string Description(string linePrefix = "")
5151
public class SyncSessionModel
5252
{
5353
public readonly string Identifier;
54+
public readonly DateTime CreatedAt;
5455

5556
public readonly string AlphaName;
5657
public readonly string AlphaPath;
@@ -99,6 +100,7 @@ public string SizeDetails
99100
public SyncSessionModel(State state)
100101
{
101102
Identifier = state.Session.Identifier;
103+
CreatedAt = state.Session.CreationTime.ToDateTime();
102104

103105
(AlphaName, AlphaPath) = NameAndPathFromUrl(state.Session.Alpha);
104106
(BetaName, BetaPath) = NameAndPathFromUrl(state.Session.Beta);

0 commit comments

Comments
 (0)