tgstation-server 6.12.0
The /tg/station 13 server suite
Loading...
Searching...
No Matches
SwarmUpdateOperation.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Linq;
4using System.Threading.Tasks;
5
7
9{
14 {
18 public IReadOnlyList<SwarmServerInformation> InvolvedServers => initialInvolvedServers ?? throw new InvalidOperationException("This property can only be checked on controller SwarmUpdateOperations!");
19
23 public Version TargetVersion { get; }
24
28 public Task<bool> CommitGate => commitTcs.Task;
29
33 readonly IReadOnlyList<SwarmServerInformation>? initialInvolvedServers;
34
38 readonly TaskCompletionSource<bool> commitTcs;
39
43 readonly HashSet<string>? nodesThatNeedToBeReadyToCommit;
44
50 public SwarmUpdateOperation(Version targetVersion)
51 {
52 TargetVersion = targetVersion ?? throw new ArgumentNullException(nameof(targetVersion));
53 commitTcs = new TaskCompletionSource<bool>();
54 }
55
62 public SwarmUpdateOperation(Version targetVersion, IEnumerable<SwarmServerInformation> currentNodes)
63 : this(targetVersion)
64 {
65 initialInvolvedServers = currentNodes?.ToList() ?? throw new ArgumentNullException(nameof(currentNodes));
67 .Where(node => !node.Controller)
68 .Select(node => node.Identifier!)
69 .ToHashSet();
70 }
71
77 {
78 if (commitTcs.TrySetResult(false))
79 return SwarmUpdateAbortResult.Aborted;
80
81 return commitTcs.Task.Result
82 ? SwarmUpdateAbortResult.CantAbortCommitted
83 : SwarmUpdateAbortResult.AlreadyAborted;
84 }
85
90 public bool Commit()
91 {
93 throw new InvalidOperationException($"Cannot commit! There are still {nodesThatNeedToBeReadyToCommit.Count} nodes that need to be ready!");
94
95 if (commitTcs.Task.IsCompleted && !commitTcs.Task.Result)
96 return false;
97
98 commitTcs.SetResult(true); // let the InvalidOperationException throw
99 return true;
100 }
101
107 public bool MarkNodeReady(string nodeIdentifier)
108 {
109 ArgumentNullException.ThrowIfNull(nodeIdentifier);
110
112 throw new InvalidOperationException("A non-controller node tried to mark a node as ready!");
113
115 {
116 if (!nodesThatNeedToBeReadyToCommit.Remove(nodeIdentifier))
117 return Abort() != SwarmUpdateAbortResult.Aborted;
118
119 if (nodesThatNeedToBeReadyToCommit.Count == 0)
120 commitTcs.TrySetResult(true);
121
122 return true;
123 }
124 }
125 }
126}
Represents the state of a distributed swarm update.
Task< bool > CommitGate
The Task<TResult> that represents the final commit. If it results in true the update has been committ...
readonly? HashSet< string > nodesThatNeedToBeReadyToCommit
HashSet<T> of SwarmServer.Identifier that need to send a ready-commit to the controller before the co...
bool MarkNodeReady(string nodeIdentifier)
Marks a SwarmServer identified by nodeIdentifier as ready to commit.
SwarmUpdateOperation(Version targetVersion)
Initializes a new instance of the SwarmUpdateOperation class.
Version TargetVersion
The Version being updated to.
IReadOnlyList< SwarmServerInformation > InvolvedServers
All of the SwarmServers that are involved in the updates.
readonly? IReadOnlyList< SwarmServerInformation > initialInvolvedServers
Backing field for InvolvedServers.
readonly TaskCompletionSource< bool > commitTcs
The backing TaskCompletionSource<TResult> for CommitGate.
SwarmUpdateOperation(Version targetVersion, IEnumerable< SwarmServerInformation > currentNodes)
Initializes a new instance of the SwarmUpdateOperation class.
SwarmUpdateAbortResult Abort()
Attempt to abort the update operation.
SwarmUpdateAbortResult
Result of attempting to abort a SwarmUpdateOperation.