Repository navigation
Expand file tree
/
Copy pathCommandOutcomeApplication.cs
More file actions
71 lines (63 loc) · 4.35 KB
/
Copy pathCommandOutcomeApplication.cs
File metadata and controls
71 lines (63 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
using KeyLoad.Core.BackupRestore.Execution;
using KeyLoad.Core.CommandOutcomes.Contracts;
using KeyLoad.Core.CommandOutcomes.Execution;
using KeyLoad.Core.CommandOutcomes.Serialization;
using KeyLoad.Storage;
using ManagedCode.Communication;
using ManagedCode.Communication.Commands;
namespace KeyLoad.Core;
/// <summary>Owns the CommandOutcomeApplication operation contract.</summary>
internal static class CommandOutcomeApplication
{
internal static StoredOutcome BuildStoredOutcome(this DatabaseEngine engine, Command<DatabaseCommand> operation, long policyEpoch, Result<object> /* KLD0041: This persistence writer preserves the original mixed-operation outcome schema and native payload metadata. */ result, global::KeyLoad.Core.DatabaseComposition.CompositionOutcomeAuthority? compositionAuthority, CommandOutcomePartitionScope partitionScope, global::KeyLoad.Core.Search.OnlineTextOutcomeAuthority? onlineTextAuthority, global::KeyLoad.Core.Messaging.RemoteTransferAcceptFailureAuthority? transferFailure, long canonicalSequence) => new(engine.Store.Identity.Incarnation, policyEpoch, result, operation)
{
CompositionAuthority = Errors.Code(result.Problem).Value is null ? compositionAuthority : null,
ScopeKind = partitionScope.Kind,
Partition = partitionScope.Partition,
CanonicalSequence = canonicalSequence,
OnlineTextAuthority = onlineTextAuthority,
RemoteTransferFailureAuthority = RemoteTransferFailureCapture.HasRemoteTransferCapacityFailure(result.Problem) ? transferFailure : null
} /* KLD0041: This constructor preserves the original native mixed-operation result in its existing persisted storage contract. */;
internal static StoredOutcome ReplayCommand(this DatabaseEngine engine, IAtomicTransaction transaction, Command<DatabaseCommand> operation, StoredOutcome previous, CommandOutcomeSelection selection, bool siloLocal, PrincipalRecord principal, long currentSequence)
{
StorageOperationApply.RequireStoredCanonicalSequence(currentSequence, previous, siloLocal);
if (previous.Incarnation != engine.Store.Identity.Incarnation)
{
throw Errors.Fail(ErrorCode.TokenInvalidated, AtomicCommandCommit.PreviousCommandIncarnationMessage);
}
DatabaseCommandContentIdentity.RequireOriginalCommandContent(operation, previous);
CommandOutcomeKeyResolver.ValidateSelectedScope(transaction, operation, selection);
var current = engine.EvaluateCommand(operation, engine.Clock.GetUtcNow());
engine.ValidateCachedResult(transaction, principal, current, previous);
return previous;
}
internal static void PersistCommandOutcome(AtomicPartitionRosterTransaction transaction, Command<DatabaseCommand> operation, byte[] resultKey, StoredOutcome outcome, long replicationIndex, bool persistOutcome)
{
// Domain effects, outcome and apply watermark share one redo transaction.
var outcomeAlreadyStored = persistOutcome && transaction.ReadOwnedValue(resultKey) is not null;
if (persistOutcome && !outcomeAlreadyStored)
{
transaction.PutRecord(resultKey, outcome);
if (outcome.ScopeKind == CommandOutcomeScopeKind.Partition)
{
if (outcome.Partition is null)
{
throw Errors.Fail(ErrorCode.Corruption, AtomicCommandCommit.MissingOutcomePartitionMessage);
}
CommandOutcomePartitionLocatorSerialization.WriteScoped(transaction, outcome.Partition, operation.UserId!, operation.CommandId);
}
}
if (replicationIndex > AtomicCommandCommit.AtomicCommandCommitInitialSequence)
{
transaction.PutRecord(StorageCommandKeys.Applied(StorageCommandKeys.PartitionOf(operation)), new StoragePartitionPosition(StorageCommandKeys.PartitionOf(operation), replicationIndex));
}
if (!persistOutcome || replicationIndex <= AtomicCommandCommit.AtomicCommandCommitInitialSequence)
{
return;
}
if (transaction.ReadOwnedValue(StorageCommandKeys.Clock(StorageCommandKeys.PartitionOf(operation))) is not { } clock || operation.Timestamp >= OrleansSerialization.Deserialize<DateTimeOffset>(clock))
{
transaction.PutRecord(StorageCommandKeys.Clock(StorageCommandKeys.PartitionOf(operation)), (DateTimeOffset)operation.Timestamp);
}
}
}