Skip to content

Commit 04a5aac

Browse files
authored
Add CompareVersionTo method for easier versioning usage (#394)
Signed-off-by: halspang <[email protected]>
1 parent 19b3b51 commit 04a5aac

File tree

3 files changed

+153
-0
lines changed

3 files changed

+153
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- Introduce default version setting to DurableTaskClient and expose to orchestrator ([#393](https://github.com/microsoft/durabletask-dotnet/pull/393))
66
- Add support for local credential types in DTS libraries ([#396](https://github.com/microsoft/durabletask-dotnet/pull/396))
7+
- Add utility for easier version comparison in orchestration context ([#394](https://github.com/microsoft/durabletask-dotnet/pull/394))
78

89
## v1.8.1
910

src/Abstractions/TaskOrchestrationContext.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,52 @@ public virtual ILogger CreateReplaySafeLogger(Type type)
403403
public virtual ILogger CreateReplaySafeLogger<T>()
404404
=> new ReplaySafeLogger(this, this.LoggerFactory.CreateLogger<T>());
405405

406+
/// <summary>
407+
/// Checks if the current orchestration version is greater than the specified version.
408+
/// </summary>
409+
/// <remarks>
410+
/// <para>
411+
/// If both versions are empty, this is considered false as neither can be greater.
412+
/// </para>
413+
/// <para>
414+
/// An empty context version is less than a defined version in the parameter.
415+
/// </para>
416+
/// <para>
417+
/// An empty parameter version is less than a defined version in the context.
418+
/// </para>
419+
/// </remarks>
420+
/// <param name="version">The version to check against.</param>
421+
/// <returns>True if the orchestration's version is greater than the provided version, false otherwise.</returns>
422+
public virtual int CompareVersionTo(string version)
423+
{
424+
// Both versions are empty, treat as equal.
425+
if (string.IsNullOrWhiteSpace(this.Version) && string.IsNullOrWhiteSpace(version))
426+
{
427+
return 0;
428+
}
429+
430+
// An empty version in the context is always less than a defined version in the parameter.
431+
if (string.IsNullOrWhiteSpace(this.Version))
432+
{
433+
return -1;
434+
}
435+
436+
// An empty version in the parameter is always less than a defined version in the context.
437+
if (string.IsNullOrWhiteSpace(version))
438+
{
439+
return 1;
440+
}
441+
442+
// If both versions use the .NET Version class, return that comparison.
443+
if (System.Version.TryParse(this.Version, out Version contextVersion) && System.Version.TryParse(version, out Version otherVersion))
444+
{
445+
return contextVersion.CompareTo(otherVersion);
446+
}
447+
448+
// If we have gotten to here, we don't know the syntax of the versions we are comparing, use a string comparison as a final check.
449+
return string.Compare(this.Version, version, StringComparison.OrdinalIgnoreCase);
450+
}
451+
406452
class ReplaySafeLogger : ILogger
407453
{
408454
readonly TaskOrchestrationContext context;
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
using Microsoft.Extensions.Logging;
5+
6+
namespace Microsoft.DurableTask.Abstractions.Tests;
7+
public class TaskOrchestrationContextVersionTests
8+
{
9+
[Theory]
10+
[InlineData("1.1", "1.0", 1)]
11+
[InlineData("1.0", "1.1", -1)]
12+
[InlineData("1.0", "1.0", 0)]
13+
[InlineData("", "1.0", -1)]
14+
[InlineData("1.0", "", 1)]
15+
[InlineData("", "", 0)]
16+
[InlineData("1.0.1", "1.0.0", 1)]
17+
[InlineData("1.0.0", "1.0.1", -1)]
18+
[InlineData("alpha", "beta", -1)]
19+
[InlineData("beta", "alpha", 1)]
20+
[InlineData("alpha", "alpha", 0)]
21+
public void OrchestrationContext_Version_ComparisonTests(string orchestrationVersion, string otherVersion, int comparisonResult)
22+
{
23+
TaskOrchestrationContext orchestrationContext = new TestTaskOrchestrationContext(orchestrationVersion);
24+
25+
if (comparisonResult > 0)
26+
{
27+
orchestrationContext.CompareVersionTo(otherVersion).Should().BeGreaterThan(0);
28+
}
29+
else if (comparisonResult < 0)
30+
{
31+
orchestrationContext.CompareVersionTo(otherVersion).Should().BeLessThan(0);
32+
}
33+
else
34+
{
35+
orchestrationContext.CompareVersionTo(otherVersion).Should().Be(0);
36+
}
37+
}
38+
39+
class TestTaskOrchestrationContext : TaskOrchestrationContext
40+
{
41+
internal readonly string version = string.Empty;
42+
43+
public TestTaskOrchestrationContext(string version)
44+
{
45+
this.version = version;
46+
}
47+
public override TaskName Name => throw new NotImplementedException();
48+
49+
public override string InstanceId => throw new NotImplementedException();
50+
51+
public override ParentOrchestrationInstance? Parent => throw new NotImplementedException();
52+
53+
public override DateTime CurrentUtcDateTime => throw new NotImplementedException();
54+
55+
public override bool IsReplaying => throw new NotImplementedException();
56+
57+
public override string Version => this.version;
58+
59+
protected override ILoggerFactory LoggerFactory => throw new NotImplementedException();
60+
61+
public override Task<TResult> CallActivityAsync<TResult>(TaskName name, object? input = null, TaskOptions? options = null)
62+
{
63+
throw new NotImplementedException();
64+
}
65+
66+
public override Task<TResult> CallSubOrchestratorAsync<TResult>(TaskName orchestratorName, object? input = null, TaskOptions? options = null)
67+
{
68+
throw new NotImplementedException();
69+
}
70+
71+
public override void ContinueAsNew(object? newInput = null, bool preserveUnprocessedEvents = true)
72+
{
73+
throw new NotImplementedException();
74+
}
75+
76+
public override Task CreateTimer(DateTime fireAt, CancellationToken cancellationToken)
77+
{
78+
throw new NotImplementedException();
79+
}
80+
81+
public override T? GetInput<T>() where T : default
82+
{
83+
throw new NotImplementedException();
84+
}
85+
86+
public override Guid NewGuid()
87+
{
88+
throw new NotImplementedException();
89+
}
90+
91+
public override void SendEvent(string instanceId, string eventName, object payload)
92+
{
93+
throw new NotImplementedException();
94+
}
95+
96+
public override void SetCustomStatus(object? customStatus)
97+
{
98+
throw new NotImplementedException();
99+
}
100+
101+
public override Task<T> WaitForExternalEvent<T>(string eventName, CancellationToken cancellationToken = default)
102+
{
103+
throw new NotImplementedException();
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)