Skip to content

Commit

Permalink
Add StartupTask feature (#90)
Browse files Browse the repository at this point in the history
* Add StartupTask feature

* Roll the extension methods into the config builder class to reduce confusion

Co-authored-by: Aaron Stannard <[email protected]>
  • Loading branch information
Arkatufus and Aaronontheweb authored Aug 11, 2022
1 parent d27f0e6 commit e377bff
Showing 1 changed file with 47 additions and 0 deletions.
47 changes: 47 additions & 0 deletions src/Akka.Hosting/AkkaConfigurationBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public enum HoconAddMode
/// </summary>
public delegate Task ActorStarter(ActorSystem system, IActorRegistry registry);

public delegate Task StartupTask(ActorSystem system, IActorRegistry registry);

/// <summary>
/// Used to help populate a <see cref="SerializationSetup"/> upon starting the <see cref="ActorSystem"/>,
/// if any are added to the builder;
Expand Down Expand Up @@ -99,6 +101,7 @@ public sealed class AkkaConfigurationBuilder
internal Option<ActorSystem> Sys { get; set; } = Option<ActorSystem>.None;

private readonly HashSet<ActorStarter> _actorStarters = new HashSet<ActorStarter>();
private readonly HashSet<StartupTask> _startupTasks = new HashSet<StartupTask>();
private bool _complete = false;

public AkkaConfigurationBuilder(IServiceCollection serviceCollection, string actorSystemName)
Expand Down Expand Up @@ -179,6 +182,17 @@ Task Starter(ActorSystem f, IActorRegistry registry)

return Starter;
}

private static StartupTask ToAsyncStartup(Action<ActorSystem, IActorRegistry> nonAsyncStartup)
{
Task Startup(ActorSystem f, IActorRegistry registry)
{
nonAsyncStartup(f, registry);
return Task.CompletedTask;
}

return Startup;
}

public AkkaConfigurationBuilder StartActors(Action<ActorSystem, IActorRegistry> starter)
{
Expand All @@ -194,6 +208,34 @@ public AkkaConfigurationBuilder StartActors(ActorStarter starter)
return this;
}

/// <summary>
/// Adds a <see cref="StartupTask"/> delegate that will be executed exactly once for application initialization
/// once the <see cref="ActorSystem"/> and all actors is started in this process.
/// </summary>
/// <param name="startupTask">A <see cref="StartupTask"/> delegate that will be run after all actors
/// have been instantiated.</param>
/// <returns>The same <see cref="AkkaConfigurationBuilder"/> instance originally passed in.</returns>
public AkkaConfigurationBuilder AddStartup(Action<ActorSystem, IActorRegistry> startupTask)
{
if (_complete) return this;
_startupTasks.Add(ToAsyncStartup(startupTask));
return this;
}

/// <summary>
/// Adds a <see cref="StartupTask"/> delegate that will be executed exactly once for application initialization
/// once the <see cref="ActorSystem"/> and all actors is started in this process.
/// </summary>
/// <param name="startupTask">A <see cref="StartupTask"/> delegate that will be run after all actors
/// have been instantiated.</param>
/// <returns>The same <see cref="AkkaConfigurationBuilder"/> instance originally passed in.</returns>
public AkkaConfigurationBuilder AddStartup(StartupTask startupTask)
{
if (_complete) return this;
_startupTasks.Add(startupTask);
return this;
}

public AkkaConfigurationBuilder WithCustomSerializer(
string serializerIdentifier, IEnumerable<Type> boundTypes,
Func<ExtendedActorSystem, Serializer> serializerFactory)
Expand Down Expand Up @@ -366,6 +408,11 @@ internal async Task<ActorSystem> StartAsync(ActorSystem sys)
await starter(sys, registry).ConfigureAwait(false);
}

foreach (var startupTask in _startupTasks)
{
await startupTask(sys, registry).ConfigureAwait(false);
}

return sys;
}
}
Expand Down

0 comments on commit e377bff

Please sign in to comment.