Skip to content

Commit 4813515

Browse files
authored
Added a "stopped task" to IActor (#15)
* Project updates * Added StoppedTask to IActor
1 parent ac542a8 commit 4813515

File tree

9 files changed

+83
-23
lines changed

9 files changed

+83
-23
lines changed

Winton.Extensions.Threading.Actor.Tests.Unit/ActorTests.cs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,41 @@ public void ShouldNotEnqueueAnyMoreWorkAfterAskedToStop()
384384
stageOrder.Should().Equal(expectedStageOrder);
385385
}
386386

387+
[Fact]
388+
public async Task ShouldCompleteStoppedTaskWhenStopCompleted()
389+
{
390+
var stageOrder = new List<string>();
391+
var expectedStageOrder =
392+
new List<string>
393+
{
394+
"Start",
395+
"Stop",
396+
"Stopped"
397+
};
398+
var actor = CreateActor(x =>
399+
{
400+
x.StartWork = new ActorStartWork(() => stageOrder.Add("Start"));
401+
x.StopWork = new ActorStopWork(
402+
() =>
403+
{
404+
Thread.Sleep(TimeSpan.FromMilliseconds(250));
405+
stageOrder.Add("Stop");
406+
});
407+
},
408+
ActorCreateOptions.None);
409+
410+
await actor.Start();
411+
412+
var stopTask = actor.Stop();
413+
414+
await actor.StoppedTask;
415+
stageOrder.Add("Stopped");
416+
417+
await stopTask;
418+
419+
stageOrder.Should().Equal(expectedStageOrder);
420+
}
421+
387422
[Theory]
388423
[InlineData(ResumeTestCase.AwaitOnTaskFactoryScheduledTask, StopWorkOutcome.Completes)]
389424
[InlineData(ResumeTestCase.AwaitOnTaskFactoryScheduledTask, StopWorkOutcome.Faults)]

Winton.Extensions.Threading.Actor.Tests.Unit/Winton.Extensions.Threading.Actor.Tests.Unit.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFrameworks>netcoreapp1.1;net462</TargetFrameworks>
4+
<TargetFrameworks>netcoreapp1.0;net462</TargetFrameworks>
55
<SignAssembly>True</SignAssembly>
66
<DelaySign>False</DelaySign>
77
<AssemblyOriginatorKeyFile>../keys/Winton.Extensions.Threading.Actor.snk</AssemblyOriginatorKeyFile>
88
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="FluentAssertions" Version="4.19.2" />
13-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
14-
<PackageReference Include="Moq" Version="4.7.12" />
12+
<PackageReference Include="FluentAssertions" Version="4.19.4" />
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
14+
<PackageReference Include="Moq" Version="4.7.137" />
1515
<PackageReference Include="xunit" Version="2.2.0" />
1616
<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
1717
</ItemGroup>

Winton.Extensions.Threading.Actor.Tests.Utilities/Winton.Extensions.Threading.Actor.Tests.Utilities.csproj

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@
1111
<SignAssembly>True</SignAssembly>
1212
<PublicSign Condition=" '$(OS)' != 'Windows_NT' ">true</PublicSign>
1313
<PackageId>Winton.Extensions.Threading.Actor.Tests.Utilities</PackageId>
14-
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.6' ">1.6.1</NetStandardImplicitPackageVersion>
1514
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
1615
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
1716
<DelaySign>False</DelaySign>
1817
</PropertyGroup>
1918

2019
<ItemGroup>
21-
<PackageReference Include="FluentAssertions" Version="4.19.2" />
20+
<PackageReference Include="FluentAssertions" Version="4.19.4" />
2221
</ItemGroup>
2322

2423
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">

Winton.Extensions.Threading.Actor.sln

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26430.13
4+
VisualStudioVersion = 15.0.26730.10
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{F9C63802-0833-4F6F-A220-3193ACA0FC67}"
77
EndProject
@@ -11,7 +11,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Winton.Extensions.Threading
1111
EndProject
1212
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Winton.Extensions.Threading.Actor.Tests.Utilities", "Winton.Extensions.Threading.Actor.Tests.Utilities\Winton.Extensions.Threading.Actor.Tests.Utilities.csproj", "{883DBF40-69C9-4DBD-BA3D-95C0AFB38F2A}"
1313
EndProject
14-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Winton.Extensions.Threading.Actor.Tests.Unit", "Winton.Extensions.Threading.Actor.Tests.Unit\Winton.Extensions.Threading.Actor.Tests.Unit.csproj", "{03F4D9C3-DEF8-4BCC-BFA6-EA42411277FD}"
14+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Winton.Extensions.Threading.Actor.Tests.Unit", "Winton.Extensions.Threading.Actor.Tests.Unit\Winton.Extensions.Threading.Actor.Tests.Unit.csproj", "{03F4D9C3-DEF8-4BCC-BFA6-EA42411277FD}"
15+
EndProject
16+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3A0C5AA3-92FF-4242-BF3E-052AB13A5DED}"
17+
ProjectSection(SolutionItems) = preProject
18+
.gitignore = .gitignore
19+
.travis.yml = .travis.yml
20+
appveyor.yml = appveyor.yml
21+
build.ps1 = build.ps1
22+
build.sh = build.sh
23+
CONTRIBUTING.md = CONTRIBUTING.md
24+
LICENSE = LICENSE
25+
README.md = README.md
26+
USAGE.md = USAGE.md
27+
EndProjectSection
1528
EndProject
1629
Global
1730
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -40,4 +53,7 @@ Global
4053
{883DBF40-69C9-4DBD-BA3D-95C0AFB38F2A} = {F9C63802-0833-4F6F-A220-3193ACA0FC67}
4154
{03F4D9C3-DEF8-4BCC-BFA6-EA42411277FD} = {E354296E-63FA-4DBA-9DBE-D4E135103671}
4255
EndGlobalSection
56+
GlobalSection(ExtensibilityGlobals) = postSolution
57+
SolutionGuid = {572EA2FB-BC0C-4C96-8DA6-3662C9A8F121}
58+
EndGlobalSection
4359
EndGlobal

Winton.Extensions.Threading.Actor/Actor.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88

99
namespace Winton.Extensions.Threading.Actor
1010
{
11-
/// <summary>
12-
/// Factories and extensions for actors.
13-
/// </summary>
11+
/// <inheritdoc />
1412
public sealed class Actor : IActor
1513
{
1614
[ThreadStatic]
@@ -50,52 +48,55 @@ public static ActorId CurrentId
5048
internal set => _currentId = value;
5149
}
5250

53-
/// <inheritdoc cref="IActor.Id"/>
51+
/// <inheritdoc />
5452
public ActorId Id => _impl.Id;
5553

56-
/// <inheritdoc cref="IActor.StartWork"/>
54+
/// <inheritdoc />
5755
public ActorStartWork StartWork
5856
{
5957
set => _impl.StartWork = value;
6058
}
6159

62-
/// <inheritdoc cref="IActor.StopWork"/>
60+
/// <inheritdoc />
6361
public ActorStopWork StopWork
6462
{
6563
set => _impl.StopWork = value;
6664
}
6765

66+
/// <inheritdoc />
67+
public Task StoppedTask => _impl.StoppedTask;
68+
6869
/// <inheritdoc cref="IActor.Start"/>
6970
public Task Start()
7071
{
7172
return _impl.Start();
7273
}
7374

74-
/// <inheritdoc cref="IActor.Stop"/>
75+
/// <inheritdoc />
7576
public Task Stop()
7677
{
7778
return _impl.Stop();
7879
}
7980

80-
/// <inheritdoc cref="IActor.Enqueue(Action,CancellationToken,ActorEnqueueOptions)"/>
81+
/// <inheritdoc />
8182
public Task Enqueue(Action action, CancellationToken cancellationToken, ActorEnqueueOptions options)
8283
{
8384
return _impl.Enqueue(action, cancellationToken, options);
8485
}
8586

86-
/// <inheritdoc cref="IActor.Enqueue{T}(Func{T},CancellationToken,ActorEnqueueOptions)"/>
87+
/// <inheritdoc />
8788
public Task<T> Enqueue<T>(Func<T> function, CancellationToken cancellationToken, ActorEnqueueOptions options)
8889
{
8990
return _impl.Enqueue(function, cancellationToken, options);
9091
}
9192

92-
/// <inheritdoc cref="IActor.Enqueue(Func{Task},CancellationToken,ActorEnqueueOptions)"/>
93+
/// <inheritdoc />
9394
public Task Enqueue(Func<Task> asyncAction, CancellationToken cancellationToken, ActorEnqueueOptions options)
9495
{
9596
return _impl.Enqueue(asyncAction, cancellationToken, options);
9697
}
9798

98-
/// <inheritdoc cref="IActor.Enqueue{T}(Func{Task{T}},CancellationToken,ActorEnqueueOptions)"/>
99+
/// <inheritdoc />
99100
public Task<T> Enqueue<T>(Func<Task<T>> asyncFunction, CancellationToken cancellationToken, ActorEnqueueOptions options)
100101
{
101102
return _impl.Enqueue(asyncFunction, cancellationToken, options);

Winton.Extensions.Threading.Actor/IActor.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ public interface IActor
3636
/// </remarks>
3737
ActorStopWork StopWork { set; }
3838

39+
/// <summary>
40+
/// This task completes when the actor stops.
41+
/// </summary>
42+
Task StoppedTask { get; }
43+
3944
/// <summary>
4045
/// Start the actor.
4146
/// </summary>

Winton.Extensions.Threading.Actor/Internal/ActorImpl.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ namespace Winton.Extensions.Threading.Actor.Internal
77
{
88
internal sealed class ActorImpl : IActor
99
{
10+
private readonly TaskCompletionSource<object> _stoppedPromise = new TaskCompletionSource<object>();
11+
1012
public ActorImpl(IActorTaskFactory actorTaskFactory)
1113
{
1214
Context = new ActorContext(actorTaskFactory);
@@ -24,14 +26,17 @@ public ActorStopWork StopWork
2426
set => Context.StopWork = value;
2527
}
2628

29+
public Task StoppedTask => _stoppedPromise.Task;
30+
2731
public Task Start()
2832
{
2933
return Context.Start();
3034
}
3135

32-
public Task Stop()
36+
public async Task Stop()
3337
{
34-
return Context.Stop();
38+
await Context.Stop();
39+
_stoppedPromise.TrySetResult(null);
3540
}
3641

3742
public Task Enqueue(Action action, CancellationToken cancellationToken, ActorEnqueueOptions options)

Winton.Extensions.Threading.Actor/Winton.Extensions.Threading.Actor.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
<PackageLicenseUrl>https://github.com/wintoncode/Winton.Extensions.Threading.Actor/blob/master/LICENSE</PackageLicenseUrl>
2121
<RepositoryType>git</RepositoryType>
2222
<RepositoryUrl>https://github.com/wintoncode/Winton.Extensions.Threading.Actor.git</RepositoryUrl>
23-
<NetStandardImplicitPackageVersion Condition=" '$(TargetFramework)' == 'netstandard1.3' ">1.6.1</NetStandardImplicitPackageVersion>
2423
<GenerateAssemblyCompanyAttribute>true</GenerateAssemblyCompanyAttribute>
2524
<GenerateAssemblyProductAttribute>true</GenerateAssemblyProductAttribute>
2625
<DelaySign>False</DelaySign>

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ dotnet build ./Winton.Extensions.Threading.Actor/Winton.Extensions.Threading.Act
2929
echo
3030

3131
echo "Testing ..."
32-
dotnet test ./Winton.Extensions.Threading.Actor.Tests.Unit/Winton.Extensions.Threading.Actor.Tests.Unit.csproj --configuration Release --framework netcoreapp1.1
32+
dotnet test ./Winton.Extensions.Threading.Actor.Tests.Unit/Winton.Extensions.Threading.Actor.Tests.Unit.csproj --configuration Release --framework netcoreapp1.0
3333
echo
3434

3535
if [ "${TRAVIS:-}" != "true" ]; then

0 commit comments

Comments
 (0)