From c1a1312ad72e453d8b1032896ff88937ebee26cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 30 Jan 2025 17:32:47 +0100 Subject: [PATCH 01/11] parametrize keep alive options --- .../ArmoniK.Api.Common/Options/GrpcChannel.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs index 5ba786101..68666a338 100644 --- a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs +++ b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs @@ -21,6 +21,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; + using JetBrains.Annotations; namespace ArmoniK.Api.Common.Options; @@ -40,4 +42,15 @@ public class GrpcChannel /// Type of gRPC Socket used /// public GrpcSocketType SocketType { get; set; } = GrpcSocketType.UnixDomainSocket; + + /// + /// Keep-alive ping timeout for http2 connections + /// + public TimeSpan KeepAlivePingTimeOut { get; set; } = TimeSpan.MaxValue; + + /// + /// Keep-alive timeout + /// + public TimeSpan KeepAliveTimeOut { get; set; } = TimeSpan.MaxValue; + } From c86a632f8e2748180ace30f482a18db6b8386f1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 31 Jan 2025 12:08:58 +0100 Subject: [PATCH 02/11] use keep alive options in worker server --- packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs | 1 - packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs index 68666a338..2b4d00fb4 100644 --- a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs +++ b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs @@ -52,5 +52,4 @@ public class GrpcChannel /// Keep-alive timeout /// public TimeSpan KeepAliveTimeOut { get; set; } = TimeSpan.MaxValue; - } diff --git a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs index 83ce861b0..173636cd3 100644 --- a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs +++ b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs @@ -133,6 +133,8 @@ public static WebApplication Create(Action listenOptions.Protocols = HttpProtocols.Http2); break; case GrpcSocketType.Tcp: + options.Limits.Http2.KeepAlivePingTimeout = computePlaneOptions.WorkerChannel.KeepAlivePingTimeOut; + options.Limits.KeepAliveTimeout = computePlaneOptions.WorkerChannel.KeepAliveTimeOut; var uri = new Uri(address); options.ListenAnyIP(uri.Port, listenOptions => listenOptions.Protocols = HttpProtocols.Http2); From 76e6f2813de9753017120c544b6d4b4dc195552e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Tue, 4 Feb 2025 18:08:48 +0100 Subject: [PATCH 03/11] use default values from oficial docs for parametrized keepalive options --- packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs index 2b4d00fb4..ebd5efb00 100644 --- a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs +++ b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs @@ -46,10 +46,10 @@ public class GrpcChannel /// /// Keep-alive ping timeout for http2 connections /// - public TimeSpan KeepAlivePingTimeOut { get; set; } = TimeSpan.MaxValue; + public TimeSpan KeepAlivePingTimeOut { get; set; } = TimeSpan.FromSeconds(20); /// /// Keep-alive timeout /// - public TimeSpan KeepAliveTimeOut { get; set; } = TimeSpan.MaxValue; + public TimeSpan KeepAliveTimeOut { get; set; } = TimeSpan.FromSeconds(130); } From cf9cc2f43bc29fa8434f3e496ebdfadd3993cf28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 5 Feb 2025 13:31:21 +0100 Subject: [PATCH 04/11] parametrize keep alive options: support to define them as 'MaxValue' --- .../Options/ComputePlane.cs | 10 +++++ .../ArmoniK.Api.Common/Options/GrpcChannel.cs | 4 +- .../ArmoniK.Api.Worker/Utils/WorkerServer.cs | 37 +++++++++++++++++-- 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs b/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs index 7af50c4a1..c8aa52210 100644 --- a/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs +++ b/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs @@ -38,6 +38,16 @@ public class ComputePlane /// public const string SettingSection = nameof(ComputePlane); + /// + /// Path to the section containing the worker channel values in configuration object + /// + public const string WorkerChannelSection = "WorkerChannel"; + + /// + /// Path to the section containing the agent channel values in configuration object + /// + public const string AgentChannelSection = "AgentChannel"; + /// /// Channel used by the Agent to send tasks to the Worker /// diff --git a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs index ebd5efb00..212e69979 100644 --- a/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs +++ b/packages/csharp/ArmoniK.Api.Common/Options/GrpcChannel.cs @@ -46,10 +46,10 @@ public class GrpcChannel /// /// Keep-alive ping timeout for http2 connections /// - public TimeSpan KeepAlivePingTimeOut { get; set; } = TimeSpan.FromSeconds(20); + public TimeSpan KeepAlivePingTimeOut { get; set; } /// /// Keep-alive timeout /// - public TimeSpan KeepAliveTimeOut { get; set; } = TimeSpan.FromSeconds(130); + public TimeSpan KeepAliveTimeOut { get; set; } } diff --git a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs index 173636cd3..c90756b7a 100644 --- a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs +++ b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs @@ -118,9 +118,9 @@ public static WebApplication Create(Action + builder.WebHost.ConfigureKestrel((context, options) => { - var address = computePlaneOptions.WorkerChannel.Address; + var address = computePlaneOptions.WorkerChannel.Address; switch (computePlaneOptions.WorkerChannel.SocketType) { case GrpcSocketType.UnixDomainSocket: @@ -133,12 +133,41 @@ public static WebApplication Create(Action listenOptions.Protocols = HttpProtocols.Http2); break; case GrpcSocketType.Tcp: - options.Limits.Http2.KeepAlivePingTimeout = computePlaneOptions.WorkerChannel.KeepAlivePingTimeOut; - options.Limits.KeepAliveTimeout = computePlaneOptions.WorkerChannel.KeepAliveTimeOut; + + var channelOptions = context.Configuration.GetRequiredSection(ComputePlane.SettingSection). + GetSection(ComputePlane.AgentChannelSection); + options.Limits.Http2.KeepAlivePingTimeout = ParseTimeSpan(channelOptions["KeepAlivePingTimeout"], + TimeSpan.FromSeconds(20)); + options.Limits.KeepAliveTimeout = ParseTimeSpan(channelOptions["KeepAliveTimeOut"], + TimeSpan.FromSeconds(130)); var uri = new Uri(address); options.ListenAnyIP(uri.Port, listenOptions => listenOptions.Protocols = HttpProtocols.Http2); break; + + /* Local function to parse the KeepAlive options from the configuration section. + If the section to parse does not exist returns the given defaultValue + If a valid Time.Span string has been provided it parses and returns it + Provide support to handle the case where the option has been set to "MaxValue". + */ + TimeSpan ParseTimeSpan(string? toParse, + TimeSpan defaultValue) + { + if (string.IsNullOrEmpty(toParse)) + { + return defaultValue; + } + if (toParse.Equals("MaxValue")) + { + return TimeSpan.MaxValue; + } + if (TimeSpan.TryParse(toParse, + out var result)) + { + return result; + } + throw new FormatException($"Provide a valid TimeSpan format: {toParse} or 'MaxValue'"); + } default: throw new InvalidOperationException("Socket type unknown"); } From 2a2bcfd40e1433efeb292d6bea59464ffd8cd462 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Wed, 5 Feb 2025 13:41:58 +0100 Subject: [PATCH 05/11] format and correct requested section --- .../csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs index c90756b7a..7e96e8b56 100644 --- a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs +++ b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs @@ -135,7 +135,7 @@ public static WebApplication Create(Action(Action Date: Wed, 5 Feb 2025 13:50:16 +0100 Subject: [PATCH 06/11] use nameof() instead of naked string --- packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs b/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs index c8aa52210..af5dbadf4 100644 --- a/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs +++ b/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs @@ -41,12 +41,12 @@ public class ComputePlane /// /// Path to the section containing the worker channel values in configuration object /// - public const string WorkerChannelSection = "WorkerChannel"; + public const string WorkerChannelSection = nameof(WorkerChannel); /// /// Path to the section containing the agent channel values in configuration object /// - public const string AgentChannelSection = "AgentChannel"; + public const string AgentChannelSection = nameof(AgentChannel); /// /// Channel used by the Agent to send tasks to the Worker From 233394492cfb2cd61c83b465b3da6cd09a877010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 6 Feb 2025 10:32:02 +0100 Subject: [PATCH 07/11] use extension methods --- .../ArmoniK.Api.Common.csproj | 3 + .../Utils/ConfigurationExt.cs | 94 +++++++++++++++++++ .../ArmoniK.Api.Worker/Utils/WorkerServer.cs | 32 +------ 3 files changed, 100 insertions(+), 29 deletions(-) create mode 100644 packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs diff --git a/packages/csharp/ArmoniK.Api.Common/ArmoniK.Api.Common.csproj b/packages/csharp/ArmoniK.Api.Common/ArmoniK.Api.Common.csproj index 7a70cbb33..f0eea8ea0 100755 --- a/packages/csharp/ArmoniK.Api.Common/ArmoniK.Api.Common.csproj +++ b/packages/csharp/ArmoniK.Api.Common/ArmoniK.Api.Common.csproj @@ -28,6 +28,9 @@ runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs b/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs new file mode 100644 index 000000000..188a59fca --- /dev/null +++ b/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs @@ -0,0 +1,94 @@ +// This file is part of the ArmoniK project +// +// Copyright (C) ANEO, 2021-2025. All rights reserved. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY, without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +using System; + +using Microsoft.Extensions.Configuration; + +namespace ArmoniK.Api.Common.Utils; + +/// +/// Extends the functionality of the +/// +public static class ConfigurationExt +{ + /// + /// Configure an object with the given configuration. + /// + /// Type of the options class + /// Configurations used to populate the class + /// Path to the Object in the configuration + /// + /// The initialized object + /// + /// the is not found in the configurations. + public static T GetRequiredValue(this IConfiguration configuration, + string key) + => configuration.GetRequiredSection(key) + .Get() ?? throw new InvalidOperationException($"{key} not found"); + + /// + /// Configure an object with the given configuration. + /// If the object is not found in the configuration, a new object in returned. + /// + /// Type of the options class + /// Configurations used to populate the class + /// Path to the Object in the configuration + /// + /// The initialized object + /// + public static T GetInitializedValue(this IConfiguration configuration, + string key) + where T : new() + => configuration.GetSection(key) + .Get() ?? new T(); + + /// + /// Retrieves a from the configuration, or returns the provided default value if not found or invalid. + /// If the configuration contains "MaxValue", it will return . + /// + /// The instance from which to retrieve the value. + /// The key of the configuration value to retrieve. + /// The default value to return if the key is not found or the value is invalid. + /// A representing the configuration value, or if invalid or missing. + /// Thrown if the value is not a valid or "MaxValue". + public static TimeSpan GetTimeSpanOrDefault(this IConfiguration configuration, + string key, + TimeSpan defaultValue) + { + try + { + return GetRequiredValue(configuration, + key); + } + catch (Exception) + { + var value = configuration.GetValue(key); + if (string.IsNullOrEmpty(value)) + { + return defaultValue; + } + + if (value!.Equals("MaxValue")) + { + return TimeSpan.MaxValue; + } + + throw new FormatException($"'{key}' must be a valid TimeSpan or 'MaxValue'."); + } + } +} diff --git a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs index 7e96e8b56..efe4a18ac 100644 --- a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs +++ b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs @@ -26,6 +26,7 @@ using ArmoniK.Api.Common.Channel.Utils; using ArmoniK.Api.Common.Options; +using ArmoniK.Api.Common.Utils; using JetBrains.Annotations; @@ -136,40 +137,13 @@ public static WebApplication Create(Action listenOptions.Protocols = HttpProtocols.Http2); break; - - /* Local function to parse the KeepAlive options from the configuration section. - If the section to parse does not exist returns the given defaultValue - If a valid Time.Span string has been provided it parses and returns it - Provide support to handle the case where the option has been set to "MaxValue". */ - TimeSpan ParseTimeSpan(string? toParse, - TimeSpan defaultValue) - { - if (string.IsNullOrEmpty(toParse)) - { - return defaultValue; - } - - if (toParse.Equals("MaxValue")) - { - return TimeSpan.MaxValue; - } - - if (TimeSpan.TryParse(toParse, - out var result)) - { - return result; - } - - throw new FormatException($"Provide a valid TimeSpan format: {toParse} or 'MaxValue'"); - } default: throw new InvalidOperationException("Socket type unknown"); } From 3cbdf4fcaa599d876ca4566bc1829bd2935633a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Thu, 6 Feb 2025 12:28:52 +0100 Subject: [PATCH 08/11] parse compute plane options before passing them to the DI --- .../ArmoniK.Api.Worker/Utils/WorkerServer.cs | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs index efe4a18ac..ecf7e59b1 100644 --- a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs +++ b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs @@ -110,19 +110,38 @@ public static WebApplication Create(Action(); - - if (computePlaneOptions?.WorkerChannel is null) - { - throw new Exception($"{nameof(computePlaneOptions.WorkerChannel)} options should not be null"); - } + var rawComputePlaneOptions = builder.Configuration.GetRequiredSection(ComputePlane.SettingSection); + var workerChannelOptions = rawComputePlaneOptions. + GetRequiredSection(ComputePlane.WorkerChannelSection); + var agentChannelOptions = rawComputePlaneOptions.GetRequiredSection(ComputePlane.WorkerChannelSection); + var parsedComputePlaneOptions = new ComputePlane + { + WorkerChannel = new GrpcChannel + { + Address = workerChannelOptions.GetRequiredValue("Address"), + SocketType = workerChannelOptions.GetValue("SocketType", GrpcSocketType.UnixDomainSocket), + KeepAlivePingTimeOut = workerChannelOptions.GetTimeSpanOrDefault("KeepAlivePingTimeOut", + TimeSpan.FromSeconds(20)), + KeepAliveTimeOut = workerChannelOptions.GetTimeSpanOrDefault("KeepAliveTimeOut", + TimeSpan.FromSeconds(130)), + }, + AgentChannel = new GrpcChannel + { + Address = agentChannelOptions.GetRequiredValue("Address"), + SocketType = agentChannelOptions.GetValue("SocketType", GrpcSocketType.UnixDomainSocket), + KeepAlivePingTimeOut = agentChannelOptions.GetTimeSpanOrDefault("KeepAlivePingTimeOut", + TimeSpan.FromSeconds(20)), + KeepAliveTimeOut = agentChannelOptions.GetTimeSpanOrDefault("KeepAliveTimeOut", + TimeSpan.FromSeconds(130)), + }, + MessageBatchSize = rawComputePlaneOptions.GetValue("MessageBatchSize", 1), + AbortAfter = rawComputePlaneOptions.GetValue("AbortAfter", TimeSpan.Zero), + }; builder.WebHost.ConfigureKestrel((context, options) => { - var address = computePlaneOptions.WorkerChannel.Address; - switch (computePlaneOptions.WorkerChannel.SocketType) + var address = parsedComputePlaneOptions.WorkerChannel.Address; + switch (parsedComputePlaneOptions.WorkerChannel.SocketType) { case GrpcSocketType.UnixDomainSocket: if (File.Exists(address)) @@ -134,12 +153,8 @@ public static WebApplication Create(Action listenOptions.Protocols = HttpProtocols.Http2); break; case GrpcSocketType.Tcp: - - var channelOptions = context.Configuration.GetRequiredSection(ComputePlane.SettingSection). - GetSection(ComputePlane.WorkerChannelSection); - options.Limits.KeepAliveTimeout = channelOptions.GetTimeSpanOrDefault("KeepAliveTimeOut",TimeSpan.FromSeconds(130)); - options.Limits.Http2.KeepAlivePingTimeout = channelOptions.GetTimeSpanOrDefault("KeepAlivePingTimeOut", - TimeSpan.FromSeconds(20)); + options.Limits.KeepAliveTimeout = parsedComputePlaneOptions.WorkerChannel.KeepAliveTimeOut; + options.Limits.Http2.KeepAlivePingTimeout = parsedComputePlaneOptions.WorkerChannel.KeepAlivePingTimeOut; var uri = new Uri(address); options.ListenAnyIP(uri.Port, listenOptions => listenOptions.Protocols = HttpProtocols.Http2); @@ -152,8 +167,8 @@ public static WebApplication Create(Action() .AddSingleton(_ => loggerFactory) .AddSingleton() - .AddSingleton(computePlaneOptions) - .AddSingleton(computePlaneOptions.AgentChannel) + .AddSingleton(parsedComputePlaneOptions) + .AddSingleton(parsedComputePlaneOptions.AgentChannel) .AddLogging() .AddGrpcReflection() .AddGrpc(options => options.MaxReceiveMessageSize = null); From c3cce58f36f94f609b32fd660fc43e24764bede6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 7 Feb 2025 01:11:27 +0100 Subject: [PATCH 09/11] add unit test and some corrections --- .../ArmoniK.Api.Tests/WorkerServerTest.cs | 52 +++++++++++++++++++ .../ArmoniK.Api.Worker/Utils/WorkerServer.cs | 6 +-- 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs b/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs index 3f84156b3..ced342e72 100644 --- a/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs +++ b/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs @@ -27,6 +27,7 @@ using ArmoniK.Api.Common.Channel.Utils; using ArmoniK.Api.Common.Options; +using ArmoniK.Api.Common.Utils; using ArmoniK.Api.Worker.Utils; using ArmoniK.Api.Worker.Worker; @@ -106,11 +107,60 @@ public Task BuildServerConfigurator() return Task.CompletedTask; } + [Test] + public Task BuildServerConfiguratorTcp() + { + var collection = new List> + { + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.WorkerChannel)}:{nameof(ComputePlane.WorkerChannel.Address)}", + "http://localhost:10667"), + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.WorkerChannel)}:{nameof(ComputePlane.WorkerChannel.SocketType)}", + GrpcSocketType.Tcp.ToString()), + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.WorkerChannel)}:{nameof(ComputePlane.WorkerChannel.KeepAliveTimeOut)}", + "MaxValue"), + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.WorkerChannel)}:{nameof(ComputePlane.WorkerChannel.KeepAlivePingTimeOut)}", + "MaxValue"), + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.Address)}", + "http://localhost:10666"), + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.KeepAliveTimeOut)}", + TimeSpan.FromSeconds(100).ToString()), + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.KeepAlivePingTimeOut)}", + TimeSpan.FromSeconds(5).ToString()), + new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.SocketType)}", + GrpcSocketType.Tcp.ToString()), + }; + + var app = WorkerServer.Create((_, + configuration) => + { + foreach (var pair in collection) + { + configuration[pair.Key] = pair.Value; + } + }); + + var computePlane = app.Services.GetRequiredService(); + + Assert.AreEqual(computePlane.WorkerChannel.KeepAliveTimeOut, + TimeSpan.MaxValue); + Assert.AreEqual(computePlane.WorkerChannel.KeepAliveTimeOut, + TimeSpan.MaxValue); + + Assert.AreEqual(computePlane.AgentChannel.KeepAliveTimeOut, + TimeSpan.FromSeconds(100)); + Assert.AreEqual(computePlane.AgentChannel.KeepAlivePingTimeOut, + TimeSpan.FromSeconds(5)); + + return Task.CompletedTask; + } + [Test] public Task BuildServerNoArgs() { Environment.SetEnvironmentVariable($"{nameof(ComputePlane)}__{nameof(ComputePlane.WorkerChannel)}__{nameof(ComputePlane.WorkerChannel.Address)}", "/tmp/worker.sock"); + Environment.SetEnvironmentVariable($"{nameof(ComputePlane)}__{nameof(ComputePlane.AgentChannel)}__{nameof(ComputePlane.AgentChannel.Address)}", + "/tmp/agent.sock"); var app = WorkerServer.Create(); return Task.CompletedTask; } @@ -120,6 +170,8 @@ public Task BuildServerAddService() { Environment.SetEnvironmentVariable($"{nameof(ComputePlane)}__{nameof(ComputePlane.WorkerChannel)}__{nameof(ComputePlane.WorkerChannel.Address)}", "/tmp/worker.sock"); + Environment.SetEnvironmentVariable($"{nameof(ComputePlane)}__{nameof(ComputePlane.AgentChannel)}__{nameof(ComputePlane.AgentChannel.Address)}", + "/tmp/agent.sock"); var app = WorkerServer.Create(serviceConfigurator: collection => collection.AddSingleton("test")); return Task.CompletedTask; } diff --git a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs index ecf7e59b1..2d6082c15 100644 --- a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs +++ b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs @@ -113,7 +113,7 @@ public static WebApplication Create(Action(Action + builder.WebHost.ConfigureKestrel(options => { var address = parsedComputePlaneOptions.WorkerChannel.Address; switch (parsedComputePlaneOptions.WorkerChannel.SocketType) From 417cf6339239e11eeeb3e9373f004290f35aa8f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 7 Feb 2025 11:13:01 +0100 Subject: [PATCH 10/11] reomve unnused function --- .../Utils/ConfigurationExt.cs | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs b/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs index 188a59fca..008fbcab2 100644 --- a/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs +++ b/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs @@ -40,23 +40,7 @@ public static T GetRequiredValue(this IConfiguration configuration, string key) => configuration.GetRequiredSection(key) .Get() ?? throw new InvalidOperationException($"{key} not found"); - - /// - /// Configure an object with the given configuration. - /// If the object is not found in the configuration, a new object in returned. - /// - /// Type of the options class - /// Configurations used to populate the class - /// Path to the Object in the configuration - /// - /// The initialized object - /// - public static T GetInitializedValue(this IConfiguration configuration, - string key) - where T : new() - => configuration.GetSection(key) - .Get() ?? new T(); - + /// /// Retrieves a from the configuration, or returns the provided default value if not found or invalid. /// If the configuration contains "MaxValue", it will return . From 3e3de18f90a0be95aca349db49341929fe28418c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Fonseca?= Date: Fri, 7 Feb 2025 11:19:48 +0100 Subject: [PATCH 11/11] fix linter --- .../Options/ComputePlane.cs | 2 +- .../Utils/ConfigurationExt.cs | 16 ++++++---- .../ArmoniK.Api.Tests/WorkerServerTest.cs | 9 +++--- .../ArmoniK.Api.Worker/Utils/WorkerServer.cs | 29 ++++++++++--------- 4 files changed, 32 insertions(+), 24 deletions(-) diff --git a/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs b/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs index af5dbadf4..fb4495574 100644 --- a/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs +++ b/packages/csharp/ArmoniK.Api.Common/Options/ComputePlane.cs @@ -44,7 +44,7 @@ public class ComputePlane public const string WorkerChannelSection = nameof(WorkerChannel); /// - /// Path to the section containing the agent channel values in configuration object + /// Path to the section containing the agent channel values in configuration object /// public const string AgentChannelSection = nameof(AgentChannel); diff --git a/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs b/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs index 008fbcab2..c408c4fdc 100644 --- a/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs +++ b/packages/csharp/ArmoniK.Api.Common/Utils/ConfigurationExt.cs @@ -40,16 +40,20 @@ public static T GetRequiredValue(this IConfiguration configuration, string key) => configuration.GetRequiredSection(key) .Get() ?? throw new InvalidOperationException($"{key} not found"); - + /// - /// Retrieves a from the configuration, or returns the provided default value if not found or invalid. - /// If the configuration contains "MaxValue", it will return . + /// Retrieves a from the configuration, or returns the provided default value if not found or + /// invalid. + /// If the configuration contains "MaxValue", it will return . /// - /// The instance from which to retrieve the value. + /// The instance from which to retrieve the value. /// The key of the configuration value to retrieve. /// The default value to return if the key is not found or the value is invalid. - /// A representing the configuration value, or if invalid or missing. - /// Thrown if the value is not a valid or "MaxValue". + /// + /// A representing the configuration value, or if invalid + /// or missing. + /// + /// Thrown if the value is not a valid or "MaxValue". public static TimeSpan GetTimeSpanOrDefault(this IConfiguration configuration, string key, TimeSpan defaultValue) diff --git a/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs b/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs index ced342e72..29a3f8d29 100644 --- a/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs +++ b/packages/csharp/ArmoniK.Api.Tests/WorkerServerTest.cs @@ -27,7 +27,6 @@ using ArmoniK.Api.Common.Channel.Utils; using ArmoniK.Api.Common.Options; -using ArmoniK.Api.Common.Utils; using ArmoniK.Api.Worker.Utils; using ArmoniK.Api.Worker.Worker; @@ -117,15 +116,17 @@ public Task BuildServerConfiguratorTcp() new($"{nameof(ComputePlane)}:{nameof(ComputePlane.WorkerChannel)}:{nameof(ComputePlane.WorkerChannel.SocketType)}", GrpcSocketType.Tcp.ToString()), new($"{nameof(ComputePlane)}:{nameof(ComputePlane.WorkerChannel)}:{nameof(ComputePlane.WorkerChannel.KeepAliveTimeOut)}", - "MaxValue"), + "MaxValue"), new($"{nameof(ComputePlane)}:{nameof(ComputePlane.WorkerChannel)}:{nameof(ComputePlane.WorkerChannel.KeepAlivePingTimeOut)}", "MaxValue"), new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.Address)}", "http://localhost:10666"), new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.KeepAliveTimeOut)}", - TimeSpan.FromSeconds(100).ToString()), + TimeSpan.FromSeconds(100) + .ToString()), new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.KeepAlivePingTimeOut)}", - TimeSpan.FromSeconds(5).ToString()), + TimeSpan.FromSeconds(5) + .ToString()), new($"{nameof(ComputePlane)}:{nameof(ComputePlane.AgentChannel)}:{nameof(ComputePlane.AgentChannel.SocketType)}", GrpcSocketType.Tcp.ToString()), }; diff --git a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs index 2d6082c15..28b653b16 100644 --- a/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs +++ b/packages/csharp/ArmoniK.Api.Worker/Utils/WorkerServer.cs @@ -111,15 +111,15 @@ public static WebApplication Create(Action("Address"), - SocketType = workerChannelOptions.GetValue("SocketType", GrpcSocketType.UnixDomainSocket), + SocketType = workerChannelOptions.GetValue("SocketType", + GrpcSocketType.UnixDomainSocket), KeepAlivePingTimeOut = workerChannelOptions.GetTimeSpanOrDefault("KeepAlivePingTimeOut", TimeSpan.FromSeconds(20)), KeepAliveTimeOut = workerChannelOptions.GetTimeSpanOrDefault("KeepAliveTimeOut", @@ -127,20 +127,23 @@ public static WebApplication Create(Action("Address"), - SocketType = agentChannelOptions.GetValue("SocketType", GrpcSocketType.UnixDomainSocket), - KeepAlivePingTimeOut = agentChannelOptions.GetTimeSpanOrDefault("KeepAlivePingTimeOut", - TimeSpan.FromSeconds(20)), - KeepAliveTimeOut = agentChannelOptions.GetTimeSpanOrDefault("KeepAliveTimeOut", - TimeSpan.FromSeconds(130)), + Address = agentChannelOptions.GetRequiredValue("Address"), + SocketType = agentChannelOptions.GetValue("SocketType", + GrpcSocketType.UnixDomainSocket), + KeepAlivePingTimeOut = agentChannelOptions.GetTimeSpanOrDefault("KeepAlivePingTimeOut", + TimeSpan.FromSeconds(20)), + KeepAliveTimeOut = agentChannelOptions.GetTimeSpanOrDefault("KeepAliveTimeOut", + TimeSpan.FromSeconds(130)), }, - MessageBatchSize = rawComputePlaneOptions.GetValue("MessageBatchSize", 1), - AbortAfter = rawComputePlaneOptions.GetValue("AbortAfter", TimeSpan.Zero), + MessageBatchSize = rawComputePlaneOptions.GetValue("MessageBatchSize", + 1), + AbortAfter = rawComputePlaneOptions.GetValue("AbortAfter", + TimeSpan.Zero), }; builder.WebHost.ConfigureKestrel(options => { - var address = parsedComputePlaneOptions.WorkerChannel.Address; + var address = parsedComputePlaneOptions.WorkerChannel.Address; switch (parsedComputePlaneOptions.WorkerChannel.SocketType) { case GrpcSocketType.UnixDomainSocket: