Skip to content

Commit

Permalink
Merge pull request #385 from MUnique/config-hot-reload
Browse files Browse the repository at this point in the history
🔥 Configuration Hot Reload
  • Loading branch information
sven-n authored Nov 11, 2023
2 parents f279efd + 0275dc8 commit de327bf
Show file tree
Hide file tree
Showing 265 changed files with 3,592 additions and 319 deletions.
4 changes: 3 additions & 1 deletion deploy/distributed/docker-compose.dcproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
<DockerLaunchAction>None</DockerLaunchAction>
<DockerServiceUrl>{Scheme}://localhost:{ServicePort}</DockerServiceUrl>
</PropertyGroup>
<PropertyGroup />
<PropertyGroup>
<DockerServiceName>openmu-distributed</DockerServiceName>
</PropertyGroup>
<ItemGroup>
<None Include="dapr-components\config.yaml" />
<None Include="dapr-components\localSecretStore.yaml" />
Expand Down
3 changes: 1 addition & 2 deletions deploy/distributed/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@
"grafana": "StartWithoutDebugging",
"loki": "StartWithoutDebugging",
"minio": "StartWithoutDebugging",
"nginx": "StartWithoutDebugging",
"nginx-80": "StartWithoutDebugging",
"prometheus": "StartWithoutDebugging",
"zipkin": "StartWithoutDebugging"
"zipkin": "StartWithoutDebugging",
"gameServer0": "StartWithoutDebugging",
"gameServer0-dapr": "StartWithoutDebugging",
Expand Down
14 changes: 14 additions & 0 deletions src/Annotations/CloneableAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// <copyright file="CloneableAttribute.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Annotations;

/// <summary>
/// Classes marked with this attribute will get a generic Clonable-Interface
/// implemented by a code generator.
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class CloneableAttribute : Attribute
{
}
12 changes: 12 additions & 0 deletions src/Annotations/MUnique.OpenMU.Annotations.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable;CS4014;VSTHRD110;VSTHRD100</WarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 10 additions & 0 deletions src/Dapr/Common/ConfigurationChangeArguments.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// <copyright file="ConfigurationChangeArguments.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Dapr.Common;

/// <summary>
/// Arguments for the change notifications of <see cref="ConfigurationChangePublisher"/>.
/// </summary>
public record class ConfigurationChangeArguments(Type Type, Guid Id, object? Configuration);
15 changes: 12 additions & 3 deletions src/Dapr/Common/ConfigurationChangePublisher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ public ConfigurationChangePublisher(DaprClient daprClient)
/// <param name="configuration">The changed configuration.</param>
public Task ConfigurationChangedAsync(Type type, Guid id, object configuration)
{
return this._daprClient.PublishEventAsync("pubsub", nameof(this.ConfigurationChangedAsync), configuration);
return this._daprClient.PublishEventAsync(
"pubsub",
nameof(this.ConfigurationChangedAsync),
new ConfigurationChangeArguments(type, id, configuration));
}

/// <summary>
Expand All @@ -43,7 +46,10 @@ public Task ConfigurationChangedAsync(Type type, Guid id, object configuration)
/// <param name="configuration">The added configuration.</param>
public Task ConfigurationAddedAsync(Type type, Guid id, object configuration)
{
return this._daprClient.PublishEventAsync("pubsub", nameof(this.ConfigurationAddedAsync), configuration);
return this._daprClient.PublishEventAsync(
"pubsub",
nameof(this.ConfigurationAddedAsync),
new ConfigurationChangeArguments(type, id, configuration));
}

/// <summary>
Expand All @@ -53,6 +59,9 @@ public Task ConfigurationAddedAsync(Type type, Guid id, object configuration)
/// <param name="id">The identifier of the removed configuration.</param>
public Task ConfigurationRemovedAsync(Type type, Guid id)
{
return this._daprClient.PublishEventAsync("pubsub", nameof(this.ConfigurationRemovedAsync), id);
return this._daprClient.PublishEventAsync(
"pubsub",
nameof(this.ConfigurationRemovedAsync),
new ConfigurationChangeArguments(type, id, null));
}
}
4 changes: 3 additions & 1 deletion src/Dapr/Common/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public static class Extensions
/// <returns>The services.</returns>
public static IServiceCollection AddPeristenceProvider(this IServiceCollection services, bool publishConfigChanges = false)
{
services.AddSingleton<IConfigurationChangeListener, ConfigurationChangeListener>();
if (publishConfigChanges)
{
services.AddSingleton<IConfigurationChangePublisher, ConfigurationChangePublisher>();
Expand All @@ -49,7 +50,8 @@ public static IServiceCollection AddPeristenceProvider(this IServiceCollection s
return services
.AddSingleton<IMigratableDatabaseContextProvider, PersistenceContextProvider>()
.AddSingleton(s => (PersistenceContextProvider)s.GetService<IMigratableDatabaseContextProvider>()!)
.AddSingleton(s => (IPersistenceContextProvider)s.GetService<IMigratableDatabaseContextProvider>()!);
.AddSingleton(s => (IPersistenceContextProvider)s.GetService<IMigratableDatabaseContextProvider>()!)
.AddSingleton(s => new Lazy<IPersistenceContextProvider>(s.GetRequiredService<IPersistenceContextProvider>));
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Dapr/Common/MUnique.OpenMU.Dapr.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<PackageReference Include="Dapr.Client" Version="1.10.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
<PackageReference Include="Microsoft.OpenApi" Version="1.4.3" />
<PackageReference Include="Microsoft.OpenApi" Version="1.6.10" />
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.3.1" />
<PackageReference Include="OpenTelemetry.Exporter.Prometheus" Version="1.2.0-rc5" />
<PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.3.1" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
Expand Down
66 changes: 66 additions & 0 deletions src/Dapr/GameServer.Host/ConfigurationChangeController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// <copyright file="ConfigurationChangeController.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.GameServer.Host;

using global::Dapr;
using Microsoft.AspNetCore.Mvc;
using MUnique.OpenMU.Dapr.Common;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Persistence.EntityFramework;

/// <summary>
/// The API controller which handles the calls of the <see cref="ConfigurationChangePublisher"/>
/// from other services, such as the AdminPanel.
/// It forwards the changes to a <see cref="IConfigurationChangeListener"/>, so
/// that the caches are updated and the game logic can react to that.
/// </summary>
[ApiController]
[Route("")]
public class ConfigurationChangeController : ControllerBase
{
private readonly IConfigurationChangeListener _changeListener;

/// <summary>
/// Initializes a new instance of the <see cref="ConfigurationChangeController" /> class.
/// </summary>
/// <param name="changeListener">The change listener.</param>
public ConfigurationChangeController(IConfigurationChangeListener changeListener)
{
this._changeListener = changeListener;
}

/// <summary>
/// Called when a configuration got added on the admin panel.
/// </summary>
/// <param name="arguments">The message arguments.</param>
[HttpPost(nameof(IConfigurationChangePublisher.ConfigurationAddedAsync))]
[Topic("pubsub", nameof(IConfigurationChangePublisher.ConfigurationAddedAsync))]
public ValueTask ConfigurationAddedAsync([FromBody] ConfigurationChangeArguments arguments)
{
return this._changeListener.ConfigurationAddedAsync(arguments.Type, arguments.Id, arguments.Configuration!, null, null);
}

/// <summary>
/// Called when a configuration got added on the admin panel.
/// </summary>
/// <param name="arguments">The message arguments.</param>
[HttpPost(nameof(IConfigurationChangePublisher.ConfigurationChangedAsync))]
[Topic("pubsub", nameof(IConfigurationChangePublisher.ConfigurationChangedAsync))]
public ValueTask ConfigurationChangedAsync([FromBody] ConfigurationChangeArguments arguments)
{
return this._changeListener.ConfigurationChangedAsync(arguments.Type, arguments.Id, arguments.Configuration!, null);
}

/// <summary>
/// Called when a configuration got removed on the admin panel.
/// </summary>
/// <param name="arguments">The message arguments.</param>
[HttpPost(nameof(IConfigurationChangePublisher.ConfigurationRemovedAsync))]
[Topic("pubsub", nameof(IConfigurationChangePublisher.ConfigurationRemovedAsync))]
public ValueTask ConfigurationRemovedAsync([FromBody] ConfigurationChangeArguments arguments)
{
return this._changeListener.ConfigurationRemovedAsync(arguments.Type, arguments.Id, null, null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
Expand Down
5 changes: 4 additions & 1 deletion src/Dapr/GameServer.Host/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
using Microsoft.Extensions.DependencyInjection;
using MUnique.OpenMU.Dapr.Common;
using MUnique.OpenMU.DataModel.Configuration;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.GameServer.Host;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Network;
using MUnique.OpenMU.PlugIns;
using MUnique.OpenMU.ServerClients;
using MUnique.OpenMU.Web.Map;
Expand All @@ -29,6 +29,9 @@
.AddSingleton<IList<IManageableServer>>(s => new List<IManageableServer>() { s.GetService<GameServer>()! })
.AddSingleton(s => s.GetService<GameServer>()!.Context)
.AddSingleton<IGameServerStateObserver, GameServerStatePublisher>()
.AddSingleton<ConfigurationChangeMediator>()
.AddSingleton<IConfigurationChangeMediator>(s => s.GetRequiredService<ConfigurationChangeMediator>())
.AddSingleton<IConfigurationChangeMediatorListener>(s => s.GetRequiredService<ConfigurationChangeMediator>())
.AddSingleton<ILoginServer, LoginServer>()
.AddSingleton<IGuildServer, GuildServer>()
.AddSingleton<IEventPublisher, EventPublisher>()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.18.1" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.5" />
</ItemGroup>

<ItemGroup>
Expand Down
51 changes: 51 additions & 0 deletions src/DataModel/AssignableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// <copyright file="AssignableExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.DataModel;

using MUnique.OpenMU.DataModel.Configuration;

/// <summary>
/// Extensions for <see cref="IAssignable{T}"/>.
/// </summary>
public static class AssignableExtensions
{
/// <summary>
/// Assigns a collection to another one, resolving the objects to the ones
/// which are contained in the given <see cref="GameConfiguration"/>.
/// </summary>
/// <typeparam name="T">The type of the collection elements.</typeparam>
/// <param name="collection">The target collection.</param>
/// <param name="other">The other collection.</param>
/// <param name="gameConfiguration">The game configuration.</param>
public static void AssignCollection<T>(this ICollection<T> collection, ICollection<T> other, GameConfiguration gameConfiguration)
where T : class
{
var newItems = collection.Except(other).ToList();
var oldItems = other.Except(collection).ToList();

oldItems.ForEach(i => collection.Remove(i));
newItems.ForEach(i => collection.Add(
gameConfiguration.GetObjectOfConfig(i)
?? (i as ICloneable<T>)?.Clone(gameConfiguration)
?? (i as ICloneable)?.Clone() as T
?? i));
}

/// <summary>
/// Assigns a collection to another one.
/// </summary>
/// <typeparam name="T">The type of the collection values.</typeparam>
/// <param name="collection">The target collection.</param>
/// <param name="other">The other collection.</param>
public static void AssignCollection<T>(this ICollection<T> collection, ICollection<T> other)
where T : struct
{
var newItems = collection.Except(other).ToList();
var oldItems = other.Except(collection).ToList();

oldItems.ForEach(i => collection.Remove(i));
newItems.ForEach(collection.Add);
}
}
4 changes: 3 additions & 1 deletion src/DataModel/Attributes/PowerUpDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
namespace MUnique.OpenMU.DataModel.Attributes;

using System.Globalization;
using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.AttributeSystem;

/// <summary>
/// The power up definition which describes the boost of an target attribute.
/// </summary>
public class PowerUpDefinition
[Cloneable]
public partial class PowerUpDefinition
{
/// <summary>
/// Gets or sets the target attribute.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Attributes/PowerUpDefinitionValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
namespace MUnique.OpenMU.DataModel.Attributes;

using System.ComponentModel;
using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.AttributeSystem;

/// <summary>
/// The power up definition value which can consist of a constant value and several related values which are all added together to get the result.
/// </summary>
public class PowerUpDefinitionValue
[Cloneable]
public partial class PowerUpDefinitionValue
{
/// <summary>
/// Gets or sets the constant value part of the value.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/BattleZoneDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines a battle zone.
/// </summary>
public class BattleZoneDefinition
[Cloneable]
public partial class BattleZoneDefinition
{
/// <summary>
/// Gets or sets the battle type.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/CharacterClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.AttributeSystem;
using MUnique.OpenMU.DataModel.Entities;

/// <summary>
/// Defines a character class.
/// </summary>
public class CharacterClass
[Cloneable]
public partial class CharacterClass
{
/// <summary>
/// Gets or sets the id of a character class.
Expand Down
Loading

0 comments on commit de327bf

Please sign in to comment.