From 645d150efb603903a549350769ad3ad5b9b5655d Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 18 Sep 2024 18:46:27 +0200 Subject: [PATCH 001/135] feat(all): retry with dead letter queue --- src/SlimData/Commands/LogSnapshotCommand.cs | 21 +++++++++++++-------- src/SlimData/Commands/SlimDataPayload.cs | 2 +- src/SlimData/Endpoints.cs | 2 +- src/SlimData/SlimDataInterpreter.cs | 20 +++++++++++--------- src/SlimData/SlimPersistentState.cs | 4 ++-- src/SlimFaas/Database/SlimDataService.cs | 2 +- 6 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index f111003d..bddf9a70 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -6,14 +6,14 @@ namespace SlimData.Commands; public readonly struct LogSnapshotCommand(Dictionary> keysValues, - Dictionary> hashsets, Dictionary>> queues) + Dictionary> hashsets, Dictionary> queues) : ISerializable { public const int Id = 5; public readonly Dictionary> keysValues = keysValues; public readonly Dictionary> hashsets = hashsets; - public readonly Dictionary>> queues = queues; + public readonly Dictionary> queues = queues; long? IDataTransferObject.Length // optional implementation, may return null @@ -31,7 +31,7 @@ public readonly struct LogSnapshotCommand(Dictionary result += x.Length); + queue.Value.ForEach(x => result += x.Value.Length + sizeof(Int32) + sizeof(Int64)); } // compute length of the serialized data, in bytes @@ -68,8 +68,11 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t { await writer.EncodeAsync(queue.Key.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(queue.Value.Count, token).ConfigureAwait(false); - foreach (var value in queue.Value) - await writer.WriteAsync(value, LengthFormat.Compressed, token).ConfigureAwait(false); + foreach (var value in queue.Value){ + await writer.WriteAsync(value.Value, LengthFormat.Compressed, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(value.RetryNumber, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(value.LastAccessTimeStamp, token).ConfigureAwait(false); + } } // write the number of entries @@ -105,18 +108,20 @@ public static async ValueTask ReadFromAsync(TReader } var countQueues = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false); - var queues = new Dictionary>>(countQueues); + var queues = new Dictionary>(countQueues); // deserialize entries while (countQueues-- > 0) { var key = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token) .ConfigureAwait(false); var countQueue = await reader.ReadLittleEndianAsync(token); - var queue = new List>(countQueue); + var queue = new List(countQueue); while (countQueue-- > 0) { using var value = await reader.ReadAsync(LengthFormat.Compressed, token: token).ConfigureAwait(false); - queue.Add(value.Memory); + var retryNumber = await reader.ReadLittleEndianAsync(token); + var lastAccessTimeStamp = await reader.ReadBigEndianAsync(token); + queue.Add(new QueueElement(value.Memory, retryNumber, lastAccessTimeStamp)); } queues.Add(key.ToString(), queue); diff --git a/src/SlimData/Commands/SlimDataPayload.cs b/src/SlimData/Commands/SlimDataPayload.cs index beb0efc3..ef504787 100644 --- a/src/SlimData/Commands/SlimDataPayload.cs +++ b/src/SlimData/Commands/SlimDataPayload.cs @@ -4,6 +4,6 @@ public struct SlimDataPayload { public IDictionary> KeyValues { get; set; } - public Dictionary>> Queues { get; set; } + public Dictionary> Queues { get; set; } public IDictionary> Hashsets { get; set; } } \ No newline at end of file diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 448cf7b1..7f0985be 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -130,7 +130,7 @@ public static async Task ListRightPopCommand(SlimPersistentState pro for (var i = 0; i < count; i++) { if (queue.Count <= i) break; - values.Items.Add(queue[i].ToArray()); + values.Items.Add(queue[i].Value.ToArray()); } var logEntry = diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 7cbe2f3c..f5c385b6 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -6,14 +6,16 @@ namespace SlimData; public record SlimDataState( Dictionary> hashsets, Dictionary> keyValues, - Dictionary>> queues); + Dictionary> queues); + +public record QueueElement(ReadOnlyMemory Value, int RetryNumber=0, long LastAccessTimeStamp=0); #pragma warning restore CA2252 public class SlimDataInterpreter : CommandInterpreter { - public SlimDataState SlimDataState = new(new Dictionary>(), new Dictionary>(), new Dictionary>>()); + public SlimDataState SlimDataState = new(new Dictionary>(), new Dictionary>(), new Dictionary>()); [CommandHandler] public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, CancellationToken token) @@ -21,11 +23,11 @@ public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, Cancel return DoListRightPopAsync(addHashSetCommand, SlimDataState.queues); } - internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetCommand, Dictionary>> queues) + internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetCommand, Dictionary> queues) { if (queues.TryGetValue(addHashSetCommand.Key, out var queue)) for (var i = 0; i < addHashSetCommand.Count; i++) - if (queue.Count > 0) + if (queue.Count > 0) queue.RemoveAt(0); else break; @@ -39,12 +41,12 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel return DoListLeftPushAsync(addHashSetCommand, SlimDataState.queues); } - internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Dictionary>> queues) + internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Dictionary> queues) { - if (queues.TryGetValue(addHashSetCommand.Key, out List>? value)) - value.Add(addHashSetCommand.Value); + if (queues.TryGetValue(addHashSetCommand.Key, out List? value)) + value.Add(new QueueElement(addHashSetCommand.Value)); else - queues.Add(addHashSetCommand.Key, new List> { addHashSetCommand.Value }); + queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value)}); return default; } @@ -82,7 +84,7 @@ public ValueTask HandleSnapshotAsync(LogSnapshotCommand command, CancellationTok return default; } - internal static ValueTask DoHandleSnapshotAsync(LogSnapshotCommand command, Dictionary> keyValues, Dictionary> hashsets, Dictionary>> queues) + internal static ValueTask DoHandleSnapshotAsync(LogSnapshotCommand command, Dictionary> keyValues, Dictionary> hashsets, Dictionary> queues) { keyValues.Clear(); foreach (var keyValue in command.keysValues) diff --git a/src/SlimData/SlimPersistentState.cs b/src/SlimData/SlimPersistentState.cs index ec5ad58f..c72ceaa4 100644 --- a/src/SlimData/SlimPersistentState.cs +++ b/src/SlimData/SlimPersistentState.cs @@ -12,7 +12,7 @@ public sealed class SlimPersistentState : MemoryBasedStateMachine, ISupplier>(), new Dictionary>(), - new Dictionary>>() + new Dictionary>() ); public CommandInterpreter Interpreter { get; } @@ -67,7 +67,7 @@ private sealed class SimpleSnapshotBuilder : IncrementalSnapshotBuilder { private readonly SlimDataState _state = new(new Dictionary>(), new Dictionary>(), - new Dictionary>>() + new Dictionary>() ); private readonly CommandInterpreter _interpreter; diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index b7ae2c91..c27f5253 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -177,7 +177,7 @@ private async Task DoListLengthAsync(string key) await MasterWaitForleaseToken(); SlimDataPayload data = SimplePersistentState.Invoke(); - long result = data.Queues.TryGetValue(key, out List>? value) ? value.Count : 0L; + long result = data.Queues.TryGetValue(key, out List? value) ? value.Count : 0L; return result; } From 36d805a4f4786a242e66f5a313fc27e16180d4aa Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Sep 2024 09:34:22 +0200 Subject: [PATCH 002/135] fix test --- tests/SlimData.Tests/CommandsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SlimData.Tests/CommandsTests.cs b/tests/SlimData.Tests/CommandsTests.cs index 2ed82e7a..198b9739 100644 --- a/tests/SlimData.Tests/CommandsTests.cs +++ b/tests/SlimData.Tests/CommandsTests.cs @@ -21,7 +21,7 @@ public static async Task InterpreterWithPersistentState() await wal.AppendAsync(entry1); Assert.Empty(wal.SlimDataState.queues); await wal.CommitAsync(CancellationToken.None); - Assert.Equal(bytes, wal.SlimDataState.queues["youhou"].First().ToArray()); + Assert.Equal(bytes, wal.SlimDataState.queues["youhou"].First().Value.ToArray()); var bin = MemoryPackSerializer.Serialize(3); var final = MemoryPackSerializer.Deserialize(bin); From e189e527eccf160aece86d9388f26173d0409bcf Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 12:14:18 +0200 Subject: [PATCH 003/135] test --- src/Fibonacci/Program.cs | 4 ++-- src/SlimData/Commands/LogSnapshotCommand.cs | 7 +++++-- src/SlimData/SlimDataInterpreter.cs | 6 +++--- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 7f10085e..7d692ac8 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -43,14 +43,14 @@ app.MapGet("/health", () => "OK"); -app.MapPost("/fibonacci4", ( +app.MapPost("/fibonacci-recursive", ( [FromServices] ILogger logger, [FromServices] Fibonacci fibonacci, FibonacciInput input) => { logger.LogInformation("Fibonacci Internal Called"); using HttpClient client = new(); - var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci4/fibonacci", input).Result; + var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", input).Result; var output = response.Content.ReadFromJsonAsync().Result; logger.LogInformation("Fibonacci Internal output: {Output}", output.Result); return output; diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index bddf9a70..a28d7eca 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -31,7 +31,7 @@ public readonly struct LogSnapshotCommand(Dictionary result += x.Value.Length + sizeof(Int32) + sizeof(Int64)); + queue.Value.ForEach(x => result += x.Value.Length + sizeof(Int32) + sizeof(Int64) + sizeof(Int64)); } // compute length of the serialized data, in bytes @@ -70,6 +70,7 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.WriteLittleEndianAsync(queue.Value.Count, token).ConfigureAwait(false); foreach (var value in queue.Value){ await writer.WriteAsync(value.Value, LengthFormat.Compressed, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(value.InsertTimeStamp, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(value.RetryNumber, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(value.LastAccessTimeStamp, token).ConfigureAwait(false); } @@ -119,9 +120,11 @@ public static async ValueTask ReadFromAsync(TReader while (countQueue-- > 0) { using var value = await reader.ReadAsync(LengthFormat.Compressed, token: token).ConfigureAwait(false); + var insertTimeStamp = await reader.ReadBigEndianAsync(token); var retryNumber = await reader.ReadLittleEndianAsync(token); var lastAccessTimeStamp = await reader.ReadBigEndianAsync(token); - queue.Add(new QueueElement(value.Memory, retryNumber, lastAccessTimeStamp)); + + queue.Add(new QueueElement(value.Memory, insertTimeStamp, retryNumber, lastAccessTimeStamp)); } queues.Add(key.ToString(), queue); diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index f5c385b6..a8426299 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -8,7 +8,7 @@ public record SlimDataState( Dictionary> keyValues, Dictionary> queues); -public record QueueElement(ReadOnlyMemory Value, int RetryNumber=0, long LastAccessTimeStamp=0); +public record QueueElement(ReadOnlyMemory Value, long InsertTimeStamp, int RetryNumber=0, long LastAccessTimeStamp=0); #pragma warning restore CA2252 @@ -44,9 +44,9 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Dictionary> queues) { if (queues.TryGetValue(addHashSetCommand.Key, out List? value)) - value.Add(new QueueElement(addHashSetCommand.Value)); + value.Add(new QueueElement(addHashSetCommand.Value, DateTime.UtcNow.Ticks)); else - queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value)}); + queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value, DateTime.UtcNow.Ticks)}); return default; } From f3539567fb143f312cf1b9d3d4a8ea61d4e915c1 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 15:10:52 +0200 Subject: [PATCH 004/135] test demo --- src/Fibonacci/Fibonacci.csproj | 4 ++++ src/Fibonacci/Program.cs | 30 ++++++++++++++++++++++-------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 7dd13f51..7049c324 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -20,4 +20,8 @@ + + + + diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 7d692ac8..79b50550 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; WebApplicationBuilder builder = WebApplication.CreateBuilder(args); IServiceCollection serviceCollection = builder.Services; @@ -43,16 +44,29 @@ app.MapGet("/health", () => "OK"); -app.MapPost("/fibonacci-recursive", ( +app.MapPost("/fibonacci-recursive", async ( [FromServices] ILogger logger, [FromServices] Fibonacci fibonacci, FibonacciInput input) => { - logger.LogInformation("Fibonacci Internal Called"); + logger.LogInformation("Fibonacci Recursive Internal Called"); using HttpClient client = new(); - var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", input).Result; - var output = response.Content.ReadFromJsonAsync().Result; - logger.LogInformation("Fibonacci Internal output: {Output}", output.Result); + var output = new FibonacciOutput(); + if (input.Input <= 2) + { + output.Result = 1; + return output; + } + var response1 = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput(){ Input = input.Input-1}); + var response2 = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput(){ Input = input.Input-2}); + if (response1.Result.IsSuccessStatusCode || response2.Result.IsSuccessStatusCode) + { + throw new Exception("Request Fail"); + } + var result1 = JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); + var result2 = JsonConvert.DeserializeObject(await response2.Result.Content.ReadAsStringAsync()); + output.Result = result1.Result + result2.Result; + logger.LogInformation("Current output: {Result}", output.Result); return output; }); @@ -62,7 +76,7 @@ [FromServices] Fibonacci fibonacci, FibonacciInput input) => { - logger.LogInformation("Fibonacci Internal Event Called"); + logger.LogInformation("Fibonacci Private Event Called"); using HttpClient client = new(); var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input).Result; logger.LogInformation("Response status code: {StatusCode}", response.StatusCode); @@ -88,10 +102,10 @@ public int Run(int i) } } -public record FibonacciInput{ +public record FibonacciInput { public int Input { get; set; } } -public record FibonacciOutput{ +public record FibonacciOutput { public int Result { get; set; } } From a51a594c012a300c245e0fc2e3a67b9b7d00ffc8 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 15:41:49 +0200 Subject: [PATCH 005/135] test --- src/Fibonacci/Program.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 79b50550..5fce9f63 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -49,7 +49,7 @@ [FromServices] Fibonacci fibonacci, FibonacciInput input) => { - logger.LogInformation("Fibonacci Recursive Internal Called"); + logger.LogInformation("Fibonacci Recursive Internal Called: {Input}", input.Input); using HttpClient client = new(); var output = new FibonacciOutput(); if (input.Input <= 2) @@ -64,7 +64,9 @@ throw new Exception("Request Fail"); } var result1 = JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); + logger.LogInformation("Current result1: {Result}", result1.Result); var result2 = JsonConvert.DeserializeObject(await response2.Result.Content.ReadAsStringAsync()); + logger.LogInformation("Current result2: {Result}", result2.Result); output.Result = result1.Result + result2.Result; logger.LogInformation("Current output: {Result}", output.Result); return output; From ea68a0f2be44542519219e4f926110d3fdf8b352 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 15:54:13 +0200 Subject: [PATCH 006/135] fix --- src/Fibonacci/Program.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 5fce9f63..9f600aab 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -5,6 +5,7 @@ IServiceCollection serviceCollection = builder.Services; serviceCollection.AddSingleton(); serviceCollection.AddCors(); +serviceCollection.AddHttpClient(); WebApplication app = builder.Build(); app.UseCors(builder => builder @@ -47,10 +48,10 @@ app.MapPost("/fibonacci-recursive", async ( [FromServices] ILogger logger, [FromServices] Fibonacci fibonacci, + [FromServices] HttpClient client, FibonacciInput input) => { logger.LogInformation("Fibonacci Recursive Internal Called: {Input}", input.Input); - using HttpClient client = new(); var output = new FibonacciOutput(); if (input.Input <= 2) { @@ -76,10 +77,10 @@ app.MapPost("/send-private-fibonacci-event", ( [FromServices] ILogger logger, [FromServices] Fibonacci fibonacci, + [FromServices] HttpClient client, FibonacciInput input) => { logger.LogInformation("Fibonacci Private Event Called"); - using HttpClient client = new(); var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input).Result; logger.LogInformation("Response status code: {StatusCode}", response.StatusCode); logger.LogInformation("Fibonacci Internal Event End"); From 2bcbf4e369f619f7e52a0aa2f278663403698fe9 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 16:30:56 +0200 Subject: [PATCH 007/135] fix --- src/Fibonacci/Program.cs | 50 ++++++++++++++++++++++++++++------------ 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 9f600aab..97a637a3 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -51,26 +51,46 @@ [FromServices] HttpClient client, FibonacciInput input) => { - logger.LogInformation("Fibonacci Recursive Internal Called: {Input}", input.Input); - var output = new FibonacciOutput(); - if (input.Input <= 2) + try { - output.Result = 1; + logger.LogInformation("Fibonacci Recursive Internal Called: {Input}", input.Input); + var output = new FibonacciOutput(); + if (input.Input <= 2) + { + output.Result = 1; + return output; + } + + var response1 = + client.PostAsJsonAsync( + "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", + new FibonacciInput() { Input = input.Input - 1 }); + var response2 = + client.PostAsJsonAsync( + "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", + new FibonacciInput() { Input = input.Input - 2 }); + if (response1.Result.IsSuccessStatusCode || response2.Result.IsSuccessStatusCode) + { + throw new Exception("Request Fail"); + } + + var result1 = + JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); + logger.LogInformation("Current result1: {Result}", result1.Result); + var result2 = + JsonConvert.DeserializeObject(await response2.Result.Content.ReadAsStringAsync()); + logger.LogInformation("Current result2: {Result}", result2.Result); + output.Result = result1.Result + result2.Result; + logger.LogInformation("Current output: {Result}", output.Result); return output; } - var response1 = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput(){ Input = input.Input-1}); - var response2 = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput(){ Input = input.Input-2}); - if (response1.Result.IsSuccessStatusCode || response2.Result.IsSuccessStatusCode) + catch (Exception ex) { - throw new Exception("Request Fail"); + logger.LogError(ex, "Error in Fibonacci Recursive Internal"); } - var result1 = JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); - logger.LogInformation("Current result1: {Result}", result1.Result); - var result2 = JsonConvert.DeserializeObject(await response2.Result.Content.ReadAsStringAsync()); - logger.LogInformation("Current result2: {Result}", result2.Result); - output.Result = result1.Result + result2.Result; - logger.LogInformation("Current output: {Result}", output.Result); - return output; + + + return new FibonacciOutput(); }); From 8a30f7605253fee85edbb1efe05838c028d282b5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 16:37:20 +0200 Subject: [PATCH 008/135] fix --- src/Fibonacci/Program.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 97a637a3..28d87116 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -69,11 +69,6 @@ client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput() { Input = input.Input - 2 }); - if (response1.Result.IsSuccessStatusCode || response2.Result.IsSuccessStatusCode) - { - throw new Exception("Request Fail"); - } - var result1 = JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); logger.LogInformation("Current result1: {Result}", result1.Result); @@ -107,9 +102,6 @@ }); - - - app.Run(); internal class Fibonacci From 7e592d56517bc415dd4065cbb48c3db45e17aa33 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 17:01:13 +0200 Subject: [PATCH 009/135] test --- src/Fibonacci/Program.cs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 28d87116..230f6a17 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -54,10 +54,11 @@ try { logger.LogInformation("Fibonacci Recursive Internal Called: {Input}", input.Input); - var output = new FibonacciOutput(); + var output = new FibonacciRecursiveOutput(); if (input.Input <= 2) { output.Result = 1; + output.NumberCall = 1; return output; } @@ -70,12 +71,13 @@ "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput() { Input = input.Input - 2 }); var result1 = - JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); + JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); logger.LogInformation("Current result1: {Result}", result1.Result); var result2 = - JsonConvert.DeserializeObject(await response2.Result.Content.ReadAsStringAsync()); + JsonConvert.DeserializeObject(await response2.Result.Content.ReadAsStringAsync()); logger.LogInformation("Current result2: {Result}", result2.Result); output.Result = result1.Result + result2.Result; + output.NumberCall = result1.NumberCall + result2.NumberCall + 1; logger.LogInformation("Current output: {Result}", output.Result); return output; } @@ -84,8 +86,7 @@ logger.LogError(ex, "Error in Fibonacci Recursive Internal"); } - - return new FibonacciOutput(); + return new FibonacciRecursiveOutput(); }); @@ -124,3 +125,9 @@ public record FibonacciInput { public record FibonacciOutput { public int Result { get; set; } } + +public record FibonacciRecursiveOutput { + public int Result { get; set; } + public int NumberCall { get; set; } +} + From 868340c39972c22a97a08ac6e1e0e8435a0850cb Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 17:32:35 +0200 Subject: [PATCH 010/135] test --- src/Fibonacci/Fibonacci.csproj | 7 ++----- src/Fibonacci/Program.cs | 31 +++++++++++++++++++++++-------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 7049c324..1ac4a51d 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,7 @@ enable enable Linux - false + true @@ -19,9 +19,6 @@ PreserveNewest - - - - + diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 230f6a17..06e990f9 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -1,5 +1,6 @@ +using System.Text.Json; +using System.Text.Json.Serialization; using Microsoft.AspNetCore.Mvc; -using Newtonsoft.Json; WebApplicationBuilder builder = WebApplication.CreateBuilder(args); IServiceCollection serviceCollection = builder.Services; @@ -65,16 +66,17 @@ var response1 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 1 }); + new FibonacciInput() { Input = input.Input - 1 }, FibonacciInputSerializerContext.Default.FibonacciInput); var response2 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 2 }); - var result1 = - JsonConvert.DeserializeObject(await response1.Result.Content.ReadAsStringAsync()); + new FibonacciInput() { Input = input.Input - 2 }, FibonacciInputSerializerContext.Default.FibonacciInput); + var result1 = JsonSerializer.Deserialize(await response1.Result.Content.ReadAsStringAsync(), + FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); logger.LogInformation("Current result1: {Result}", result1.Result); - var result2 = - JsonConvert.DeserializeObject(await response2.Result.Content.ReadAsStringAsync()); + var result2 = JsonSerializer.Deserialize(await response2.Result.Content.ReadAsStringAsync(), + FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); + logger.LogInformation("Current result2: {Result}", result2.Result); output.Result = result1.Result + result2.Result; output.NumberCall = result1.NumberCall + result2.NumberCall + 1; @@ -97,7 +99,7 @@ FibonacciInput input) => { logger.LogInformation("Fibonacci Private Event Called"); - var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input).Result; + var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input, FibonacciInputSerializerContext.Default.FibonacciInput).Result; logger.LogInformation("Response status code: {StatusCode}", response.StatusCode); logger.LogInformation("Fibonacci Internal Event End"); }); @@ -122,6 +124,13 @@ public record FibonacciInput { public int Input { get; set; } } +[JsonSerializable(typeof(FibonacciInput))] +[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +public partial class FibonacciInputSerializerContext : JsonSerializerContext +{ +} + + public record FibonacciOutput { public int Result { get; set; } } @@ -131,3 +140,9 @@ public record FibonacciRecursiveOutput { public int NumberCall { get; set; } } +[JsonSerializable(typeof(FibonacciRecursiveOutput))] +[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +public partial class FibonacciRecursiveOutputSerializerContext : JsonSerializerContext +{ +} + From a31b2f728692d990ebd9dbd293eb5b16e7f3b216 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 18:07:31 +0200 Subject: [PATCH 011/135] dada --- src/Fibonacci/Program.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 06e990f9..a4a22be8 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -15,8 +15,6 @@ .AllowAnyHeader() ); - - app.MapPost("/fibonacci", ( [FromServices] ILogger logger, [FromServices] Fibonacci fibonacci, @@ -130,11 +128,17 @@ public partial class FibonacciInputSerializerContext : JsonSerializerContext { } - public record FibonacciOutput { public int Result { get; set; } } + +[JsonSerializable(typeof(FibonacciOutput))] +[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +public partial class FibonacciOutputSerializerContext : JsonSerializerContext +{ +} + public record FibonacciRecursiveOutput { public int Result { get; set; } public int NumberCall { get; set; } From b551e525caaace9340f81a32d55277ca244c3e8e Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 20:24:02 +0200 Subject: [PATCH 012/135] update --- src/Fibonacci/Program.cs | 31 +++++++++++++------------------ 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index a4a22be8..67657c53 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -8,6 +8,11 @@ serviceCollection.AddCors(); serviceCollection.AddHttpClient(); +serviceCollection.Configure(options => +{ + options.JsonSerializerOptions.TypeInfoResolver = FibonacciSerializerContext.Default; +}); + WebApplication app = builder.Build(); app.UseCors(builder => builder .AllowAnyOrigin() @@ -64,16 +69,16 @@ var response1 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 1 }, FibonacciInputSerializerContext.Default.FibonacciInput); + new FibonacciInput() { Input = input.Input - 1 }, FibonacciSerializerContext.Default.FibonacciInput); var response2 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 2 }, FibonacciInputSerializerContext.Default.FibonacciInput); + new FibonacciInput() { Input = input.Input - 2 }, FibonacciSerializerContext.Default.FibonacciInput); var result1 = JsonSerializer.Deserialize(await response1.Result.Content.ReadAsStringAsync(), - FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); + FibonacciSerializerContext.Default.FibonacciRecursiveOutput); logger.LogInformation("Current result1: {Result}", result1.Result); var result2 = JsonSerializer.Deserialize(await response2.Result.Content.ReadAsStringAsync(), - FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); + FibonacciSerializerContext.Default.FibonacciRecursiveOutput); logger.LogInformation("Current result2: {Result}", result2.Result); output.Result = result1.Result + result2.Result; @@ -97,7 +102,7 @@ FibonacciInput input) => { logger.LogInformation("Fibonacci Private Event Called"); - var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input, FibonacciInputSerializerContext.Default.FibonacciInput).Result; + var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input, FibonacciSerializerContext.Default.FibonacciInput).Result; logger.LogInformation("Response status code: {StatusCode}", response.StatusCode); logger.LogInformation("Fibonacci Internal Event End"); }); @@ -122,31 +127,21 @@ public record FibonacciInput { public int Input { get; set; } } -[JsonSerializable(typeof(FibonacciInput))] -[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] -public partial class FibonacciInputSerializerContext : JsonSerializerContext -{ -} - public record FibonacciOutput { public int Result { get; set; } } -[JsonSerializable(typeof(FibonacciOutput))] -[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] -public partial class FibonacciOutputSerializerContext : JsonSerializerContext -{ -} - public record FibonacciRecursiveOutput { public int Result { get; set; } public int NumberCall { get; set; } } [JsonSerializable(typeof(FibonacciRecursiveOutput))] +[JsonSerializable(typeof(FibonacciOutput))] +[JsonSerializable(typeof(FibonacciInput))] [JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] -public partial class FibonacciRecursiveOutputSerializerContext : JsonSerializerContext +public partial class FibonacciSerializerContext : JsonSerializerContext { } From 9be7563233bea4275737c819f5f49d5681802cde Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 20:41:42 +0200 Subject: [PATCH 013/135] fix --- src/Fibonacci/Program.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 67657c53..10177ed7 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -29,7 +29,7 @@ var output = new FibonacciOutput(); output.Result = fibonacci.Run(input.Input); logger.LogInformation("Fibonacci output: {Output}", output.Result); - return output; + return Results.Ok(output); }); app.MapGet("/download", ([FromServices] ILogger logger) => @@ -63,7 +63,7 @@ { output.Result = 1; output.NumberCall = 1; - return output; + return Results.Ok(output); } var response1 = @@ -84,14 +84,13 @@ output.Result = result1.Result + result2.Result; output.NumberCall = result1.NumberCall + result2.NumberCall + 1; logger.LogInformation("Current output: {Result}", output.Result); - return output; + return Results.Ok(output); } catch (Exception ex) { logger.LogError(ex, "Error in Fibonacci Recursive Internal"); } - - return new FibonacciRecursiveOutput(); + return Results.BadRequest(new FibonacciRecursiveOutput()); }); From 73378524c1c5ee4dddc64d7732e556ecf1d8ac99 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 20:54:32 +0200 Subject: [PATCH 014/135] fix --- src/Fibonacci/Fibonacci.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 1ac4a51d..a330db94 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,7 @@ enable enable Linux - true + false From b02c40a5b98fe34fe0bcb262c9226edfdcd55752 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 20:55:26 +0200 Subject: [PATCH 015/135] fix --- src/Fibonacci/Fibonacci.csproj | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index a330db94..8feab346 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,8 @@ enable enable Linux - false + true + true From fee300d9bcb9edfd9b88f94a73e9ab795e1ba63a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 21:08:07 +0200 Subject: [PATCH 016/135] fix --- src/Fibonacci/Fibonacci.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 8feab346..cdf82995 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,7 @@ enable enable Linux - true + false true From 374438e4fd37de4266f9f20970d8a4c1c2ddf7ae Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 21:17:34 +0200 Subject: [PATCH 017/135] dqsdqs --- src/Fibonacci/Fibonacci.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index cdf82995..a330db94 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -6,7 +6,6 @@ enable Linux false - true From f66db0d895714fcd7d4bbee58210774884c709d6 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 21:35:52 +0200 Subject: [PATCH 018/135] test --- src/Fibonacci/Program.cs | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 10177ed7..7da7f1a4 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -1,5 +1,6 @@ using System.Text.Json; using System.Text.Json.Serialization; +using System.Text.Json.Serialization.Metadata; using Microsoft.AspNetCore.Mvc; WebApplicationBuilder builder = WebApplication.CreateBuilder(args); @@ -10,7 +11,11 @@ serviceCollection.Configure(options => { - options.JsonSerializerOptions.TypeInfoResolver = FibonacciSerializerContext.Default; + options.JsonSerializerOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine( + options.JsonSerializerOptions.TypeInfoResolver, + FibonacciInputSerializerContext.Default, + FibonacciOutputSerializerContext.Default, + FibonacciRecursiveOutputSerializerContext.Default); }); WebApplication app = builder.Build(); @@ -69,16 +74,16 @@ var response1 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 1 }, FibonacciSerializerContext.Default.FibonacciInput); + new FibonacciInput() { Input = input.Input - 1 }, FibonacciInput.Default.FibonacciInput); var response2 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 2 }, FibonacciSerializerContext.Default.FibonacciInput); + new FibonacciInput() { Input = input.Input - 2 }, FibonacciInput.Default.FibonacciInput); var result1 = JsonSerializer.Deserialize(await response1.Result.Content.ReadAsStringAsync(), - FibonacciSerializerContext.Default.FibonacciRecursiveOutput); + FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); logger.LogInformation("Current result1: {Result}", result1.Result); var result2 = JsonSerializer.Deserialize(await response2.Result.Content.ReadAsStringAsync(), - FibonacciSerializerContext.Default.FibonacciRecursiveOutput); + FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); logger.LogInformation("Current result2: {Result}", result2.Result); output.Result = result1.Result + result2.Result; @@ -101,7 +106,7 @@ FibonacciInput input) => { logger.LogInformation("Fibonacci Private Event Called"); - var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input, FibonacciSerializerContext.Default.FibonacciInput).Result; + var response = client.PostAsJsonAsync("http://slimfaas.slimfaas-demo.svc.cluster.local:5000/publish-event/fibo-private/fibonacci", input, FibonacciInputSerializerContext.Default.FibonacciInput).Result; logger.LogInformation("Response status code: {StatusCode}", response.StatusCode); logger.LogInformation("Fibonacci Internal Event End"); }); @@ -126,21 +131,32 @@ public record FibonacciInput { public int Input { get; set; } } + + +[JsonSerializable(typeof(FibonacciInput))] +[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +public partial class FibonacciInputSerializerContext : JsonSerializerContext +{ +} + public record FibonacciOutput { public int Result { get; set; } } +[JsonSerializable(typeof(FibonacciOutput))] +[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +public partial class FibonacciOutputSerializerContext : JsonSerializerContext +{ +} + public record FibonacciRecursiveOutput { public int Result { get; set; } public int NumberCall { get; set; } } [JsonSerializable(typeof(FibonacciRecursiveOutput))] -[JsonSerializable(typeof(FibonacciOutput))] -[JsonSerializable(typeof(FibonacciInput))] [JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] -public partial class FibonacciSerializerContext : JsonSerializerContext +public partial class FibonacciRecursiveOutputSerializerContext : JsonSerializerContext { } - From 76820f02b936b68f5b7b838d1acac61fe2c066d5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 21:36:17 +0200 Subject: [PATCH 019/135] fix --- src/Fibonacci/Program.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 7da7f1a4..cd171c38 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -74,11 +74,11 @@ var response1 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 1 }, FibonacciInput.Default.FibonacciInput); + new FibonacciInput() { Input = input.Input - 1 }, FibonacciInputSerializerContext.Default.FibonacciInput); var response2 = client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", - new FibonacciInput() { Input = input.Input - 2 }, FibonacciInput.Default.FibonacciInput); + new FibonacciInput() { Input = input.Input - 2 }, FibonacciInputSerializerContext.Default.FibonacciInput); var result1 = JsonSerializer.Deserialize(await response1.Result.Content.ReadAsStringAsync(), FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); logger.LogInformation("Current result1: {Result}", result1.Result); From ac26a2b763b842f4c29aa938747dd2af89c08cee Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 2 Oct 2024 21:51:25 +0200 Subject: [PATCH 020/135] test --- src/Fibonacci/Program.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index cd171c38..b919afc5 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -79,13 +79,15 @@ client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput() { Input = input.Input - 2 }, FibonacciInputSerializerContext.Default.FibonacciInput); - var result1 = JsonSerializer.Deserialize(await response1.Result.Content.ReadAsStringAsync(), + var result1str = await response1.Result.Content.ReadAsStringAsync(); + var result1 = JsonSerializer.Deserialize(result1str, FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); - logger.LogInformation("Current result1: {Result}", result1.Result); - var result2 = JsonSerializer.Deserialize(await response2.Result.Content.ReadAsStringAsync(), + logger.LogInformation("Current result1: {Result}", result1str); + var result2str = await response2.Result.Content.ReadAsStringAsync(); + var result2 = JsonSerializer.Deserialize(result2str, FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); - logger.LogInformation("Current result2: {Result}", result2.Result); + logger.LogInformation("Current result2: {Result}", result2str); output.Result = result1.Result + result2.Result; output.NumberCall = result1.NumberCall + result2.NumberCall + 1; logger.LogInformation("Current output: {Result}", output.Result); From 3038b8e3f2920e80213e011cf4dfcd240ab3e199 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 09:29:48 +0200 Subject: [PATCH 021/135] test --- src/Fibonacci/Fibonacci.csproj | 4 ++-- src/Fibonacci/Program.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index a330db94..1c6f862c 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,7 @@ enable enable Linux - false + true @@ -19,6 +19,6 @@ PreserveNewest - + diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index b919afc5..d0046bd0 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -11,6 +11,7 @@ serviceCollection.Configure(options => { + options.JsonSerializerOptions.PropertyNamingPolicy = null; options.JsonSerializerOptions.TypeInfoResolver = JsonTypeInfoResolver.Combine( options.JsonSerializerOptions.TypeInfoResolver, FibonacciInputSerializerContext.Default, From edaa5cfd14c19e70c183878e3216933e5d898d85 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 12:41:52 +0200 Subject: [PATCH 022/135] fix --- src/Fibonacci/Fibonacci.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 1c6f862c..86f7f7ed 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,7 @@ enable enable Linux - true + false From 76f33f0dbbf6ab27974b01d70ab638d39c257553 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 16:16:09 +0200 Subject: [PATCH 023/135] qdqd --- src/Fibonacci/Fibonacci.csproj | 2 +- src/Fibonacci/Program.cs | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 86f7f7ed..1c6f862c 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,7 @@ enable enable Linux - false + true diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index d0046bd0..b48fa296 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -137,7 +137,9 @@ public record FibonacciInput { [JsonSerializable(typeof(FibonacciInput))] -[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +[JsonSourceGenerationOptions(WriteIndented = false, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] public partial class FibonacciInputSerializerContext : JsonSerializerContext { } @@ -148,7 +150,9 @@ public record FibonacciOutput { [JsonSerializable(typeof(FibonacciOutput))] -[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +[JsonSourceGenerationOptions(WriteIndented = false, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] public partial class FibonacciOutputSerializerContext : JsonSerializerContext { } @@ -159,7 +163,9 @@ public record FibonacciRecursiveOutput { } [JsonSerializable(typeof(FibonacciRecursiveOutput))] -[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +[JsonSourceGenerationOptions(WriteIndented = false, + DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull, + PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)] public partial class FibonacciRecursiveOutputSerializerContext : JsonSerializerContext { } From e40c24639d384b989d9dd264baf4ba20195f2425 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 20:15:22 +0200 Subject: [PATCH 024/135] fix --- src/Fibonacci/Fibonacci.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 1c6f862c..86f7f7ed 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,7 +5,7 @@ enable enable Linux - true + false From 00adc78594c364662b45987ca9b2ac139cd41c7f Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 21:29:57 +0200 Subject: [PATCH 025/135] Update global.json --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index d557db79..e3a52669 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "8.0.401", + "version": "8.0.402", "rollForward": "latestFeature", "allowPrerelease": true } From 80b7604ee8c481691be021a621e440bfcfe72822 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 21:34:29 +0200 Subject: [PATCH 026/135] Update Fibonacci.csproj --- src/Fibonacci/Fibonacci.csproj | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index 86f7f7ed..fbecf9d1 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,8 +5,11 @@ enable enable Linux - false + true + + + From 3ff62daf82c6695a46e4861f5f14990cedfab715 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 21:40:25 +0200 Subject: [PATCH 027/135] fix --- src/Fibonacci/Program.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index b48fa296..b4125151 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -3,7 +3,7 @@ using System.Text.Json.Serialization.Metadata; using Microsoft.AspNetCore.Mvc; -WebApplicationBuilder builder = WebApplication.CreateBuilder(args); +WebApplicationBuilder builder = WebApplication.CreateSlimBuilder(args); IServiceCollection serviceCollection = builder.Services; serviceCollection.AddSingleton(); serviceCollection.AddCors(); From a39225386a68dfe9dc58d6251834869adf190990 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 21:41:16 +0200 Subject: [PATCH 028/135] qsddf --- demo/deployment-functions.yml | 12 ++++++------ demo/deployment-slimfaas.yml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 4002f4e7..3ede0fe6 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -28,7 +28,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci1 - image: axaguildev/fibonacci:latest + image: axaguildev/fibonacci:pr-77-733 livenessProbe: httpGet: path: /health @@ -41,11 +41,11 @@ spec: value: http://+:5000 resources: limits: - memory: "96Mi" + memory: "256Mi" cpu: "50m" requests: ephemeral-storage: "200Mi" - memory: "96Mi" + memory: "256Mi" cpu: "10m" ports: - containerPort: 5000 @@ -75,7 +75,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci2 - image: axaguildev/fibonacci:latest + image: axaguildev/fibonacci:pr-77-714 livenessProbe: httpGet: path: /health @@ -124,7 +124,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci3 - image: axaguildev/fibonacci:latest + image: axaguildev/fibonacci:pr-77-714 livenessProbe: httpGet: path: /health @@ -173,7 +173,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci4 - image: axaguildev/fibonacci:latest + image: axaguildev/fibonacci:pr-77-714 livenessProbe: httpGet: path: /health diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 1c4699ee..bd0f6d45 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:latest + image: axaguildev/slimfaas:pr-77-714 livenessProbe: httpGet: path: /health From 11f14d5cd27a3dfbd93bfdff030ca901cf26ea87 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 21:42:46 +0200 Subject: [PATCH 029/135] fix --- src/Fibonacci/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index b4125151..21c39186 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -80,6 +80,7 @@ client.PostAsJsonAsync( "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", new FibonacciInput() { Input = input.Input - 2 }, FibonacciInputSerializerContext.Default.FibonacciInput); + await Task.WhenAll(response1, response2); var result1str = await response1.Result.Content.ReadAsStringAsync(); var result1 = JsonSerializer.Deserialize(result1str, FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); From dae5f4fbfb2b48966d3bbe1a7642db8f129bf4e5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 3 Oct 2024 21:52:16 +0200 Subject: [PATCH 030/135] fix --- demo/deployment-functions.yml | 2 +- src/Fibonacci/Fibonacci.csproj | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 3ede0fe6..5716590d 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -28,7 +28,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci1 - image: axaguildev/fibonacci:pr-77-733 + image: axaguildev/fibonacci:pr-77-735 livenessProbe: httpGet: path: /health diff --git a/src/Fibonacci/Fibonacci.csproj b/src/Fibonacci/Fibonacci.csproj index fbecf9d1..86f7f7ed 100644 --- a/src/Fibonacci/Fibonacci.csproj +++ b/src/Fibonacci/Fibonacci.csproj @@ -5,11 +5,8 @@ enable enable Linux - true + false - - - From 5f6a78bf9d53f08158c53d41eb2aec3b95ac946a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 7 Oct 2024 16:56:24 +0200 Subject: [PATCH 031/135] update documentation --- README.md | 61 ++++++++++++++++------------------ demo/deployment-functions.yml | 39 ++++++---------------- src/Fibonacci/Program.cs | 51 +++++++++++++--------------- src/Fibonacci/appsettings.json | 6 ++-- 4 files changed, 64 insertions(+), 93 deletions(-) diff --git a/README.md b/README.md index 34b3669d..feca5656 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,11 @@ Why use SlimFaas? - Synchronous HTTP calls - Asynchronous HTTP calls - Allows you to limit the number of parallel HTTP requests for each underlying function -- Synchronous Publish event via HTTP calls (events) to every replicas which deployment subscribe to the event name +- Synchronous Publish/Subscribe events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple you application with SlimFaas**) - Retry: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds - Private and Public functions - Private functions can be accessed only by internal namespace http call from pods -- Mind Changer: REST API that show the status of your functions and allow to wake up your infrastructure +- Mind Changer: REST API that show the status of your functions and allow to wake up your infrastructure (**Couple your application with Slimfaas**) - Very useful to inform end users that your infrastructure is starting - Plug and Play: just deploy a standard pod - No impact on your current kubernetes manifests: just add an annotation to the pod you want to auto-scale @@ -23,53 +23,46 @@ Why use SlimFaas? ## Getting Started with Kubernetes -To test slimfaas on your local machine by using kubernetes with Docker Desktop, please use these commands: +To test SlimFaas on your local machine by using kubernetes with Docker Desktop, please use these commands: ```bash git clone https://github.com/AxaFrance/slimfaas.git cd slimfaas/demo # Create slimfaas service account and pods -kubectl apply -f deployment-slimfaas.yml -# Expose SlimFaaS service as NodePort or Ingress -kubectl apply -f slimfaas-nodeport.yml -# or -# kubectl apply -f slimfaas-ingress.yml -# Install three instances of fibonacci functions -# fibonacci1, fibonacci2 and fibonacci3 -kubectl apply -f deployment-functions.yml -# Install MySql -kubectl apply -f deployment-mysql.yml -# to run Single Page webapp demo (optional) on http://localhost:8000 -docker run -p 8000:8000 --rm axaguildev/fibonacci-webapp:latest +cd ``` - Now, you can access your pod via SlimFaas proxy: Synchronous way: -- http://localhost:30021/function/fibonacci1/hello/guillaume -- http://localhost:30021/function/fibonacci2/hello/elodie -- http://localhost:30021/function/fibonacci3/hello/julie +- http://localhost:30021/function/fibonacci1/hello/guillaume => HTTP 200 (OK) +- http://localhost:30021/function/fibonacci2/hello/elodie => HTTP 200 (OK) +- http://localhost:30021/function/fibonacci3/hello/julie => HTTP 200 (OK) +- http://localhost:30021/function/fibonacci4/hello/julie => HTTP 404 (Not Found) Asynchronous way: -- http://localhost:30021/async-function/fibonacci1/hello/guillaume -- http://localhost:30021/async-function/fibonacci2/hello/elodie -- http://localhost:30021/async-function/fibonacci3/hello/julie +- http://localhost:30021/async-function/fibonacci1/hello/guillaume => HTTP 200 (OK) +- http://localhost:30021/async-function/fibonacci2/hello/elodie => HTTP 200 (OK) +- http://localhost:30021/async-function/fibonacci3/hello/julie => HTTP 200 (OK) +- http://localhost:30021/async-function/fibonacci3/hello/julie => HTTP 404 (Not Found) Just wake up function: -- http://localhost:30021/wake-function/fibonacci1 -- http://localhost:30021/wake-function/fibonacci2 -- http://localhost:30021/wake-function/fibonacci3 +- http://localhost:30021/wake-function/fibonacci1 => HTTP 204 (OK - No Content) +- http://localhost:30021/wake-function/fibonacci2 => HTTP 204 (OK - No Content) +- http://localhost:30021/wake-function/fibonacci3 => HTTP 204 (OK - No Content) +- http://localhost:30021/wake-function/fibonacci4 => HTTP 204 (OK - No Content) Get function status: - http://localhost:30021/status-function/fibonacci1 => {"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Public","Name":"fibonacci1"} - http://localhost:30021/status-function/fibonacci2 => {"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Public","Name":"fibonacci2"} - http://localhost:30021/status-function/fibonacci3 => {"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Public","Name":"fibonacci3"} +- http://localhost:30021/status-function/fibonacci4 => {"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Private","Name":"fibonacci4"} List all function status: - http://localhost:30021/status-functions => [{"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Public","Name":"fibonacci1"}, {"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Public","Name":"fibonacci2"}, - {"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Public","Name":"fibonacci3"}] + {"NumberReady":1,"numberRequested":1,PodType":"Deployment","Visibility":"Public","Name":"fibonacci3"}, + {"NumberReady":2,"numberRequested":2,PodType":"Deployment","Visibility":"Private","Name":"fibonacci4"}] Send event to every function replicas (which deployment subscribe to the event name) in synchronous way: @@ -153,11 +146,11 @@ spec: SlimFaas/ReplicasMin: "0" SlimFaas/ReplicasAtStart: "1" SlimFaas/ReplicasStartAsSoonAsOneFunctionRetrieveARequest: "false" + SlimFaas/DependsOn: "mysql,fibonacci2" # comma separated list of deployment or statefulset names SlimFaas/TimeoutSecondBeforeSetReplicasMin: "300" SlimFaas/NumberParallelRequest : "10" SlimFaas/Schedule: | - {"TimeZoneID":"Europe/Paris","Default":{"WakeUp":["07:00"],"ScaleDownTimeout":[{"Time":"07:00","Value":20},{"Time":"21:00","Value":10}]}} - SlimFaas/DependsOn: "mysql,fibonacci2" # comma separated list of deployment or statefulset names + {"TimeZoneID":"Europe/Paris","Default":{"WakeUp":["07:00"],"ScaleDownTimeout":[{"Time":"07:00","Value":3600},{"Time":"21:00","Value":60}]}} SlimFaas/SubscribeEvents: "Public:my-event-name1,Private:my-event-name2,my-event-name3" # comma separated list of event names SlimFaas/DefaultVisibility: "Public" # Public or Private (private can be accessed only by internal namespace https call from pods) SlimFaas/UrlsPathStartWithVisibility: "Private:/mypath/subPath,Private:/mysecondpath" # Public or Private (private can be accessed only by internal namespace https call from pods) @@ -322,7 +315,6 @@ spec: > Yours **service name** must be the same as the SlimFaas **Deployment/StatefulSet name** - ### SlimFaas Annotations with defaults values - **SlimFaas/Function**: "true" - Activate SlimFaas on this pod, so your pod will be auto-scaled @@ -395,7 +387,7 @@ Instead of creating many pods, SlimFaas use internally many workers in the same - **ReplicasSynchronizationWorker**: Manage replicas synchronization between the pod and kubernetes - **ReplicasScaleWorker**: If master, then scale up and down kubernetes pods -**SlimData** is a simple redis like database included inside SlimFaas executable. It is based on **Raft** algorithm offered by awesome https://github.com/dotnet/dotNext library. +**SlimData** is a simple redis like database included inside SlimFaas executable. It is based on **Raft** (https://raft.github.io/) algorithm offered by awesome dotNext library (https://github.com/dotnet/dotNext). By default, **SlimData** use a second HTTP port 3262 to expose its API. Don't expose it and keep it internal. SlimFaas requires at least 3 nodes in production. 2 nodes are required to keep the database in a consistent state. @@ -422,6 +414,9 @@ Why .NET? ## What Next? -1. Scale up dynamically from SlimFaas -2. Wake up from External Source (example: Kafka, etc.) -3. Continue Optimization +0. Retry pattern fully controllable with dead letter queue +1. Scale up dynamically from SlimFaas in Async Mode +2. Scale up dynamically from SlimFaas in Sync Mode (Copy KEDA syntax) +3. Aggregate all swaggers from functions in one exposed by SlimFaas +4. New pod to "Wake up" from External Source (example: Kafka, etc.) using https://cloudevents.io/ as standard https://github.com/cloudevents/sdk-csharp +5. Continue Optimization diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 5716590d..62494c46 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -14,21 +14,13 @@ spec: app: fibonacci1 annotations: SlimFaas/Function: "true" - SlimFaas/ReplicasMin: "0" - SlimFaas/ReplicasAtStart: "1" - SlimFaas/ReplicasStartAsSoonAsOneFunctionRetrieveARequest: "false" SlimFaas/TimeoutSecondBeforeSetReplicasMin: "10" - SlimFaas/NumberParallelRequest: "10" - SlimFaas/DependsOn: "fibonacci2" - SlimFaas/SubscribeEvents : "Public:fibo-public,Private:fibo-private" - #SlimFaas/Schedule: | - # {"TimeZoneID":"Europe/Paris","Default":{"WakeUp":["07:00"],"ScaleDownTimeout":[{"Time": "21:00","Value":20},{"Time":"07:00","Value": 10}]}} spec: serviceAccountName: default automountServiceAccountToken: false containers: - name: fibonacci1 - image: axaguildev/fibonacci:pr-77-735 + image: axaguildev/fibonacci:pr-77-736 livenessProbe: httpGet: path: /health @@ -41,11 +33,11 @@ spec: value: http://+:5000 resources: limits: - memory: "256Mi" + memory: "96Mi" cpu: "50m" requests: ephemeral-storage: "200Mi" - memory: "256Mi" + memory: "96Mi" cpu: "10m" ports: - containerPort: 5000 @@ -65,11 +57,8 @@ spec: app: fibonacci2 annotations: SlimFaas/Function: "true" - SlimFaas/ReplicasMin: "0" - SlimFaas/ReplicasAtStart: "1" SlimFaas/TimeoutSecondBeforeSetReplicasMin: "10" - SlimFaas/NumberParallelRequest : "10" - SlimFaas/SubscribeEvents : "Public:fibo-public,Private:fibo-private" + SlimFaas/DependsOn: "fibonacci1,mysql" spec: serviceAccountName: default automountServiceAccountToken: false @@ -112,12 +101,7 @@ spec: app: fibonacci3 annotations: SlimFaas/Function: "true" - SlimFaas/ReplicasMin: "0" - SlimFaas/ReplicasAtStart: "1" - SlimFaas/ReplicasStartAsSoonAsOneFunctionRetrieveARequest: "false" - SlimFaas/TimeoutSecondBeforeSetReplicasMin: "10" - SlimFaas/NumberParallelRequest : "10" - SlimFaas/DependsOn: "mysql" + SlimFaas/TimeoutSecondBeforeSetReplicasMin: "60" SlimFaas/SubscribeEvents : "Public:fibo-public,Private:fibo-private" spec: serviceAccountName: default @@ -135,13 +119,15 @@ spec: env: - name: ASPNETCORE_URLS value: http://+:5000 + - name: Logging__LogLevel__Default + value: Warning resources: limits: - memory: "96Mi" - cpu: "50m" + memory: "512Mi" + cpu: "100m" requests: ephemeral-storage: "200Mi" - memory: "96Mi" + memory: "512Mi" cpu: "10m" ports: - containerPort: 5000 @@ -161,11 +147,6 @@ spec: app: fibonacci4 annotations: SlimFaas/Function: "true" - SlimFaas/ReplicasMin: "2" - SlimFaas/ReplicasAtStart: "2" - SlimFaas/ReplicasStartAsSoonAsOneFunctionRetrieveARequest: "false" - SlimFaas/TimeoutSecondBeforeSetReplicasMin: "10" - SlimFaas/NumberParallelRequest : "10" SlimFaas/DefaultVisibility : "Private" SlimFaas/SubscribeEvents : "Public:fibo-public,Private:fibo-private" spec: diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 21c39186..fb31b6bc 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -26,16 +26,10 @@ .AllowAnyHeader() ); -app.MapPost("/fibonacci", ( - [FromServices] ILogger logger, - [FromServices] Fibonacci fibonacci, - FibonacciInput input) => +app.MapGet("/hello/{name}", ([FromServices] ILogger logger, string name) => { - logger.LogInformation("Fibonacci Called"); - var output = new FibonacciOutput(); - output.Result = fibonacci.Run(input.Input); - logger.LogInformation("Fibonacci output: {Output}", output.Result); - return Results.Ok(output); + logger.LogInformation("Hello Called with name: {Name}", name); + return $"Hello {name}!"; }); app.MapGet("/download", ([FromServices] ILogger logger) => @@ -45,16 +39,20 @@ return Results.File(path, "image/png"); }); -app.MapGet("/hello/{name}", ([FromServices] ILogger logger, string name) => +app.MapPost("/fibonacci", ( + [FromServices] ILogger logger, + [FromServices] Fibonacci fibonacci, + FibonacciInput input) => { - logger.LogInformation("Hello Called with name: {Name}", name); - return $"Hello {name}!"; + logger.LogInformation("Fibonacci Called"); + var output = new FibonacciOutput(); + output.Result = fibonacci.Run(input.Input); + logger.LogInformation("Fibonacci output: {Output}", output.Result); + return Results.Ok(output); }); - app.MapGet("/health", () => "OK"); - app.MapPost("/fibonacci-recursive", async ( [FromServices] ILogger logger, [FromServices] Fibonacci fibonacci, @@ -72,24 +70,25 @@ return Results.Ok(output); } - var response1 = + var httpResponse1 = client.PostAsJsonAsync( - "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", + "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci3/fibonacci-recursive", new FibonacciInput() { Input = input.Input - 1 }, FibonacciInputSerializerContext.Default.FibonacciInput); - var response2 = + var httpResponse2 = client.PostAsJsonAsync( - "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci1/fibonacci-recursive", + "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci3/fibonacci-recursive", new FibonacciInput() { Input = input.Input - 2 }, FibonacciInputSerializerContext.Default.FibonacciInput); - await Task.WhenAll(response1, response2); - var result1str = await response1.Result.Content.ReadAsStringAsync(); - var result1 = JsonSerializer.Deserialize(result1str, + await Task.WhenAll(httpResponse1, httpResponse2); + + var result1JsonResponse = await httpResponse1.Result.Content.ReadAsStringAsync(); + var result1 = JsonSerializer.Deserialize(result1JsonResponse, FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); - logger.LogInformation("Current result1: {Result}", result1str); - var result2str = await response2.Result.Content.ReadAsStringAsync(); - var result2 = JsonSerializer.Deserialize(result2str, + logger.LogInformation("Current result1: {Result}", result1JsonResponse); + var result2JsonResponse = await httpResponse2.Result.Content.ReadAsStringAsync(); + var result2 = JsonSerializer.Deserialize(result2JsonResponse, FibonacciRecursiveOutputSerializerContext.Default.FibonacciRecursiveOutput); - logger.LogInformation("Current result2: {Result}", result2str); + logger.LogInformation("Current result2: {Result}", result2JsonResponse); output.Result = result1.Result + result2.Result; output.NumberCall = result1.NumberCall + result2.NumberCall + 1; logger.LogInformation("Current output: {Result}", output.Result); @@ -102,7 +101,6 @@ return Results.BadRequest(new FibonacciRecursiveOutput()); }); - app.MapPost("/send-private-fibonacci-event", ( [FromServices] ILogger logger, [FromServices] Fibonacci fibonacci, @@ -115,7 +113,6 @@ logger.LogInformation("Fibonacci Internal Event End"); }); - app.Run(); internal class Fibonacci diff --git a/src/Fibonacci/appsettings.json b/src/Fibonacci/appsettings.json index ca6e46e9..e56fdf70 100644 --- a/src/Fibonacci/appsettings.json +++ b/src/Fibonacci/appsettings.json @@ -1,10 +1,8 @@ { - "Logging": { + "Logging": { "LogLevel": { "Default": "Debug", - "Microsoft.AspNetCore": "Warning", - "SlimFaas": "Debug", - "SlimData": "Warning" + "Microsoft.AspNetCore": "Warning" } }, "AllowedHosts": "*" From 25ace8ba823256623b0261305f666125be915d8a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 7 Oct 2024 17:56:38 +0200 Subject: [PATCH 032/135] update --- README.md | 15 +++++++++++++-- demo/deployment-functions.yml | 8 ++++---- src/Fibonacci/Program.cs | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index feca5656..0a3d688a 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Why use SlimFaas? - Synchronous HTTP calls - Asynchronous HTTP calls - Allows you to limit the number of parallel HTTP requests for each underlying function -- Synchronous Publish/Subscribe events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple you application with SlimFaas**) +- Synchronous Publish/Subscribe internal events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple you application with SlimFaas**) - Retry: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds - Private and Public functions - Private functions can be accessed only by internal namespace http call from pods @@ -29,7 +29,18 @@ To test SlimFaas on your local machine by using kubernetes with Docker Desktop, git clone https://github.com/AxaFrance/slimfaas.git cd slimfaas/demo # Create slimfaas service account and pods -cd +kubectl apply -f deployment-slimfaas.yml +# Expose SlimFaaS service as NodePort or Ingress +kubectl apply -f slimfaas-nodeport.yml +# or +# kubectl apply -f slimfaas-ingress.yml +# Install three instances of fibonacci functions +# fibonacci1, fibonacci2 and fibonacci3 +kubectl apply -f deployment-functions.yml +# Install MySql +kubectl apply -f deployment-mysql.yml +# to run Single Page webapp demo (optional) on http://localhost:8000 +docker run -p 8000:8000 --rm axaguildev/fibonacci-webapp:latest ``` Now, you can access your pod via SlimFaas proxy: diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 62494c46..1b98f83c 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -20,7 +20,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci1 - image: axaguildev/fibonacci:pr-77-736 + image: axaguildev/fibonacci:pr-77-737 livenessProbe: httpGet: path: /health @@ -64,7 +64,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci2 - image: axaguildev/fibonacci:pr-77-714 + image: axaguildev/fibonacci:pr-77-737 livenessProbe: httpGet: path: /health @@ -108,7 +108,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci3 - image: axaguildev/fibonacci:pr-77-714 + image: axaguildev/fibonacci:pr-77-737 livenessProbe: httpGet: path: /health @@ -154,7 +154,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci4 - image: axaguildev/fibonacci:pr-77-714 + image: axaguildev/fibonacci:pr-77-737 livenessProbe: httpGet: path: /health diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index fb31b6bc..1063f9d8 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -113,6 +113,38 @@ logger.LogInformation("Fibonacci Internal Event End"); }); +app.MapPost("/fibonacci4", async ( + [FromServices] ILogger logger, + [FromServices] Fibonacci fibonacci, + [FromServices] HttpClient client, + FibonacciInput input) => +{ + try + { + logger.LogInformation("Fibonacci4 Internal Called: {Input}", input.Input); + var output = new FibonacciOutput(); + var httpResponse1 = + client.PostAsJsonAsync( + "http://slimfaas.slimfaas-demo.svc.cluster.local:5000/function/fibonacci4/fibonacci", + new FibonacciInput() { Input = input.Input - 1 }, FibonacciInputSerializerContext.Default.FibonacciInput); + await Task.WhenAll(httpResponse1); + + var result1JsonResponse = await httpResponse1.Result.Content.ReadAsStringAsync(); + var result1 = JsonSerializer.Deserialize(result1JsonResponse, + FibonacciOutputSerializerContext.Default.FibonacciOutput); + logger.LogInformation("Current result1: {Result}", result1JsonResponse); + + output.Result = result1.Result; + logger.LogInformation("Current output: {Result}", output.Result); + return Results.Ok(output); + } + catch (Exception ex) + { + logger.LogError(ex, "Error in Fibonacci Recursive Internal"); + } + return Results.BadRequest(new FibonacciRecursiveOutput()); +}); + app.Run(); internal class Fibonacci From 6ee04cbb0fb65f04510d9b1e70cd42236b97617a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 8 Nov 2024 12:27:46 +0100 Subject: [PATCH 033/135] test --- src/SlimData/Commands/AddKeyValueCommand.cs | 2 +- src/SlimData/Commands/ListLeftPushCommand.cs | 3 +- src/SlimData/Commands/ListRightPopCommand.cs | 7 +- src/SlimData/Commands/LogSnapshotCommand.cs | 37 ++++- src/SlimData/Endpoints.cs | 10 +- src/SlimData/SlimDataInterpreter.cs | 146 ++++++++++++++++++- src/SlimFaas/ReplicasService.cs | 2 +- 7 files changed, 181 insertions(+), 26 deletions(-) diff --git a/src/SlimData/Commands/AddKeyValueCommand.cs b/src/SlimData/Commands/AddKeyValueCommand.cs index 6bb877df..c1d0af1f 100644 --- a/src/SlimData/Commands/AddKeyValueCommand.cs +++ b/src/SlimData/Commands/AddKeyValueCommand.cs @@ -12,7 +12,7 @@ public struct AddKeyValueCommand : ISerializable public string Key { get; set; } public ReadOnlyMemory Value { get; set; } - long? IDataTransferObject.Length => sizeof(int) + Value.Length; + long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + Value.Length; public async ValueTask WriteToAsync(TWriter writer, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter diff --git a/src/SlimData/Commands/ListLeftPushCommand.cs b/src/SlimData/Commands/ListLeftPushCommand.cs index 8fa9a60f..934bbf5b 100644 --- a/src/SlimData/Commands/ListLeftPushCommand.cs +++ b/src/SlimData/Commands/ListLeftPushCommand.cs @@ -10,9 +10,10 @@ public struct ListLeftPushCommand : ISerializable public const int Id = 13; public string Key { get; set; } + public ReadOnlyMemory Value { get; set; } - long? IDataTransferObject.Length => sizeof(int) + Value.Length; + long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + Value.Length; public async ValueTask WriteToAsync(TWriter writer, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter diff --git a/src/SlimData/Commands/ListRightPopCommand.cs b/src/SlimData/Commands/ListRightPopCommand.cs index c78956ef..d32c36da 100644 --- a/src/SlimData/Commands/ListRightPopCommand.cs +++ b/src/SlimData/Commands/ListRightPopCommand.cs @@ -11,8 +11,9 @@ public struct ListRightPopCommand : ISerializable public string Key { get; set; } public int Count { get; set; } + public long NowTicks { get; set; } - long? IDataTransferObject.Length => sizeof(int); + long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + sizeof(int) + sizeof(long); public async ValueTask WriteToAsync(TWriter writer, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter @@ -21,6 +22,7 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.EncodeAsync(command.Key.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(Count, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(NowTicks, token).ConfigureAwait(false); } #pragma warning disable CA2252 @@ -32,7 +34,8 @@ public static async ValueTask ReadFromAsync(TReade return new ListRightPopCommand { Key = key.ToString(), - Count = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false) + Count = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false), + NowTicks = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false) }; } } \ No newline at end of file diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index a28d7eca..2416d276 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -31,7 +31,15 @@ public readonly struct LogSnapshotCommand(Dictionary result += x.Value.Length + sizeof(Int32) + sizeof(Int64) + sizeof(Int64)); + queue.Value.ForEach(x => + { + result += x.Value.Length + Encoding.UTF8.GetByteCount(x.Id) + sizeof(Int64); + result += sizeof(Int32); // 4 bytes for hashset count + foreach (var retryQueueElement in x.RetryQueueElements) + { + result += sizeof(Int64) * 2 + sizeof(Int32); + } + }); } // compute length of the serialized data, in bytes @@ -70,9 +78,15 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.WriteLittleEndianAsync(queue.Value.Count, token).ConfigureAwait(false); foreach (var value in queue.Value){ await writer.WriteAsync(value.Value, LengthFormat.Compressed, token).ConfigureAwait(false); - await writer.WriteLittleEndianAsync(value.InsertTimeStamp, token).ConfigureAwait(false); - await writer.WriteLittleEndianAsync(value.RetryNumber, token).ConfigureAwait(false); - await writer.WriteLittleEndianAsync(value.LastAccessTimeStamp, token).ConfigureAwait(false); + await writer.EncodeAsync(value.Id.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); + await writer.WriteBigEndianAsync(value.InsertTimeStamp, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(value.RetryQueueElements.Count, token).ConfigureAwait(false); + foreach (var retryQueueElement in value.RetryQueueElements) + { + await writer.WriteBigEndianAsync(retryQueueElement.StartTimeStamp, token).ConfigureAwait(false); + await writer.WriteBigEndianAsync(retryQueueElement.EndTimeStamp, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(retryQueueElement.HttpCode, token).ConfigureAwait(false); + }; } } @@ -120,11 +134,20 @@ public static async ValueTask ReadFromAsync(TReader while (countQueue-- > 0) { using var value = await reader.ReadAsync(LengthFormat.Compressed, token: token).ConfigureAwait(false); + var id = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token) + .ConfigureAwait(false); var insertTimeStamp = await reader.ReadBigEndianAsync(token); - var retryNumber = await reader.ReadLittleEndianAsync(token); - var lastAccessTimeStamp = await reader.ReadBigEndianAsync(token); + var countRetryQueueElements = await reader.ReadLittleEndianAsync(token); + var retryQueueElements = new List(countRetryQueueElements); + while (countRetryQueueElements-- > 0) + { + var startTimestamp = await reader.ReadBigEndianAsync(token); + var endTimestamp = await reader.ReadBigEndianAsync(token); + var httpCode = await reader.ReadLittleEndianAsync(token); + retryQueueElements.Add(new RetryQueueElement(startTimestamp, endTimestamp, httpCode)); + } - queue.Add(new QueueElement(value.Memory, insertTimeStamp, retryNumber, lastAccessTimeStamp)); + queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, retryQueueElements)); } queues.Add(key.ToString(), queue); diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 7f0985be..b96eda00 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -124,18 +124,16 @@ public static async Task ListRightPopCommand(SlimPersistentState pro Console.WriteLine("Master node is waiting for lease token"); await Task.Delay(10); } + var nowTicks = DateTime.UtcNow.Ticks; var queues = ((ISupplier)provider).Invoke().Queues; if (queues.TryGetValue(key, out var queue)) { - for (var i = 0; i < count; i++) - { - if (queue.Count <= i) break; - values.Items.Add(queue[i].Value.ToArray()); - } + var queueElements = queue.GetQueueAvailableElement([2, 6, 10], nowTicks, count); + values.Items.AddRange(queueElements.Select(x => x.Value.ToArray())); var logEntry = provider.Interpreter.CreateLogEntry( - new ListRightPopCommand { Key = key, Count = count }, + new ListRightPopCommand { Key = key, Count = count, NowTicks = nowTicks }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); } diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index a8426299..7a057a90 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -3,12 +3,121 @@ namespace SlimData; + + public record SlimDataState( Dictionary> hashsets, Dictionary> keyValues, Dictionary> queues); -public record QueueElement(ReadOnlyMemory Value, long InsertTimeStamp, int RetryNumber=0, long LastAccessTimeStamp=0); +public record QueueElement( + ReadOnlyMemory Value, + string Id, + long InsertTimeStamp, + IList RetryQueueElements); + +public class RetryQueueElement(long StartTimeStamp=0, long EndTimeStamp=0, int HttpCode=0) +{ + public long StartTimeStamp { get; set; } = StartTimeStamp; + public long EndTimeStamp { get;set; } = EndTimeStamp; + public int HttpCode { get;set; } = HttpCode; +} + +public static class QueueElementExtensions +{ + + public static IList GetQueueTimeoutElement(this IList element, long nowTicks, int timeout=30) + { + var timeoutElements = new List(); + foreach (var queueElement in element) + { + if(queueElement.RetryQueueElements.Count > 0) + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp == 0 && + retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) + { + timeoutElements.Add(queueElement); + } + } + + } + return timeoutElements; + } + + public static IList GetQueueRunningElement(this IList element, long nowTicks, int timeout=30) + { + var runningElement = new List(); + foreach (var queueElement in element) + { + if(queueElement.RetryQueueElements.Count > 0) + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp == 0 && + retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks > nowTicks) + { + runningElement.Add(queueElement); + } + } + + } + return runningElement; + } + + public static IList GetQueueAvailableElement(this IList element, List retries, long nowTicks, int maximum) + { + var currentCount = 0; + var availableElements = new List(); + foreach (var queueElement in element) + { + if (currentCount == maximum) + { + return availableElements; + } + var count = queueElement.RetryQueueElements.Count; + if (count == 0) + { + availableElements.Add(queueElement); + currentCount++; + } + else + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.HttpCode >= 400 + && retries.Count <= count + && retryQueueElement.EndTimeStamp != 0 + && nowTicks > retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks + ) + { + availableElements.Add(queueElement); + currentCount++; + } + } + + } + return availableElements; + } + + public static IList GetQueueFinishedElement(this IList element, List retries) + { + var runningElement = new List(); + foreach (var queueElement in element) + { + var count = queueElement.RetryQueueElements.Count; + if(count > 0) + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.HttpCode is >= 200 and < 400 || retries.Count <= count) + { + runningElement.Add(queueElement); + } + } + + } + return runningElement; + } + +} #pragma warning restore CA2252 @@ -22,15 +131,36 @@ public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, Cancel { return DoListRightPopAsync(addHashSetCommand, SlimDataState.queues); } + + private static readonly List Retries = [2, 6, 10]; + private static readonly int RetryTimeout = 30; + private static readonly int NumberParralel = 1; internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetCommand, Dictionary> queues) { if (queues.TryGetValue(addHashSetCommand.Key, out var queue)) - for (var i = 0; i < addHashSetCommand.Count; i++) - if (queue.Count > 0) - queue.RemoveAt(0); - else - break; + { + var nowTicks =addHashSetCommand.NowTicks; + var queueTimeoutElements = queue.GetQueueTimeoutElement(nowTicks, RetryTimeout); + foreach (var queueTimeoutElement in queueTimeoutElements) + { + var retryQueueElement = queueTimeoutElement.RetryQueueElements[^1]; + retryQueueElement.EndTimeStamp = nowTicks; + retryQueueElement.HttpCode = 520; + } + + var queueFinishedElements = queue.GetQueueFinishedElement(Retries); + foreach (var queueFinishedElement in queueFinishedElements) + { + queue.Remove(queueFinishedElement); + } + + var queueAvailableElements = queue.GetQueueAvailableElement(Retries, nowTicks, addHashSetCommand.Count); + foreach (var queueAvailableElement in queueAvailableElements) + { + queueAvailableElement.RetryQueueElements.Add(new RetryQueueElement(nowTicks)); + } + } return default; } @@ -44,9 +174,9 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Dictionary> queues) { if (queues.TryGetValue(addHashSetCommand.Key, out List? value)) - value.Add(new QueueElement(addHashSetCommand.Value, DateTime.UtcNow.Ticks)); + value.Add(new QueueElement(addHashSetCommand.Value, Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())); else - queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value, DateTime.UtcNow.Ticks)}); + queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value,Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())}); return default; } diff --git a/src/SlimFaas/ReplicasService.cs b/src/SlimFaas/ReplicasService.cs index d0a3de87..96224779 100644 --- a/src/SlimFaas/ReplicasService.cs +++ b/src/SlimFaas/ReplicasService.cs @@ -70,7 +70,7 @@ public async Task SyncDeploymentsAsync(string kubeNames "with {TimeoutSecondBeforeSetReplicasMin} timeout second before set replicas min \n" + "with {PodType} pod type \n" + "with {ResourceVersion} resource version \n"+ - "with {NumberParallelRequest} number parallel request \n", + "with {NumberParallelRequest} number parallel request \n" + "with dependOn {DependsOn} \n", deploymentInformation.Deployment, deploymentInformation.Replicas, deploymentInformation.ReplicasAtStart, deploymentInformation.ReplicasMin, deploymentInformation.ReplicasStartAsSoonAsOneFunctionRetrieveARequest, deploymentInformation.TimeoutSecondBeforeSetReplicasMin, From c63ece3dea5b80044175f5daec76c9db16636b8c Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 9 Nov 2024 22:27:08 +0100 Subject: [PATCH 034/135] updae --- .../Commands/ListSetQueueItemStatusCommand.cs | 40 +++++ src/SlimData/Endpoints.cs | 44 ++++- src/SlimData/ListString.cs | 2 +- src/SlimData/QueueElementExtensions.cs | 97 +++++++++++ src/SlimData/SlimDataInterpreter.cs | 156 +++++------------- src/SlimData/SlimPersistentState.cs | 12 +- src/SlimFaas/Database/DatabaseMockService.cs | 6 +- src/SlimFaas/Database/IDatabaseService.cs | 7 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 47 +++++- .../Database/SlimFaasSlimFaasQueue.cs | 14 +- src/SlimFaas/SlimWorker.cs | 8 +- tests/SlimData.Tests/CommandsTests.cs | 4 +- tests/SlimData.Tests/RaftClusterTests.cs | 4 +- 14 files changed, 293 insertions(+), 150 deletions(-) create mode 100644 src/SlimData/Commands/ListSetQueueItemStatusCommand.cs create mode 100644 src/SlimData/QueueElementExtensions.cs diff --git a/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs b/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs new file mode 100644 index 00000000..b3732b38 --- /dev/null +++ b/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs @@ -0,0 +1,40 @@ +using System.Text; +using DotNext.IO; +using DotNext.Runtime.Serialization; +using DotNext.Text; + +namespace SlimData.Commands; + +public struct ListSetQueueItemStatusCommand : ISerializable +{ + public const int Id = 15; + + public string Identifier { get; set; } + public string Key { get; set; } + + public int HttpCode { get; set; } + + public async ValueTask WriteToAsync(TWriter writer, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter + { + var command = this; + await writer.EncodeAsync(command.Identifier.AsMemory(), new EncodingContext(Encoding.UTF8, false), + LengthFormat.LittleEndian, token).ConfigureAwait(false); + await writer.EncodeAsync(command.Key.AsMemory(), new EncodingContext(Encoding.UTF8, false), + LengthFormat.LittleEndian, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(HttpCode, token).ConfigureAwait(false); + } + + long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Identifier) + sizeof(int); + + public static async ValueTask ReadFromAsync(TReader reader, CancellationToken token) where TReader : notnull, IAsyncBinaryReader + { + var identifier = await reader.DecodeAsync( new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); + var key = await reader.DecodeAsync( new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); + return new ListSetQueueItemStatusCommand + { + Identifier = identifier.ToString(), + Key = key.ToString(), + HttpCode = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false) + }; + } +} \ No newline at end of file diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index b96eda00..10263d2b 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -1,6 +1,7 @@ using DotNext; using DotNext.Net.Cluster.Consensus.Raft; using MemoryPack; +using Microsoft.Extensions.Primitives; using SlimData.Commands; namespace SlimData; @@ -106,7 +107,7 @@ public static async Task ListRightPopCommand(SlimPersistentState pro CancellationTokenSource source) { var values = new ListString(); - values.Items = new List(); + values.Items = new Dictionary(); if(SemaphoreSlims.TryGetValue(key, out var semaphoreSlim)) { @@ -129,7 +130,10 @@ public static async Task ListRightPopCommand(SlimPersistentState pro if (queues.TryGetValue(key, out var queue)) { var queueElements = queue.GetQueueAvailableElement([2, 6, 10], nowTicks, count); - values.Items.AddRange(queueElements.Select(x => x.Value.ToArray())); + foreach (var queueElement in queueElements) + { + values.Items[queueElement.Id] = queueElement.Value.ToArray(); + } var logEntry = provider.Interpreter.CreateLogEntry( @@ -174,6 +178,42 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); } + + public record QueueItemStatus(string Id, int HttpCode); + + public static Task ListSetQueueItemStatusCommand(HttpContext context) + { + return DoAsync(context, async (cluster, provider, source) => + { + context.Request.Query.TryGetValue("key", out var key); + if (string.IsNullOrEmpty(key)) + { + context.Response.StatusCode = StatusCodes.Status400BadRequest; + await context.Response.WriteAsync("not data found", context.RequestAborted); + return; + } + + var inputStream = context.Request.Body; + await using var memoryStream = new MemoryStream(); + await inputStream.CopyToAsync(memoryStream, source.Token); + var value = memoryStream.ToArray(); + var list = MemoryPackSerializer.Deserialize>(value); + await ListSetQueueItemStatus(provider, key, list, cluster, source); + }); + } + + private static async Task ListSetQueueItemStatus(SlimPersistentState provider, StringValues key, List list, IRaftCluster cluster, CancellationTokenSource source) + { + foreach (var queueItemStatus in list) + { + var logEntry = + provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand { Identifier = queueItemStatus.Id, + Key = key, + HttpCode = queueItemStatus.HttpCode }, + cluster.Term); + await cluster.ReplicateAsync(logEntry, source.Token); + } + } private static (string key, string value) GetKeyValue(IFormCollection form) { diff --git a/src/SlimData/ListString.cs b/src/SlimData/ListString.cs index cbeeb232..2ce9be5e 100644 --- a/src/SlimData/ListString.cs +++ b/src/SlimData/ListString.cs @@ -6,5 +6,5 @@ namespace SlimData; [MemoryPackable] public partial class ListString { - public List Items { get; set; } + public IDictionary Items { get; set; } } \ No newline at end of file diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs new file mode 100644 index 00000000..981a589b --- /dev/null +++ b/src/SlimData/QueueElementExtensions.cs @@ -0,0 +1,97 @@ +namespace SlimData; + +public static class QueueElementExtensions +{ + + public static List GetQueueTimeoutElement(this List element, long nowTicks, int timeout=30) + { + var timeoutElements = new List(); + foreach (var queueElement in element) + { + if(queueElement.RetryQueueElements.Count > 0) + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp == 0 && + retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) + { + timeoutElements.Add(queueElement); + } + } + + } + return timeoutElements; + } + + public static List GetQueueRunningElement(this List element, long nowTicks, int timeout=30) + { + var runningElement = new List(); + foreach (var queueElement in element) + { + if(queueElement.RetryQueueElements.Count > 0) + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp == 0 && + retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks > nowTicks) + { + runningElement.Add(queueElement); + } + } + + } + return runningElement; + } + + public static List GetQueueAvailableElement(this List element, List retries, long nowTicks, int maximum) + { + var currentCount = 0; + var availableElements = new List(); + foreach (var queueElement in element) + { + if (currentCount == maximum) + { + return availableElements; + } + var count = queueElement.RetryQueueElements.Count; + if (count == 0) + { + availableElements.Add(queueElement); + currentCount++; + } + else + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.HttpCode >= 400 + && retries.Count <= count + && retryQueueElement.EndTimeStamp != 0 + && nowTicks > retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks + ) + { + availableElements.Add(queueElement); + currentCount++; + } + } + + } + return availableElements; + } + + public static IList GetQueueFinishedElement(this IList element, List retries) + { + var runningElement = new List(); + foreach (var queueElement in element) + { + var count = queueElement.RetryQueueElements.Count; + if(count > 0) + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.HttpCode is >= 200 and < 400 || retries.Count <= count) + { + runningElement.Add(queueElement); + } + } + + } + return runningElement; + } + +} \ No newline at end of file diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 7a057a90..64826c3a 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -6,9 +6,9 @@ namespace SlimData; public record SlimDataState( - Dictionary> hashsets, - Dictionary> keyValues, - Dictionary> queues); + Dictionary> Hashsets, + Dictionary> KeyValues, + Dictionary> Queues); public record QueueElement( ReadOnlyMemory Value, @@ -16,110 +16,13 @@ public record QueueElement( long InsertTimeStamp, IList RetryQueueElements); -public class RetryQueueElement(long StartTimeStamp=0, long EndTimeStamp=0, int HttpCode=0) +public class RetryQueueElement(long startTimeStamp=0, long endTimeStamp=0, int httpCode=0) { - public long StartTimeStamp { get; set; } = StartTimeStamp; - public long EndTimeStamp { get;set; } = EndTimeStamp; - public int HttpCode { get;set; } = HttpCode; + public long StartTimeStamp { get; set; } = startTimeStamp; + public long EndTimeStamp { get;set; } = endTimeStamp; + public int HttpCode { get;set; } = httpCode; } -public static class QueueElementExtensions -{ - - public static IList GetQueueTimeoutElement(this IList element, long nowTicks, int timeout=30) - { - var timeoutElements = new List(); - foreach (var queueElement in element) - { - if(queueElement.RetryQueueElements.Count > 0) - { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.EndTimeStamp == 0 && - retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) - { - timeoutElements.Add(queueElement); - } - } - - } - return timeoutElements; - } - - public static IList GetQueueRunningElement(this IList element, long nowTicks, int timeout=30) - { - var runningElement = new List(); - foreach (var queueElement in element) - { - if(queueElement.RetryQueueElements.Count > 0) - { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.EndTimeStamp == 0 && - retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks > nowTicks) - { - runningElement.Add(queueElement); - } - } - - } - return runningElement; - } - - public static IList GetQueueAvailableElement(this IList element, List retries, long nowTicks, int maximum) - { - var currentCount = 0; - var availableElements = new List(); - foreach (var queueElement in element) - { - if (currentCount == maximum) - { - return availableElements; - } - var count = queueElement.RetryQueueElements.Count; - if (count == 0) - { - availableElements.Add(queueElement); - currentCount++; - } - else - { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.HttpCode >= 400 - && retries.Count <= count - && retryQueueElement.EndTimeStamp != 0 - && nowTicks > retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks - ) - { - availableElements.Add(queueElement); - currentCount++; - } - } - - } - return availableElements; - } - - public static IList GetQueueFinishedElement(this IList element, List retries) - { - var runningElement = new List(); - foreach (var queueElement in element) - { - var count = queueElement.RetryQueueElements.Count; - if(count > 0) - { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.HttpCode is >= 200 and < 400 || retries.Count <= count) - { - runningElement.Add(queueElement); - } - } - - } - return runningElement; - } - -} - - #pragma warning restore CA2252 public class SlimDataInterpreter : CommandInterpreter { @@ -129,7 +32,7 @@ public class SlimDataInterpreter : CommandInterpreter [CommandHandler] public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, CancellationToken token) { - return DoListRightPopAsync(addHashSetCommand, SlimDataState.queues); + return DoListRightPopAsync(addHashSetCommand, SlimDataState.Queues); } private static readonly List Retries = [2, 6, 10]; @@ -168,7 +71,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm [CommandHandler] public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, CancellationToken token) { - return DoListLeftPushAsync(addHashSetCommand, SlimDataState.queues); + return DoListLeftPushAsync(addHashSetCommand, SlimDataState.Queues); } internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Dictionary> queues) @@ -180,11 +83,32 @@ internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetComm return default; } + + [CommandHandler] + public ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHashSetCommand, CancellationToken token) + { + return DoListSetQueueItemStatusAsync(addHashSetCommand, SlimDataState.Queues); + } + + internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHashSetCommand, Dictionary> queues) + { + if (!queues.TryGetValue(addHashSetCommand.Key, out List? value)) return default; + var queueElement = value.Find(x => x.Id == addHashSetCommand.Identifier); + if (queueElement != null) + { + var retryQueueElement = queueElement.RetryQueueElements[^1]; + retryQueueElement.EndTimeStamp = DateTime.UtcNow.Ticks; + retryQueueElement.HttpCode = addHashSetCommand.HttpCode; + } + return default; + } + + [CommandHandler] public ValueTask AddHashSetAsync(AddHashSetCommand addHashSetCommand, CancellationToken token) { - return DoAddHashSetAsync(addHashSetCommand, SlimDataState.hashsets); + return DoAddHashSetAsync(addHashSetCommand, SlimDataState.Hashsets); } internal static ValueTask DoAddHashSetAsync(AddHashSetCommand addHashSetCommand, Dictionary> hashsets) @@ -196,7 +120,7 @@ internal static ValueTask DoAddHashSetAsync(AddHashSetCommand addHashSetCommand, [CommandHandler] public ValueTask AddKeyValueAsync(AddKeyValueCommand valueCommand, CancellationToken token) { - return DoAddKeyValueAsync(valueCommand, SlimDataState.keyValues); + return DoAddKeyValueAsync(valueCommand, SlimDataState.KeyValues); } internal static ValueTask DoAddKeyValueAsync(AddKeyValueCommand valueCommand, Dictionary> keyValues) @@ -208,9 +132,9 @@ internal static ValueTask DoAddKeyValueAsync(AddKeyValueCommand valueCommand, Di [CommandHandler(IsSnapshotHandler = true)] public ValueTask HandleSnapshotAsync(LogSnapshotCommand command, CancellationToken token) { - SlimDataState = SlimDataState with { keyValues = command.keysValues }; - SlimDataState = SlimDataState with { queues = command.queues }; - SlimDataState = SlimDataState with { hashsets = command.hashsets }; + SlimDataState = SlimDataState with { KeyValues = command.keysValues }; + SlimDataState = SlimDataState with { Queues = command.queues }; + SlimDataState = SlimDataState with { Hashsets = command.hashsets }; return default; } @@ -238,11 +162,11 @@ internal static ValueTask DoHandleSnapshotAsync(LogSnapshotCommand command, Dict public static CommandInterpreter InitInterpreter(SlimDataState state) { - ValueTask ListRightPopHandler(ListRightPopCommand command, CancellationToken token) => DoListRightPopAsync(command, state.queues); - ValueTask ListLeftPushHandler(ListLeftPushCommand command, CancellationToken token) => DoListLeftPushAsync(command, state.queues); - ValueTask AddHashSetHandler(AddHashSetCommand command, CancellationToken token) => DoAddHashSetAsync(command, state.hashsets); - ValueTask AddKeyValueHandler(AddKeyValueCommand command, CancellationToken token) => DoAddKeyValueAsync(command, state.keyValues); - ValueTask SnapshotHandler(LogSnapshotCommand command, CancellationToken token) => DoHandleSnapshotAsync(command, state.keyValues, state.hashsets, state.queues); + ValueTask ListRightPopHandler(ListRightPopCommand command, CancellationToken token) => DoListRightPopAsync(command, state.Queues); + ValueTask ListLeftPushHandler(ListLeftPushCommand command, CancellationToken token) => DoListLeftPushAsync(command, state.Queues); + ValueTask AddHashSetHandler(AddHashSetCommand command, CancellationToken token) => DoAddHashSetAsync(command, state.Hashsets); + ValueTask AddKeyValueHandler(AddKeyValueCommand command, CancellationToken token) => DoAddKeyValueAsync(command, state.KeyValues); + ValueTask SnapshotHandler(LogSnapshotCommand command, CancellationToken token) => DoHandleSnapshotAsync(command, state.KeyValues, state.Hashsets, state.Queues); var interpreter = new Builder() .Add(ListRightPopCommand.Id, (Func)ListRightPopHandler) diff --git a/src/SlimData/SlimPersistentState.cs b/src/SlimData/SlimPersistentState.cs index c72ceaa4..42cb7f16 100644 --- a/src/SlimData/SlimPersistentState.cs +++ b/src/SlimData/SlimPersistentState.cs @@ -42,9 +42,9 @@ SlimDataPayload ISupplier.Invoke() { return new SlimDataPayload() { - KeyValues = _state.keyValues, - Hashsets = _state.hashsets, - Queues = _state.queues + KeyValues = _state.KeyValues, + Hashsets = _state.Hashsets, + Queues = _state.Queues }; } @@ -84,9 +84,9 @@ protected override async ValueTask ApplyAsync(LogEntry entry) public override async ValueTask WriteToAsync(TWriter writer, CancellationToken token) { - var keysValues = _state.keyValues; - var queues = _state.queues; - var hashsets = _state.hashsets; + var keysValues = _state.KeyValues; + var queues = _state.Queues; + var hashsets = _state.Hashsets; LogSnapshotCommand command = new(keysValues, hashsets, queues); await command.WriteToAsync(writer, token).ConfigureAwait(false); diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index c236760b..a1c0d3c6 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -74,15 +74,15 @@ public Task ListLeftPushAsync(string key, byte[] field) return Task.CompletedTask; } - public Task> ListRightPopAsync(string key, int count = 1) + public Task> ListRightPopAsync(string key, int count = 1) { if (!queue.ContainsKey(key)) { - return Task.FromResult>(new List()); + return Task.FromResult>(new Dictionary()); } List list = queue[key]; - + IDictionary dictionaryToReturn = new Dictionary(); List listToReturn = list.TakeLast((int)count).ToList(); if (listToReturn.Count > 0) { diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index 73df2733..266b2515 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -1,4 +1,6 @@ -namespace SlimFaas; +using SlimData; + +namespace SlimFaas; public interface IDatabaseService { @@ -7,6 +9,7 @@ public interface IDatabaseService Task HashSetAsync(string key, IDictionary values); Task> HashGetAllAsync(string key); Task ListLeftPushAsync(string key, byte[] field); - Task> ListRightPopAsync(string key, int count = 1); + Task> ListRightPopAsync(string key, int count = 1); Task ListLengthAsync(string key); + Task ListSetQueueItemStatus(string key, IList queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index c181247f..c3c1b335 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -3,7 +3,7 @@ public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); - Task> DequeueAsync(string key, long count = 1); + Task> DequeueAsync(string key, long count = 1); public Task CountAsync(string key); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index c27f5253..f66311a8 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -132,12 +132,12 @@ private async Task DoListLeftPushAsync(string key, byte[] field) } } - public async Task> ListRightPopAsync(string key, int count = 1) + public async Task> ListRightPopAsync(string key, int count = 1) { - return await Retry.Do(() =>DoListRightPopAsync(key, count), _retryInterval, logger, MaxAttemptCount); + return await Retry.Do(() => DoListRightPopAsync(key, count), _retryInterval, logger, MaxAttemptCount); } - private async Task> DoListRightPopAsync(string key, int count = 1) + private async Task> DoListRightPopAsync(string key, int count = 1) { EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) @@ -162,13 +162,40 @@ private async Task> DoListRightPopAsync(string key, int count = 1) var bin = await response.Content.ReadAsByteArrayAsync(); ListString? result = MemoryPackSerializer.Deserialize(bin); - return result?.Items ?? new List(); + return result?.Items ?? new Dictionary(); + } + } + + public async Task ListSetQueueItemStatus(string key, IList queueItemStatus) + { + await Retry.Do(() => DoListSetQueueItemStatus(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); + } + + private async Task DoListSetQueueItemStatus(string key, IList queueItemStatus) + { + var field = MemoryPackSerializer.Serialize(queueItemStatus); + EndPoint endpoint = await GetAndWaitForLeader(); + if (!cluster.LeadershipToken.IsCancellationRequested) + { + var simplePersistentState = serviceProvider.GetRequiredService(); + await Endpoints.ListSetQueueItemStatusCommand(simplePersistentState, key, field, cluster, new CancellationTokenSource()); + } + else + { + using HttpRequestMessage request = new(HttpMethod.Post, new Uri($"{endpoint}SlimData/ListSetQueueItemStatus?key={key}")); + request.Content = new ByteArrayContent(field); + using var httpClient = httpClientFactory.CreateClient(HttpClientName); + using HttpResponseMessage response = await httpClient.SendAsync(request); + if ((int)response.StatusCode >= 500) + { + throw new DataException("Error in calling SlimData HTTP Service"); + } } } public async Task ListLengthAsync(string key) { - return await Retry.Do(() =>DoListLengthAsync(key), _retryInterval, logger, MaxAttemptCount); + return await Retry.Do(() => DoListLengthAsync(key), _retryInterval, logger, MaxAttemptCount); } private async Task DoListLengthAsync(string key) @@ -177,8 +204,13 @@ private async Task DoListLengthAsync(string key) await MasterWaitForleaseToken(); SlimDataPayload data = SimplePersistentState.Invoke(); - long result = data.Queues.TryGetValue(key, out List? value) ? value.Count : 0L; - return result; + + if (data.Queues.TryGetValue(key, out List? value)) + { + return value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, int.MaxValue).Count; + } + + return 0L; } private async Task MasterWaitForleaseToken() @@ -211,7 +243,6 @@ private async Task GetAndWaitForLeader() public static class Retry { - public static T Do( Func action, TimeSpan retryInterval, diff --git a/src/SlimFaas/Database/SlimFaasSlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasSlimFaasQueue.cs index 3e4460ac..bcc0cf26 100644 --- a/src/SlimFaas/Database/SlimFaasSlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasSlimFaasQueue.cs @@ -1,4 +1,8 @@ -namespace SlimFaas.Database; +using SlimData; + +namespace SlimFaas.Database; + + public class SlimFaasSlimFaasQueue(IDatabaseService databaseService) : ISlimFaasQueue { @@ -7,11 +11,15 @@ public class SlimFaasSlimFaasQueue(IDatabaseService databaseService) : ISlimFaas public async Task EnqueueAsync(string key, byte[] data) => await databaseService.ListLeftPushAsync($"{KeyPrefix}{key}", data); - public async Task> DequeueAsync(string key, long count = 1) + public async Task> DequeueAsync(string key, long count = 1) { - IList data = await databaseService.ListRightPopAsync($"{KeyPrefix}{key}"); + var data = await databaseService.ListRightPopAsync($"{KeyPrefix}{key}"); return data; } +#pragma warning disable CA2252 + public async Task SetQueueItemStatus(string key, IList queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); +#pragma warning restore CA2252 + public async Task CountAsync(string key) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}"); } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 1045a3bb..adc245a0 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -4,7 +4,7 @@ namespace SlimFaas; -internal record struct RequestToWait(Task Task, CustomRequest CustomRequest); +internal record struct RequestToWait(Task Task, CustomRequest CustomRequest, string id); public class SlimWorker(ISlimFaasQueue slimFaasQueue, IReplicasService replicasService, HistoryHttpMemoryService historyHttpService, ILogger logger, IServiceProvider serviceProvider, @@ -78,11 +78,11 @@ private async Task SendHttpRequestToFunction(Dictionary jsons = await slimFaasQueue.DequeueAsync(functionDeployment, + IDictionary jsons = await slimFaasQueue.DequeueAsync(functionDeployment, numberTasksToDequeue.HasValue ? (long)numberTasksToDequeue : 1); foreach (var requestJson in jsons) { - CustomRequest customRequest = MemoryPackSerializer.Deserialize(requestJson); + CustomRequest customRequest = MemoryPackSerializer.Deserialize(requestJson.Value); logger.LogDebug("{CustomRequestMethod}: {CustomRequestPath}{CustomRequestQuery} Sending", customRequest.Method, customRequest.Path, customRequest.Query); @@ -91,7 +91,7 @@ private async Task SendHttpRequestToFunction(Dictionary taskResponse = scope.ServiceProvider.GetRequiredService() .SendHttpRequestAsync(customRequest); - processingTasks[functionDeployment].Add(new RequestToWait(taskResponse, customRequest)); + processingTasks[functionDeployment].Add(new RequestToWait(taskResponse, customRequest, requestJson.Key)); } } diff --git a/tests/SlimData.Tests/CommandsTests.cs b/tests/SlimData.Tests/CommandsTests.cs index 198b9739..ac139abb 100644 --- a/tests/SlimData.Tests/CommandsTests.cs +++ b/tests/SlimData.Tests/CommandsTests.cs @@ -19,9 +19,9 @@ public static async Task InterpreterWithPersistentState() using var wal = new SlimPersistentState(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); var entry1 = wal.CreateLogEntry(new ListLeftPushCommand { Key = "youhou" , Value = bytes }); await wal.AppendAsync(entry1); - Assert.Empty(wal.SlimDataState.queues); + Assert.Empty(wal.SlimDataState.Queues); await wal.CommitAsync(CancellationToken.None); - Assert.Equal(bytes, wal.SlimDataState.queues["youhou"].First().Value.ToArray()); + Assert.Equal(bytes, wal.SlimDataState.Queues["youhou"].First().Value.ToArray()); var bin = MemoryPackSerializer.Serialize(3); var final = MemoryPackSerializer.Deserialize(bin); diff --git a/tests/SlimData.Tests/RaftClusterTests.cs b/tests/SlimData.Tests/RaftClusterTests.cs index 9f49e29a..32cd4e31 100644 --- a/tests/SlimData.Tests/RaftClusterTests.cs +++ b/tests/SlimData.Tests/RaftClusterTests.cs @@ -254,8 +254,8 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", long listLength = await databaseServiceSlave.ListLengthAsync("listKey1"); Assert.Equal(1, listLength); - IList listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); - Assert.Equal("value1", MemoryPackSerializer.Deserialize(listRightPop[0])); + IDictionary listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); + Assert.Equal("value1", MemoryPackSerializer.Deserialize(listRightPop.First().Value)); await host1.StopAsync(); await host2.StopAsync(); From 15f7f515b85b6244344210f39bc5215fe9efa7b9 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 11 Nov 2024 23:38:11 +0100 Subject: [PATCH 035/135] update --- src/SlimData/Endpoints.cs | 14 ++++----- src/SlimData/ListString.cs | 4 ++- src/SlimData/SlimData.csproj | 1 - src/SlimData/Startup.cs | 3 ++ src/SlimFaas/Database/DatabaseMockService.cs | 29 +++++++++++-------- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 8 +++-- src/SlimFaas/Database/SlimDataService.cs | 11 +++---- ...mFaasSlimFaasQueue.cs => SlimFaasQueue.cs} | 8 ++--- src/SlimFaas/Program.cs | 2 +- src/SlimFaas/SlimWorker.cs | 12 +++++--- tests/SlimData.Tests/RaftClusterTests.cs | 4 +-- .../SlimProxyMiddlewareTests.cs | 3 +- tests/SlimFaas.Tests/SlimWorkerShould.cs | 4 +-- 14 files changed, 60 insertions(+), 45 deletions(-) rename src/SlimFaas/Database/{SlimFaasSlimFaasQueue.cs => SlimFaasQueue.cs} (52%) diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 10263d2b..f92153a6 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -1,7 +1,6 @@ using DotNext; using DotNext.Net.Cluster.Consensus.Raft; using MemoryPack; -using Microsoft.Extensions.Primitives; using SlimData.Commands; namespace SlimData; @@ -107,7 +106,7 @@ public static async Task ListRightPopCommand(SlimPersistentState pro CancellationTokenSource source) { var values = new ListString(); - values.Items = new Dictionary(); + values.Items = new List(); if(SemaphoreSlims.TryGetValue(key, out var semaphoreSlim)) { @@ -132,7 +131,7 @@ public static async Task ListRightPopCommand(SlimPersistentState pro var queueElements = queue.GetQueueAvailableElement([2, 6, 10], nowTicks, count); foreach (var queueElement in queueElements) { - values.Items[queueElement.Id] = queueElement.Value.ToArray(); + values.Items.Add(new QueueData(queueElement.Id ,queueElement.Value.ToArray())); } var logEntry = @@ -181,7 +180,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin public record QueueItemStatus(string Id, int HttpCode); - public static Task ListSetQueueItemStatusCommand(HttpContext context) + public static Task ListSetQueueItemStatus(HttpContext context) { return DoAsync(context, async (cluster, provider, source) => { @@ -198,16 +197,17 @@ public static Task ListSetQueueItemStatusCommand(HttpContext context) await inputStream.CopyToAsync(memoryStream, source.Token); var value = memoryStream.ToArray(); var list = MemoryPackSerializer.Deserialize>(value); - await ListSetQueueItemStatus(provider, key, list, cluster, source); + await ListSetQueueItemStatusCommand(provider, key, list, cluster, source); }); } - private static async Task ListSetQueueItemStatus(SlimPersistentState provider, StringValues key, List list, IRaftCluster cluster, CancellationTokenSource source) + public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provider, string key, IList list, IRaftCluster cluster, CancellationTokenSource source) { foreach (var queueItemStatus in list) { var logEntry = - provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand { Identifier = queueItemStatus.Id, + provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand { + Identifier = queueItemStatus.Id, Key = key, HttpCode = queueItemStatus.HttpCode }, cluster.Term); diff --git a/src/SlimData/ListString.cs b/src/SlimData/ListString.cs index 2ce9be5e..67175fb9 100644 --- a/src/SlimData/ListString.cs +++ b/src/SlimData/ListString.cs @@ -3,8 +3,10 @@ namespace SlimData; +public record QueueData(string Id, byte[] Data); + [MemoryPackable] public partial class ListString { - public IDictionary Items { get; set; } + public List Items { get; set; } } \ No newline at end of file diff --git a/src/SlimData/SlimData.csproj b/src/SlimData/SlimData.csproj index a841141d..c67f9460 100644 --- a/src/SlimData/SlimData.csproj +++ b/src/SlimData/SlimData.csproj @@ -5,7 +5,6 @@ net8.0 enable true - true true full false diff --git a/src/SlimData/Startup.cs b/src/SlimData/Startup.cs index 7841256e..cbb712c0 100644 --- a/src/SlimData/Startup.cs +++ b/src/SlimData/Startup.cs @@ -23,6 +23,7 @@ public void Configure(IApplicationBuilder app) const string ListLeftPushResource = "/SlimData/ListLeftPush"; const string AddKeyValueResource = "/SlimData/AddKeyValue"; const string ListLengthResource = "/SlimData/ListLength"; + const string ListSetQueueItemStatus = "/SlimData/ListSetQueueItemStatus"; const string HealthResource = "/health"; app.UseConsensusProtocolHandler() @@ -32,6 +33,7 @@ public void Configure(IApplicationBuilder app) .RedirectToLeader(ListRightPopResource) .RedirectToLeader(AddKeyValueResource) .RedirectToLeader(AddHashSetResource) + .RedirectToLeader(ListSetQueueItemStatus) .UseRouting() .UseEndpoints(static endpoints => { @@ -41,6 +43,7 @@ public void Configure(IApplicationBuilder app) endpoints.MapPost(ListRightPopResource, Endpoints.ListRightPop); endpoints.MapPost(AddHashSetResource, Endpoints.AddHashSet); endpoints.MapPost(AddKeyValueResource, Endpoints.AddKeyValue); + endpoints.MapPost(ListSetQueueItemStatus, Endpoints.ListSetQueueItemStatus); }); } diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index a1c0d3c6..7fde2463 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -1,4 +1,5 @@ using System.Collections.Concurrent; +using SlimData; namespace SlimFaas; @@ -7,7 +8,7 @@ public class DatabaseMockService : IDatabaseService private readonly ConcurrentDictionary> hashSet = new(); private readonly ConcurrentDictionary keys = new(); - private readonly ConcurrentDictionary> queue = new(); + private readonly ConcurrentDictionary> queue = new(); public Task GetAsync(string key) { @@ -59,38 +60,37 @@ public Task> HashGetAllAsync(string key) public Task ListLeftPushAsync(string key, byte[] field) { - List list; + List list; if (queue.ContainsKey(key)) { list = queue[key]; } else { - list = new List(); + list = new List(); queue.TryAdd(key, list); } - list.Add(field); + list.Add(new QueueData(Guid.NewGuid().ToString(), field)); return Task.CompletedTask; } - public Task> ListRightPopAsync(string key, int count = 1) + public Task> ListRightPopAsync(string key, int count = 1) { if (!queue.ContainsKey(key)) { - return Task.FromResult>(new Dictionary()); + return Task.FromResult>(new List()); } - List list = queue[key]; - IDictionary dictionaryToReturn = new Dictionary(); - List listToReturn = list.TakeLast((int)count).ToList(); + var list = queue[key]; + var listToReturn = list.TakeLast(count).ToList(); if (listToReturn.Count > 0) { list.RemoveRange(listToReturn.Count - 1, listToReturn.Count); - return Task.FromResult>(listToReturn); + return Task.FromResult>(listToReturn); } - return Task.FromResult>(new List()); + return Task.FromResult>(new List()); } public Task ListLengthAsync(string key) @@ -100,8 +100,13 @@ public Task ListLengthAsync(string key) return Task.FromResult(0); } - List list = queue[key]; + var list = queue[key]; return Task.FromResult(list.Count); } + + public async Task ListSetQueueItemStatus(string key, IList queueItemStatus) + { + await Task.Delay(100); + } } diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index 266b2515..486224a5 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -9,7 +9,7 @@ public interface IDatabaseService Task HashSetAsync(string key, IDictionary values); Task> HashGetAllAsync(string key); Task ListLeftPushAsync(string key, byte[] field); - Task> ListRightPopAsync(string key, int count = 1); + Task> ListRightPopAsync(string key, int count = 1); Task ListLengthAsync(string key); Task ListSetQueueItemStatus(string key, IList queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index c3c1b335..57583a10 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -1,9 +1,11 @@ -namespace SlimFaas.Database; +using SlimData; + +namespace SlimFaas.Database; public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); - Task> DequeueAsync(string key, long count = 1); - + Task> DequeueAsync(string key, long count = 1); + Task ListSetQueueItemStatus(string key, IList queueItemStatus); public Task CountAsync(string key); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index f66311a8..f5b9e65c 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -132,12 +132,12 @@ private async Task DoListLeftPushAsync(string key, byte[] field) } } - public async Task> ListRightPopAsync(string key, int count = 1) + public async Task> ListRightPopAsync(string key, int count = 1) { return await Retry.Do(() => DoListRightPopAsync(key, count), _retryInterval, logger, MaxAttemptCount); } - private async Task> DoListRightPopAsync(string key, int count = 1) + private async Task> DoListRightPopAsync(string key, int count = 1) { EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) @@ -162,7 +162,7 @@ private async Task> DoListRightPopAsync(string key, var bin = await response.Content.ReadAsByteArrayAsync(); ListString? result = MemoryPackSerializer.Deserialize(bin); - return result?.Items ?? new Dictionary(); + return result?.Items ?? new List(); } } @@ -173,16 +173,17 @@ public async Task ListSetQueueItemStatus(string key, IList queueItemStatus) { - var field = MemoryPackSerializer.Serialize(queueItemStatus); + EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) { var simplePersistentState = serviceProvider.GetRequiredService(); - await Endpoints.ListSetQueueItemStatusCommand(simplePersistentState, key, field, cluster, new CancellationTokenSource()); + await Endpoints.ListSetQueueItemStatusCommand(simplePersistentState, key, queueItemStatus, cluster, new CancellationTokenSource()); } else { using HttpRequestMessage request = new(HttpMethod.Post, new Uri($"{endpoint}SlimData/ListSetQueueItemStatus?key={key}")); + var field = MemoryPackSerializer.Serialize(queueItemStatus); request.Content = new ByteArrayContent(field); using var httpClient = httpClientFactory.CreateClient(HttpClientName); using HttpResponseMessage response = await httpClient.SendAsync(request); diff --git a/src/SlimFaas/Database/SlimFaasSlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs similarity index 52% rename from src/SlimFaas/Database/SlimFaasSlimFaasQueue.cs rename to src/SlimFaas/Database/SlimFaasQueue.cs index bcc0cf26..cbcab3a4 100644 --- a/src/SlimFaas/Database/SlimFaasSlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -4,22 +4,20 @@ namespace SlimFaas.Database; -public class SlimFaasSlimFaasQueue(IDatabaseService databaseService) : ISlimFaasQueue +public class SlimFaasQueue(IDatabaseService databaseService) : ISlimFaasQueue { private const string KeyPrefix = "Queue:"; public async Task EnqueueAsync(string key, byte[] data) => await databaseService.ListLeftPushAsync($"{KeyPrefix}{key}", data); - public async Task> DequeueAsync(string key, long count = 1) + public async Task> DequeueAsync(string key, long count = 1) { var data = await databaseService.ListRightPopAsync($"{KeyPrefix}{key}"); return data; } -#pragma warning disable CA2252 - public async Task SetQueueItemStatus(string key, IList queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); -#pragma warning restore CA2252 + public async Task ListSetQueueItemStatus(string key, IList queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); public async Task CountAsync(string key) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}"); } diff --git a/src/SlimFaas/Program.cs b/src/SlimFaas/Program.cs index ed1a434d..643b3f4a 100644 --- a/src/SlimFaas/Program.cs +++ b/src/SlimFaas/Program.cs @@ -76,7 +76,7 @@ serviceCollectionSlimFaas.AddHostedService(); serviceCollectionSlimFaas.AddHostedService(); serviceCollectionSlimFaas.AddHttpClient(); -serviceCollectionSlimFaas.AddSingleton(); +serviceCollectionSlimFaas.AddSingleton(); serviceCollectionSlimFaas.AddSingleton(); serviceCollectionSlimFaas.AddSingleton(sp => (ReplicasService)serviceProviderStarter.GetService()!); diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index adc245a0..3e1568fb 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -1,4 +1,5 @@ using MemoryPack; +using SlimData; using SlimFaas.Database; using SlimFaas.Kubernetes; @@ -78,11 +79,11 @@ private async Task SendHttpRequestToFunction(Dictionary jsons = await slimFaasQueue.DequeueAsync(functionDeployment, + IList jsons = await slimFaasQueue.DequeueAsync(functionDeployment, numberTasksToDequeue.HasValue ? (long)numberTasksToDequeue : 1); foreach (var requestJson in jsons) { - CustomRequest customRequest = MemoryPackSerializer.Deserialize(requestJson.Value); + CustomRequest customRequest = MemoryPackSerializer.Deserialize(requestJson.Data); logger.LogDebug("{CustomRequestMethod}: {CustomRequestPath}{CustomRequestQuery} Sending", customRequest.Method, customRequest.Path, customRequest.Query); @@ -91,7 +92,7 @@ private async Task SendHttpRequestToFunction(Dictionary taskResponse = scope.ServiceProvider.GetRequiredService() .SendHttpRequestAsync(customRequest); - processingTasks[functionDeployment].Add(new RequestToWait(taskResponse, customRequest, requestJson.Key)); + processingTasks[functionDeployment].Add(new RequestToWait(taskResponse, customRequest, requestJson.Id)); } } @@ -131,7 +132,7 @@ private async Task UpdateTickLastCallIfRequestStillInProgress(int? functio return numberLimitProcessingTasks; } - private int ManageProcessingTasks(Dictionary> processingTasks, + private int ManageProcessingTasks(ISlimFaasQueue slimFaasQueue, Dictionary> processingTasks, string functionDeployment) { if (processingTasks.ContainsKey(functionDeployment) == false) @@ -166,10 +167,13 @@ private int ManageProcessingTasks(Dictionary> proce } } + var list = new List(); foreach (RequestToWait httpResponseMessage in httpResponseMessagesToDelete) { + list.Add(new Endpoints.QueueItemStatus()); processingTasks[functionDeployment].Remove(httpResponseMessage); } + slimFaasQueue.ListSetQueueItemStatus(functionDeployment, int numberProcessingTasks = processingTasks[functionDeployment].Count; return numberProcessingTasks; diff --git a/tests/SlimData.Tests/RaftClusterTests.cs b/tests/SlimData.Tests/RaftClusterTests.cs index 32cd4e31..c8a70887 100644 --- a/tests/SlimData.Tests/RaftClusterTests.cs +++ b/tests/SlimData.Tests/RaftClusterTests.cs @@ -254,8 +254,8 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", long listLength = await databaseServiceSlave.ListLengthAsync("listKey1"); Assert.Equal(1, listLength); - IDictionary listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); - Assert.Equal("value1", MemoryPackSerializer.Deserialize(listRightPop.First().Value)); + IList listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); + Assert.Equal("value1", MemoryPackSerializer.Deserialize(listRightPop.First().Data)); await host1.StopAsync(); await host2.StopAsync(); diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 295f5cff..7b79d7a3 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -9,6 +9,7 @@ using Moq; using SlimFaas.Kubernetes; using MemoryPack; +using SlimData; using SlimFaas.Database; namespace SlimFaas.Tests; @@ -72,7 +73,7 @@ public async Task SyncDeploymentsFromSlimData(DeploymentsInformations deployment internal class MemorySlimFaasQueue : ISlimFaasQueue { - public Task> DequeueAsync(string key, long count = 1) => throw new NotImplementedException(); + public Task> DequeueAsync(string key, long count = 1) => throw new NotImplementedException(); public Task CountAsync(string key) => throw new NotImplementedException(); diff --git a/tests/SlimFaas.Tests/SlimWorkerShould.cs b/tests/SlimFaas.Tests/SlimWorkerShould.cs index 02f4d311..1b53d07c 100644 --- a/tests/SlimFaas.Tests/SlimWorkerShould.cs +++ b/tests/SlimFaas.Tests/SlimWorkerShould.cs @@ -61,7 +61,7 @@ public async Task OnlyCallOneFunctionAsync() HistoryHttpMemoryService historyHttpService = new HistoryHttpMemoryService(); Mock> logger = new Mock>(); - SlimFaasSlimFaasQueue redisQueue = new SlimFaasSlimFaasQueue(new DatabaseMockService()); + SlimFaasQueue redisQueue = new SlimFaasQueue(new DatabaseMockService()); CustomRequest customRequest = new CustomRequest(new List { new() { Key = "key", Values = new[] { "value1" } } }, new byte[1], "fibonacci", "/download", "GET", ""); @@ -103,7 +103,7 @@ public async Task LogErrorWhenExceptionIsThrown() replicasService.Setup(rs => rs.Deployments).Throws(new Exception()); HistoryHttpMemoryService historyHttpService = new HistoryHttpMemoryService(); Mock> logger = new Mock>(); - SlimFaasSlimFaasQueue redisQueue = new SlimFaasSlimFaasQueue(new DatabaseMockService()); + SlimFaasQueue redisQueue = new SlimFaasQueue(new DatabaseMockService()); Mock slimDataStatus = new Mock(); slimDataStatus.Setup(s => s.WaitForReadyAsync()).Returns(Task.CompletedTask); From 476c574cc8916d7baa2ec91535e885515dc890b9 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 13 Nov 2024 11:59:42 +0100 Subject: [PATCH 036/135] first build --- src/SlimData/Endpoints.cs | 4 ++-- src/SlimData/{ListString.cs => ListItems.cs} | 5 +++-- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 2 +- src/SlimFaas/Database/SlimFaasQueue.cs | 2 +- src/SlimFaas/Program.cs | 4 ++-- src/SlimFaas/SlimWorker.cs | 14 ++++++++------ tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs | 2 ++ 8 files changed, 20 insertions(+), 15 deletions(-) rename src/SlimData/{ListString.cs => ListItems.cs} (58%) diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index f92153a6..33ea07ec 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -102,10 +102,10 @@ public static Task ListRightPop(HttpContext context) } private static readonly IDictionary SemaphoreSlims = new Dictionary(); - public static async Task ListRightPopCommand(SlimPersistentState provider, string key, int count, IRaftCluster cluster, + public static async Task ListRightPopCommand(SlimPersistentState provider, string key, int count, IRaftCluster cluster, CancellationTokenSource source) { - var values = new ListString(); + var values = new ListItems(); values.Items = new List(); if(SemaphoreSlims.TryGetValue(key, out var semaphoreSlim)) diff --git a/src/SlimData/ListString.cs b/src/SlimData/ListItems.cs similarity index 58% rename from src/SlimData/ListString.cs rename to src/SlimData/ListItems.cs index 67175fb9..cd9a1bcb 100644 --- a/src/SlimData/ListString.cs +++ b/src/SlimData/ListItems.cs @@ -3,10 +3,11 @@ namespace SlimData; -public record QueueData(string Id, byte[] Data); +[MemoryPackable] +public partial record QueueData(string Id, byte[] Data); [MemoryPackable] -public partial class ListString +public partial class ListItems { public List Items { get; set; } } \ No newline at end of file diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 57583a10..9c63d61d 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -6,6 +6,6 @@ public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); Task> DequeueAsync(string key, long count = 1); - Task ListSetQueueItemStatus(string key, IList queueItemStatus); + Task ListSetQueueItemStatusAsync(string key, IList queueItemStatus); public Task CountAsync(string key); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index f5b9e65c..1fdd021d 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -161,7 +161,7 @@ private async Task> DoListRightPopAsync(string key, int count = } var bin = await response.Content.ReadAsByteArrayAsync(); - ListString? result = MemoryPackSerializer.Deserialize(bin); + ListItems? result = MemoryPackSerializer.Deserialize(bin); return result?.Items ?? new List(); } } diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index cbcab3a4..15e29b6b 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -17,7 +17,7 @@ public async Task> DequeueAsync(string key, long count = 1) return data; } - public async Task ListSetQueueItemStatus(string key, IList queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); + public async Task ListSetQueueItemStatusAsync(string key, IList queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); public async Task CountAsync(string key) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}"); } diff --git a/src/SlimFaas/Program.cs b/src/SlimFaas/Program.cs index 643b3f4a..3e73e1c0 100644 --- a/src/SlimFaas/Program.cs +++ b/src/SlimFaas/Program.cs @@ -198,8 +198,8 @@ } return httpClientHandler; - }) - .AddPolicyHandler(GetRetryPolicy()); + }); + //.AddPolicyHandler(GetRetryPolicy()); if (!string.IsNullOrEmpty(podDataDirectoryPersistantStorage)) { diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 3e1568fb..a87e6c4c 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -41,7 +41,7 @@ private async Task DoOneCycle(CancellationToken stoppingToken, { string functionDeployment = function.Deployment; setTickLastCallCounterDictionary.TryAdd(functionDeployment, 0); - int numberProcessingTasks = ManageProcessingTasks(processingTasks, functionDeployment); + int numberProcessingTasks = await ManageProcessingTasksAsync(slimFaasQueue, processingTasks, functionDeployment); int? numberLimitProcessingTasks = ComputeNumberLimitProcessingTasks(slimFaas, function); setTickLastCallCounterDictionary[functionDeployment]++; int functionReplicas = function.Replicas; @@ -132,14 +132,14 @@ private async Task UpdateTickLastCallIfRequestStillInProgress(int? functio return numberLimitProcessingTasks; } - private int ManageProcessingTasks(ISlimFaasQueue slimFaasQueue, Dictionary> processingTasks, + private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, Dictionary> processingTasks, string functionDeployment) { if (processingTasks.ContainsKey(functionDeployment) == false) { processingTasks.Add(functionDeployment, new List()); } - + var queueItemStatusList = new List(); List httpResponseMessagesToDelete = new(); foreach (RequestToWait processing in processingTasks[functionDeployment]) { @@ -152,28 +152,30 @@ private int ManageProcessingTasks(ISlimFaasQueue slimFaasQueue, Dictionary(); foreach (RequestToWait httpResponseMessage in httpResponseMessagesToDelete) { - list.Add(new Endpoints.QueueItemStatus()); processingTasks[functionDeployment].Remove(httpResponseMessage); } - slimFaasQueue.ListSetQueueItemStatus(functionDeployment, + await slimFaasQueue.ListSetQueueItemStatusAsync(functionDeployment, queueItemStatusList); int numberProcessingTasks = processingTasks[functionDeployment].Count; return numberProcessingTasks; diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 7b79d7a3..ddfbdc2f 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -77,6 +77,8 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue public Task CountAsync(string key) => throw new NotImplementedException(); + public Task ListSetQueueItemStatusAsync(string key, IList queueItemStatus) => throw new NotImplementedException(); + public async Task EnqueueAsync(string key, byte[] message) => await Task.Delay(100); } From 03d997650658d7ef9f1601a9dfbcc04946cd3053 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 13 Nov 2024 16:00:48 +0100 Subject: [PATCH 037/135] fix serialization --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Database/DatabaseMockService.cs | 2 +- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 4 ++-- src/SlimFaas/Database/SlimFaasQueue.cs | 2 +- tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index f5999190..17244014 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:0.24.18 + image: axaguildev/slimfaas:pr-77-748 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index 7fde2463..c6581ba6 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -105,7 +105,7 @@ public Task ListLengthAsync(string key) return Task.FromResult(list.Count); } - public async Task ListSetQueueItemStatus(string key, IList queueItemStatus) + public async Task ListSetQueueItemStatus(string key, List queueItemStatus) { await Task.Delay(100); } diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index 486224a5..2398d124 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -11,5 +11,5 @@ public interface IDatabaseService Task ListLeftPushAsync(string key, byte[] field); Task> ListRightPopAsync(string key, int count = 1); Task ListLengthAsync(string key); - Task ListSetQueueItemStatus(string key, IList queueItemStatus); + Task ListSetQueueItemStatus(string key, List queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 9c63d61d..30794601 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -6,6 +6,6 @@ public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); Task> DequeueAsync(string key, long count = 1); - Task ListSetQueueItemStatusAsync(string key, IList queueItemStatus); + Task ListSetQueueItemStatusAsync(string key, List queueItemStatus); public Task CountAsync(string key); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 1fdd021d..195fc3c8 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -166,12 +166,12 @@ private async Task> DoListRightPopAsync(string key, int count = } } - public async Task ListSetQueueItemStatus(string key, IList queueItemStatus) + public async Task ListSetQueueItemStatus(string key, List queueItemStatus) { await Retry.Do(() => DoListSetQueueItemStatus(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); } - private async Task DoListSetQueueItemStatus(string key, IList queueItemStatus) + private async Task DoListSetQueueItemStatus(string key, List queueItemStatus) { EndPoint endpoint = await GetAndWaitForLeader(); diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index 15e29b6b..868e330a 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -17,7 +17,7 @@ public async Task> DequeueAsync(string key, long count = 1) return data; } - public async Task ListSetQueueItemStatusAsync(string key, IList queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); + public async Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); public async Task CountAsync(string key) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}"); } diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index ddfbdc2f..e39b4e49 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -77,7 +77,7 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue public Task CountAsync(string key) => throw new NotImplementedException(); - public Task ListSetQueueItemStatusAsync(string key, IList queueItemStatus) => throw new NotImplementedException(); + public Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => throw new NotImplementedException(); public async Task EnqueueAsync(string key, byte[] message) => await Task.Delay(100); } From 8e17abe2cdacfae89f00a944736570438ad98f98 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 13 Nov 2024 17:19:04 +0100 Subject: [PATCH 038/135] fix --- src/SlimData/Endpoints.cs | 1 + src/SlimData/QueueElementExtensions.cs | 12 +++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 33ea07ec..dab7dbf2 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -178,6 +178,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin await cluster.ReplicateAsync(logEntry, source.Token); } + [MemoryPackable] public record QueueItemStatus(string Id, int HttpCode); public static Task ListSetQueueItemStatus(HttpContext context) diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 981a589b..9c1a8d90 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -1,7 +1,17 @@ -namespace SlimData; +using System.Net; + +namespace SlimData; public static class QueueElementExtensions { + public static HttpStatusCode[] httpStatusCodesWorthRetrying = + { + HttpStatusCode.RequestTimeout, // 408 + HttpStatusCode.InternalServerError, // 500 + HttpStatusCode.BadGateway, // 502 + HttpStatusCode.ServiceUnavailable, // 503 + HttpStatusCode.GatewayTimeout // 504 + }; public static List GetQueueTimeoutElement(this List element, long nowTicks, int timeout=30) { From 99c6ed0524512ce5b7648ceee5568c255b5300a5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 13 Nov 2024 17:34:52 +0100 Subject: [PATCH 039/135] fix --- src/SlimData/Endpoints.cs | 2 +- src/SlimData/QueueElementExtensions.cs | 26 ++++++++++++-------------- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index dab7dbf2..8d2e9f93 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -179,7 +179,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin } [MemoryPackable] - public record QueueItemStatus(string Id, int HttpCode); + public partial record QueueItemStatus(string Id, int HttpCode); public static Task ListSetQueueItemStatus(HttpContext context) { diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 9c1a8d90..37c7efbb 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -1,16 +1,14 @@ -using System.Net; - -namespace SlimData; +namespace SlimData; public static class QueueElementExtensions { - public static HttpStatusCode[] httpStatusCodesWorthRetrying = + public static int[] httpStatusCodesWorthRetrying = { - HttpStatusCode.RequestTimeout, // 408 - HttpStatusCode.InternalServerError, // 500 - HttpStatusCode.BadGateway, // 502 - HttpStatusCode.ServiceUnavailable, // 503 - HttpStatusCode.GatewayTimeout // 504 + 408 , // HttpStatusCode.RequestTimeout, // 408 + 500, // HttpStatusCode.InternalServerError, // 500 + 502, // HttpStatusCode.BadGateway, // 502 + 503, //HttpStatusCode.ServiceUnavailable, // 503 + 504, // HttpStatusCode.GatewayTimeout // 504 }; public static List GetQueueTimeoutElement(this List element, long nowTicks, int timeout=30) @@ -70,7 +68,7 @@ public static List GetQueueAvailableElement(this List= 400 + if (httpStatusCodesWorthRetrying.Contains( retryQueueElement.HttpCode) && retries.Count <= count && retryQueueElement.EndTimeStamp != 0 && nowTicks > retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks @@ -87,21 +85,21 @@ public static List GetQueueAvailableElement(this List GetQueueFinishedElement(this IList element, List retries) { - var runningElement = new List(); + var queueFinishedElement = new List(); foreach (var queueElement in element) { var count = queueElement.RetryQueueElements.Count; if(count > 0) { var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.HttpCode is >= 200 and < 400 || retries.Count <= count) + if (retryQueueElement.HttpCode is >= 0 and < 400 || retries.Count <= count) { - runningElement.Add(queueElement); + queueFinishedElement.Add(queueElement); } } } - return runningElement; + return queueFinishedElement; } } \ No newline at end of file From 0f8a3fc03329684c6da6033cff8fec1df5865204 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 13 Nov 2024 18:00:38 +0100 Subject: [PATCH 040/135] fix --- src/SlimData/Endpoints.cs | 7 ++++--- src/SlimData/ListItems.cs | 3 +-- src/SlimFaas/Database/DatabaseMockService.cs | 2 +- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 4 ++-- src/SlimFaas/Database/SlimFaasQueue.cs | 2 +- src/SlimFaas/SlimWorker.cs | 6 +++--- tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs | 2 +- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 8d2e9f93..a056d18e 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -5,6 +5,10 @@ namespace SlimData; + +[MemoryPackable] +public partial record QueueItemStatus(string Id, int HttpCode); + public class Endpoints { public delegate Task RespondDelegate(IRaftCluster cluster, SlimPersistentState provider, @@ -178,9 +182,6 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin await cluster.ReplicateAsync(logEntry, source.Token); } - [MemoryPackable] - public partial record QueueItemStatus(string Id, int HttpCode); - public static Task ListSetQueueItemStatus(HttpContext context) { return DoAsync(context, async (cluster, provider, source) => diff --git a/src/SlimData/ListItems.cs b/src/SlimData/ListItems.cs index cd9a1bcb..5f020969 100644 --- a/src/SlimData/ListItems.cs +++ b/src/SlimData/ListItems.cs @@ -1,5 +1,4 @@ -using System.Text.Json.Serialization; -using MemoryPack; +using MemoryPack; namespace SlimData; diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index c6581ba6..738c73b3 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -105,7 +105,7 @@ public Task ListLengthAsync(string key) return Task.FromResult(list.Count); } - public async Task ListSetQueueItemStatus(string key, List queueItemStatus) + public async Task ListSetQueueItemStatus(string key, List queueItemStatus) { await Task.Delay(100); } diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index 2398d124..f7846788 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -11,5 +11,5 @@ public interface IDatabaseService Task ListLeftPushAsync(string key, byte[] field); Task> ListRightPopAsync(string key, int count = 1); Task ListLengthAsync(string key); - Task ListSetQueueItemStatus(string key, List queueItemStatus); + Task ListSetQueueItemStatus(string key, List queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 30794601..a9bf0e00 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -6,6 +6,6 @@ public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); Task> DequeueAsync(string key, long count = 1); - Task ListSetQueueItemStatusAsync(string key, List queueItemStatus); + Task ListSetQueueItemStatusAsync(string key, List queueItemStatus); public Task CountAsync(string key); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 195fc3c8..db50c662 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -166,12 +166,12 @@ private async Task> DoListRightPopAsync(string key, int count = } } - public async Task ListSetQueueItemStatus(string key, List queueItemStatus) + public async Task ListSetQueueItemStatus(string key, List queueItemStatus) { await Retry.Do(() => DoListSetQueueItemStatus(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); } - private async Task DoListSetQueueItemStatus(string key, List queueItemStatus) + private async Task DoListSetQueueItemStatus(string key, List queueItemStatus) { EndPoint endpoint = await GetAndWaitForLeader(); diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index 868e330a..8ffbc0df 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -17,7 +17,7 @@ public async Task> DequeueAsync(string key, long count = 1) return data; } - public async Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); + public async Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); public async Task CountAsync(string key) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}"); } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index a87e6c4c..1524af1a 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -139,7 +139,7 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, { processingTasks.Add(functionDeployment, new List()); } - var queueItemStatusList = new List(); + var queueItemStatusList = new List(); List httpResponseMessagesToDelete = new(); foreach (RequestToWait processing in processingTasks[functionDeployment]) { @@ -160,11 +160,11 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, processing.CustomRequest.Method, processing.CustomRequest.Path, processing.CustomRequest.Query, httpResponseMessage.StatusCode); httpResponseMessagesToDelete.Add(processing); - queueItemStatusList.Add(new Endpoints.QueueItemStatus(processing.id, statusCode)); + queueItemStatusList.Add(new QueueItemStatus(processing.id, statusCode)); } catch (Exception e) { - queueItemStatusList.Add(new Endpoints.QueueItemStatus(processing.id, 500)); + queueItemStatusList.Add(new QueueItemStatus(processing.id, 500)); httpResponseMessagesToDelete.Add(processing); logger.LogWarning("Request Error: {Message} {StackTrace}", e.Message, e.StackTrace); historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index e39b4e49..f3b8e07d 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -77,7 +77,7 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue public Task CountAsync(string key) => throw new NotImplementedException(); - public Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => throw new NotImplementedException(); + public Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => throw new NotImplementedException(); public async Task EnqueueAsync(string key, byte[] message) => await Task.Delay(100); } From d5b2f16983710be61c8c35939b5872a749e5008a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 14 Nov 2024 19:41:36 +0100 Subject: [PATCH 041/135] update --- README.md | 5 ++- demo/deployment-slimfaas.yml | 2 +- src/SlimData/ListItems.cs | 4 +-- src/SlimData/QueueElementExtensions.cs | 18 +++++----- src/SlimFaas/Database/DatabaseMockService.cs | 8 ++--- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 4 +-- src/SlimFaas/Database/SlimFaasQueue.cs | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 35 +++++++++++++++++-- src/SlimFaas/SlimWorker.cs | 6 +++- tests/SlimData.Tests/RaftClusterTests.cs | 2 +- .../SlimProxyMiddlewareTests.cs | 2 +- 13 files changed, 64 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 3538a508..52ee403e 100644 --- a/README.md +++ b/README.md @@ -6,10 +6,11 @@ Why use SlimFaas? - Scale to 0 after a period of inactivity (work with deployment and statefulset) +- Scale up : compatible with HPA (Horizontal Auto Scaler) and Keda - Synchronous HTTP calls - Asynchronous HTTP calls - Allows you to limit the number of parallel HTTP requests for each underlying function -- Retry: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds +- Retry Pattern Configurable: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds - Private and Public functions - Private functions can be accessed only by internal namespace http call from pods - Synchronous Publish/Subscribe internal events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple you application with SlimFaas**) @@ -159,6 +160,8 @@ spec: SlimFaas/SubscribeEvents: "Public:my-event-name1,Private:my-event-name2,my-event-name3" # comma separated list of event names SlimFaas/DefaultVisibility: "Public" # Public or Private (private can be accessed only by internal namespace https call from pods) SlimFaas/UrlsPathStartWithVisibility: "Private:/mypath/subPath,Private:/mysecondpath" # Public or Private (private can be accessed only by internal namespace https call from pods) + SlimFaas/SynchrounousRetry: "2;4;8" + SlimFaas/AsynchrounousRetry: "2;4;8" spec: serviceAccountName: default containers: diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 17244014..8062c4d3 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-748 + image: axaguildev/slimfaas:pr-77-751 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/ListItems.cs b/src/SlimData/ListItems.cs index 5f020969..a4b43129 100644 --- a/src/SlimData/ListItems.cs +++ b/src/SlimData/ListItems.cs @@ -6,7 +6,7 @@ namespace SlimData; public partial record QueueData(string Id, byte[] Data); [MemoryPackable] -public partial class ListItems +public partial record ListItems { - public List Items { get; set; } + public List? Items { get; set; } } \ No newline at end of file diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 37c7efbb..75d01019 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -2,14 +2,14 @@ public static class QueueElementExtensions { - public static int[] httpStatusCodesWorthRetrying = - { - 408 , // HttpStatusCode.RequestTimeout, // 408 - 500, // HttpStatusCode.InternalServerError, // 500 - 502, // HttpStatusCode.BadGateway, // 502 - 503, //HttpStatusCode.ServiceUnavailable, // 503 - 504, // HttpStatusCode.GatewayTimeout // 504 - }; + public static int[] HttpStatusCodesWorthRetrying = + [ + 408 , // HttpStatusCode.RequestTimeout, + 500, // HttpStatusCode.InternalServerError, + 502, // HttpStatusCode.BadGateway, + 503, // HttpStatusCode.ServiceUnavailable, + 504 // HttpStatusCode.GatewayTimeout + ]; public static List GetQueueTimeoutElement(this List element, long nowTicks, int timeout=30) { @@ -68,7 +68,7 @@ public static List GetQueueAvailableElement(this List retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index 738c73b3..4c297aa7 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -75,11 +75,11 @@ public Task ListLeftPushAsync(string key, byte[] field) return Task.CompletedTask; } - public Task> ListRightPopAsync(string key, int count = 1) + public Task?> ListRightPopAsync(string key, int count = 1) { if (!queue.ContainsKey(key)) { - return Task.FromResult>(new List()); + return Task.FromResult?>(new List()); } var list = queue[key]; @@ -87,10 +87,10 @@ public Task> ListRightPopAsync(string key, int count = 1) if (listToReturn.Count > 0) { list.RemoveRange(listToReturn.Count - 1, listToReturn.Count); - return Task.FromResult>(listToReturn); + return Task.FromResult?>(listToReturn); } - return Task.FromResult>(new List()); + return Task.FromResult?>(new List()); } public Task ListLengthAsync(string key) diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index f7846788..c5a5dbaa 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -9,7 +9,7 @@ public interface IDatabaseService Task HashSetAsync(string key, IDictionary values); Task> HashGetAllAsync(string key); Task ListLeftPushAsync(string key, byte[] field); - Task> ListRightPopAsync(string key, int count = 1); + Task?> ListRightPopAsync(string key, int count = 1); Task ListLengthAsync(string key); Task ListSetQueueItemStatus(string key, List queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index a9bf0e00..98f5e228 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -5,7 +5,7 @@ namespace SlimFaas.Database; public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); - Task> DequeueAsync(string key, long count = 1); + Task?> DequeueAsync(string key, long count = 1); Task ListSetQueueItemStatusAsync(string key, List queueItemStatus); public Task CountAsync(string key); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index db50c662..80d582fb 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -132,12 +132,12 @@ private async Task DoListLeftPushAsync(string key, byte[] field) } } - public async Task> ListRightPopAsync(string key, int count = 1) + public async Task?> ListRightPopAsync(string key, int count = 1) { return await Retry.Do(() => DoListRightPopAsync(key, count), _retryInterval, logger, MaxAttemptCount); } - private async Task> DoListRightPopAsync(string key, int count = 1) + private async Task?> DoListRightPopAsync(string key, int count = 1) { EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index 8ffbc0df..651e0e99 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -11,7 +11,7 @@ public class SlimFaasQueue(IDatabaseService databaseService) : ISlimFaasQueue public async Task EnqueueAsync(string key, byte[] data) => await databaseService.ListLeftPushAsync($"{KeyPrefix}{key}", data); - public async Task> DequeueAsync(string key, long count = 1) + public async Task?> DequeueAsync(string key, long count = 1) { var data = await databaseService.ListRightPopAsync($"{KeyPrefix}{key}"); return data; diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 86bb5d06..f957142a 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -1,8 +1,10 @@ using System.Diagnostics.CodeAnalysis; +using System.Globalization; using System.Net; using System.Text; using System.Text.Json; using System.Text.Json.Serialization; +using DotNext.Collections.Generic; using k8s; using k8s.Autorest; using k8s.Models; @@ -68,7 +70,9 @@ public record DeploymentInformation(string Deployment, string Namespace, IList

? PathsStartWithVisibility = null, IList? ExcludeDeploymentsFromVisibilityPrivate = null, - string ResourceVersion = "" + string ResourceVersion = "", + IList? AsynchrounousRetry = null, + IList? SynchrounousRetry = null ); public record PodInformation(string Name, bool? Started, bool? Ready, string Ip, string DeploymentName); @@ -91,6 +95,10 @@ public class KubernetesService : IKubernetesService private const string TimeoutSecondBeforeSetReplicasMin = "SlimFaas/TimeoutSecondBeforeSetReplicasMin"; private const string NumberParallelRequest = "SlimFaas/NumberParallelRequest"; + private const string SynchrounousRetry = "SlimFaas/SynchrounousRetry"; + private const string AsynchrounousRetry = "SlimFaas/AsynchrounousRetry"; + + private const string SlimfaasDeploymentName = "slimfaas"; private readonly ILogger _logger; private readonly k8s.Kubernetes _client; @@ -201,6 +209,23 @@ public async Task ListFunctionsAsync(string kubeNamespa } } + private static IList ReadRetryAnnotation( IDictionary? annotations) + { + if (annotations != null && annotations.TryGetValue(AsynchrounousRetry, out string? valueAsynchrounousRetry)) + { + var result = new List(); + var array = valueAsynchrounousRetry.Split(';'); + foreach (string s in array) + { + result.Add( int.Parse(s, NumberStyles.Integer)); + } + + return result; + } + + return new List(){2, 4, 8}; + } + private static void AddDeployments(string kubeNamespace, V1DeploymentList deploymentList, IEnumerable podList, IList deploymentInformationList, ILogger logger) { @@ -251,7 +276,9 @@ private static void AddDeployments(string kubeNamespace, V1DeploymentList deploy ? valueUrlsStartWithVisibility.Split(',').ToList() : new List(), annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), - deploymentListItem.Metadata.ResourceVersion + deploymentListItem.Metadata.ResourceVersion, + AsynchrounousRetry: ReadRetryAnnotation(annotations), + SynchrounousRetry: ReadRetryAnnotation(annotations) ); deploymentInformationList.Add(deploymentInformation); } @@ -329,7 +356,9 @@ private static void AddStatefulSets(string kubeNamespace, V1StatefulSetList depl ? valueUrlsStartWithVisibility.Split(',').ToList() : new List(), annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), - deploymentListItem.Metadata.ResourceVersion); + deploymentListItem.Metadata.ResourceVersion, + AsynchrounousRetry: ReadRetryAnnotation(annotations), + SynchrounousRetry: ReadRetryAnnotation(annotations)); deploymentInformationList.Add(deploymentInformation); } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 1524af1a..48f76211 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -79,8 +79,12 @@ private async Task SendHttpRequestToFunction(Dictionary jsons = await slimFaasQueue.DequeueAsync(functionDeployment, + IList? jsons = await slimFaasQueue.DequeueAsync(functionDeployment, numberTasksToDequeue.HasValue ? (long)numberTasksToDequeue : 1); + if (jsons == null) + { + return; + } foreach (var requestJson in jsons) { CustomRequest customRequest = MemoryPackSerializer.Deserialize(requestJson.Data); diff --git a/tests/SlimData.Tests/RaftClusterTests.cs b/tests/SlimData.Tests/RaftClusterTests.cs index c8a70887..ee24cb78 100644 --- a/tests/SlimData.Tests/RaftClusterTests.cs +++ b/tests/SlimData.Tests/RaftClusterTests.cs @@ -254,7 +254,7 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", long listLength = await databaseServiceSlave.ListLengthAsync("listKey1"); Assert.Equal(1, listLength); - IList listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); + IList? listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); Assert.Equal("value1", MemoryPackSerializer.Deserialize(listRightPop.First().Data)); await host1.StopAsync(); diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index f3b8e07d..7b5919a5 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -73,7 +73,7 @@ public async Task SyncDeploymentsFromSlimData(DeploymentsInformations deployment internal class MemorySlimFaasQueue : ISlimFaasQueue { - public Task> DequeueAsync(string key, long count = 1) => throw new NotImplementedException(); + public Task?> DequeueAsync(string key, long count = 1) => throw new NotImplementedException(); public Task CountAsync(string key) => throw new NotImplementedException(); From 9e95c4a94fecd7e4886f45d7384cdb8f330f1d75 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 14 Nov 2024 20:04:52 +0100 Subject: [PATCH 042/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Endpoints.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 8062c4d3..b12ad388 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-751 + image: axaguildev/slimfaas:pr-77-752 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index a056d18e..b1bc12f2 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -7,7 +7,7 @@ namespace SlimData; [MemoryPackable] -public partial record QueueItemStatus(string Id, int HttpCode); +public partial record QueueItemStatus(string Id="", int HttpCode=0); public class Endpoints { From 3aa2d21b755ec2e20f952f26089f9b5c5b4bd693 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 16 Nov 2024 13:46:57 +0100 Subject: [PATCH 043/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Endpoints.cs | 26 ++++++++++++++----- src/SlimFaas/Database/DatabaseMockService.cs | 2 +- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 4 +-- src/SlimFaas/Database/SlimFaasQueue.cs | 2 +- src/SlimFaas/SlimWorker.cs | 4 ++- .../SlimProxyMiddlewareTests.cs | 2 +- 9 files changed, 31 insertions(+), 15 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index b12ad388..fc369c93 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-752 + image: axaguildev/slimfaas:pr-77-753 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index b1bc12f2..cdc08f6e 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -6,9 +6,16 @@ namespace SlimData; + [MemoryPackable] public partial record QueueItemStatus(string Id="", int HttpCode=0); +[MemoryPackable] +public partial record ListQueueItemStatus +{ + public List? Items { get; set; } +} + public class Endpoints { public delegate Task RespondDelegate(IRaftCluster cluster, SlimPersistentState provider, @@ -198,20 +205,27 @@ public static Task ListSetQueueItemStatus(HttpContext context) await using var memoryStream = new MemoryStream(); await inputStream.CopyToAsync(memoryStream, source.Token); var value = memoryStream.ToArray(); - var list = MemoryPackSerializer.Deserialize>(value); + var list = MemoryPackSerializer.Deserialize(value); await ListSetQueueItemStatusCommand(provider, key, list, cluster, source); }); } - public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provider, string key, IList list, IRaftCluster cluster, CancellationTokenSource source) + public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provider, string key, ListQueueItemStatus list, IRaftCluster cluster, CancellationTokenSource source) { - foreach (var queueItemStatus in list) + if (list.Items == null) + { + return; + } + + foreach (var queueItemStatus in list.Items) { var logEntry = - provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand { - Identifier = queueItemStatus.Id, + provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand + { + Identifier = queueItemStatus.Id, Key = key, - HttpCode = queueItemStatus.HttpCode }, + HttpCode = queueItemStatus.HttpCode + }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); } diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index 4c297aa7..95f3db2c 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -105,7 +105,7 @@ public Task ListLengthAsync(string key) return Task.FromResult(list.Count); } - public async Task ListSetQueueItemStatus(string key, List queueItemStatus) + public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) { await Task.Delay(100); } diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index c5a5dbaa..9f1dace7 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -11,5 +11,5 @@ public interface IDatabaseService Task ListLeftPushAsync(string key, byte[] field); Task?> ListRightPopAsync(string key, int count = 1); Task ListLengthAsync(string key); - Task ListSetQueueItemStatus(string key, List queueItemStatus); + Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 98f5e228..a8078806 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -6,6 +6,6 @@ public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); Task?> DequeueAsync(string key, long count = 1); - Task ListSetQueueItemStatusAsync(string key, List queueItemStatus); + Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus); public Task CountAsync(string key); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 80d582fb..9c25b941 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -166,12 +166,12 @@ private async Task DoListLeftPushAsync(string key, byte[] field) } } - public async Task ListSetQueueItemStatus(string key, List queueItemStatus) + public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) { await Retry.Do(() => DoListSetQueueItemStatus(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); } - private async Task DoListSetQueueItemStatus(string key, List queueItemStatus) + private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) { EndPoint endpoint = await GetAndWaitForLeader(); diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index 651e0e99..99c96316 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -17,7 +17,7 @@ public async Task EnqueueAsync(string key, byte[] data) => return data; } - public async Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); + public async Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); public async Task CountAsync(string key) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}"); } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 48f76211..c146340f 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -143,7 +143,9 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, { processingTasks.Add(functionDeployment, new List()); } + var listQueueItemStatus = new ListQueueItemStatus(); var queueItemStatusList = new List(); + listQueueItemStatus.Items = queueItemStatusList; List httpResponseMessagesToDelete = new(); foreach (RequestToWait processing in processingTasks[functionDeployment]) { @@ -179,7 +181,7 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, { processingTasks[functionDeployment].Remove(httpResponseMessage); } - await slimFaasQueue.ListSetQueueItemStatusAsync(functionDeployment, queueItemStatusList); + await slimFaasQueue.ListSetQueueItemStatusAsync(functionDeployment, listQueueItemStatus); int numberProcessingTasks = processingTasks[functionDeployment].Count; return numberProcessingTasks; diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 7b5919a5..84460931 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -77,7 +77,7 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue public Task CountAsync(string key) => throw new NotImplementedException(); - public Task ListSetQueueItemStatusAsync(string key, List queueItemStatus) => throw new NotImplementedException(); + public Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => throw new NotImplementedException(); public async Task EnqueueAsync(string key, byte[] message) => await Task.Delay(100); } From 5e9dfd9290fdc323ef4ff27b6da154567d9766fa Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 16 Nov 2024 15:36:37 +0100 Subject: [PATCH 044/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/SlimDataInterpreter.cs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index fc369c93..bb4e4a24 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-753 + image: axaguildev/slimfaas:pr-77-754 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 64826c3a..221b7263 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -166,6 +166,7 @@ public static CommandInterpreter InitInterpreter(SlimDataState state) ValueTask ListLeftPushHandler(ListLeftPushCommand command, CancellationToken token) => DoListLeftPushAsync(command, state.Queues); ValueTask AddHashSetHandler(AddHashSetCommand command, CancellationToken token) => DoAddHashSetAsync(command, state.Hashsets); ValueTask AddKeyValueHandler(AddKeyValueCommand command, CancellationToken token) => DoAddKeyValueAsync(command, state.KeyValues); + ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand command, CancellationToken token) => DoListSetQueueItemStatusAsync(command, new Dictionary>() ); ValueTask SnapshotHandler(LogSnapshotCommand command, CancellationToken token) => DoHandleSnapshotAsync(command, state.KeyValues, state.Hashsets, state.Queues); var interpreter = new Builder() @@ -173,6 +174,7 @@ public static CommandInterpreter InitInterpreter(SlimDataState state) .Add(ListLeftPushCommand.Id, (Func)ListLeftPushHandler) .Add(AddHashSetCommand.Id, (Func)AddHashSetHandler) .Add(AddKeyValueCommand.Id, (Func)AddKeyValueHandler) + .Add(ListSetQueueItemStatusCommand.Id, (Func)ListSetQueueItemStatusAsync) .Add(LogSnapshotCommand.Id, (Func)SnapshotHandler, true) .Build(); From a76a587cdb06d0ebcc0658b3d23c987254f4f7e0 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 16 Nov 2024 15:40:42 +0100 Subject: [PATCH 045/135] fix --- src/SlimFaas/Program.cs | 21 --------------------- src/SlimFaas/SlimFaas.csproj | 1 - 2 files changed, 22 deletions(-) diff --git a/src/SlimFaas/Program.cs b/src/SlimFaas/Program.cs index 3e73e1c0..e61cd5df 100644 --- a/src/SlimFaas/Program.cs +++ b/src/SlimFaas/Program.cs @@ -2,8 +2,6 @@ using System.Text.Json; using DotNext.Net.Cluster.Consensus.Raft.Http; using Microsoft.AspNetCore.Server.Kestrel.Core; -using Polly; -using Polly.Extensions.Http; using Prometheus; using SlimData; using SlimFaas; @@ -315,25 +313,6 @@ serviceProviderStarter.Dispose(); -static IAsyncPolicy GetRetryPolicy() -{ - return HttpPolicyExtensions - .HandleTransientHttpError() - .OrResult(msg => - { - HttpStatusCode[] httpStatusCodesWorthRetrying = - { - HttpStatusCode.RequestTimeout, // 408 - HttpStatusCode.InternalServerError, // 500 - HttpStatusCode.BadGateway, // 502 - HttpStatusCode.ServiceUnavailable, // 503 - HttpStatusCode.GatewayTimeout // 504 - }; - return httpStatusCodesWorthRetrying.Contains(msg.StatusCode); - }) - .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, - retryAttempt))); -} public partial class Program diff --git a/src/SlimFaas/SlimFaas.csproj b/src/SlimFaas/SlimFaas.csproj index 0abedd3c..dc6aad0a 100644 --- a/src/SlimFaas/SlimFaas.csproj +++ b/src/SlimFaas/SlimFaas.csproj @@ -32,7 +32,6 @@ - From 4a488a7242b077df1f7c97b1a47b5740b285da9c Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 14:47:59 +0100 Subject: [PATCH 046/135] test --- demo/deployment-functions.yml | 36 ++++++++++++++++++++ demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 3 +- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 0c24187a..f5d6b718 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -29,6 +29,15 @@ spec: initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health + port: 5000 + initialDelaySeconds: 3 + periodSeconds: 1 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 env: - name: ASPNETCORE_URLS value: http://+:5000 @@ -73,6 +82,15 @@ spec: initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health + port: 5000 + initialDelaySeconds: 3 + periodSeconds: 1 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 env: - name: ASPNETCORE_URLS value: http://+:5000 @@ -117,6 +135,15 @@ spec: initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health + port: 5000 + initialDelaySeconds: 3 + periodSeconds: 1 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 env: - name: ASPNETCORE_URLS value: http://+:5000 @@ -166,6 +193,15 @@ spec: initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 5 + readinessProbe: + httpGet: + path: /health + port: 5000 + initialDelaySeconds: 3 + periodSeconds: 1 + timeoutSeconds: 1 + successThreshold: 1 + failureThreshold: 3 env: - name: ASPNETCORE_URLS value: http://+:5000 diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index bb4e4a24..afeae517 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-754 + image: axaguildev/slimfaas:pr-77-756 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index f957142a..0708b363 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -382,9 +382,10 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis V1ContainerStatus? containerStatus = item.Status.ContainerStatuses.FirstOrDefault(); bool ready = containerStatus?.Ready ?? false; bool started = containerStatus?.Started ?? false; + bool running = containerStatus?.State.Running != null; string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, ready, podIp, deploymentName); + PodInformation podInformation = new(podName, started, running, podIp, deploymentName); yield return podInformation; } } From 23bd13e60fec74683b57cbce8413365b561ec478 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 15:00:22 +0100 Subject: [PATCH 047/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index afeae517..e7a77ebd 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-756 + image: axaguildev/slimfaas:pr-77-758 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 0708b363..059168d3 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -383,6 +383,9 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis bool ready = containerStatus?.Ready ?? false; bool started = containerStatus?.Started ?? false; bool running = containerStatus?.State.Running != null; + // I need the state when readiness probe is ok + bool? podReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "Ready")?.Status == "True"; + string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; PodInformation podInformation = new(podName, started, running, podIp, deploymentName); From 579d8d50cc82a0f35d2b1fa0c82429130d9733f5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 15:04:19 +0100 Subject: [PATCH 048/135] fix --- src/SlimFaas/Kubernetes/KubernetesService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 059168d3..f2a4ebf1 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -388,7 +388,7 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, running, podIp, deploymentName); + PodInformation podInformation = new(podName, started, podReady, podIp, deploymentName); yield return podInformation; } } From 1864219c14b254efeb3d5ded93d7de83a2a93aac Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 15:14:58 +0100 Subject: [PATCH 049/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index e7a77ebd..2a79ded8 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-758 + image: axaguildev/slimfaas:pr-77-759 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index f2a4ebf1..29983f5b 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -385,10 +385,12 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis bool running = containerStatus?.State.Running != null; // I need the state when readiness probe is ok bool? podReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "Ready")?.Status == "True"; + // I want the state when the pod is ready to receive http request + bool podReadyHttp = item.Status.Conditions.FirstOrDefault(c => c.Type == "PodScheduled")?.Status == "True"; string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, podReady, podIp, deploymentName); + PodInformation podInformation = new(podName, started, podReadyHttp, podIp, deploymentName); yield return podInformation; } } From 58b386ff1fb8ba10539c6d93b7e721c835c8e892 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 15:27:33 +0100 Subject: [PATCH 050/135] test --- src/SlimFaas/Kubernetes/KubernetesService.cs | 28 +++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 29983f5b..ebebbcfd 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -388,9 +388,35 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis // I want the state when the pod is ready to receive http request bool podReadyHttp = item.Status.Conditions.FirstOrDefault(c => c.Type == "PodScheduled")?.Status == "True"; + // display pod name + Console.WriteLine("------------------"); + Console.WriteLine(item.Metadata.Name); + // I want display all conditions + foreach (V1PodCondition v1PodCondition in item.Status.Conditions) + { + Console.WriteLine(v1PodCondition.Type); + Console.WriteLine(v1PodCondition.Status); + Console.WriteLine(v1PodCondition.LastProbeTime); + Console.WriteLine(v1PodCondition.LastTransitionTime); + Console.WriteLine(v1PodCondition.Reason); + Console.WriteLine(v1PodCondition.Message); + } + Console.WriteLine("------"); + // I want to get readiness probe status + var status = item.Status.ContainerStatuses; + foreach (V1ContainerStatus v1ContainerStatus in status) + { + Console.WriteLine(v1ContainerStatus.Name); + Console.WriteLine(v1ContainerStatus.Ready); + Console.WriteLine(v1ContainerStatus.State.Running); + Console.WriteLine(v1ContainerStatus.State.Terminated); + Console.WriteLine(v1ContainerStatus.State.Waiting); + } + Console.WriteLine("------------------"); + string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, podReadyHttp, podIp, deploymentName); + PodInformation podInformation = new(podName, started, podReady, podIp, deploymentName); yield return podInformation; } } From 24bfaf99cf9fff64cce52d6a2dd8f9347dd4fd73 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 15:44:35 +0100 Subject: [PATCH 051/135] text --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 49 +++++++++++--------- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 2a79ded8..a23071a7 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-759 + image: axaguildev/slimfaas:pr-77-761 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index ebebbcfd..4c81315d 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -389,30 +389,35 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis bool podReadyHttp = item.Status.Conditions.FirstOrDefault(c => c.Type == "PodScheduled")?.Status == "True"; // display pod name - Console.WriteLine("------------------"); - Console.WriteLine(item.Metadata.Name); - // I want display all conditions - foreach (V1PodCondition v1PodCondition in item.Status.Conditions) + if (item.Metadata.Name.Contains("fibonacci1")) { - Console.WriteLine(v1PodCondition.Type); - Console.WriteLine(v1PodCondition.Status); - Console.WriteLine(v1PodCondition.LastProbeTime); - Console.WriteLine(v1PodCondition.LastTransitionTime); - Console.WriteLine(v1PodCondition.Reason); - Console.WriteLine(v1PodCondition.Message); - } - Console.WriteLine("------"); - // I want to get readiness probe status - var status = item.Status.ContainerStatuses; - foreach (V1ContainerStatus v1ContainerStatus in status) - { - Console.WriteLine(v1ContainerStatus.Name); - Console.WriteLine(v1ContainerStatus.Ready); - Console.WriteLine(v1ContainerStatus.State.Running); - Console.WriteLine(v1ContainerStatus.State.Terminated); - Console.WriteLine(v1ContainerStatus.State.Waiting); + Console.WriteLine("------------------"); + Console.WriteLine(item.Metadata.Name); + // I want display all conditions + foreach (V1PodCondition v1PodCondition in item.Status.Conditions) + { + Console.WriteLine("Type: " +v1PodCondition.Type); + Console.WriteLine("Status: " +v1PodCondition.Status); + Console.WriteLine("LastProbeTime: " +v1PodCondition.LastProbeTime); + Console.WriteLine("LastTransitionTime: " +v1PodCondition.LastTransitionTime); + Console.WriteLine("Reason: " +v1PodCondition.Reason); + Console.WriteLine("Message: " +v1PodCondition.Message); + } + + Console.WriteLine("------"); + // I want to get readiness probe status + var status = item.Status.ContainerStatuses; + foreach (V1ContainerStatus v1ContainerStatus in status) + { + Console.WriteLine(v1ContainerStatus.Name); + Console.WriteLine("Ready : " + v1ContainerStatus.Ready); + //Console.WriteLine(v1ContainerStatus.State.Running); + //Console.WriteLine(v1ContainerStatus.State.Terminated); + //Console.WriteLine(v1ContainerStatus.State.Waiting); + } + + Console.WriteLine("------------------"); } - Console.WriteLine("------------------"); string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; From d79c21237d0496cafcb382b7592ce854220f9fe0 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 15:59:05 +0100 Subject: [PATCH 052/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index a23071a7..a8e1b4de 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-761 + image: axaguildev/slimfaas:pr-77-762 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 4c81315d..14f01ac1 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -387,6 +387,7 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis bool? podReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "Ready")?.Status == "True"; // I want the state when the pod is ready to receive http request bool podReadyHttp = item.Status.Conditions.FirstOrDefault(c => c.Type == "PodScheduled")?.Status == "True"; + bool containerReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "ContainersReady")?.Status == "True"; // display pod name if (item.Metadata.Name.Contains("fibonacci1")) @@ -421,7 +422,7 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, podReady, podIp, deploymentName); + PodInformation podInformation = new(podName, started, containerReady, podIp, deploymentName); yield return podInformation; } } From f4990d0bee064be32ad9a86120caffe5382cca97 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 16:16:41 +0100 Subject: [PATCH 053/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 34 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index a8e1b4de..a4c140c4 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-762 + image: axaguildev/slimfaas:pr-77-763 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 14f01ac1..d4d1f563 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -379,6 +379,8 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis continue; } + // I want to get the state when the pod is ready to receive http request + V1ContainerStatus? containerStatus = item.Status.ContainerStatuses.FirstOrDefault(); bool ready = containerStatus?.Ready ?? false; bool started = containerStatus?.Started ?? false; @@ -387,6 +389,9 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis bool? podReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "Ready")?.Status == "True"; // I want the state when the pod is ready to receive http request bool podReadyHttp = item.Status.Conditions.FirstOrDefault(c => c.Type == "PodScheduled")?.Status == "True"; + + // I want the state when the container is ready and 1 second after the container is ready + bool containerReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "ContainersReady")?.Status == "True"; // display pod name @@ -427,4 +432,33 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis } } + private static bool PodReady(V1Pod pod) + { + DateTime readyTime = DateTime.MinValue; + + foreach (var condition in pod.Status.Conditions) + { + if (condition.Type == "Ready" && condition.Status == "True") + { + readyTime = condition.LastTransitionTime ?? DateTime.UtcNow; // Convertir le timestamp en UTC + break; + } + } + + if (readyTime != DateTime.MinValue) + { + TimeSpan timeSinceReady = DateTime.UtcNow - readyTime; // Utiliser DateTime.UtcNow pour obtenir le temps actuel en UTC + + if (timeSinceReady.TotalSeconds > 1) + { + // Attendre que le temps écoulé depuis l'état "ready" soit supérieur à 1 seconde avant d'exécuter une action + // Par exemple, effectuer une requête HTTP vers le pod + return true; + } + + } + + return false; + } + } From b3d654fc804b0e57bc589fa74ae0d5a9347bf921 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 16:19:00 +0100 Subject: [PATCH 054/135] fix --- src/SlimFaas/SlimWorker.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index c146340f..2cf8aea1 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -103,11 +103,11 @@ private async Task SendHttpRequestToFunction(Dictionary UpdateTickLastCallIfRequestStillInProgress(int? functionReplicas, Dictionary setTickLastCallCounterDictionnary, string functionDeployment, int numberProcessingTasks) { - int counterLimit = functionReplicas == 0 ? 10 : 300; + //int counterLimit = functionReplicas == 0 ? 10 : 300; long queueLength = await slimFaasQueue.CountAsync(functionDeployment); - if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) + //if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) { - setTickLastCallCounterDictionnary[functionDeployment] = 0; + //setTickLastCallCounterDictionnary[functionDeployment] = 0; if (queueLength > 0 || numberProcessingTasks > 0) { From 5331249dfd47b0904509160f826760652a5242ca Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 17 Nov 2024 16:45:56 +0100 Subject: [PATCH 055/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/QueueElementExtensions.cs | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index a4c140c4..53f4b46e 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-763 + image: axaguildev/slimfaas:pr-77-764 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 75d01019..ecb7bd45 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -51,9 +51,15 @@ public static List GetQueueRunningElement(this List public static List GetQueueAvailableElement(this List element, List retries, long nowTicks, int maximum) { - var currentCount = 0; + var runningElement = GetQueueRunningElement(element, nowTicks); var availableElements = new List(); - foreach (var queueElement in element) + var currentCount = runningElement.Count; + if (currentCount >= maximum) + { + return availableElements; + } + var currentElements = element.Except(runningElement); + foreach (var queueElement in currentElements) { if (currentCount == maximum) { From 9c8d98d8b4a2fa66d81a635f4188e87c2ad57f2a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 18 Nov 2024 16:17:56 +0100 Subject: [PATCH 056/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/QueueElementExtensions.cs | 14 +++++++------- .../SlimData.Tests/QueueElementExtentionsTests.cs | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 tests/SlimData.Tests/QueueElementExtentionsTests.cs diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 53f4b46e..4f4d56f7 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-764 + image: axaguildev/slimfaas:pr-77-765 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index ecb7bd45..1a78c39b 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -30,7 +30,7 @@ public static List GetQueueTimeoutElement(this List return timeoutElements; } - public static List GetQueueRunningElement(this List element, long nowTicks, int timeout=30) + public static List GetQueueRunningElement(this List element, long nowTicks, int timeoutSeconds=30) { var runningElement = new List(); foreach (var queueElement in element) @@ -38,8 +38,8 @@ public static List GetQueueRunningElement(this List if(queueElement.RetryQueueElements.Count > 0) { var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.EndTimeStamp == 0 && - retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks > nowTicks) + if (retryQueueElement.EndTimeStamp == 0 || + retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeoutSeconds).Ticks > nowTicks) { runningElement.Add(queueElement); } @@ -75,9 +75,9 @@ public static List GetQueueAvailableElement(this List retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks + && retries.Count < count + && (retryQueueElement.EndTimeStamp != 0 + || nowTicks > retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks ) ) { availableElements.Add(queueElement); @@ -98,7 +98,7 @@ public static IList GetQueueFinishedElement(this IList 0) { var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.HttpCode is >= 0 and < 400 || retries.Count <= count) + if (retries.Count >= count && retryQueueElement.EndTimeStamp > 0) { queueFinishedElement.Add(queueElement); } diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs new file mode 100644 index 00000000..4dd03143 --- /dev/null +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -0,0 +1,14 @@ +namespace SlimData.Tests; + +public class QueueElementExtentionsTests +{ + [Fact] + public static void QueueElementExtensionsGetQueueRunningElement() + { + // I want a test which text my extention + List queueElements = new List(); + + // queueElements.GetQueueAvailableElement() + + } +} From 755dcd2d9caec9d14df3db96e99a3d525c013414 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 19 Nov 2024 11:58:29 +0100 Subject: [PATCH 057/135] update --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/QueueElementExtensions.cs | 12 ++--- src/SlimData/SlimDataInterpreter.cs | 7 ++- src/SlimFaas/Kubernetes/KubernetesService.cs | 4 +- .../QueueElementExtentionsTests.cs | 44 ++++++++++++++++++- 5 files changed, 54 insertions(+), 15 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 4f4d56f7..f7b5c50b 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-765 + image: axaguildev/slimfaas:pr-77-766 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 1a78c39b..ed59a1ac 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -38,7 +38,7 @@ public static List GetQueueRunningElement(this List if(queueElement.RetryQueueElements.Count > 0) { var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.EndTimeStamp == 0 || + if (retryQueueElement.EndTimeStamp == 0 && retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeoutSeconds).Ticks > nowTicks) { runningElement.Add(queueElement); @@ -75,9 +75,9 @@ public static List GetQueueAvailableElement(this List retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks ) + && retries.Count < count + && retryQueueElement.EndTimeStamp != 0 + && nowTicks > retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks ) { availableElements.Add(queueElement); @@ -89,7 +89,7 @@ public static List GetQueueAvailableElement(this List GetQueueFinishedElement(this IList element, List retries) + public static IList GetQueueFinishedElement(this IList element, long nowTicks, List retries, int timeoutSeconds=30) { var queueFinishedElement = new List(); foreach (var queueElement in element) @@ -98,7 +98,7 @@ public static IList GetQueueFinishedElement(this IList 0) { var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retries.Count >= count && retryQueueElement.EndTimeStamp > 0) + if (retries.Count >= count && (retryQueueElement.EndTimeStamp > 0 || retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeoutSeconds).Ticks <= nowTicks)) { queueFinishedElement.Add(queueElement); } diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 221b7263..8bf781cb 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -35,9 +35,8 @@ public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, Cancel return DoListRightPopAsync(addHashSetCommand, SlimDataState.Queues); } - private static readonly List Retries = [2, 6, 10]; - private static readonly int RetryTimeout = 30; - private static readonly int NumberParralel = 1; + public static readonly List Retries = [2, 6, 10]; + public static readonly int RetryTimeout = 30; internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetCommand, Dictionary> queues) { @@ -52,7 +51,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm retryQueueElement.HttpCode = 520; } - var queueFinishedElements = queue.GetQueueFinishedElement(Retries); + var queueFinishedElements = queue.GetQueueFinishedElement( nowTicks, Retries, RetryTimeout); foreach (var queueFinishedElement in queueFinishedElements) { queue.Remove(queueFinishedElement); diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index d4d1f563..3262f071 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -395,7 +395,7 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis bool containerReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "ContainersReady")?.Status == "True"; // display pod name - if (item.Metadata.Name.Contains("fibonacci1")) + /*if (item.Metadata.Name.Contains("fibonacci1")) { Console.WriteLine("------------------"); Console.WriteLine(item.Metadata.Name); @@ -423,7 +423,7 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis } Console.WriteLine("------------------"); - } + }*/ string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 4dd03143..49093ad6 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -6,9 +6,49 @@ public class QueueElementExtentionsTests public static void QueueElementExtensionsGetQueueRunningElement() { // I want a test which text my extention - List queueElements = new List(); + var nowTicks = DateTime.UtcNow.Ticks; + var timeoutSpanTicks = TimeSpan.FromSeconds(31).Ticks; + List queueElements = new(); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, new List() + { + new(nowTicks -100, nowTicks, 500), + new(nowTicks -50, nowTicks, 500), + new(nowTicks -20, nowTicks, 500), + })); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, new List() + { + new(nowTicks - timeoutSpanTicks -100, nowTicks, 500), + new(nowTicks- timeoutSpanTicks -50, nowTicks, 500), + new(nowTicks- timeoutSpanTicks -20, 0, 0), + })); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, new List() + { + new(nowTicks - 1000, nowTicks, 500), + new(nowTicks- 500, nowTicks, 500), + new(nowTicks- 100, 0, 0), + })); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, new List() + { + new(nowTicks - 1000, nowTicks, 500), + new(nowTicks- 500, nowTicks, 500), + new(nowTicks- timeoutSpanTicks, 0, 0), + })); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, new List())); - // queueElements.GetQueueAvailableElement() + var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.Retries, nowTicks, 3); + Assert.Equal(2, availableElements.Count); + Assert.Equal("2", availableElements[0].Id); + Assert.Equal("3", availableElements[1].Id); + + var runningElements = queueElements.GetQueueRunningElement(nowTicks); + Assert.Equal(1, runningElements.Count); + Assert.Equal("1", runningElements[0].Id); + + + var finishedElements = queueElements.GetQueueFinishedElement( nowTicks, SlimDataInterpreter.Retries); + Assert.Equal(2, finishedElements.Count); } } From dccd5ffa337c6f21ec6ef345fac61ee0704880ac Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 19 Nov 2024 14:03:30 +0100 Subject: [PATCH 058/135] fix test --- demo/deployment-slimfaas.yml | 2 +- tests/SlimData.Tests/QueueElementExtentionsTests.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index f7b5c50b..ac933802 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-766 + image: axaguildev/slimfaas:pr-77-767 livenessProbe: httpGet: path: /health diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 49093ad6..7657a934 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -49,6 +49,6 @@ public static void QueueElementExtensionsGetQueueRunningElement() var finishedElements = queueElements.GetQueueFinishedElement( nowTicks, SlimDataInterpreter.Retries); - Assert.Equal(2, finishedElements.Count); + Assert.Equal(3, finishedElements.Count); } } From f438057f8f83d24fa51694ceb01c79f5ffc9065d Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 19 Nov 2024 15:47:51 +0100 Subject: [PATCH 059/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Commands/LogSnapshotCommand.cs | 4 +- src/SlimData/QueueElementExtensions.cs | 147 ++++++++++++------ src/SlimData/SlimDataInterpreter.cs | 12 +- .../QueueElementExtentionsTests.cs | 28 ++-- 5 files changed, 125 insertions(+), 68 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index ac933802..3a0c1650 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-767 + image: axaguildev/slimfaas:pr-77-768 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index 2416d276..6f2fb701 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -138,13 +138,13 @@ public static async ValueTask ReadFromAsync(TReader .ConfigureAwait(false); var insertTimeStamp = await reader.ReadBigEndianAsync(token); var countRetryQueueElements = await reader.ReadLittleEndianAsync(token); - var retryQueueElements = new List(countRetryQueueElements); + var retryQueueElements = new List(countRetryQueueElements); while (countRetryQueueElements-- > 0) { var startTimestamp = await reader.ReadBigEndianAsync(token); var endTimestamp = await reader.ReadBigEndianAsync(token); var httpCode = await reader.ReadLittleEndianAsync(token); - retryQueueElements.Add(new RetryQueueElement(startTimestamp, endTimestamp, httpCode)); + retryQueueElements.Add(new QueueHttpTryElement(startTimestamp, endTimestamp, httpCode)); } queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, retryQueueElements)); diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index ed59a1ac..479c8c0c 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -8,22 +8,84 @@ public static class QueueElementExtensions 500, // HttpStatusCode.InternalServerError, 502, // HttpStatusCode.BadGateway, 503, // HttpStatusCode.ServiceUnavailable, - 504 // HttpStatusCode.GatewayTimeout + 504, // HttpStatusCode.GatewayTimeout ]; + public static bool IsTimeout(this QueueElement element, long nowTicks, int timeout=30) + { + if(element.RetryQueueElements.Count > 0) + { + var retryQueueElement = element.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp == 0 && + retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) + { + return true; + } + } + return false; + } + + public static bool IsWaitingForRetry(this QueueElement element, long nowTicks, List retries, int timeoutSeconds=30) + { + var count = element.RetryQueueElements.Count; + if(count == 0) return false; + + if (element.IsFinished(nowTicks, retries, timeoutSeconds)) return false; + + if(element.IsRunning(nowTicks, timeoutSeconds)) return false; + + var retryQueueElement = element.RetryQueueElements[^1]; + var retryTimeout = retries[count - 1]; + if (retryQueueElement.EndTimeStamp != 0 && + (retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retryTimeout).Ticks > nowTicks)) + { + return true; + } + return false; + } + + public static bool IsFinished(this QueueElement queueElement, long nowTicks, List retries, int timeoutSeconds=30) + { + var count = queueElement.RetryQueueElements.Count; + if (count <= 0) return false; + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp > 0 && + !HttpStatusCodesWorthRetrying.Contains(retryQueueElement.HttpCode)) + { + return true; + } + + if (retries.Count < count) + { + if (queueElement.IsTimeout(nowTicks, timeoutSeconds) || retryQueueElement.EndTimeStamp > 0) + { + return true; + } + } + + return false; + } + + public static bool IsRunning(this QueueElement queueElement, long nowTicks, int timeoutSeconds=30) + { + if (queueElement.RetryQueueElements.Count <= 0) return false; + var retryQueueElement = queueElement.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp == 0 && + !queueElement.IsTimeout(nowTicks, timeoutSeconds)) + { + return true; + } + return false; + } + public static List GetQueueTimeoutElement(this List element, long nowTicks, int timeout=30) { var timeoutElements = new List(); foreach (var queueElement in element) { - if(queueElement.RetryQueueElements.Count > 0) + if(queueElement.IsTimeout(nowTicks, timeout)) { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.EndTimeStamp == 0 && - retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) - { - timeoutElements.Add(queueElement); - } + timeoutElements.Add(queueElement); } } @@ -35,77 +97,64 @@ public static List GetQueueRunningElement(this List var runningElement = new List(); foreach (var queueElement in element) { - if(queueElement.RetryQueueElements.Count > 0) + if(queueElement.IsRunning(nowTicks, timeoutSeconds)) { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retryQueueElement.EndTimeStamp == 0 && - retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeoutSeconds).Ticks > nowTicks) - { - runningElement.Add(queueElement); - } + runningElement.Add(queueElement); } - } return runningElement; } - public static List GetQueueAvailableElement(this List element, List retries, long nowTicks, int maximum) + public static List GetQueueWaitingForRetryElement(this List element, long nowTicks, List retries, int timeoutSeconds=30) { - var runningElement = GetQueueRunningElement(element, nowTicks); + var waitingForRetry = new List(); + foreach (var queueElement in element) + { + if (queueElement.IsWaitingForRetry(nowTicks, retries, timeoutSeconds)) + { + waitingForRetry.Add(queueElement); + } + } + return waitingForRetry; + } + + public static List GetQueueAvailableElement(this List elements, List retries, long nowTicks, int maximum, int timeoutSeconds=30) + { + var runningElements = elements.GetQueueRunningElement(nowTicks); + var runningWaitingForRetryElements = elements.GetQueueWaitingForRetryElement(nowTicks, retries); + var finishedElements = elements.GetQueueFinishedElement(nowTicks, retries, timeoutSeconds); + var timeoutElements = elements.GetQueueTimeoutElement(nowTicks, timeoutSeconds); var availableElements = new List(); - var currentCount = runningElement.Count; + var currentCount = runningElements.Count + runningWaitingForRetryElements.Count; if (currentCount >= maximum) { return availableElements; } - var currentElements = element.Except(runningElement); + var currentElements = elements.Except(runningElements).Except(runningWaitingForRetryElements).Except(finishedElements).Except(timeoutElements); foreach (var queueElement in currentElements) { if (currentCount == maximum) { return availableElements; } - var count = queueElement.RetryQueueElements.Count; - if (count == 0) - { - availableElements.Add(queueElement); - currentCount++; - } - else - { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (HttpStatusCodesWorthRetrying.Contains(retryQueueElement.HttpCode) - && retries.Count < count - && retryQueueElement.EndTimeStamp != 0 - && nowTicks > retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retries[count - 1]).Ticks - ) - { - availableElements.Add(queueElement); - currentCount++; - } - } - + availableElements.Add(queueElement); + currentCount++; } return availableElements; } public static IList GetQueueFinishedElement(this IList element, long nowTicks, List retries, int timeoutSeconds=30) { - var queueFinishedElement = new List(); + var queueFinishedElements = new List(); foreach (var queueElement in element) { - var count = queueElement.RetryQueueElements.Count; - if(count > 0) + if (queueElement.IsFinished(nowTicks, retries, timeoutSeconds)) { - var retryQueueElement = queueElement.RetryQueueElements[^1]; - if (retries.Count >= count && (retryQueueElement.EndTimeStamp > 0 || retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeoutSeconds).Ticks <= nowTicks)) - { - queueFinishedElement.Add(queueElement); - } + queueFinishedElements.Add(queueElement); } } - return queueFinishedElement; + return queueFinishedElements; } } \ No newline at end of file diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 8bf781cb..1eb9e0be 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -14,9 +14,9 @@ public record QueueElement( ReadOnlyMemory Value, string Id, long InsertTimeStamp, - IList RetryQueueElements); + IList RetryQueueElements); -public class RetryQueueElement(long startTimeStamp=0, long endTimeStamp=0, int httpCode=0) +public class QueueHttpTryElement(long startTimeStamp=0, long endTimeStamp=0, int httpCode=0) { public long StartTimeStamp { get; set; } = startTimeStamp; public long EndTimeStamp { get;set; } = endTimeStamp; @@ -60,7 +60,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm var queueAvailableElements = queue.GetQueueAvailableElement(Retries, nowTicks, addHashSetCommand.Count); foreach (var queueAvailableElement in queueAvailableElements) { - queueAvailableElement.RetryQueueElements.Add(new RetryQueueElement(nowTicks)); + queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); } } @@ -76,9 +76,9 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Dictionary> queues) { if (queues.TryGetValue(addHashSetCommand.Key, out List? value)) - value.Add(new QueueElement(addHashSetCommand.Value, Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())); + value.Add(new QueueElement(addHashSetCommand.Value, Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())); else - queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value,Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())}); + queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value,Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())}); return default; } @@ -92,7 +92,7 @@ public ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHa internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHashSetCommand, Dictionary> queues) { if (!queues.TryGetValue(addHashSetCommand.Key, out List? value)) return default; - var queueElement = value.Find(x => x.Id == addHashSetCommand.Identifier); + var queueElement = value.FirstOrDefault(x => x.Id == addHashSetCommand.Identifier); if (queueElement != null) { var retryQueueElement = queueElement.RetryQueueElements[^1]; diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 7657a934..cb8aba26 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -9,35 +9,43 @@ public static void QueueElementExtensionsGetQueueRunningElement() var nowTicks = DateTime.UtcNow.Ticks; var timeoutSpanTicks = TimeSpan.FromSeconds(31).Ticks; List queueElements = new(); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, new List() { new(nowTicks -100, nowTicks, 500), new(nowTicks -50, nowTicks, 500), new(nowTicks -20, nowTicks, 500), + new(nowTicks -10, nowTicks, 500), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, new List() { new(nowTicks - timeoutSpanTicks -100, nowTicks, 500), new(nowTicks- timeoutSpanTicks -50, nowTicks, 500), + new(nowTicks- timeoutSpanTicks -30, nowTicks, 500), new(nowTicks- timeoutSpanTicks -20, 0, 0), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, new List() + { + new(nowTicks -100, nowTicks, 200), + })); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), + new(nowTicks- 200, nowTicks, 500), new(nowTicks- 100, 0, 0), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), + new(nowTicks- 400, nowTicks, 500), new(nowTicks- timeoutSpanTicks, 0, 0), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, new List())); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, new List())); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, new List())); - var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.Retries, nowTicks, 3); + var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.Retries, nowTicks, 3, 30); Assert.Equal(2, availableElements.Count); Assert.Equal("2", availableElements[0].Id); @@ -48,7 +56,7 @@ public static void QueueElementExtensionsGetQueueRunningElement() Assert.Equal("1", runningElements[0].Id); - var finishedElements = queueElements.GetQueueFinishedElement( nowTicks, SlimDataInterpreter.Retries); - Assert.Equal(3, finishedElements.Count); + var finishedElements = queueElements.GetQueueFinishedElement(nowTicks, SlimDataInterpreter.Retries); + Assert.Equal(4, finishedElements.Count); } } From 83bcc2795caf366df994fdac4b12e1c02309a612 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 19 Nov 2024 15:59:59 +0100 Subject: [PATCH 060/135] last fix --- src/SlimData/Endpoints.cs | 2 +- src/SlimData/QueueElementExtensions.cs | 25 ++++++++++++++----------- src/SlimData/SlimDataInterpreter.cs | 2 +- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index cdc08f6e..24c0d8d2 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -139,7 +139,7 @@ public static async Task ListRightPopCommand(SlimPersistentState prov var queues = ((ISupplier)provider).Invoke().Queues; if (queues.TryGetValue(key, out var queue)) { - var queueElements = queue.GetQueueAvailableElement([2, 6, 10], nowTicks, count); + var queueElements = queue.GetQueueAvailableElement([2, 4, 10], nowTicks, count); foreach (var queueElement in queueElements) { values.Items.Add(new QueueData(queueElement.Id ,queueElement.Value.ToArray())); diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 479c8c0c..01a99d4a 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -13,14 +13,12 @@ public static class QueueElementExtensions public static bool IsTimeout(this QueueElement element, long nowTicks, int timeout=30) { - if(element.RetryQueueElements.Count > 0) + if (element.RetryQueueElements.Count <= 0) return false; + var retryQueueElement = element.RetryQueueElements[^1]; + if (retryQueueElement.EndTimeStamp == 0 && + retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) { - var retryQueueElement = element.RetryQueueElements[^1]; - if (retryQueueElement.EndTimeStamp == 0 && - retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) - { - return true; - } + return true; } return false; } @@ -28,19 +26,25 @@ public static bool IsTimeout(this QueueElement element, long nowTicks, int timeo public static bool IsWaitingForRetry(this QueueElement element, long nowTicks, List retries, int timeoutSeconds=30) { var count = element.RetryQueueElements.Count; - if(count == 0) return false; + if(count == 0 || count > retries.Count ) return false; - if (element.IsFinished(nowTicks, retries, timeoutSeconds)) return false; + if(element.IsFinished(nowTicks, retries, timeoutSeconds)) return false; if(element.IsRunning(nowTicks, timeoutSeconds)) return false; var retryQueueElement = element.RetryQueueElements[^1]; var retryTimeout = retries[count - 1]; + if(element.IsTimeout(nowTicks, timeoutSeconds) && retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(retryTimeout).Ticks <= nowTicks) + { + return true; + } + if (retryQueueElement.EndTimeStamp != 0 && (retryQueueElement.EndTimeStamp + TimeSpan.FromSeconds(retryTimeout).Ticks > nowTicks)) { return true; } + return false; } @@ -123,14 +127,13 @@ public static List GetQueueAvailableElement(this List(); var currentCount = runningElements.Count + runningWaitingForRetryElements.Count; if (currentCount >= maximum) { return availableElements; } - var currentElements = elements.Except(runningElements).Except(runningWaitingForRetryElements).Except(finishedElements).Except(timeoutElements); + var currentElements = elements.Except(runningElements).Except(runningWaitingForRetryElements).Except(finishedElements); foreach (var queueElement in currentElements) { if (currentCount == maximum) diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 1eb9e0be..4223f84d 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -48,7 +48,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm { var retryQueueElement = queueTimeoutElement.RetryQueueElements[^1]; retryQueueElement.EndTimeStamp = nowTicks; - retryQueueElement.HttpCode = 520; + retryQueueElement.HttpCode = 504; } var queueFinishedElements = queue.GetQueueFinishedElement( nowTicks, Retries, RetryTimeout); From c3992e8330c620c1e4308e6861972ef30cb20fac Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 19 Nov 2024 17:25:18 +0100 Subject: [PATCH 061/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/SlimDataInterpreter.cs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 3a0c1650..9553f6ee 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-768 + image: axaguildev/slimfaas:pr-77-769 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 4223f84d..ac050f45 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -98,7 +98,13 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo var retryQueueElement = queueElement.RetryQueueElements[^1]; retryQueueElement.EndTimeStamp = DateTime.UtcNow.Ticks; retryQueueElement.HttpCode = addHashSetCommand.HttpCode; + + if(queueElement.IsFinished(DateTime.UtcNow.Ticks, Retries, RetryTimeout)) + { + value.Remove(queueElement); + } } + return default; } @@ -165,7 +171,7 @@ public static CommandInterpreter InitInterpreter(SlimDataState state) ValueTask ListLeftPushHandler(ListLeftPushCommand command, CancellationToken token) => DoListLeftPushAsync(command, state.Queues); ValueTask AddHashSetHandler(AddHashSetCommand command, CancellationToken token) => DoAddHashSetAsync(command, state.Hashsets); ValueTask AddKeyValueHandler(AddKeyValueCommand command, CancellationToken token) => DoAddKeyValueAsync(command, state.KeyValues); - ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand command, CancellationToken token) => DoListSetQueueItemStatusAsync(command, new Dictionary>() ); + ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand command, CancellationToken token) => DoListSetQueueItemStatusAsync(command, state.Queues); ValueTask SnapshotHandler(LogSnapshotCommand command, CancellationToken token) => DoHandleSnapshotAsync(command, state.KeyValues, state.Hashsets, state.Queues); var interpreter = new Builder() From 34f84b2894b4a06468ad323dfe9ac5a0796454a0 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 19 Nov 2024 21:05:07 +0100 Subject: [PATCH 062/135] test --- demo/deployment-slimfaas.yml | 2 +- src/Fibonacci/Program.cs | 7 +- src/SlimData/SlimDataInterpreter.cs | 8 ++- src/SlimFaas/Database/SlimDataService.cs | 5 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 71 -------------------- 5 files changed, 16 insertions(+), 77 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 9553f6ee..dcf899ee 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-769 + image: axaguildev/slimfaas:pr-77-770 livenessProbe: httpGet: path: /health diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 987ead94..1dd91223 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -28,6 +28,11 @@ app.MapGet("/health", () => "OK"); +app.MapGet("/error", () => +{ + throw new Exception("Error"); +}); + app.MapGet("/hello/{name}", ([FromServices] ILogger logger, string name) => { logger.LogInformation("Hello Called with name: {Name}", name); @@ -46,7 +51,7 @@ [FromServices] Fibonacci fibonacci, FibonacciInput input) => { - logger.LogInformation("Fibonacci Called"); + logger.LogInformation("Fibonacci Called with input: {Input}", input.Input); var output = new FibonacciOutput(); output.Result = fibonacci.Run(input.Input); logger.LogInformation("Fibonacci output: {Output}", output.Result); diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index ac050f45..d1efb41d 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -79,7 +79,7 @@ internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetComm value.Add(new QueueElement(addHashSetCommand.Value, Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())); else queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value,Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())}); - + Console.WriteLine("ListLeftPushAsync count " + queues[addHashSetCommand.Key].Count); return default; } @@ -91,20 +91,24 @@ public ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHa internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHashSetCommand, Dictionary> queues) { + Console.WriteLine("ListSetQueueItemStatusAsync"); if (!queues.TryGetValue(addHashSetCommand.Key, out List? value)) return default; + Console.WriteLine("ListSetQueueItemStatusAsync 2"); var queueElement = value.FirstOrDefault(x => x.Id == addHashSetCommand.Identifier); if (queueElement != null) { + Console.WriteLine("ListSetQueueItemStatusAsync 3"); var retryQueueElement = queueElement.RetryQueueElements[^1]; retryQueueElement.EndTimeStamp = DateTime.UtcNow.Ticks; retryQueueElement.HttpCode = addHashSetCommand.HttpCode; if(queueElement.IsFinished(DateTime.UtcNow.Ticks, Retries, RetryTimeout)) { + Console.WriteLine("ListSetQueueItemStatusAsync 4 finished"); value.Remove(queueElement); } } - + Console.WriteLine("DoListSetQueueItemStatusAsync count " + queues[addHashSetCommand.Key].Count); return default; } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 9c25b941..859e51be 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -173,7 +173,6 @@ public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueIt private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) { - EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) { @@ -208,7 +207,9 @@ private async Task DoListLengthAsync(string key) if (data.Queues.TryGetValue(key, out List? value)) { - return value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, int.MaxValue).Count; + var number = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, int.MaxValue).Count; + Console.WriteLine($"DoListLengthAsync: Number of available elements: {number} for key: {key}"); + return number; } return 0L; diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 3262f071..d5adbdee 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -379,52 +379,9 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis continue; } - // I want to get the state when the pod is ready to receive http request - V1ContainerStatus? containerStatus = item.Status.ContainerStatuses.FirstOrDefault(); - bool ready = containerStatus?.Ready ?? false; bool started = containerStatus?.Started ?? false; - bool running = containerStatus?.State.Running != null; - // I need the state when readiness probe is ok - bool? podReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "Ready")?.Status == "True"; - // I want the state when the pod is ready to receive http request - bool podReadyHttp = item.Status.Conditions.FirstOrDefault(c => c.Type == "PodScheduled")?.Status == "True"; - - // I want the state when the container is ready and 1 second after the container is ready - bool containerReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "ContainersReady")?.Status == "True"; - - // display pod name - /*if (item.Metadata.Name.Contains("fibonacci1")) - { - Console.WriteLine("------------------"); - Console.WriteLine(item.Metadata.Name); - // I want display all conditions - foreach (V1PodCondition v1PodCondition in item.Status.Conditions) - { - Console.WriteLine("Type: " +v1PodCondition.Type); - Console.WriteLine("Status: " +v1PodCondition.Status); - Console.WriteLine("LastProbeTime: " +v1PodCondition.LastProbeTime); - Console.WriteLine("LastTransitionTime: " +v1PodCondition.LastTransitionTime); - Console.WriteLine("Reason: " +v1PodCondition.Reason); - Console.WriteLine("Message: " +v1PodCondition.Message); - } - - Console.WriteLine("------"); - // I want to get readiness probe status - var status = item.Status.ContainerStatuses; - foreach (V1ContainerStatus v1ContainerStatus in status) - { - Console.WriteLine(v1ContainerStatus.Name); - Console.WriteLine("Ready : " + v1ContainerStatus.Ready); - //Console.WriteLine(v1ContainerStatus.State.Running); - //Console.WriteLine(v1ContainerStatus.State.Terminated); - //Console.WriteLine(v1ContainerStatus.State.Waiting); - } - - Console.WriteLine("------------------"); - }*/ - string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; PodInformation podInformation = new(podName, started, containerReady, podIp, deploymentName); @@ -432,33 +389,5 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis } } - private static bool PodReady(V1Pod pod) - { - DateTime readyTime = DateTime.MinValue; - - foreach (var condition in pod.Status.Conditions) - { - if (condition.Type == "Ready" && condition.Status == "True") - { - readyTime = condition.LastTransitionTime ?? DateTime.UtcNow; // Convertir le timestamp en UTC - break; - } - } - - if (readyTime != DateTime.MinValue) - { - TimeSpan timeSinceReady = DateTime.UtcNow - readyTime; // Utiliser DateTime.UtcNow pour obtenir le temps actuel en UTC - - if (timeSinceReady.TotalSeconds > 1) - { - // Attendre que le temps écoulé depuis l'état "ready" soit supérieur à 1 seconde avant d'exécuter une action - // Par exemple, effectuer une requête HTTP vers le pod - return true; - } - - } - - return false; - } } From 674c2c04140001fc9f9697e579da84a0a8a77090 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 19 Nov 2024 21:17:42 +0100 Subject: [PATCH 063/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Database/SlimDataService.cs | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index dcf899ee..6588349e 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-770 + image: axaguildev/slimfaas:pr-77-771 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 859e51be..4438391d 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -207,7 +207,18 @@ private async Task DoListLengthAsync(string key) if (data.Queues.TryGetValue(key, out List? value)) { - var number = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, int.MaxValue).Count; + var elements = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, int.MaxValue); + + foreach (QueueElement queueElement in elements) + { + Console.WriteLine($"DoListLengthAsync: Element Id: {queueElement.Id}"); + foreach (QueueHttpTryElement queueElementRetryQueueElement in queueElement.RetryQueueElements) + { + Console.WriteLine($"DoListLengthAsync StartTimeStamp: {queueElementRetryQueueElement.StartTimeStamp} EndTimeStamp: {queueElementRetryQueueElement.EndTimeStamp} HttpCode: {queueElementRetryQueueElement.HttpCode} "); + } + } + + var number = elements.Count; Console.WriteLine($"DoListLengthAsync: Number of available elements: {number} for key: {key}"); return number; } From 445650cf9e8ac8a0b220cce20cf4115e2c0b3c65 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 20 Nov 2024 09:03:49 +0100 Subject: [PATCH 064/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/SlimDataInterpreter.cs | 43 ++++++++++++++++++----------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 6588349e..b49e5f44 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-771 + image: axaguildev/slimfaas:pr-77-772 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index d1efb41d..9af4ccdb 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -10,11 +10,17 @@ public record SlimDataState( Dictionary> KeyValues, Dictionary> Queues); -public record QueueElement( - ReadOnlyMemory Value, - string Id, - long InsertTimeStamp, - IList RetryQueueElements); +public class QueueElement( + ReadOnlyMemory value, + string id, + long insertTimeStamp, + IList retryQueueElements) +{ + public ReadOnlyMemory Value { get; } = value; + public string Id { get; } = id; + public long InsertTimeStamp { get; } = insertTimeStamp; + public IList RetryQueueElements { get; } = retryQueueElements; +} public class QueueHttpTryElement(long startTimeStamp=0, long endTimeStamp=0, int httpCode=0) { @@ -62,6 +68,8 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm { queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); } + + Console.WriteLine("ListRightPopAsync count " + queues[addHashSetCommand.Key].Count); } return default; @@ -95,19 +103,22 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo if (!queues.TryGetValue(addHashSetCommand.Key, out List? value)) return default; Console.WriteLine("ListSetQueueItemStatusAsync 2"); var queueElement = value.FirstOrDefault(x => x.Id == addHashSetCommand.Identifier); - if (queueElement != null) + if (queueElement == null) { - Console.WriteLine("ListSetQueueItemStatusAsync 3"); - var retryQueueElement = queueElement.RetryQueueElements[^1]; - retryQueueElement.EndTimeStamp = DateTime.UtcNow.Ticks; - retryQueueElement.HttpCode = addHashSetCommand.HttpCode; - - if(queueElement.IsFinished(DateTime.UtcNow.Ticks, Retries, RetryTimeout)) - { - Console.WriteLine("ListSetQueueItemStatusAsync 4 finished"); - value.Remove(queueElement); - } + return default; } + + Console.WriteLine("ListSetQueueItemStatusAsync 3"); + var retryQueueElement = queueElement.RetryQueueElements[^1]; + retryQueueElement.EndTimeStamp = DateTime.UtcNow.Ticks; + retryQueueElement.HttpCode = addHashSetCommand.HttpCode; + + if (queueElement.IsFinished(DateTime.UtcNow.Ticks, Retries, RetryTimeout)) + { + Console.WriteLine("ListSetQueueItemStatusAsync 4 finished"); + value.Remove(queueElement); + } + Console.WriteLine("DoListSetQueueItemStatusAsync count " + queues[addHashSetCommand.Key].Count); return default; } From c135ec2e2d8babb1b95f0fc2a81603b203d8c0f5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 20 Nov 2024 09:58:16 +0100 Subject: [PATCH 065/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/SlimDataInterpreter.cs | 9 +++------ src/SlimFaas/SlimWorker.cs | 6 +++--- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index b49e5f44..a14347da 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-772 + image: axaguildev/slimfaas:pr-77-773 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 9af4ccdb..3eeed60d 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -52,6 +52,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm var queueTimeoutElements = queue.GetQueueTimeoutElement(nowTicks, RetryTimeout); foreach (var queueTimeoutElement in queueTimeoutElements) { + Console.WriteLine("ListRightPopAsync timeout " + queueTimeoutElement.Id + " " + addHashSetCommand.Key); var retryQueueElement = queueTimeoutElement.RetryQueueElements[^1]; retryQueueElement.EndTimeStamp = nowTicks; retryQueueElement.HttpCode = 504; @@ -69,7 +70,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); } - Console.WriteLine("ListRightPopAsync count " + queues[addHashSetCommand.Key].Count); + Console.WriteLine("ListRightPopAsync count " + queues[addHashSetCommand.Key].Count + " " + addHashSetCommand.Key); } return default; @@ -122,8 +123,6 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo Console.WriteLine("DoListSetQueueItemStatusAsync count " + queues[addHashSetCommand.Key].Count); return default; } - - [CommandHandler] public ValueTask AddHashSetAsync(AddHashSetCommand addHashSetCommand, CancellationToken token) @@ -152,9 +151,7 @@ internal static ValueTask DoAddKeyValueAsync(AddKeyValueCommand valueCommand, Di [CommandHandler(IsSnapshotHandler = true)] public ValueTask HandleSnapshotAsync(LogSnapshotCommand command, CancellationToken token) { - SlimDataState = SlimDataState with { KeyValues = command.keysValues }; - SlimDataState = SlimDataState with { Queues = command.queues }; - SlimDataState = SlimDataState with { Hashsets = command.hashsets }; + DoHandleSnapshotAsync(command, SlimDataState.KeyValues, SlimDataState.Hashsets, SlimDataState.Queues); return default; } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 2cf8aea1..7c036f75 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -103,11 +103,11 @@ private async Task SendHttpRequestToFunction(Dictionary UpdateTickLastCallIfRequestStillInProgress(int? functionReplicas, Dictionary setTickLastCallCounterDictionnary, string functionDeployment, int numberProcessingTasks) { - //int counterLimit = functionReplicas == 0 ? 10 : 300; + int counterLimit = functionReplicas == 0 ? 10 : 100; long queueLength = await slimFaasQueue.CountAsync(functionDeployment); - //if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) + if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) { - //setTickLastCallCounterDictionnary[functionDeployment] = 0; + setTickLastCallCounterDictionnary[functionDeployment] = 0; if (queueLength > 0 || numberProcessingTasks > 0) { From 3b6a752846637f7f2990ead475d9109f846adf96 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 20 Nov 2024 11:48:16 +0100 Subject: [PATCH 066/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/SlimDataInterpreter.cs | 4 ++++ src/SlimFaas/Database/SlimDataService.cs | 8 ++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index a14347da..ef4fbc14 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-773 + image: axaguildev/slimfaas:pr-77-774 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 3eeed60d..17612467 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -103,6 +103,10 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo Console.WriteLine("ListSetQueueItemStatusAsync"); if (!queues.TryGetValue(addHashSetCommand.Key, out List? value)) return default; Console.WriteLine("ListSetQueueItemStatusAsync 2"); + foreach (var element in value) + { + Console.WriteLine("ListSetQueueItemStatusAsync 2 " + element.Id + "==" + addHashSetCommand.Identifier); + } var queueElement = value.FirstOrDefault(x => x.Id == addHashSetCommand.Identifier); if (queueElement == null) { diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 4438391d..7be607f0 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -173,6 +173,14 @@ public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueIt private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) { + if(queueItemStatus.Items != null) + { + foreach (var listQueueItemStatus in queueItemStatus.Items) + { + Console.WriteLine($"DoListSetQueueItemStatus: Id: {listQueueItemStatus.Id}"); + } + } + EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) { From adba751389167eef9dc32c4ed2965a6516928dbe Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 21 Nov 2024 14:37:04 +0100 Subject: [PATCH 067/135] update --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Endpoints.cs | 1 + src/SlimFaas/Database/SlimDataService.cs | 8 ++++++++ src/SlimFaas/SlimWorker.cs | 12 ++++++++---- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index ef4fbc14..921184be 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-774 + image: axaguildev/slimfaas:pr-77-775 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 24c0d8d2..2889c926 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -219,6 +219,7 @@ public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provi foreach (var queueItemStatus in list.Items) { + Console.WriteLine("Endpoint ListSetQueueItemStatusCommand " + queueItemStatus.Id + " " + queueItemStatus.HttpCode); var logEntry = provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand { diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 7be607f0..5172f5d7 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -162,6 +162,14 @@ private async Task DoListLeftPushAsync(string key, byte[] field) var bin = await response.Content.ReadAsByteArrayAsync(); ListItems? result = MemoryPackSerializer.Deserialize(bin); + if(result != null && result.Items != null) + { + foreach (var listItem in result.Items) + { + Console.WriteLine($"DoListRightPopAsync: Id: {listItem.Id}"); + } + } + return result?.Items ?? new List(); } } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 7c036f75..757d30f1 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -5,7 +5,7 @@ namespace SlimFaas; -internal record struct RequestToWait(Task Task, CustomRequest CustomRequest, string id); +internal record struct RequestToWait(Task Task, CustomRequest CustomRequest, string Id); public class SlimWorker(ISlimFaasQueue slimFaasQueue, IReplicasService replicasService, HistoryHttpMemoryService historyHttpService, ILogger logger, IServiceProvider serviceProvider, @@ -87,6 +87,7 @@ private async Task SendHttpRequestToFunction(Dictionary(requestJson.Data); logger.LogDebug("{CustomRequestMethod}: {CustomRequestPath}{CustomRequestQuery} Sending", @@ -136,7 +137,8 @@ private async Task UpdateTickLastCallIfRequestStillInProgress(int? functio return numberLimitProcessingTasks; } - private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, Dictionary> processingTasks, + private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, + Dictionary> processingTasks, string functionDeployment) { if (processingTasks.ContainsKey(functionDeployment) == false) @@ -166,11 +168,13 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, processing.CustomRequest.Method, processing.CustomRequest.Path, processing.CustomRequest.Query, httpResponseMessage.StatusCode); httpResponseMessagesToDelete.Add(processing); - queueItemStatusList.Add(new QueueItemStatus(processing.id, statusCode)); + Console.WriteLine("RequestToWait: " + processing.Id); + queueItemStatusList.Add(new QueueItemStatus(processing.Id, statusCode)); } catch (Exception e) { - queueItemStatusList.Add(new QueueItemStatus(processing.id, 500)); + Console.WriteLine("RequestToWait ERROR: " + processing.Id); + queueItemStatusList.Add(new QueueItemStatus(processing.Id, 500)); httpResponseMessagesToDelete.Add(processing); logger.LogWarning("Request Error: {Message} {StackTrace}", e.Message, e.StackTrace); historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); From 4c4cf1de54b2dba2b496901e31193a24bb7ad53a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 21 Nov 2024 18:26:03 +0100 Subject: [PATCH 068/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Commands/ListLeftPushCommand.cs | 6 ++++++ src/SlimData/Commands/LogSnapshotCommand.cs | 3 ++- src/SlimData/Endpoints.cs | 3 ++- src/SlimData/SlimDataInterpreter.cs | 11 ++++++----- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 921184be..10e36b0f 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-775 + image: axaguildev/slimfaas:pr-77-776 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Commands/ListLeftPushCommand.cs b/src/SlimData/Commands/ListLeftPushCommand.cs index 934bbf5b..ce82df76 100644 --- a/src/SlimData/Commands/ListLeftPushCommand.cs +++ b/src/SlimData/Commands/ListLeftPushCommand.cs @@ -11,6 +11,8 @@ public struct ListLeftPushCommand : ISerializable public string Key { get; set; } + public string Identifier { get; set; } + public ReadOnlyMemory Value { get; set; } long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + Value.Length; @@ -21,6 +23,8 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t var command = this; await writer.EncodeAsync(command.Key.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); + await writer.EncodeAsync(command.Identifier.AsMemory(), new EncodingContext(Encoding.UTF8, false), + LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteAsync(command.Value, LengthFormat.Compressed, token).ConfigureAwait(false); } @@ -30,10 +34,12 @@ public static async ValueTask ReadFromAsync(TReade where TReader : notnull, IAsyncBinaryReader { var key = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); + var identifier = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); using var value = await reader.ReadAsync(LengthFormat.Compressed, token: token).ConfigureAwait(false); return new ListLeftPushCommand { Key = key.ToString(), + Identifier = identifier.ToString(), Value = value.Memory.ToArray() }; } diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index 6f2fb701..78e50ac5 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -146,7 +146,8 @@ public static async ValueTask ReadFromAsync(TReader var httpCode = await reader.ReadLittleEndianAsync(token); retryQueueElements.Add(new QueueHttpTryElement(startTimestamp, endTimestamp, httpCode)); } - + + Console.WriteLine("SnapshotCommand QueueElement Id " + id); queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, retryQueueElements)); } diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 2889c926..3e502b61 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -142,6 +142,7 @@ public static async Task ListRightPopCommand(SlimPersistentState prov var queueElements = queue.GetQueueAvailableElement([2, 4, 10], nowTicks, count); foreach (var queueElement in queueElements) { + Console.WriteLine("Endpoint ListRightPopCommand " + queueElement.Id); values.Items.Add(new QueueData(queueElement.Id ,queueElement.Value.ToArray())); } @@ -184,7 +185,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin IRaftCluster cluster, CancellationTokenSource source) { var logEntry = - provider.Interpreter.CreateLogEntry(new ListLeftPushCommand { Key = key, Value = value }, + provider.Interpreter.CreateLogEntry(new ListLeftPushCommand { Key = key, Identifier = Guid.NewGuid().ToString(), Value = value }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); } diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 17612467..f4808e08 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -82,13 +82,14 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel return DoListLeftPushAsync(addHashSetCommand, SlimDataState.Queues); } - internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Dictionary> queues) + internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCommand, Dictionary> queues) { - if (queues.TryGetValue(addHashSetCommand.Key, out List? value)) - value.Add(new QueueElement(addHashSetCommand.Value, Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())); + if (queues.TryGetValue(listLeftPushCommand.Key, out List? value)) + value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, DateTime.UtcNow.Ticks,new List())); else - queues.Add(addHashSetCommand.Key, new List() {new(addHashSetCommand.Value,Guid.NewGuid().ToString(), DateTime.UtcNow.Ticks,new List())}); - Console.WriteLine("ListLeftPushAsync count " + queues[addHashSetCommand.Key].Count); + queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, DateTime.UtcNow.Ticks,new List())}); + Console.WriteLine("ListLeftPushAsync count " + queues[listLeftPushCommand.Key].Count); + Console.WriteLine("ListLeftPushAsync Last element ID " + queues[listLeftPushCommand.Key][^1].Id); return default; } From a37e2074581fa3c59ff1be84545c609a5423524f Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 21 Nov 2024 20:28:01 +0100 Subject: [PATCH 069/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Endpoints.cs | 2 +- src/SlimData/SlimDataInterpreter.cs | 29 ++++++++---------------- src/SlimFaas/Database/SlimDataService.cs | 19 ---------------- src/SlimFaas/SlimWorker.cs | 8 ++----- 5 files changed, 13 insertions(+), 47 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 10e36b0f..121d34de 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-776 + image: axaguildev/slimfaas:pr-77-777 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 3e502b61..0e614bef 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -220,7 +220,7 @@ public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provi foreach (var queueItemStatus in list.Items) { - Console.WriteLine("Endpoint ListSetQueueItemStatusCommand " + queueItemStatus.Id + " " + queueItemStatus.HttpCode); + var logEntry = provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand { diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index f4808e08..b545a43a 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -52,13 +52,12 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm var queueTimeoutElements = queue.GetQueueTimeoutElement(nowTicks, RetryTimeout); foreach (var queueTimeoutElement in queueTimeoutElements) { - Console.WriteLine("ListRightPopAsync timeout " + queueTimeoutElement.Id + " " + addHashSetCommand.Key); var retryQueueElement = queueTimeoutElement.RetryQueueElements[^1]; retryQueueElement.EndTimeStamp = nowTicks; retryQueueElement.HttpCode = 504; } - var queueFinishedElements = queue.GetQueueFinishedElement( nowTicks, Retries, RetryTimeout); + var queueFinishedElements = queue.GetQueueFinishedElement(nowTicks, Retries, RetryTimeout); foreach (var queueFinishedElement in queueFinishedElements) { queue.Remove(queueFinishedElement); @@ -69,8 +68,6 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm { queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); } - - Console.WriteLine("ListRightPopAsync count " + queues[addHashSetCommand.Key].Count + " " + addHashSetCommand.Key); } return default; @@ -88,8 +85,6 @@ internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCo value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, DateTime.UtcNow.Ticks,new List())); else queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, DateTime.UtcNow.Ticks,new List())}); - Console.WriteLine("ListLeftPushAsync count " + queues[listLeftPushCommand.Key].Count); - Console.WriteLine("ListLeftPushAsync Last element ID " + queues[listLeftPushCommand.Key][^1].Id); return default; } @@ -99,33 +94,27 @@ public ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHa return DoListSetQueueItemStatusAsync(addHashSetCommand, SlimDataState.Queues); } - internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHashSetCommand, Dictionary> queues) + internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand liaddHashSetCommand, Dictionary> queues) { - Console.WriteLine("ListSetQueueItemStatusAsync"); - if (!queues.TryGetValue(addHashSetCommand.Key, out List? value)) return default; - Console.WriteLine("ListSetQueueItemStatusAsync 2"); - foreach (var element in value) - { - Console.WriteLine("ListSetQueueItemStatusAsync 2 " + element.Id + "==" + addHashSetCommand.Identifier); - } - var queueElement = value.FirstOrDefault(x => x.Id == addHashSetCommand.Identifier); + if (!queues.TryGetValue(liaddHashSetCommand.Key, out List? value)) return default; + + var queueElement = value.FirstOrDefault(x => x.Id == liaddHashSetCommand.Identifier); if (queueElement == null) { return default; } - - Console.WriteLine("ListSetQueueItemStatusAsync 3"); + Console.WriteLine("ListSetQueueItemStatusAsync " + liaddHashSetCommand.Identifier + " " + liaddHashSetCommand.HttpCode); var retryQueueElement = queueElement.RetryQueueElements[^1]; retryQueueElement.EndTimeStamp = DateTime.UtcNow.Ticks; - retryQueueElement.HttpCode = addHashSetCommand.HttpCode; + retryQueueElement.HttpCode = liaddHashSetCommand.HttpCode; if (queueElement.IsFinished(DateTime.UtcNow.Ticks, Retries, RetryTimeout)) { - Console.WriteLine("ListSetQueueItemStatusAsync 4 finished"); + Console.WriteLine("ListSetQueueItemStatusAsync finished" + queueElement.Id); value.Remove(queueElement); } - Console.WriteLine("DoListSetQueueItemStatusAsync count " + queues[addHashSetCommand.Key].Count); + Console.WriteLine("ListSetQueueItemStatusAsyncs count " + queues[liaddHashSetCommand.Key].Count); return default; } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 5172f5d7..24067581 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -181,14 +181,6 @@ public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueIt private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) { - if(queueItemStatus.Items != null) - { - foreach (var listQueueItemStatus in queueItemStatus.Items) - { - Console.WriteLine($"DoListSetQueueItemStatus: Id: {listQueueItemStatus.Id}"); - } - } - EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) { @@ -224,18 +216,7 @@ private async Task DoListLengthAsync(string key) if (data.Queues.TryGetValue(key, out List? value)) { var elements = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, int.MaxValue); - - foreach (QueueElement queueElement in elements) - { - Console.WriteLine($"DoListLengthAsync: Element Id: {queueElement.Id}"); - foreach (QueueHttpTryElement queueElementRetryQueueElement in queueElement.RetryQueueElements) - { - Console.WriteLine($"DoListLengthAsync StartTimeStamp: {queueElementRetryQueueElement.StartTimeStamp} EndTimeStamp: {queueElementRetryQueueElement.EndTimeStamp} HttpCode: {queueElementRetryQueueElement.HttpCode} "); - } - } - var number = elements.Count; - Console.WriteLine($"DoListLengthAsync: Number of available elements: {number} for key: {key}"); return number; } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 757d30f1..ba29a091 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -87,7 +87,6 @@ private async Task SendHttpRequestToFunction(Dictionary(requestJson.Data); logger.LogDebug("{CustomRequestMethod}: {CustomRequestPath}{CustomRequestQuery} Sending", @@ -104,7 +103,7 @@ private async Task SendHttpRequestToFunction(Dictionary UpdateTickLastCallIfRequestStillInProgress(int? functionReplicas, Dictionary setTickLastCallCounterDictionnary, string functionDeployment, int numberProcessingTasks) { - int counterLimit = functionReplicas == 0 ? 10 : 100; + int counterLimit = functionReplicas == 0 ? 10 : 40; long queueLength = await slimFaasQueue.CountAsync(functionDeployment); if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) { @@ -161,19 +160,16 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, HttpResponseMessage httpResponseMessage = processing.Task.Result; var statusCode = (int)httpResponseMessage.StatusCode; - - httpResponseMessage.Dispose(); logger.LogDebug( "{CustomRequestMethod}: /async-function/{CustomRequestPath}{CustomRequestQuery} {StatusCode}", processing.CustomRequest.Method, processing.CustomRequest.Path, processing.CustomRequest.Query, httpResponseMessage.StatusCode); httpResponseMessagesToDelete.Add(processing); - Console.WriteLine("RequestToWait: " + processing.Id); queueItemStatusList.Add(new QueueItemStatus(processing.Id, statusCode)); + httpResponseMessage.Dispose(); } catch (Exception e) { - Console.WriteLine("RequestToWait ERROR: " + processing.Id); queueItemStatusList.Add(new QueueItemStatus(processing.Id, 500)); httpResponseMessagesToDelete.Add(processing); logger.LogWarning("Request Error: {Message} {StackTrace}", e.Message, e.StackTrace); From 559fa07786fa32e4eb5b1c30372447116f980726 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 21 Nov 2024 21:05:08 +0100 Subject: [PATCH 070/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/QueueElementExtensions.cs | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 121d34de..3e481d1e 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-777 + image: axaguildev/slimfaas:pr-77-778 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 01a99d4a..2c9ac913 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -131,6 +131,9 @@ public static List GetQueueAvailableElement(this List= maximum) { + Console.WriteLine("runningWaitingForRetryElements.Count " + runningWaitingForRetryElements.Count); + Console.WriteLine("runningElements.Count " + runningElements.Count); + Console.WriteLine("GetQueueAvailableElement: currentCount >= maximum " + currentCount + " " + maximum); return availableElements; } var currentElements = elements.Except(runningElements).Except(runningWaitingForRetryElements).Except(finishedElements); From 711163d521003cac29e08c1b8b7925719e0d710a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 22 Nov 2024 22:32:22 +0100 Subject: [PATCH 071/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Commands/ListLeftPushCommand.cs | 4 ++++ src/SlimData/Commands/ListSetQueueItemStatusCommand.cs | 7 ++++++- src/SlimData/Endpoints.cs | 5 +++-- src/SlimData/SlimDataInterpreter.cs | 8 ++++---- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 3e481d1e..c1633171 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-778 + image: axaguildev/slimfaas:pr-77-779 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Commands/ListLeftPushCommand.cs b/src/SlimData/Commands/ListLeftPushCommand.cs index ce82df76..1379d3e9 100644 --- a/src/SlimData/Commands/ListLeftPushCommand.cs +++ b/src/SlimData/Commands/ListLeftPushCommand.cs @@ -12,6 +12,7 @@ public struct ListLeftPushCommand : ISerializable public string Key { get; set; } public string Identifier { get; set; } + public long NowTicks { get; set; } public ReadOnlyMemory Value { get; set; } @@ -25,6 +26,7 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.EncodeAsync(command.Identifier.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(NowTicks, token).ConfigureAwait(false); await writer.WriteAsync(command.Value, LengthFormat.Compressed, token).ConfigureAwait(false); } @@ -35,11 +37,13 @@ public static async ValueTask ReadFromAsync(TReade { var key = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); var identifier = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); + var nowTicks = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false); using var value = await reader.ReadAsync(LengthFormat.Compressed, token: token).ConfigureAwait(false); return new ListLeftPushCommand { Key = key.ToString(), Identifier = identifier.ToString(), + NowTicks = nowTicks, Value = value.Memory.ToArray() }; } diff --git a/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs b/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs index b3732b38..f74cd9df 100644 --- a/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs +++ b/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs @@ -13,6 +13,8 @@ public struct ListSetQueueItemStatusCommand : ISerializable(TWriter writer, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter { @@ -22,6 +24,7 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.EncodeAsync(command.Key.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(HttpCode, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(NowTicks, token).ConfigureAwait(false); } long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Identifier) + sizeof(int); @@ -30,11 +33,13 @@ public static async ValueTask ReadFromAsync(token).ConfigureAwait(false) + HttpCode = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false), + NowTicks = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false) }; } } \ No newline at end of file diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 0e614bef..27265176 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -185,7 +185,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin IRaftCluster cluster, CancellationTokenSource source) { var logEntry = - provider.Interpreter.CreateLogEntry(new ListLeftPushCommand { Key = key, Identifier = Guid.NewGuid().ToString(), Value = value }, + provider.Interpreter.CreateLogEntry(new ListLeftPushCommand { Key = key, Identifier = Guid.NewGuid().ToString(), Value = value, NowTicks = DateTime.UtcNow.Ticks }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); } @@ -226,7 +226,8 @@ public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provi { Identifier = queueItemStatus.Id, Key = key, - HttpCode = queueItemStatus.HttpCode + HttpCode = queueItemStatus.HttpCode, + NowTicks = DateTime.UtcNow.Ticks }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index b545a43a..a27f1a0c 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -82,9 +82,9 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCommand, Dictionary> queues) { if (queues.TryGetValue(listLeftPushCommand.Key, out List? value)) - value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, DateTime.UtcNow.Ticks,new List())); + value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks,new List())); else - queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, DateTime.UtcNow.Ticks,new List())}); + queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks,new List())}); return default; } @@ -105,10 +105,10 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo } Console.WriteLine("ListSetQueueItemStatusAsync " + liaddHashSetCommand.Identifier + " " + liaddHashSetCommand.HttpCode); var retryQueueElement = queueElement.RetryQueueElements[^1]; - retryQueueElement.EndTimeStamp = DateTime.UtcNow.Ticks; + retryQueueElement.EndTimeStamp = liaddHashSetCommand.NowTicks; retryQueueElement.HttpCode = liaddHashSetCommand.HttpCode; - if (queueElement.IsFinished(DateTime.UtcNow.Ticks, Retries, RetryTimeout)) + if (queueElement.IsFinished(liaddHashSetCommand.NowTicks, Retries, RetryTimeout)) { Console.WriteLine("ListSetQueueItemStatusAsync finished" + queueElement.Id); value.Remove(queueElement); From 5695601ea8b981c707da28b2087bebca6e0d83d1 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 23 Nov 2024 10:28:11 +0100 Subject: [PATCH 072/135] fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/QueueElementExtensions.cs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index c1633171..36e1c2ed 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-779 + image: axaguildev/slimfaas:pr-77-780 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 2c9ac913..184621c0 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -129,10 +129,11 @@ public static List GetQueueAvailableElement(this List(); var currentCount = runningElements.Count + runningWaitingForRetryElements.Count; + Console.WriteLine("GetQueueAvailableElement runningWaitingForRetryElements.Count " + runningWaitingForRetryElements.Count); + Console.WriteLine("GetQueueAvailableElement runningElements.Count " + runningElements.Count); + Console.WriteLine("GetQueueAvailableElement finishedElements.Count " + finishedElements.Count); if (currentCount >= maximum) { - Console.WriteLine("runningWaitingForRetryElements.Count " + runningWaitingForRetryElements.Count); - Console.WriteLine("runningElements.Count " + runningElements.Count); Console.WriteLine("GetQueueAvailableElement: currentCount >= maximum " + currentCount + " " + maximum); return availableElements; } @@ -141,11 +142,13 @@ public static List GetQueueAvailableElement(this List Date: Sat, 23 Nov 2024 11:36:17 +0100 Subject: [PATCH 073/135] ddd --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/QueueElementExtensions.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 36e1c2ed..4af79d26 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-780 + image: axaguildev/slimfaas:pr-77-781 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 184621c0..5f46ca08 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -138,6 +138,7 @@ public static List GetQueueAvailableElement(this List Date: Sat, 23 Nov 2024 15:22:41 +0100 Subject: [PATCH 074/135] sss --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/QueueElementExtensions.cs | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 4af79d26..93b825f1 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-781 + image: axaguildev/slimfaas:pr-77-782 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 5f46ca08..e3443cba 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -131,14 +131,16 @@ public static List GetQueueAvailableElement(this List= maximum) { - Console.WriteLine("GetQueueAvailableElement: currentCount >= maximum " + currentCount + " " + maximum); + Console.WriteLine("GetQueueAvailableElement ---availableElements.Count " + availableElements.Count); return availableElements; } - var currentElements = elements.Except(runningElements).Except(runningWaitingForRetryElements).Except(finishedElements); - Console.WriteLine("GetQueueAvailableElement ------currentElements.Count " + currentElements.ToArray().Count()); + foreach (var queueElement in currentElements) { if (currentCount == maximum) From 6fe25737b1a2b8f07611ec9e7d357ba0d16763ab Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 23 Nov 2024 15:38:50 +0100 Subject: [PATCH 075/135] sssssss --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Commands/LogSnapshotCommand.cs | 15 +++++++++++++- src/SlimData/SlimDataInterpreter.cs | 23 ++++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 93b825f1..acca8dad 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-782 + image: axaguildev/slimfaas:pr-77-783 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index 78e50ac5..2e61c838 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -147,8 +147,21 @@ public static async ValueTask ReadFromAsync(TReader retryQueueElements.Add(new QueueHttpTryElement(startTimestamp, endTimestamp, httpCode)); } - Console.WriteLine("SnapshotCommand QueueElement Id " + id); + Console.WriteLine("SnapshotCommand QueueElement Id " + id + "key " + key); queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, retryQueueElements)); + // Print all data from queue + foreach (var queueElement in queue) + { + Console.WriteLine("SnapshotCommand QueueElement Id " + queueElement.Id); + Console.WriteLine("SnapshotCommand QueueElement Value " + queueElement.Value); + Console.WriteLine("SnapshotCommand QueueElement InsertTimeStamp " + queueElement.InsertTimeStamp); + foreach (var retryQueueElement in queueElement.RetryQueueElements) + { + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement StartTimeStamp " + retryQueueElement.StartTimeStamp); + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement EndTimeStamp " + retryQueueElement.EndTimeStamp); + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement HttpCode " + retryQueueElement.HttpCode); + } + } } queues.Add(key.ToString(), queue); diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index a27f1a0c..efe1a7b5 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -156,7 +156,28 @@ internal static ValueTask DoHandleSnapshotAsync(LogSnapshotCommand command, Dict { keyValues[keyValue.Key] = keyValue.Value; } - + // Print all data from queues + // Print all data from queue + foreach (var queueElement in command.queues) + { + foreach (var queue in queues) + { + Console.WriteLine("SnapshotCommand Queue Key " + queue.Key); + foreach (var element in queue.Value) + { + Console.WriteLine("SnapshotCommand QueueElement Id " + element.Id); + Console.WriteLine("SnapshotCommand QueueElement Value " + element.Value); + Console.WriteLine("SnapshotCommand QueueElement InsertTimeStamp " + element.InsertTimeStamp); + foreach (var retryQueueElement in element.RetryQueueElements) + { + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement StartTimeStamp " + retryQueueElement.StartTimeStamp); + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement EndTimeStamp " + retryQueueElement.EndTimeStamp); + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement HttpCode " + retryQueueElement.HttpCode); + } + } + } + } + queues.Clear(); foreach (var queue in command.queues) { From 92371ddd04633a6cad05e136984bb746a1e7bb27 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sun, 24 Nov 2024 21:45:21 +0100 Subject: [PATCH 076/135] fox --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Commands/LogSnapshotCommand.cs | 16 +--- src/SlimData/QueueElementExtensions.cs | 7 -- src/SlimData/SlimDataInterpreter.cs | 82 +++++++++++++------ .../QueueElementExtentionsTests.cs | 28 +++++++ tests/SlimData.Tests/RaftClusterTests.cs | 19 +++++ 6 files changed, 107 insertions(+), 47 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index acca8dad..b608e958 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-783 + image: axaguildev/slimfaas:pr-77-784 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index 2e61c838..6f2fb701 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -146,22 +146,8 @@ public static async ValueTask ReadFromAsync(TReader var httpCode = await reader.ReadLittleEndianAsync(token); retryQueueElements.Add(new QueueHttpTryElement(startTimestamp, endTimestamp, httpCode)); } - - Console.WriteLine("SnapshotCommand QueueElement Id " + id + "key " + key); + queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, retryQueueElements)); - // Print all data from queue - foreach (var queueElement in queue) - { - Console.WriteLine("SnapshotCommand QueueElement Id " + queueElement.Id); - Console.WriteLine("SnapshotCommand QueueElement Value " + queueElement.Value); - Console.WriteLine("SnapshotCommand QueueElement InsertTimeStamp " + queueElement.InsertTimeStamp); - foreach (var retryQueueElement in queueElement.RetryQueueElements) - { - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement StartTimeStamp " + retryQueueElement.StartTimeStamp); - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement EndTimeStamp " + retryQueueElement.EndTimeStamp); - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement HttpCode " + retryQueueElement.HttpCode); - } - } } queues.Add(key.ToString(), queue); diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index e3443cba..9da9a819 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -129,15 +129,10 @@ public static List GetQueueAvailableElement(this List(); var currentCount = runningElements.Count + runningWaitingForRetryElements.Count; - Console.WriteLine("GetQueueAvailableElement runningWaitingForRetryElements.Count " + runningWaitingForRetryElements.Count); - Console.WriteLine("GetQueueAvailableElement runningElements.Count " + runningElements.Count); - Console.WriteLine("GetQueueAvailableElement finishedElements.Count " + finishedElements.Count); var currentElements = elements.Except(runningElements).Except(runningWaitingForRetryElements).Except(finishedElements); - Console.WriteLine("GetQueueAvailableElement currentElements.Count " + currentElements.ToArray().Count()); if (currentCount >= maximum) { - Console.WriteLine("GetQueueAvailableElement ---availableElements.Count " + availableElements.Count); return availableElements; } @@ -145,13 +140,11 @@ public static List GetQueueAvailableElement(this List())); else queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks,new List())}); + // print all queue elements + foreach (var queueElemen in value) + { + Console.WriteLine("DoListLeftPushAsync QueueElement Id " + queueElemen.Id); + Console.WriteLine("DoListLeftPushAsync QueueElement Value " + queueElemen.Value); + Console.WriteLine("DoListLeftPushAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); + foreach (var retryQueueElemen in queueElemen.RetryQueueElements) + { + Console.WriteLine("DoListLeftPushAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); + Console.WriteLine("DoListLeftPushAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); + Console.WriteLine("DoListLeftPushAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); + } + } return default; } @@ -94,27 +121,37 @@ public ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHa return DoListSetQueueItemStatusAsync(addHashSetCommand, SlimDataState.Queues); } - internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand liaddHashSetCommand, Dictionary> queues) + internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand listSetQueueItemStatusCommand, Dictionary> queues) { - if (!queues.TryGetValue(liaddHashSetCommand.Key, out List? value)) return default; + if (!queues.TryGetValue(listSetQueueItemStatusCommand.Key, out List? value)) return default; - var queueElement = value.FirstOrDefault(x => x.Id == liaddHashSetCommand.Identifier); + var queueElement = value.FirstOrDefault(x => x.Id == listSetQueueItemStatusCommand.Identifier); if (queueElement == null) { return default; } - Console.WriteLine("ListSetQueueItemStatusAsync " + liaddHashSetCommand.Identifier + " " + liaddHashSetCommand.HttpCode); var retryQueueElement = queueElement.RetryQueueElements[^1]; - retryQueueElement.EndTimeStamp = liaddHashSetCommand.NowTicks; - retryQueueElement.HttpCode = liaddHashSetCommand.HttpCode; + retryQueueElement.EndTimeStamp = listSetQueueItemStatusCommand.NowTicks; + retryQueueElement.HttpCode = listSetQueueItemStatusCommand.HttpCode; - if (queueElement.IsFinished(liaddHashSetCommand.NowTicks, Retries, RetryTimeout)) + if (queueElement.IsFinished(listSetQueueItemStatusCommand.NowTicks, Retries, RetryTimeout)) { - Console.WriteLine("ListSetQueueItemStatusAsync finished" + queueElement.Id); value.Remove(queueElement); } - - Console.WriteLine("ListSetQueueItemStatusAsyncs count " + queues[liaddHashSetCommand.Key].Count); + Console.WriteLine("DoListSetQueueItemStatusAsync QueueKey " + listSetQueueItemStatusCommand.Key); + // print all queue elements + foreach (var queueElemen in value) + { + Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement Id " + queueElemen.Id); + Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement Value " + queueElemen.Value); + Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); + foreach (var retryQueueElemen in queueElemen.RetryQueueElements) + { + Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); + Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); + Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); + } + } return default; } @@ -157,26 +194,23 @@ internal static ValueTask DoHandleSnapshotAsync(LogSnapshotCommand command, Dict keyValues[keyValue.Key] = keyValue.Value; } // Print all data from queues - // Print all data from queue - foreach (var queueElement in command.queues) + foreach (var queue in command.queues) { - foreach (var queue in queues) + Console.WriteLine("SnapshotCommand Queue Key " + queue.Key); + foreach (var element in queue.Value) { - Console.WriteLine("SnapshotCommand Queue Key " + queue.Key); - foreach (var element in queue.Value) + Console.WriteLine("SnapshotCommand QueueElement Id " + element.Id); + Console.WriteLine("SnapshotCommand QueueElement Value " + element.Value); + Console.WriteLine("SnapshotCommand QueueElement InsertTimeStamp " + element.InsertTimeStamp); + foreach (var retryQueueElement in element.RetryQueueElements) { - Console.WriteLine("SnapshotCommand QueueElement Id " + element.Id); - Console.WriteLine("SnapshotCommand QueueElement Value " + element.Value); - Console.WriteLine("SnapshotCommand QueueElement InsertTimeStamp " + element.InsertTimeStamp); - foreach (var retryQueueElement in element.RetryQueueElements) - { - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement StartTimeStamp " + retryQueueElement.StartTimeStamp); - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement EndTimeStamp " + retryQueueElement.EndTimeStamp); - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement HttpCode " + retryQueueElement.HttpCode); - } + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement StartTimeStamp " + retryQueueElement.StartTimeStamp); + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement EndTimeStamp " + retryQueueElement.EndTimeStamp); + Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement HttpCode " + retryQueueElement.HttpCode); } } } + queues.Clear(); foreach (var queue in command.queues) diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index cb8aba26..6254e7d4 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -56,6 +56,34 @@ public static void QueueElementExtensionsGetQueueRunningElement() Assert.Equal("1", runningElements[0].Id); + var finishedElements = queueElements.GetQueueFinishedElement(nowTicks, SlimDataInterpreter.Retries); + Assert.Equal(4, finishedElements.Count); + } + + [Fact] + public static void QueueElementExtensionsGetQueueRunningElement2() + { + // I want a test which text my extention + var nowTicks = DateTime.UtcNow.Ticks; + List queueElements = new(); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", nowTicks, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", nowTicks, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", nowTicks, new List())); + + var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.Retries, nowTicks, 1, 30); + + foreach (QueueElement queueElement in queueElements) + { + Assert.Equal(2, availableElements.Count); + Assert.Equal("2", availableElements[0].Id); + Assert.Equal("3", availableElements[1].Id); + } + + var runningElements = queueElements.GetQueueRunningElement(nowTicks); + Assert.Equal(1, runningElements.Count); + Assert.Equal("1", runningElements[0].Id); + + var finishedElements = queueElements.GetQueueFinishedElement(nowTicks, SlimDataInterpreter.Retries); Assert.Equal(4, finishedElements.Count); } diff --git a/tests/SlimData.Tests/RaftClusterTests.cs b/tests/SlimData.Tests/RaftClusterTests.cs index ee24cb78..4e8fe495 100644 --- a/tests/SlimData.Tests/RaftClusterTests.cs +++ b/tests/SlimData.Tests/RaftClusterTests.cs @@ -257,6 +257,25 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", IList? listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); Assert.Equal("value1", MemoryPackSerializer.Deserialize(listRightPop.First().Data)); + ListQueueItemStatus queueItemStatus = new() + { + Items = new List { }, + }; + foreach (QueueData queueData in listRightPop) + { + queueItemStatus.Items.Add(new QueueItemStatus + { + Id = queueData.Id, + HttpCode = 200, + }); + } + await databaseServiceSlave.ListSetQueueItemStatus("listKey1", queueItemStatus); + + await GetLocalClusterView(host1).ForceReplicationAsync(); + var listLength2 = await databaseServiceSlave.ListLengthAsync("listKey1"); + + Assert.Equal(0, listLength2); + await host1.StopAsync(); await host2.StopAsync(); await host3.StopAsync(); From 8149515db9d100f82795bdad1fd3a6c055ca476e Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 25 Nov 2024 10:31:53 +0100 Subject: [PATCH 077/135] fix --- src/SlimData/SlimDataInterpreter.cs | 3 ++- tests/SlimData.Tests/QueueElementExtentionsTests.cs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 71156418..e07931d8 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -100,7 +100,8 @@ internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCo else queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks,new List())}); // print all queue elements - foreach (var queueElemen in value) + var elements = queues[listLeftPushCommand.Key]; + foreach (var queueElemen in elements) { Console.WriteLine("DoListLeftPushAsync QueueElement Id " + queueElemen.Id); Console.WriteLine("DoListLeftPushAsync QueueElement Value " + queueElemen.Value); diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 6254e7d4..02d456ad 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -60,7 +60,7 @@ public static void QueueElementExtensionsGetQueueRunningElement() Assert.Equal(4, finishedElements.Count); } - [Fact] + /* [Fact] public static void QueueElementExtensionsGetQueueRunningElement2() { // I want a test which text my extention @@ -86,5 +86,5 @@ public static void QueueElementExtensionsGetQueueRunningElement2() var finishedElements = queueElements.GetQueueFinishedElement(nowTicks, SlimDataInterpreter.Retries); Assert.Equal(4, finishedElements.Count); - } + }*/ } From d7ed680908f2d724abe7d5ecc9e6192977174105 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 26 Nov 2024 07:07:51 +0100 Subject: [PATCH 078/135] optimzation du be able to read logs --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Database/DatabaseMockService.cs | 2 +- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 8 +-- src/SlimFaas/Database/SlimFaasQueue.cs | 2 +- src/SlimFaas/SlimWorker.cs | 55 ++++++++++++------- .../SlimProxyMiddlewareTests.cs | 2 +- tests/SlimFaas.Tests/SlimWorkerShould.cs | 13 ++++- 9 files changed, 57 insertions(+), 31 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index b608e958..161fb49b 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-784 + image: axaguildev/slimfaas:pr-77-786 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index 95f3db2c..8c50b5f3 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -93,7 +93,7 @@ public Task ListLeftPushAsync(string key, byte[] field) return Task.FromResult?>(new List()); } - public Task ListLengthAsync(string key) + public Task ListLengthAsync(string key, int maximum = int.MaxValue) { if (!queue.ContainsKey(key)) { diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index 9f1dace7..b335c566 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -10,6 +10,6 @@ public interface IDatabaseService Task> HashGetAllAsync(string key); Task ListLeftPushAsync(string key, byte[] field); Task?> ListRightPopAsync(string key, int count = 1); - Task ListLengthAsync(string key); + Task ListLengthAsync(string key, int maximum = int.MaxValue); Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index a8078806..3e6ea7ae 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -7,5 +7,5 @@ public interface ISlimFaasQueue Task EnqueueAsync(string key, byte[] message); Task?> DequeueAsync(string key, long count = 1); Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus); - public Task CountAsync(string key); + public Task CountAsync(string key, int maximum = int.MaxValue); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 24067581..b083b142 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -201,12 +201,12 @@ private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queu } } - public async Task ListLengthAsync(string key) + public async Task ListLengthAsync(string key, int maximum) { - return await Retry.Do(() => DoListLengthAsync(key), _retryInterval, logger, MaxAttemptCount); + return await Retry.Do(() => DoListLengthAsync(key, maximum), _retryInterval, logger, MaxAttemptCount); } - private async Task DoListLengthAsync(string key) + private async Task DoListLengthAsync(string key, int maximum) { await GetAndWaitForLeader(); await MasterWaitForleaseToken(); @@ -215,7 +215,7 @@ private async Task DoListLengthAsync(string key) if (data.Queues.TryGetValue(key, out List? value)) { - var elements = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, int.MaxValue); + var elements = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, maximum); var number = elements.Count; return number; } diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index 99c96316..83f083a0 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -19,5 +19,5 @@ public async Task EnqueueAsync(string key, byte[] data) => public async Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); - public async Task CountAsync(string key) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}"); + public async Task CountAsync(string key, int maximum = int.MaxValue) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}", maximum); } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index ba29a091..6e400a14 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -8,8 +8,10 @@ namespace SlimFaas; internal record struct RequestToWait(Task Task, CustomRequest CustomRequest, string Id); public class SlimWorker(ISlimFaasQueue slimFaasQueue, IReplicasService replicasService, - HistoryHttpMemoryService historyHttpService, ILogger logger, IServiceProvider serviceProvider, + HistoryHttpMemoryService historyHttpService, ILogger logger, + IServiceProvider serviceProvider, ISlimDataStatus slimDataStatus, + IMasterService masterService, int delay = EnvironmentVariables.SlimWorkerDelayMillisecondsDefault) : BackgroundService { @@ -42,12 +44,17 @@ private async Task DoOneCycle(CancellationToken stoppingToken, string functionDeployment = function.Deployment; setTickLastCallCounterDictionary.TryAdd(functionDeployment, 0); int numberProcessingTasks = await ManageProcessingTasksAsync(slimFaasQueue, processingTasks, functionDeployment); - int? numberLimitProcessingTasks = ComputeNumberLimitProcessingTasks(slimFaas, function); + int numberLimitProcessingTasks = ComputeNumberLimitProcessingTasks(slimFaas, function); setTickLastCallCounterDictionary[functionDeployment]++; int functionReplicas = function.Replicas; - long queueLength = await UpdateTickLastCallIfRequestStillInProgress(functionReplicas, + long queueLength = await UpdateTickLastCallIfRequestStillInProgress( + masterService, + functionReplicas, setTickLastCallCounterDictionary, - functionDeployment, numberProcessingTasks); + functionDeployment, + numberProcessingTasks, + numberLimitProcessingTasks); + if (functionReplicas == 0 || queueLength <= 0) { continue; @@ -75,12 +82,11 @@ await SendHttpRequestToFunction(processingTasks, numberLimitProcessingTasks, num } private async Task SendHttpRequestToFunction(Dictionary> processingTasks, - int? numberLimitProcessingTasks, int numberProcessingTasks, + int numberLimitProcessingTasks, int numberProcessingTasks, string functionDeployment) { - int? numberTasksToDequeue = numberLimitProcessingTasks - numberProcessingTasks; - IList? jsons = await slimFaasQueue.DequeueAsync(functionDeployment, - numberTasksToDequeue.HasValue ? (long)numberTasksToDequeue : 1); + int numberTasksToDequeue = numberLimitProcessingTasks - numberProcessingTasks; + var jsons = await slimFaasQueue.DequeueAsync(functionDeployment, numberTasksToDequeue); if (jsons == null) { return; @@ -100,28 +106,39 @@ private async Task SendHttpRequestToFunction(Dictionary UpdateTickLastCallIfRequestStillInProgress(int? functionReplicas, - Dictionary setTickLastCallCounterDictionnary, string functionDeployment, int numberProcessingTasks) + private async Task UpdateTickLastCallIfRequestStillInProgress(IMasterService masterService, int? functionReplicas, + Dictionary setTickLastCallCounterDictionnary, + string functionDeployment, + int numberProcessingTasks, + int numberLimitProcessingTasks) { - int counterLimit = functionReplicas == 0 ? 10 : 40; - long queueLength = await slimFaasQueue.CountAsync(functionDeployment); - if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) + if (masterService.IsMaster) { - setTickLastCallCounterDictionnary[functionDeployment] = 0; + int counterLimit = functionReplicas == 0 ? 10 : 40; + long queueLength = await slimFaasQueue.CountAsync(functionDeployment); + if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) + { + setTickLastCallCounterDictionnary[functionDeployment] = 0; - if (queueLength > 0 || numberProcessingTasks > 0) + if (queueLength > 0 || numberProcessingTasks > 0) + { + historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); + } + } + + if (queueLength == 0) { - historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); + return 0; } } - return queueLength; + return await slimFaasQueue.CountAsync(functionDeployment, numberLimitProcessingTasks); } - private static int? ComputeNumberLimitProcessingTasks(SlimFaasDeploymentInformation slimFaas, + private static int ComputeNumberLimitProcessingTasks(SlimFaasDeploymentInformation slimFaas, DeploymentInformation function) { - int? numberLimitProcessingTasks; + int numberLimitProcessingTasks; int numberReplicas = slimFaas.Replicas; if (function.NumberParallelRequest < numberReplicas || numberReplicas == 0) diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 84460931..b8205364 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -75,7 +75,7 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue { public Task?> DequeueAsync(string key, long count = 1) => throw new NotImplementedException(); - public Task CountAsync(string key) => throw new NotImplementedException(); + public Task CountAsync(string key, int maximum) => throw new NotImplementedException(); public Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => throw new NotImplementedException(); diff --git a/tests/SlimFaas.Tests/SlimWorkerShould.cs b/tests/SlimFaas.Tests/SlimWorkerShould.cs index 1b53d07c..a55880f6 100644 --- a/tests/SlimFaas.Tests/SlimWorkerShould.cs +++ b/tests/SlimFaas.Tests/SlimWorkerShould.cs @@ -41,6 +41,9 @@ public async Task OnlyCallOneFunctionAsync() Mock slimDataStatus = new Mock(); slimDataStatus.Setup(s => s.WaitForReadyAsync()).Returns(Task.CompletedTask); + Mock masterService = new Mock(); + masterService.Setup(s => s.IsMaster).Returns(true); + Mock replicasService = new Mock(); replicasService.Setup(rs => rs.Deployments).Returns(new DeploymentsInformations( SlimFaas: new SlimFaasDeploymentInformation(2, new List()), @@ -84,7 +87,9 @@ public async Task OnlyCallOneFunctionAsync() replicasService.Object, historyHttpService, logger.Object, - serviceProvider.Object, slimDataStatus.Object); + serviceProvider.Object, + slimDataStatus.Object, + masterService.Object); Task task = service.StartAsync(CancellationToken.None); @@ -107,12 +112,16 @@ public async Task LogErrorWhenExceptionIsThrown() Mock slimDataStatus = new Mock(); slimDataStatus.Setup(s => s.WaitForReadyAsync()).Returns(Task.CompletedTask); + Mock masterService = new Mock(); + masterService.Setup(s => s.IsMaster).Returns(true); + SlimWorker service = new SlimWorker(redisQueue, replicasService.Object, historyHttpService, logger.Object, serviceProvider.Object, - slimDataStatus.Object); + slimDataStatus.Object, + masterService.Object); Task task = service.StartAsync(CancellationToken.None); From 842868211310d619adb04c49c800ca80e64462d6 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 26 Nov 2024 07:42:50 +0100 Subject: [PATCH 079/135] to be finieshed --- src/SlimData/Commands/ListLeftPushCommand.cs | 22 +++++++++++++++++- .../Commands/ListSetQueueItemStatusCommand.cs | 2 +- src/SlimData/Commands/LogSnapshotCommand.cs | 23 ++++++++++++++++++- src/SlimData/SlimDataInterpreter.cs | 12 +++++++--- 4 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/SlimData/Commands/ListLeftPushCommand.cs b/src/SlimData/Commands/ListLeftPushCommand.cs index 1379d3e9..c919d3fe 100644 --- a/src/SlimData/Commands/ListLeftPushCommand.cs +++ b/src/SlimData/Commands/ListLeftPushCommand.cs @@ -14,9 +14,13 @@ public struct ListLeftPushCommand : ISerializable public string Identifier { get; set; } public long NowTicks { get; set; } + public int Timeout { get; set; } + + public List Retries { get; set; } + public ReadOnlyMemory Value { get; set; } - long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + Value.Length; + long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + Value.Length + Encoding.UTF8.GetByteCount(Identifier) + sizeof(long) + sizeof(int) + Retries.Count * sizeof(int); public async ValueTask WriteToAsync(TWriter writer, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter @@ -27,7 +31,13 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.EncodeAsync(command.Identifier.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(NowTicks, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(Timeout, token).ConfigureAwait(false); await writer.WriteAsync(command.Value, LengthFormat.Compressed, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(Retries.Count, token).ConfigureAwait(false); + foreach (var retry in Retries) + { + await writer.WriteLittleEndianAsync(retry, token).ConfigureAwait(false); + } } #pragma warning disable CA2252 @@ -38,12 +48,22 @@ public static async ValueTask ReadFromAsync(TReade var key = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); var identifier = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); var nowTicks = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false); + var timeout = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false); using var value = await reader.ReadAsync(LengthFormat.Compressed, token: token).ConfigureAwait(false); + var retriesCount = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false); + var retries = new List(retriesCount); + while (retriesCount-- > 0) + { + retries.Add(await reader.ReadLittleEndianAsync(token).ConfigureAwait(false)); + } + return new ListLeftPushCommand { Key = key.ToString(), Identifier = identifier.ToString(), NowTicks = nowTicks, + Timeout = timeout, + Retries = retries, Value = value.Memory.ToArray() }; } diff --git a/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs b/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs index f74cd9df..d6b4ac5f 100644 --- a/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs +++ b/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs @@ -27,7 +27,7 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.WriteLittleEndianAsync(NowTicks, token).ConfigureAwait(false); } - long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Identifier) + sizeof(int); + long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Identifier) + sizeof(int) + Encoding.UTF8.GetByteCount(Key) + sizeof(long); public static async ValueTask ReadFromAsync(TReader reader, CancellationToken token) where TReader : notnull, IAsyncBinaryReader { diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index 6f2fb701..3d2a4182 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -34,6 +34,10 @@ public readonly struct LogSnapshotCommand(Dictionary { result += x.Value.Length + Encoding.UTF8.GetByteCount(x.Id) + sizeof(Int64); + result += sizeof(Int32); // 4 bytes for timeout + result += sizeof(Int32); // 4 bytes for retries count + result += x.Retries.Count * sizeof(Int32); + result += sizeof(Int32); // 4 bytes for hashset count foreach (var retryQueueElement in x.RetryQueueElements) { @@ -80,6 +84,14 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.WriteAsync(value.Value, LengthFormat.Compressed, token).ConfigureAwait(false); await writer.EncodeAsync(value.Id.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteBigEndianAsync(value.InsertTimeStamp, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(value.Timeout, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(value.Retries.Count, token).ConfigureAwait(false); + foreach (var valueRetry in value.Retries) + { + await writer.WriteLittleEndianAsync(valueRetry, token).ConfigureAwait(false); + } + + await writer.WriteLittleEndianAsync(value.RetryQueueElements.Count, token).ConfigureAwait(false); foreach (var retryQueueElement in value.RetryQueueElements) { @@ -137,6 +149,15 @@ public static async ValueTask ReadFromAsync(TReader var id = await reader.DecodeAsync(new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token) .ConfigureAwait(false); var insertTimeStamp = await reader.ReadBigEndianAsync(token); + var timeout = await reader.ReadLittleEndianAsync(token); + var countRetries = await reader.ReadLittleEndianAsync(token); + var retries = new List(countRetries); + while (countRetries-- > 0) + { + retries.Add(await reader.ReadLittleEndianAsync(token)); + } + + var countRetryQueueElements = await reader.ReadLittleEndianAsync(token); var retryQueueElements = new List(countRetryQueueElements); while (countRetryQueueElements-- > 0) @@ -147,7 +168,7 @@ public static async ValueTask ReadFromAsync(TReader retryQueueElements.Add(new QueueHttpTryElement(startTimestamp, endTimestamp, httpCode)); } - queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, retryQueueElements)); + queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, timeout, retries, retryQueueElements)); } queues.Add(key.ToString(), queue); diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index e07931d8..f5877d66 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -13,12 +13,18 @@ public record SlimDataState( public class QueueElement( ReadOnlyMemory value, string id, - long insertTimeStamp, + long insertTimeStamp, + int timeout, + List retries, IList retryQueueElements) { public ReadOnlyMemory Value { get; } = value; public string Id { get; } = id; public long InsertTimeStamp { get; } = insertTimeStamp; + + public List Retries { get; } = retries; + + public int Timeout { get; } = timeout; public IList RetryQueueElements { get; } = retryQueueElements; } @@ -96,9 +102,9 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCommand, Dictionary> queues) { if (queues.TryGetValue(listLeftPushCommand.Key, out List? value)) - value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks,new List())); + value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.Timeout, listLeftPushCommand.Retries,new List())); else - queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks,new List())}); + queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.Timeout, listLeftPushCommand.Retries,new List())}); // print all queue elements var elements = queues[listLeftPushCommand.Key]; foreach (var queueElemen in elements) From 0ac1cf0ebb154642f01e9ef2803d516a8744771d Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 27 Nov 2024 10:19:10 +0100 Subject: [PATCH 080/135] fix --- src/SlimData/Commands/ListLeftPushCommand.cs | 6 +++--- src/SlimData/Endpoints.cs | 8 +++++++- src/SlimData/SlimDataInterpreter.cs | 4 ++-- .../QueueElementExtentionsTests.cs | 18 ++++++++++-------- 4 files changed, 22 insertions(+), 14 deletions(-) diff --git a/src/SlimData/Commands/ListLeftPushCommand.cs b/src/SlimData/Commands/ListLeftPushCommand.cs index c919d3fe..4ca34cb0 100644 --- a/src/SlimData/Commands/ListLeftPushCommand.cs +++ b/src/SlimData/Commands/ListLeftPushCommand.cs @@ -14,7 +14,7 @@ public struct ListLeftPushCommand : ISerializable public string Identifier { get; set; } public long NowTicks { get; set; } - public int Timeout { get; set; } + public int RetryTimeout { get; set; } public List Retries { get; set; } @@ -31,7 +31,7 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.EncodeAsync(command.Identifier.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(NowTicks, token).ConfigureAwait(false); - await writer.WriteLittleEndianAsync(Timeout, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(RetryTimeout, token).ConfigureAwait(false); await writer.WriteAsync(command.Value, LengthFormat.Compressed, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(Retries.Count, token).ConfigureAwait(false); foreach (var retry in Retries) @@ -62,7 +62,7 @@ public static async ValueTask ReadFromAsync(TReade Key = key.ToString(), Identifier = identifier.ToString(), NowTicks = nowTicks, - Timeout = timeout, + RetryTimeout = timeout, Retries = retries, Value = value.Memory.ToArray() }; diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 27265176..918915d6 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -185,7 +185,13 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin IRaftCluster cluster, CancellationTokenSource source) { var logEntry = - provider.Interpreter.CreateLogEntry(new ListLeftPushCommand { Key = key, Identifier = Guid.NewGuid().ToString(), Value = value, NowTicks = DateTime.UtcNow.Ticks }, + provider.Interpreter.CreateLogEntry(new ListLeftPushCommand { Key = key, + Identifier = Guid.NewGuid().ToString(), + Value = value, + NowTicks = DateTime.UtcNow.Ticks, + Retries = SlimDataInterpreter.Retries, + RetryTimeout = SlimDataInterpreter.RetryTimeout, + }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); } diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index f5877d66..d9fe2df8 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -102,9 +102,9 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCommand, Dictionary> queues) { if (queues.TryGetValue(listLeftPushCommand.Key, out List? value)) - value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.Timeout, listLeftPushCommand.Retries,new List())); + value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List())); else - queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.Timeout, listLeftPushCommand.Retries,new List())}); + queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List())}); // print all queue elements var elements = queues[listLeftPushCommand.Key]; foreach (var queueElemen in elements) diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 02d456ad..28951817 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -7,43 +7,45 @@ public static void QueueElementExtensionsGetQueueRunningElement() { // I want a test which text my extention var nowTicks = DateTime.UtcNow.Ticks; + + var timeout = 30; var timeoutSpanTicks = TimeSpan.FromSeconds(31).Ticks; List queueElements = new(); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks -100, nowTicks, 500), new(nowTicks -50, nowTicks, 500), new(nowTicks -20, nowTicks, 500), new(nowTicks -10, nowTicks, 500), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks - timeoutSpanTicks -100, nowTicks, 500), new(nowTicks- timeoutSpanTicks -50, nowTicks, 500), new(nowTicks- timeoutSpanTicks -30, nowTicks, 500), new(nowTicks- timeoutSpanTicks -20, 0, 0), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks -100, nowTicks, 200), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 200, nowTicks, 500), new(nowTicks- 100, 0, 0), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 400, nowTicks, 500), new(nowTicks- timeoutSpanTicks, 0, 0), })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, new List())); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, new List())); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, timeout, SlimDataInterpreter.Retries, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, SlimDataInterpreter.Retries, new List())); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, SlimDataInterpreter.Retries, new List())); var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.Retries, nowTicks, 3, 30); From 21e145ffbe68e537266206b26476bfde0d8bb2a0 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 27 Nov 2024 22:23:03 +0100 Subject: [PATCH 081/135] fix --- tests/SlimData.Tests/CommandsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SlimData.Tests/CommandsTests.cs b/tests/SlimData.Tests/CommandsTests.cs index ac139abb..e030106d 100644 --- a/tests/SlimData.Tests/CommandsTests.cs +++ b/tests/SlimData.Tests/CommandsTests.cs @@ -17,7 +17,7 @@ public static async Task InterpreterWithPersistentState() { byte[] bytes = RandomBytes(1000); using var wal = new SlimPersistentState(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - var entry1 = wal.CreateLogEntry(new ListLeftPushCommand { Key = "youhou" , Value = bytes }); + var entry1 = wal.CreateLogEntry(new ListLeftPushCommand { Key = "youhou" , Value = bytes, Identifier = "1", RetryTimeout = 100, Retries = new List { 1, 2, 3 }, NowTicks = DateTime.UtcNow.Ticks }); await wal.AppendAsync(entry1); Assert.Empty(wal.SlimDataState.Queues); await wal.CommitAsync(CancellationToken.None); From 5199d1728bf685999be738a14ccc34fc288da40d Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 27 Nov 2024 22:35:29 +0100 Subject: [PATCH 082/135] f --- demo/deployment-slimfaas.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 161fb49b..ee4c0541 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-786 + image: axaguildev/slimfaas:pr-77-790 livenessProbe: httpGet: path: /health From 9aa0f8fd941264c9aab217cc8d56d368585b0348 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 12 Dec 2024 21:07:17 +0100 Subject: [PATCH 083/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index ee4c0541..bfbee12c 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-790 + image: axaguildev/slimfaas:pr-77-810 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index d5adbdee..965f472a 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -382,9 +382,11 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis V1ContainerStatus? containerStatus = item.Status.ContainerStatuses.FirstOrDefault(); bool started = containerStatus?.Started ?? false; bool containerReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "ContainersReady")?.Status == "True"; + bool podReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "Ready")?.Status == "True"; + bool? isReady = containerStatus?.Ready; string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, containerReady, podIp, deploymentName); + PodInformation podInformation = new(podName, started, containerReady && podReady && isReady.HasValue && isReady.Value, podIp, deploymentName); yield return podInformation; } } From 103a40e250fa7611831184466c908650f742e230 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 14 Dec 2024 16:14:35 +0100 Subject: [PATCH 084/135] test --- README.md | 1 + demo/deployment-functions.yml | 8 ++++---- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 20 ++++++++++++++++---- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 1bbc251d..90fdcf65 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,7 @@ kubectl apply -f deployment-functions.yml kubectl apply -f deployment-mysql.yml # to run Single Page webapp demo (optional) on http://localhost:8000 docker run -p 8000:8000 --rm axaguildev/fibonacci-webapp:latest +kubectl port-forward svc/slimfaas-nodeport 30021:5000 -n slimfaas-demo ``` Now, you can access your pod via SlimFaas proxy: diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index f5d6b718..af78f7f7 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -21,7 +21,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci1 - image: axaguildev/fibonacci:0.24.18 + image: axaguildev/fibonacci:pr-77-815 livenessProbe: httpGet: path: /health @@ -74,7 +74,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci2 - image: axaguildev/fibonacci:0.24.18 + image: axaguildev/fibonacci:77-815 livenessProbe: httpGet: path: /health @@ -127,7 +127,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci3 - image: axaguildev/fibonacci:0.24.18 + image: axaguildev/fibonacci:pr-77-815 livenessProbe: httpGet: path: /health @@ -185,7 +185,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci4 - image: axaguildev/fibonacci:0.24.18 + image: axaguildev/fibonacci:pr-77-815 livenessProbe: httpGet: path: /health diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index bfbee12c..07a431d8 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -84,7 +84,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-810 + image: axaguildev/slimfaas:pr-77-815 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 965f472a..dc0685bd 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -184,7 +184,7 @@ public async Task ListFunctionsAsync(string kubeNamespa await Task.WhenAll(deploymentListTask, podListTask, statefulSetListTask); V1DeploymentList? deploymentList = deploymentListTask.Result; - IEnumerable podList = MapPodInformations(podListTask.Result); + IEnumerable podList = await MapPodInformations(podListTask.Result, client); V1StatefulSetList? statefulSetList = statefulSetListTask.Result; SlimFaasDeploymentInformation? slimFaasDeploymentInformation = statefulSetList.Items @@ -369,8 +369,9 @@ private static void AddStatefulSets(string kubeNamespace, V1StatefulSetList depl } } - private static IEnumerable MapPodInformations(V1PodList v1PodList) + private static async Task> MapPodInformations(V1PodList v1PodList, k8s.Kubernetes client) { + var result = new List(); foreach (V1Pod? item in v1PodList.Items) { string? podIp = item.Status.PodIP; @@ -386,9 +387,20 @@ private static IEnumerable MapPodInformations(V1PodList v1PodLis bool? isReady = containerStatus?.Ready; string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, containerReady && podReady && isReady.HasValue && isReady.Value, podIp, deploymentName); - yield return podInformation; + + bool readyAddress = false; + if(podReady) + { + var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(podName, item.Namespace()); + var readyAddresses = endpoints.Subsets.SelectMany(s => s.Addresses).ToList(); + readyAddress = readyAddresses.Count > 0; + } + + + PodInformation podInformation = new(podName, started, readyAddress, podIp, deploymentName); + result.Add(podInformation); } + return result; } From 10f33524764ab0149745dfdd1afa8af0f1c01d21 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 14 Dec 2024 16:38:34 +0100 Subject: [PATCH 085/135] test --- demo/deployment-slimfaas.yml | 27 +++++++++++++++++++- src/SlimData/SlimData.csproj | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 2 +- tests/SlimData.Tests/SlimData.Tests.csproj | 4 +-- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 07a431d8..21469fe2 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -60,6 +60,31 @@ roleRef: name: deployment-statefulset-manager apiGroup: rbac.authorization.k8s.io --- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: endpoints-viewer + namespace: slimfaas-demo +rules: + - apiGroups: [""] + resources: ["endpoints"] + verbs: ["get", "list", "watch"] + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: slimfaas-endpoints-viewer + namespace: slimfaas-demo +subjects: + - kind: ServiceAccount + name: slimfaas + namespace: slimfaas-demo +roleRef: + kind: Role + name: endpoints-viewer + apiGroup: rbac.authorization.k8s.io +--- apiVersion: apps/v1 kind: StatefulSet metadata: @@ -84,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-815 + image: axaguildev/slimfaas:pr-77-816 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimData.csproj b/src/SlimData/SlimData.csproj index c67f9460..276514e4 100644 --- a/src/SlimData/SlimData.csproj +++ b/src/SlimData/SlimData.csproj @@ -13,7 +13,7 @@ - + diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index dc0685bd..aa62a458 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -391,7 +391,7 @@ private static async Task> MapPodInformations(V1PodL bool readyAddress = false; if(podReady) { - var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(podName, item.Namespace()); + var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(deploymentName, item.Namespace()); var readyAddresses = endpoints.Subsets.SelectMany(s => s.Addresses).ToList(); readyAddress = readyAddresses.Count > 0; } diff --git a/tests/SlimData.Tests/SlimData.Tests.csproj b/tests/SlimData.Tests/SlimData.Tests.csproj index 7a070244..7a885d0c 100644 --- a/tests/SlimData.Tests/SlimData.Tests.csproj +++ b/tests/SlimData.Tests/SlimData.Tests.csproj @@ -14,10 +14,10 @@ - + - + runtime; build; native; contentfiles; analyzers; buildtransitive From 18c007c86df030cc47c9e3e5a0d96d7385074481 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 17 Dec 2024 17:55:44 +0100 Subject: [PATCH 086/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 21469fe2..494e98b3 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-816 + image: axaguildev/slimfaas:pr-77-817 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index aa62a458..1434c649 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -389,14 +389,24 @@ private static async Task> MapPodInformations(V1PodL string deploymentName = item.Metadata.OwnerReferences[0].Name; bool readyAddress = false; - if(podReady) + + try + { + if(podReady) + { + var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(deploymentName, item.Namespace()); + var readyAddresses = endpoints.Subsets.SelectMany(s => s.Addresses).ToList(); + readyAddress = readyAddresses.Count > 0; + } + } + catch (Exception e) { - var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(deploymentName, item.Namespace()); - var readyAddresses = endpoints.Subsets.SelectMany(s => s.Addresses).ToList(); - readyAddress = readyAddresses.Count > 0; + Console.WriteLine(e); + throw; } + PodInformation podInformation = new(podName, started, readyAddress, podIp, deploymentName); result.Add(podInformation); } From e3df9c62bb6f67e3a5d3f88cd3e99177bc908077 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 17 Dec 2024 18:11:10 +0100 Subject: [PATCH 087/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 37 ++++++++++---------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 494e98b3..9fc2cb29 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-817 + image: axaguildev/slimfaas:pr-77-818 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 1434c649..e4644386 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -195,7 +195,7 @@ public async Task ListFunctionsAsync(string kubeNamespa .FirstOrDefault(); IEnumerable podInformations = podList.ToArray(); - AddDeployments(kubeNamespace, deploymentList, podInformations, deploymentInformationList, _logger); + AddDeployments(kubeNamespace, deploymentList, podInformations, deploymentInformationList, _logger, client); AddStatefulSets(kubeNamespace, statefulSetList, podInformations, deploymentInformationList, _logger); return new DeploymentsInformations(deploymentInformationList, @@ -226,8 +226,8 @@ private static IList ReadRetryAnnotation( IDictionary? anno return new List(){2, 4, 8}; } - private static void AddDeployments(string kubeNamespace, V1DeploymentList deploymentList, IEnumerable podList, - IList deploymentInformationList, ILogger logger) + private static async Task AddDeployments(string kubeNamespace, V1DeploymentList deploymentList, IEnumerable podList, + IList deploymentInformationList, ILogger logger, k8s.Kubernetes client ) { foreach (V1Deployment? deploymentListItem in deploymentList.Items) { @@ -243,6 +243,20 @@ private static void AddDeployments(string kubeNamespace, V1DeploymentList deploy var name = deploymentListItem.Metadata.Name; ScheduleConfig? scheduleConfig = GetScheduleConfig(annotations, name, logger); + try + { + + var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(name, kubeNamespace); + var readyAddresses = endpoints.Subsets.SelectMany(s => s.Addresses).ToList(); + Console.WriteLine("ReadyAdresses: " + name + " - " +readyAddresses.Count); + + } + catch (Exception e) + { + Console.WriteLine(e); + throw; + } + DeploymentInformation deploymentInformation = new( name, kubeNamespace, @@ -390,24 +404,11 @@ private static async Task> MapPodInformations(V1PodL bool readyAddress = false; - try - { - if(podReady) - { - var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(deploymentName, item.Namespace()); - var readyAddresses = endpoints.Subsets.SelectMany(s => s.Addresses).ToList(); - readyAddress = readyAddresses.Count > 0; - } - } - catch (Exception e) - { - Console.WriteLine(e); - throw; - } - PodInformation podInformation = new(podName, started, readyAddress, podIp, deploymentName); + + PodInformation podInformation = new(podName, started, containerReady, podIp, deploymentName); result.Add(podInformation); } return result; From ec64ab5476b158da8b7c27d75eaeb98786b61a9a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 17 Dec 2024 18:11:31 +0100 Subject: [PATCH 088/135] ss --- src/SlimFaas/Kubernetes/KubernetesService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index e4644386..6a4fb360 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -195,7 +195,7 @@ public async Task ListFunctionsAsync(string kubeNamespa .FirstOrDefault(); IEnumerable podInformations = podList.ToArray(); - AddDeployments(kubeNamespace, deploymentList, podInformations, deploymentInformationList, _logger, client); + await AddDeployments(kubeNamespace, deploymentList, podInformations, deploymentInformationList, _logger, client); AddStatefulSets(kubeNamespace, statefulSetList, podInformations, deploymentInformationList, _logger); return new DeploymentsInformations(deploymentInformationList, From d818dbe457cdf00bf7ed3852cf05786c79730808 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 17 Dec 2024 18:30:37 +0100 Subject: [PATCH 089/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 9fc2cb29..2d6294c2 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-818 + image: axaguildev/slimfaas:pr-77-820 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 6a4fb360..13feba59 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -4,7 +4,6 @@ using System.Text; using System.Text.Json; using System.Text.Json.Serialization; -using DotNext.Collections.Generic; using k8s; using k8s.Autorest; using k8s.Models; @@ -254,7 +253,6 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList catch (Exception e) { Console.WriteLine(e); - throw; } DeploymentInformation deploymentInformation = new( From 80b09b3bb6b8dbf6710d56c2f4ea8dd91b9832ce Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 17 Dec 2024 20:00:37 +0100 Subject: [PATCH 090/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 2d6294c2..6bb9d21e 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-820 + image: axaguildev/slimfaas:pr-77-821 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 13feba59..73c2e08b 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -246,8 +246,15 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList { var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(name, kubeNamespace); - var readyAddresses = endpoints.Subsets.SelectMany(s => s.Addresses).ToList(); - Console.WriteLine("ReadyAdresses: " + name + " - " +readyAddresses.Count); + if(endpoints != null && endpoints.Subsets != null) + { + var readyAddresses = endpoints.Subsets + .Where(s => s.Addresses != null) + .SelectMany(s => s.Addresses) + .ToList(); + Console.WriteLine("ReadyAdresses: " + name + " - " +readyAddresses.Count); + } + } catch (Exception e) From 757c1832edfcdec36288b02f14c48bfbca994a3d Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 17 Dec 2024 21:01:07 +0100 Subject: [PATCH 091/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/SlimDataInterpreter.cs | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 6bb9d21e..8476b4c9 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-821 + image: axaguildev/slimfaas:pr-77-822 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index d9fe2df8..87a3bbab 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -74,21 +74,23 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm { queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); } - } - - // print all queue elements - foreach (var queueElemen in queue) - { - Console.WriteLine("DoListRightPopAsync QueueElement Id " + queueElemen.Id); - Console.WriteLine("DoListRightPopAsync QueueElement Value " + queueElemen.Value); - Console.WriteLine("DoListRightPopAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); - foreach (var retryQueueElemen in queueElemen.RetryQueueElements) + Console.WriteLine("DoListRightPopAsync"); + // print all queue elements + foreach (var queueElemen in queue) { - Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); - Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); - Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); + Console.WriteLine("DoListRightPopAsync QueueElement Id " + queueElemen.Id); + Console.WriteLine("DoListRightPopAsync QueueElement Value " + queueElemen.Value); + Console.WriteLine("DoListRightPopAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); + foreach (var retryQueueElemen in queueElemen.RetryQueueElements) + { + Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); + Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); + Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); + } } } + + return default; } From dc5b1d551d8405add13325d81f029e926cb51d7a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 18 Dec 2024 15:07:08 +0100 Subject: [PATCH 092/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/IKubernetesService.cs | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 77 ++++++++++--------- .../Kubernetes/MockKubernetesService.cs | 2 +- src/SlimFaas/ReplicasService.cs | 2 +- .../HistorySynchronizationWorkerShould.cs | 2 +- .../ReplicasScaleWorkerShould.cs | 2 +- 7 files changed, 47 insertions(+), 42 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 8476b4c9..4d065c36 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-822 + image: axaguildev/slimfaas:pr-77-823 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/IKubernetesService.cs b/src/SlimFaas/Kubernetes/IKubernetesService.cs index e1b22718..c2218f98 100644 --- a/src/SlimFaas/Kubernetes/IKubernetesService.cs +++ b/src/SlimFaas/Kubernetes/IKubernetesService.cs @@ -5,5 +5,5 @@ namespace SlimFaas; public interface IKubernetesService { Task ScaleAsync(ReplicaRequest request); - Task ListFunctionsAsync(string kubeNamespace); + Task ListFunctionsAsync(string kubeNamespace, DeploymentsInformations previousDeployments); } diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 73c2e08b..9b380d70 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -71,7 +71,8 @@ public record DeploymentInformation(string Deployment, string Namespace, IList

? ExcludeDeploymentsFromVisibilityPrivate = null, string ResourceVersion = "", IList? AsynchrounousRetry = null, - IList? SynchrounousRetry = null + IList? SynchrounousRetry = null, + bool EndpointReady = false ); public record PodInformation(string Name, bool? Started, bool? Ready, string Ip, string DeploymentName); @@ -170,7 +171,7 @@ public KubernetesService(ILogger logger, bool useKubeConfig) } - public async Task ListFunctionsAsync(string kubeNamespace) + public async Task ListFunctionsAsync(string kubeNamespace, DeploymentsInformations previousDeployments) { try { @@ -183,7 +184,7 @@ public async Task ListFunctionsAsync(string kubeNamespa await Task.WhenAll(deploymentListTask, podListTask, statefulSetListTask); V1DeploymentList? deploymentList = deploymentListTask.Result; - IEnumerable podList = await MapPodInformations(podListTask.Result, client); + IEnumerable podList = await MapPodInformations(podListTask.Result); V1StatefulSetList? statefulSetList = statefulSetListTask.Result; SlimFaasDeploymentInformation? slimFaasDeploymentInformation = statefulSetList.Items @@ -194,7 +195,7 @@ public async Task ListFunctionsAsync(string kubeNamespa .FirstOrDefault(); IEnumerable podInformations = podList.ToArray(); - await AddDeployments(kubeNamespace, deploymentList, podInformations, deploymentInformationList, _logger, client); + await AddDeployments(kubeNamespace, deploymentList, podInformations, deploymentInformationList, _logger, client, previousDeployments.Functions); AddStatefulSets(kubeNamespace, statefulSetList, podInformations, deploymentInformationList, _logger); return new DeploymentsInformations(deploymentInformationList, @@ -226,7 +227,7 @@ private static IList ReadRetryAnnotation( IDictionary? anno } private static async Task AddDeployments(string kubeNamespace, V1DeploymentList deploymentList, IEnumerable podList, - IList deploymentInformationList, ILogger logger, k8s.Kubernetes client ) + IList deploymentInformationList, ILogger logger, k8s.Kubernetes client , IList previousDeploymentInformationList) { foreach (V1Deployment? deploymentListItem in deploymentList.Items) { @@ -240,32 +241,14 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList } var name = deploymentListItem.Metadata.Name; + var pods = podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(); ScheduleConfig? scheduleConfig = GetScheduleConfig(annotations, name, logger); - - try - { - - var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(name, kubeNamespace); - if(endpoints != null && endpoints.Subsets != null) - { - var readyAddresses = endpoints.Subsets - .Where(s => s.Addresses != null) - .SelectMany(s => s.Addresses) - .ToList(); - Console.WriteLine("ReadyAdresses: " + name + " - " +readyAddresses.Count); - } - - - } - catch (Exception e) - { - Console.WriteLine(e); - } + bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeploymentInformationList, name, pods); DeploymentInformation deploymentInformation = new( name, kubeNamespace, - podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(), + pods, deploymentListItem.Spec.Replicas ?? 0, annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) ? int.Parse(annotationReplicasAtStart) @@ -297,7 +280,8 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), deploymentListItem.Metadata.ResourceVersion, AsynchrounousRetry: ReadRetryAnnotation(annotations), - SynchrounousRetry: ReadRetryAnnotation(annotations) + SynchrounousRetry: ReadRetryAnnotation(annotations), + EndpointReady: endpointReady ); deploymentInformationList.Add(deploymentInformation); } @@ -308,6 +292,34 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList } } + private static async Task GetEndpointReady(string kubeNamespace, k8s.Kubernetes client, + IList previousDeploymentInformationList, string name, List pods) + { + bool endpointReady = false; + try + { + var previousDeployment = previousDeploymentInformationList.FirstOrDefault(d => d.Deployment == name); + if (previousDeployment is { EndpointReady: false } && pods.Count == 1) + { + var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(name, kubeNamespace); + if(endpoints is { Subsets: not null }) + { + var readyAddresses = endpoints.Subsets + .Where(s => s.Addresses != null) + .SelectMany(s => s.Addresses) + .ToList(); + endpointReady = readyAddresses.Count > 0; + } + } + } + catch (Exception e) + { + Console.WriteLine(e); + } + + return endpointReady; + } + private static ScheduleConfig? GetScheduleConfig(IDictionary annotations, string name, ILogger logger) { try @@ -388,7 +400,7 @@ private static void AddStatefulSets(string kubeNamespace, V1StatefulSetList depl } } - private static async Task> MapPodInformations(V1PodList v1PodList, k8s.Kubernetes client) + private static async Task> MapPodInformations(V1PodList v1PodList) { var result = new List(); foreach (V1Pod? item in v1PodList.Items) @@ -403,17 +415,10 @@ private static async Task> MapPodInformations(V1PodL bool started = containerStatus?.Started ?? false; bool containerReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "ContainersReady")?.Status == "True"; bool podReady = item.Status.Conditions.FirstOrDefault(c => c.Type == "Ready")?.Status == "True"; - bool? isReady = containerStatus?.Ready; string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - bool readyAddress = false; - - - - - - PodInformation podInformation = new(podName, started, containerReady, podIp, deploymentName); + PodInformation podInformation = new(podName, started, containerReady && podReady, podIp, deploymentName); result.Add(podInformation); } return result; diff --git a/src/SlimFaas/Kubernetes/MockKubernetesService.cs b/src/SlimFaas/Kubernetes/MockKubernetesService.cs index b5a688d0..d49c4771 100644 --- a/src/SlimFaas/Kubernetes/MockKubernetesService.cs +++ b/src/SlimFaas/Kubernetes/MockKubernetesService.cs @@ -74,7 +74,7 @@ public MockKubernetesService() return Task.FromResult(request); } - public Task ListFunctionsAsync(string kubeNamespace) + public Task ListFunctionsAsync(string kubeNamespace, DeploymentsInformations previousDeployments) { return Task.FromResult(_deploymentInformations); } diff --git a/src/SlimFaas/ReplicasService.cs b/src/SlimFaas/ReplicasService.cs index 96224779..6d1d14df 100644 --- a/src/SlimFaas/ReplicasService.cs +++ b/src/SlimFaas/ReplicasService.cs @@ -49,7 +49,7 @@ public async Task SyncDeploymentsFromSlimData(DeploymentsInformations deployment public async Task SyncDeploymentsAsync(string kubeNamespace) { - DeploymentsInformations deployments = await kubernetesService.ListFunctionsAsync(kubeNamespace); + DeploymentsInformations deployments = await kubernetesService.ListFunctionsAsync(kubeNamespace, Deployments); lock (Lock) { if (logger.IsEnabled(LogLevel.Information)) diff --git a/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs b/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs index 04e7698f..62dbeec3 100644 --- a/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs +++ b/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs @@ -21,7 +21,7 @@ public async Task SyncLastTicksBetweenDatabaseAndMemory() new("fibonacci2", "default", Replicas: 0, Pods: new List()) }, new SlimFaasDeploymentInformation(1, new List()), new List()); - kubernetesService.Setup(k => k.ListFunctionsAsync(It.IsAny())).ReturnsAsync(deploymentsInformations); + kubernetesService.Setup(k => k.ListFunctionsAsync(It.IsAny(), It.IsAny())).ReturnsAsync(deploymentsInformations); HistoryHttpMemoryService historyHttpMemoryService = new HistoryHttpMemoryService(); Mock> loggerReplicasService = new Mock>(); diff --git a/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs b/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs index 8ab15292..a5b49861 100644 --- a/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs +++ b/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs @@ -68,7 +68,7 @@ public async Task ScaleFunctionUpAndDown(DeploymentsInformations deploymentsInfo historyHttpService, loggerReplicasService.Object); masterService.Setup(ms => ms.IsMaster).Returns(true); - kubernetesService.Setup(k => k.ListFunctionsAsync(It.IsAny())).ReturnsAsync(deploymentsInformations); + kubernetesService.Setup(k => k.ListFunctionsAsync(It.IsAny(), It.IsAny())).ReturnsAsync(deploymentsInformations); ReplicaRequest scaleRequestFibonacci1 = new("fibonacci1", "default", 0, PodType.Deployment); kubernetesService.Setup(k => k.ScaleAsync(scaleRequestFibonacci1)).ReturnsAsync(scaleRequestFibonacci1); From 67ed9b1fd04fc397206bae1d60775f9a0ce8cbb5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 18 Dec 2024 17:07:29 +0100 Subject: [PATCH 093/135] update --- src/SlimFaas/SlimProxyMiddleware.cs | 2 +- src/SlimFaas/SlimWorker.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index 6ce7b481..c09b6754 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -437,7 +437,7 @@ private async Task WaitForAnyPodStartedAsync(HttpContext context, HistoryHttpMem while (numberLoop > 0) { bool isAnyContainerStarted = replicasService.Deployments.Functions.Any(f => - f is { Replicas: > 0, Pods: not null } && f.Pods.Any(p => p.Ready.HasValue && p.Ready.Value)); + f is { Replicas: > 0, EndpointReady: true } && f.Pods.Any(p => p.Ready.HasValue && p.Ready.Value)); if (!isAnyContainerStarted && !context.RequestAborted.IsCancellationRequested) { numberLoop--; diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 6e400a14..70c568cf 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -61,7 +61,7 @@ private async Task DoOneCycle(CancellationToken stoppingToken, } bool? isAnyContainerStarted = function.Pods?.Any(p => p.Ready.HasValue && p.Ready.Value); - if (!isAnyContainerStarted.HasValue || !isAnyContainerStarted.Value) + if (!isAnyContainerStarted.HasValue || !isAnyContainerStarted.Value || !function.EndpointReady) { continue; } From ad41a80c25236cbbe05313211dd56a628e45adf5 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 18 Dec 2024 17:56:38 +0100 Subject: [PATCH 094/135] test --- tests/SlimFaas.Tests/SlimWorkerShould.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/SlimFaas.Tests/SlimWorkerShould.cs b/tests/SlimFaas.Tests/SlimWorkerShould.cs index a55880f6..8f6900fc 100644 --- a/tests/SlimFaas.Tests/SlimWorkerShould.cs +++ b/tests/SlimFaas.Tests/SlimWorkerShould.cs @@ -52,14 +52,14 @@ public async Task OnlyCallOneFunctionAsync() new(Replicas: 1, Deployment: "fibonacci", Namespace: "default", NumberParallelRequest: 1, ReplicasMin: 0, ReplicasAtStart: 1, TimeoutSecondBeforeSetReplicasMin: 300, ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, - Pods: new List { new("", true, true, "", "") }), + Pods: new List { new("", true, true, "", "")}, EndpointReady: true), new(Replicas: 1, Deployment: "no-pod-started", Namespace: "default", NumberParallelRequest: 1, ReplicasMin: 0, ReplicasAtStart: 1, TimeoutSecondBeforeSetReplicasMin: 300, ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, - Pods: new List { new("", false, false, "", "") }), + Pods: new List { new("", false, false, "", "")}, EndpointReady: true), new(Replicas: 0, Deployment: "no-replicas", Namespace: "default", NumberParallelRequest: 1, ReplicasMin: 0, ReplicasAtStart: 1, TimeoutSecondBeforeSetReplicasMin: 300, - ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, Pods: new List()) + ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, Pods: new List(), EndpointReady: false) }, Pods: new List())); HistoryHttpMemoryService historyHttpService = new HistoryHttpMemoryService(); Mock> logger = new Mock>(); From c59e405edf895e5d7e67a7d54c13498a2d5929f2 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 18 Dec 2024 18:53:37 +0100 Subject: [PATCH 095/135] update --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 46 ++++++++++++-------- src/SlimFaas/ReplicasService.cs | 11 +++-- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 4d065c36..72b492f5 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-823 + image: axaguildev/slimfaas:pr-77-826 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 9b380d70..db8d3807 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -196,7 +196,7 @@ public async Task ListFunctionsAsync(string kubeNamespa IEnumerable podInformations = podList.ToArray(); await AddDeployments(kubeNamespace, deploymentList, podInformations, deploymentInformationList, _logger, client, previousDeployments.Functions); - AddStatefulSets(kubeNamespace, statefulSetList, podInformations, deploymentInformationList, _logger); + await AddStatefulSets(kubeNamespace, statefulSetList, podInformations, deploymentInformationList, _logger, client, previousDeployments.Functions); return new DeploymentsInformations(deploymentInformationList, slimFaasDeploymentInformation ?? new SlimFaasDeploymentInformation(1, new List()), podInformations); @@ -295,29 +295,36 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList private static async Task GetEndpointReady(string kubeNamespace, k8s.Kubernetes client, IList previousDeploymentInformationList, string name, List pods) { - bool endpointReady = false; try { + if (pods.Count == 0) + { + return false; + } + var previousDeployment = previousDeploymentInformationList.FirstOrDefault(d => d.Deployment == name); - if (previousDeployment is { EndpointReady: false } && pods.Count == 1) + if (previousDeployment is not { EndpointReady: false } || pods.Count != 1) { - var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(name, kubeNamespace); - if(endpoints is { Subsets: not null }) - { - var readyAddresses = endpoints.Subsets - .Where(s => s.Addresses != null) - .SelectMany(s => s.Addresses) - .ToList(); - endpointReady = readyAddresses.Count > 0; - } + return previousDeployment is { EndpointReady: true }; + } + + var endpoints = await client.CoreV1.ReadNamespacedEndpointsAsync(name, kubeNamespace); + if (endpoints is not { Subsets: not null }) + { + return previousDeployment is { EndpointReady: true }; } + + var readyAddresses = endpoints.Subsets + .Where(s => s.Addresses != null) + .SelectMany(s => s.Addresses) + .ToList(); + return readyAddresses.Count > 0; } catch (Exception e) { Console.WriteLine(e); } - - return endpointReady; + return false; } private static ScheduleConfig? GetScheduleConfig(IDictionary annotations, string name, ILogger logger) @@ -337,8 +344,8 @@ private static async Task GetEndpointReady(string kubeNamespace, k8s.Kuber return new ScheduleConfig(); } - private static void AddStatefulSets(string kubeNamespace, V1StatefulSetList deploymentList, IEnumerable podList, - IList deploymentInformationList, ILogger logger) + private static async Task AddStatefulSets(string kubeNamespace, V1StatefulSetList deploymentList, IEnumerable podList, + IList deploymentInformationList, ILogger logger, k8s.Kubernetes client , IList previousDeploymentInformationList) { foreach (V1StatefulSet? deploymentListItem in deploymentList.Items) { @@ -352,12 +359,14 @@ private static void AddStatefulSets(string kubeNamespace, V1StatefulSetList depl } var name = deploymentListItem.Metadata.Name; + var pods = podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(); ScheduleConfig? scheduleConfig = GetScheduleConfig(annotations, name, logger); + bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeploymentInformationList, name, pods); DeploymentInformation deploymentInformation = new( name, kubeNamespace, - podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(), + pods, deploymentListItem.Spec.Replicas ?? 0, annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) ? int.Parse(annotationReplicasAtStart) @@ -389,7 +398,8 @@ private static void AddStatefulSets(string kubeNamespace, V1StatefulSetList depl annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), deploymentListItem.Metadata.ResourceVersion, AsynchrounousRetry: ReadRetryAnnotation(annotations), - SynchrounousRetry: ReadRetryAnnotation(annotations)); + SynchrounousRetry: ReadRetryAnnotation(annotations), + EndpointReady: endpointReady); deploymentInformationList.Add(deploymentInformation); } diff --git a/src/SlimFaas/ReplicasService.cs b/src/SlimFaas/ReplicasService.cs index 6d1d14df..0c4d4146 100644 --- a/src/SlimFaas/ReplicasService.cs +++ b/src/SlimFaas/ReplicasService.cs @@ -71,17 +71,16 @@ public async Task SyncDeploymentsAsync(string kubeNames "with {PodType} pod type \n" + "with {ResourceVersion} resource version \n"+ "with {NumberParallelRequest} number parallel request \n" + - "with dependOn {DependsOn} \n", + "with dependOn {DependsOn} \n" + + "with {EndpointReady} endpoint ready \n", deploymentInformation.Deployment, deploymentInformation.Replicas, deploymentInformation.ReplicasAtStart, deploymentInformation.ReplicasMin, deploymentInformation.ReplicasStartAsSoonAsOneFunctionRetrieveARequest, deploymentInformation.TimeoutSecondBeforeSetReplicasMin, - deploymentInformation.PodType, deploymentInformation.ResourceVersion, deploymentInformation.NumberParallelRequest, deploymentInformation.DependsOn); - + deploymentInformation.PodType, deploymentInformation.ResourceVersion, deploymentInformation.NumberParallelRequest, + deploymentInformation.DependsOn, + deploymentInformation.EndpointReady); } } - } - - _deployments = deployments; } return deployments; From 7cff6aba94f3ab831ad884b6e8c46585df7303d0 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Wed, 18 Dec 2024 21:20:07 +0100 Subject: [PATCH 096/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/SlimDataInterpreter.cs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 72b492f5..97d57275 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-826 + image: axaguildev/slimfaas:pr-77-827 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 87a3bbab..a65b7d95 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -52,6 +52,7 @@ public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, Cancel internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetCommand, Dictionary> queues) { + Console.WriteLine("DoListRightPopAsync Key " + addHashSetCommand.Key); if (queues.TryGetValue(addHashSetCommand.Key, out var queue)) { var nowTicks =addHashSetCommand.NowTicks; @@ -74,7 +75,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm { queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); } - Console.WriteLine("DoListRightPopAsync"); + // print all queue elements foreach (var queueElemen in queue) { @@ -108,6 +109,7 @@ internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCo else queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List())}); // print all queue elements + Console.WriteLine("DoListLeftPushAsync key " + listLeftPushCommand.Key + " Identifier " + listLeftPushCommand.Identifier); var elements = queues[listLeftPushCommand.Key]; foreach (var queueElemen in elements) { @@ -134,6 +136,7 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo { if (!queues.TryGetValue(listSetQueueItemStatusCommand.Key, out List? value)) return default; + Console.WriteLine("DoListSetQueueItemStatusAsync QueueKey " + listSetQueueItemStatusCommand.Key + " Identifier " + listSetQueueItemStatusCommand.Identifier); var queueElement = value.FirstOrDefault(x => x.Id == listSetQueueItemStatusCommand.Identifier); if (queueElement == null) { @@ -147,7 +150,7 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo { value.Remove(queueElement); } - Console.WriteLine("DoListSetQueueItemStatusAsync QueueKey " + listSetQueueItemStatusCommand.Key); + // print all queue elements foreach (var queueElemen in value) { From d650f60c6ead0fe3924ae2b2a6ac0ffad1d4ed2a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 11:07:53 +0100 Subject: [PATCH 097/135] test --- demo/deployment-functions.yml | 2 ++ demo/deployment-slimfaas.yml | 7 +++++-- src/SlimFaas/SlimWorker.cs | 7 ++++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index af78f7f7..1fc9f77d 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -41,6 +41,8 @@ spec: env: - name: ASPNETCORE_URLS value: http://+:5000 + - name: Logging__LogLevel__Default + value: Debug resources: limits: memory: "96Mi" diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 97d57275..2d68ff64 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 3 + replicas: 1 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-827 + image: axaguildev/slimfaas:pr-77-828 livenessProbe: httpGet: path: /health @@ -137,6 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" + - name: SLIMDATA_CONFIGURATION + value: | + {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"} diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 70c568cf..4784d183 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -65,6 +65,7 @@ private async Task DoOneCycle(CancellationToken stoppingToken, { continue; } + logger.LogDebug("Function {FunctionDeployment} is ready", functionDeployment); if (numberProcessingTasks >= numberLimitProcessingTasks) { @@ -198,7 +199,11 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, { processingTasks[functionDeployment].Remove(httpResponseMessage); } - await slimFaasQueue.ListSetQueueItemStatusAsync(functionDeployment, listQueueItemStatus); + + if (listQueueItemStatus.Items.Count > 0) + { + await slimFaasQueue.ListSetQueueItemStatusAsync(functionDeployment, listQueueItemStatus); + } int numberProcessingTasks = processingTasks[functionDeployment].Count; return numberProcessingTasks; From cb248e706a478f8d3177746ff085ace0499cca06 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 11:18:15 +0100 Subject: [PATCH 098/135] test --- src/SlimData/QueueElementExtensions.cs | 4 ++-- src/SlimFaas/SlimWorker.cs | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index 9da9a819..bb0874a7 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -4,11 +4,11 @@ public static class QueueElementExtensions { public static int[] HttpStatusCodesWorthRetrying = [ - 408 , // HttpStatusCode.RequestTimeout, + // 408 , // HttpStatusCode.RequestTimeout, 500, // HttpStatusCode.InternalServerError, 502, // HttpStatusCode.BadGateway, 503, // HttpStatusCode.ServiceUnavailable, - 504, // HttpStatusCode.GatewayTimeout + //504, // HttpStatusCode.GatewayTimeout ]; public static bool IsTimeout(this QueueElement element, long nowTicks, int timeout=30) diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 4784d183..dfa0b435 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -186,6 +186,14 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, queueItemStatusList.Add(new QueueItemStatus(processing.Id, statusCode)); httpResponseMessage.Dispose(); } + // Filter by InnerException. + catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) + { + queueItemStatusList.Add(new QueueItemStatus(processing.Id, 504)); + httpResponseMessagesToDelete.Add(processing); + logger.LogWarning("Request Timeout Error: {Message} {StackTrace}", ex.Message, ex.StackTrace); + historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); + } catch (Exception e) { queueItemStatusList.Add(new QueueItemStatus(processing.Id, 500)); From f1d62468f381fc51085b944c0c4f423aa0f013a3 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 15:06:17 +0100 Subject: [PATCH 099/135] update --- demo/deployment-slimfaas.yml | 2 +- src/Fibonacci/Program.cs | 3 +- src/SlimData/Endpoints.cs | 1 - src/SlimFaas/Database/DatabaseMockService.cs | 14 ++++++++- src/SlimFaas/Database/IDatabaseService.cs | 3 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 3 +- src/SlimFaas/Database/SlimDataService.cs | 30 +++++++++++++++++-- src/SlimFaas/Database/SlimFaasQueue.cs | 6 +++- src/SlimFaas/SlimWorker.cs | 4 +-- tests/SlimData.Tests/RaftClusterTests.cs | 4 +-- .../SlimProxyMiddlewareTests.cs | 4 ++- 11 files changed, 59 insertions(+), 15 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 2d68ff64..e40dbc2a 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-828 + image: axaguildev/slimfaas:pr-77-830 livenessProbe: httpGet: path: /health diff --git a/src/Fibonacci/Program.cs b/src/Fibonacci/Program.cs index 1dd91223..9e879ea8 100644 --- a/src/Fibonacci/Program.cs +++ b/src/Fibonacci/Program.cs @@ -28,8 +28,9 @@ app.MapGet("/health", () => "OK"); -app.MapGet("/error", () => +app.MapGet("/error", async () => { + await Task.Delay(100); throw new Exception("Error"); }); diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 918915d6..c5c6aec4 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -226,7 +226,6 @@ public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provi foreach (var queueItemStatus in list.Items) { - var logEntry = provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand { diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index 8c50b5f3..c093e1ed 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -93,7 +93,19 @@ public Task ListLeftPushAsync(string key, byte[] field) return Task.FromResult?>(new List()); } - public Task ListLengthAsync(string key, int maximum = int.MaxValue) + public Task ListCountAvailableElementAsync(string key, int maximum = int.MaxValue) + { + if (!queue.ContainsKey(key)) + { + return Task.FromResult(0); + } + + var list = queue[key]; + + return Task.FromResult(list.Count); + } + + public Task ListCountElementAsync(string key, int maximum = Int32.MaxValue) { if (!queue.ContainsKey(key)) { diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index b335c566..191430a4 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -10,6 +10,7 @@ public interface IDatabaseService Task> HashGetAllAsync(string key); Task ListLeftPushAsync(string key, byte[] field); Task?> ListRightPopAsync(string key, int count = 1); - Task ListLengthAsync(string key, int maximum = int.MaxValue); + Task ListCountAvailableElementAsync(string key, int maximum = int.MaxValue); + Task ListCountElementAsync(string key, int maximum = int.MaxValue); Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 3e6ea7ae..4fed91e1 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -7,5 +7,6 @@ public interface ISlimFaasQueue Task EnqueueAsync(string key, byte[] message); Task?> DequeueAsync(string key, long count = 1); Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus); - public Task CountAsync(string key, int maximum = int.MaxValue); + public Task CountAvailableElementAsync(string key, int maximum = int.MaxValue); + public Task CountElementAsync(string key, int maximum = int.MaxValue); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index b083b142..d8a8fa62 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -174,6 +174,30 @@ private async Task DoListLeftPushAsync(string key, byte[] field) } } + public Task ListCountElementAsync(string key, int maximum = Int32.MaxValue) + { + return Retry.Do(() => DoListCountElementAsync(key, maximum), _retryInterval, logger, MaxAttemptCount); + } + + private async Task DoListCountElementAsync(string key, int maximum) + { + await GetAndWaitForLeader(); + await MasterWaitForleaseToken(); + + SlimDataPayload data = SimplePersistentState.Invoke(); + + if (data.Queues.TryGetValue(key, out List? value)) + { + var nowTicks = DateTime.UtcNow.Ticks; + var elements = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, maximum); + var runningElements = elements.GetQueueRunningElement(nowTicks); + var runningWaitingForRetryElements = elements.GetQueueWaitingForRetryElement(nowTicks, [2, 6, 10]); + return elements.Count + runningElements.Count + runningWaitingForRetryElements.Count;; + } + + return 0L; + } + public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) { await Retry.Do(() => DoListSetQueueItemStatus(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); @@ -201,12 +225,12 @@ private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queu } } - public async Task ListLengthAsync(string key, int maximum) + public async Task ListCountAvailableElementAsync(string key, int maximum) { - return await Retry.Do(() => DoListLengthAsync(key, maximum), _retryInterval, logger, MaxAttemptCount); + return await Retry.Do(() => DoListCountAvailableElementAsync(key, maximum), _retryInterval, logger, MaxAttemptCount); } - private async Task DoListLengthAsync(string key, int maximum) + private async Task DoListCountAvailableElementAsync(string key, int maximum) { await GetAndWaitForLeader(); await MasterWaitForleaseToken(); diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index 83f083a0..ba1fb9cf 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -19,5 +19,9 @@ public async Task EnqueueAsync(string key, byte[] data) => public async Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); - public async Task CountAsync(string key, int maximum = int.MaxValue) => await databaseService.ListLengthAsync($"{KeyPrefix}{key}", maximum); + public async Task CountAvailableElementAsync(string key, int maximum = int.MaxValue) => await databaseService.ListCountAvailableElementAsync($"{KeyPrefix}{key}", maximum); + + public async Task CountElementAsync(string key, int maximum = int.MaxValue) => await databaseService.ListCountElementAsync($"{KeyPrefix}{key}", maximum); + + } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index dfa0b435..6741925b 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -116,7 +116,7 @@ private async Task UpdateTickLastCallIfRequestStillInProgress(IMasterServi if (masterService.IsMaster) { int counterLimit = functionReplicas == 0 ? 10 : 40; - long queueLength = await slimFaasQueue.CountAsync(functionDeployment); + long queueLength = await slimFaasQueue.CountElementAsync(functionDeployment); if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) { setTickLastCallCounterDictionnary[functionDeployment] = 0; @@ -133,7 +133,7 @@ private async Task UpdateTickLastCallIfRequestStillInProgress(IMasterServi } } - return await slimFaasQueue.CountAsync(functionDeployment, numberLimitProcessingTasks); + return await slimFaasQueue.CountAvailableElementAsync(functionDeployment, numberLimitProcessingTasks); } private static int ComputeNumberLimitProcessingTasks(SlimFaasDeploymentInformation slimFaas, diff --git a/tests/SlimData.Tests/RaftClusterTests.cs b/tests/SlimData.Tests/RaftClusterTests.cs index 4e8fe495..8d7fe182 100644 --- a/tests/SlimData.Tests/RaftClusterTests.cs +++ b/tests/SlimData.Tests/RaftClusterTests.cs @@ -251,7 +251,7 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", await databaseServiceSlave.ListLeftPushAsync("listKey1", MemoryPackSerializer.Serialize("value1")); await GetLocalClusterView(host1).ForceReplicationAsync(); - long listLength = await databaseServiceSlave.ListLengthAsync("listKey1"); + long listLength = await databaseServiceSlave.ListCountAvailableElementAsync("listKey1"); Assert.Equal(1, listLength); IList? listRightPop = await databaseServiceSlave.ListRightPopAsync("listKey1"); @@ -272,7 +272,7 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", await databaseServiceSlave.ListSetQueueItemStatus("listKey1", queueItemStatus); await GetLocalClusterView(host1).ForceReplicationAsync(); - var listLength2 = await databaseServiceSlave.ListLengthAsync("listKey1"); + var listLength2 = await databaseServiceSlave.ListCountAvailableElementAsync("listKey1"); Assert.Equal(0, listLength2); diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index b8205364..e87fa792 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -75,11 +75,13 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue { public Task?> DequeueAsync(string key, long count = 1) => throw new NotImplementedException(); - public Task CountAsync(string key, int maximum) => throw new NotImplementedException(); + public Task CountAvailableElementAsync(string key, int maximum) => throw new NotImplementedException(); + public Task CountElementAsync(string key, int maximum) => throw new NotImplementedException(); public Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => throw new NotImplementedException(); public async Task EnqueueAsync(string key, byte[] message) => await Task.Delay(100); + } internal record SendData(string FunctionName, string Path, string BaseUrl); From 710b1510010caf2529861761c0b2a7f78508ae81 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 15:43:20 +0100 Subject: [PATCH 100/135] test --- README.md | 16 ++++++++++++++++ demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Database/SlimDataService.cs | 4 ++-- src/SlimFaas/SlimWorker.cs | 2 ++ 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 90fdcf65..848a4b34 100644 --- a/README.md +++ b/README.md @@ -376,6 +376,22 @@ spec: - **SlimFaas/ExcludeDeploymentsFromVisibilityPrivate** : "" - Comma separated list of deployment names or statefulset names - Message from that pods will be considered as public. It is useful if you want to exclude some pods from the private visibility, for example for a backend for frontend. +- **SlimFaas/Retries** : json configuration + - Allows you to define a schedule for your functions. If you want to wake up your infrastructure at 07:00 or for example scale down after 60 seconds of inactivity after 07:00 and scale down after 10 seconds of inactivity after 21:00. Time zones are defined as IANA time zones. The full list is available [here](https://nodatime.org/TimeZones) + + +````bash +{ + "TimeZoneID":"Europe/Paris", # Time Zone ID can be found here: https://nodatime.org/TimeZones + "Default":{ + "WakeUp":["07:00"], // Wake up your infrastructure at 07:00 + "ScaleDownTimeout":[ + {"Time":"07:00","Value":20}, // Scale down after 20 seconds of inactivity after 07:00 + {"Time":"21:00","Value":10} // Scale down after 10 seconds of inactivity after 21:00 + ] + } +} +```` - **SlimFaas/Schedule** : json configuration - Allows you to define a schedule for your functions. If you want to wake up your infrastructure at 07:00 or for example scale down after 60 seconds of inactivity after 07:00 and scale down after 10 seconds of inactivity after 21:00. Time zones are defined as IANA time zones. The full list is available [here](https://nodatime.org/TimeZones) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index e40dbc2a..ff62316e 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-830 + image: axaguildev/slimfaas:pr-77-831 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index d8a8fa62..5d7f01fd 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -189,10 +189,10 @@ private async Task DoListCountElementAsync(string key, int maximum) if (data.Queues.TryGetValue(key, out List? value)) { var nowTicks = DateTime.UtcNow.Ticks; - var elements = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, maximum); + var elements = value.GetQueueAvailableElement([2, 6, 10], nowTicks, maximum); var runningElements = elements.GetQueueRunningElement(nowTicks); var runningWaitingForRetryElements = elements.GetQueueWaitingForRetryElement(nowTicks, [2, 6, 10]); - return elements.Count + runningElements.Count + runningWaitingForRetryElements.Count;; + return elements.Count + runningElements.Count + runningWaitingForRetryElements.Count; } return 0L; diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 6741925b..324a15a8 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -117,8 +117,10 @@ private async Task UpdateTickLastCallIfRequestStillInProgress(IMasterServi { int counterLimit = functionReplicas == 0 ? 10 : 40; long queueLength = await slimFaasQueue.CountElementAsync(functionDeployment); + Console.WriteLine($"--------------QueueLength: {queueLength}"); if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) { + Console.WriteLine($"--------------HERE"); setTickLastCallCounterDictionnary[functionDeployment] = 0; if (queueLength > 0 || numberProcessingTasks > 0) From e3de7c1254ff4fdc5cf20fde672d377053929084 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 16:28:46 +0100 Subject: [PATCH 101/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Database/SlimDataService.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index ff62316e..0c4c3d94 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-831 + image: axaguildev/slimfaas:pr-77-832 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 5d7f01fd..8b9e458d 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -190,8 +190,8 @@ private async Task DoListCountElementAsync(string key, int maximum) { var nowTicks = DateTime.UtcNow.Ticks; var elements = value.GetQueueAvailableElement([2, 6, 10], nowTicks, maximum); - var runningElements = elements.GetQueueRunningElement(nowTicks); - var runningWaitingForRetryElements = elements.GetQueueWaitingForRetryElement(nowTicks, [2, 6, 10]); + var runningElements = value.GetQueueRunningElement(nowTicks); + var runningWaitingForRetryElements = value.GetQueueWaitingForRetryElement(nowTicks, [2, 6, 10]); return elements.Count + runningElements.Count + runningWaitingForRetryElements.Count; } From 14156cee4b8ce3309681e5b3b9586b23c5b2ee49 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 20:59:28 +0100 Subject: [PATCH 102/135] start clean up --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Endpoints.cs | 2 +- src/SlimData/QueueElementExtensions.cs | 24 +++++++++++-------- src/SlimData/SlimDataInterpreter.cs | 6 ++--- src/SlimFaas/Database/SlimDataService.cs | 6 ++--- src/SlimFaas/SlimWorker.cs | 2 -- .../QueueElementExtentionsTests.cs | 4 ++-- 7 files changed, 24 insertions(+), 22 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 0c4c3d94..ac83ad70 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-832 + image: axaguildev/slimfaas:pr-77-833 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index c5c6aec4..aa1bf12b 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -139,7 +139,7 @@ public static async Task ListRightPopCommand(SlimPersistentState prov var queues = ((ISupplier)provider).Invoke().Queues; if (queues.TryGetValue(key, out var queue)) { - var queueElements = queue.GetQueueAvailableElement([2, 4, 10], nowTicks, count); + var queueElements = queue.GetQueueAvailableElement( nowTicks, count); foreach (var queueElement in queueElements) { Console.WriteLine("Endpoint ListRightPopCommand " + queueElement.Id); diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index bb0874a7..d3e91076 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -23,12 +23,14 @@ public static bool IsTimeout(this QueueElement element, long nowTicks, int timeo return false; } - public static bool IsWaitingForRetry(this QueueElement element, long nowTicks, List retries, int timeoutSeconds=30) + public static bool IsWaitingForRetry(this QueueElement element, long nowTicks) { + List retries= element.Retries; + int timeoutSeconds = element.Timeout; var count = element.RetryQueueElements.Count; if(count == 0 || count > retries.Count ) return false; - if(element.IsFinished(nowTicks, retries, timeoutSeconds)) return false; + if(element.IsFinished(nowTicks)) return false; if(element.IsRunning(nowTicks, timeoutSeconds)) return false; @@ -48,10 +50,12 @@ public static bool IsWaitingForRetry(this QueueElement element, long nowTicks, L return false; } - public static bool IsFinished(this QueueElement queueElement, long nowTicks, List retries, int timeoutSeconds=30) + public static bool IsFinished(this QueueElement queueElement, long nowTicks) { var count = queueElement.RetryQueueElements.Count; if (count <= 0) return false; + List retries= queueElement.Retries; + int timeoutSeconds=queueElement.Timeout; var retryQueueElement = queueElement.RetryQueueElements[^1]; if (retryQueueElement.EndTimeStamp > 0 && !HttpStatusCodesWorthRetrying.Contains(retryQueueElement.HttpCode)) @@ -109,12 +113,12 @@ public static List GetQueueRunningElement(this List return runningElement; } - public static List GetQueueWaitingForRetryElement(this List element, long nowTicks, List retries, int timeoutSeconds=30) + public static List GetQueueWaitingForRetryElement(this List element, long nowTicks) { var waitingForRetry = new List(); foreach (var queueElement in element) { - if (queueElement.IsWaitingForRetry(nowTicks, retries, timeoutSeconds)) + if (queueElement.IsWaitingForRetry(nowTicks)) { waitingForRetry.Add(queueElement); } @@ -122,11 +126,11 @@ public static List GetQueueWaitingForRetryElement(this List GetQueueAvailableElement(this List elements, List retries, long nowTicks, int maximum, int timeoutSeconds=30) + public static List GetQueueAvailableElement(this List elements, long nowTicks, int maximum) { var runningElements = elements.GetQueueRunningElement(nowTicks); - var runningWaitingForRetryElements = elements.GetQueueWaitingForRetryElement(nowTicks, retries); - var finishedElements = elements.GetQueueFinishedElement(nowTicks, retries, timeoutSeconds); + var runningWaitingForRetryElements = elements.GetQueueWaitingForRetryElement(nowTicks); + var finishedElements = elements.GetQueueFinishedElement(nowTicks); var availableElements = new List(); var currentCount = runningElements.Count + runningWaitingForRetryElements.Count; var currentElements = elements.Except(runningElements).Except(runningWaitingForRetryElements).Except(finishedElements); @@ -148,12 +152,12 @@ public static List GetQueueAvailableElement(this List GetQueueFinishedElement(this IList element, long nowTicks, List retries, int timeoutSeconds=30) + public static IList GetQueueFinishedElement(this IList element, long nowTicks) { var queueFinishedElements = new List(); foreach (var queueElement in element) { - if (queueElement.IsFinished(nowTicks, retries, timeoutSeconds)) + if (queueElement.IsFinished(nowTicks)) { queueFinishedElements.Add(queueElement); } diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index a65b7d95..87ec0db7 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -64,13 +64,13 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm retryQueueElement.HttpCode = 504; } - var queueFinishedElements = queue.GetQueueFinishedElement(nowTicks, Retries, RetryTimeout); + var queueFinishedElements = queue.GetQueueFinishedElement(nowTicks); foreach (var queueFinishedElement in queueFinishedElements) { queue.Remove(queueFinishedElement); } - var queueAvailableElements = queue.GetQueueAvailableElement(Retries, nowTicks, addHashSetCommand.Count); + var queueAvailableElements = queue.GetQueueAvailableElement(nowTicks, addHashSetCommand.Count); foreach (var queueAvailableElement in queueAvailableElements) { queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); @@ -146,7 +146,7 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo retryQueueElement.EndTimeStamp = listSetQueueItemStatusCommand.NowTicks; retryQueueElement.HttpCode = listSetQueueItemStatusCommand.HttpCode; - if (queueElement.IsFinished(listSetQueueItemStatusCommand.NowTicks, Retries, RetryTimeout)) + if (queueElement.IsFinished(listSetQueueItemStatusCommand.NowTicks)) { value.Remove(queueElement); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 8b9e458d..5ab4d9c2 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -189,9 +189,9 @@ private async Task DoListCountElementAsync(string key, int maximum) if (data.Queues.TryGetValue(key, out List? value)) { var nowTicks = DateTime.UtcNow.Ticks; - var elements = value.GetQueueAvailableElement([2, 6, 10], nowTicks, maximum); + var elements = value.GetQueueAvailableElement(nowTicks, maximum); var runningElements = value.GetQueueRunningElement(nowTicks); - var runningWaitingForRetryElements = value.GetQueueWaitingForRetryElement(nowTicks, [2, 6, 10]); + var runningWaitingForRetryElements = value.GetQueueWaitingForRetryElement(nowTicks); return elements.Count + runningElements.Count + runningWaitingForRetryElements.Count; } @@ -239,7 +239,7 @@ private async Task DoListCountAvailableElementAsync(string key, int maximu if (data.Queues.TryGetValue(key, out List? value)) { - var elements = value.GetQueueAvailableElement([2, 6, 10], DateTime.UtcNow.Ticks, maximum); + var elements = value.GetQueueAvailableElement(DateTime.UtcNow.Ticks, maximum); var number = elements.Count; return number; } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 324a15a8..6741925b 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -117,10 +117,8 @@ private async Task UpdateTickLastCallIfRequestStillInProgress(IMasterServi { int counterLimit = functionReplicas == 0 ? 10 : 40; long queueLength = await slimFaasQueue.CountElementAsync(functionDeployment); - Console.WriteLine($"--------------QueueLength: {queueLength}"); if (setTickLastCallCounterDictionnary[functionDeployment] > counterLimit) { - Console.WriteLine($"--------------HERE"); setTickLastCallCounterDictionnary[functionDeployment] = 0; if (queueLength > 0 || numberProcessingTasks > 0) diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 28951817..f11fdd9d 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -47,7 +47,7 @@ public static void QueueElementExtensionsGetQueueRunningElement() queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, SlimDataInterpreter.Retries, new List())); queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, SlimDataInterpreter.Retries, new List())); - var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.Retries, nowTicks, 3, 30); + var availableElements = queueElements.GetQueueAvailableElement(nowTicks, 3); Assert.Equal(2, availableElements.Count); Assert.Equal("2", availableElements[0].Id); @@ -58,7 +58,7 @@ public static void QueueElementExtensionsGetQueueRunningElement() Assert.Equal("1", runningElements[0].Id); - var finishedElements = queueElements.GetQueueFinishedElement(nowTicks, SlimDataInterpreter.Retries); + var finishedElements = queueElements.GetQueueFinishedElement(nowTicks); Assert.Equal(4, finishedElements.Count); } From 8a9a29ebe8789984de887c782535f104740e78a3 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 21:32:33 +0100 Subject: [PATCH 103/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimData/Endpoints.cs | 14 ++++++++++---- src/SlimFaas/Database/SlimDataService.cs | 7 +++++-- src/SlimFaas/Kubernetes/KubernetesService.cs | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index ac83ad70..1ca5e875 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-833 + image: axaguildev/slimfaas:pr-77-834 livenessProbe: httpGet: path: /health diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index aa1bf12b..aac110d8 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -139,7 +139,7 @@ public static async Task ListRightPopCommand(SlimPersistentState prov var queues = ((ISupplier)provider).Invoke().Queues; if (queues.TryGetValue(key, out var queue)) { - var queueElements = queue.GetQueueAvailableElement( nowTicks, count); + var queueElements = queue.GetQueueAvailableElement(nowTicks, count); foreach (var queueElement in queueElements) { Console.WriteLine("Endpoint ListRightPopCommand " + queueElement.Id); @@ -160,6 +160,10 @@ public static async Task ListRightPopCommand(SlimPersistentState prov return values; } + + public record ListLeftPushInput(byte[] Value, byte[] RetryInformation); + + public record RetryInformation(List Retries, int RetryTimeoutSeconds); public static Task ListLeftPush(HttpContext context) { @@ -184,13 +188,15 @@ public static Task ListLeftPush(HttpContext context) public static async Task ListLeftPushCommand(SlimPersistentState provider, string key, byte[] value, IRaftCluster cluster, CancellationTokenSource source) { + ListLeftPushInput input = MemoryPackSerializer.Deserialize(value); + RetryInformation retryInformation = MemoryPackSerializer.Deserialize(input.RetryInformation); var logEntry = provider.Interpreter.CreateLogEntry(new ListLeftPushCommand { Key = key, Identifier = Guid.NewGuid().ToString(), - Value = value, + Value = input.Value, NowTicks = DateTime.UtcNow.Ticks, - Retries = SlimDataInterpreter.Retries, - RetryTimeout = SlimDataInterpreter.RetryTimeout, + Retries = retryInformation.Retries, + RetryTimeout = retryInformation.RetryTimeoutSeconds, }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 5ab4d9c2..840379e6 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -114,15 +114,18 @@ public async Task ListLeftPushAsync(string key, byte[] field) private async Task DoListLeftPushAsync(string key, byte[] field) { EndPoint endpoint = await GetAndWaitForLeader(); + Endpoints.RetryInformation retryInformation = new([2, 4, 10], 30); + Endpoints.ListLeftPushInput listLeftPushInput = new(field, MemoryPackSerializer.Serialize(retryInformation)); + byte[] serialize = MemoryPackSerializer.Serialize(listLeftPushInput); if (!cluster.LeadershipToken.IsCancellationRequested) { var simplePersistentState = serviceProvider.GetRequiredService(); - await Endpoints.ListLeftPushCommand(simplePersistentState, key, field, cluster, new CancellationTokenSource()); + await Endpoints.ListLeftPushCommand(simplePersistentState, key, serialize, cluster, new CancellationTokenSource()); } else { using HttpRequestMessage request = new(HttpMethod.Post, new Uri($"{endpoint}SlimData/ListLeftPush?key={key}")); - request.Content = new ByteArrayContent(field); + request.Content = new ByteArrayContent(serialize); using var httpClient = httpClientFactory.CreateClient(HttpClientName); HttpResponseMessage response = await httpClient.SendAsync(request); if ((int)response.StatusCode >= 500) diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index db8d3807..750b1a6c 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -428,7 +428,7 @@ private static async Task> MapPodInformations(V1PodL string? podName = item.Metadata.Name; string deploymentName = item.Metadata.OwnerReferences[0].Name; - PodInformation podInformation = new(podName, started, containerReady && podReady, podIp, deploymentName); + PodInformation podInformation = new(podName, started, started && containerReady && podReady, podIp, deploymentName); result.Add(podInformation); } return result; From f1afb10c52eb1b1f9ae39fd807ff614050878415 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 21:50:14 +0100 Subject: [PATCH 104/135] fix --- README.md | 19 ++++++------------- src/SlimFaas/SendClient.cs | 12 ++++-------- src/SlimFaas/SlimProxyMiddleware.cs | 13 +++++++------ .../SlimProxyMiddlewareTests.cs | 4 ++-- tests/SlimFaas.Tests/SlimWorkerShould.cs | 4 ++-- 5 files changed, 21 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index 848a4b34..b2cb0a4d 100644 --- a/README.md +++ b/README.md @@ -376,20 +376,13 @@ spec: - **SlimFaas/ExcludeDeploymentsFromVisibilityPrivate** : "" - Comma separated list of deployment names or statefulset names - Message from that pods will be considered as public. It is useful if you want to exclude some pods from the private visibility, for example for a backend for frontend. -- **SlimFaas/Retries** : json configuration +- **SlimFaas/Async** : json configuration - Allows you to define a schedule for your functions. If you want to wake up your infrastructure at 07:00 or for example scale down after 60 seconds of inactivity after 07:00 and scale down after 10 seconds of inactivity after 21:00. Time zones are defined as IANA time zones. The full list is available [here](https://nodatime.org/TimeZones) - ````bash { - "TimeZoneID":"Europe/Paris", # Time Zone ID can be found here: https://nodatime.org/TimeZones - "Default":{ - "WakeUp":["07:00"], // Wake up your infrastructure at 07:00 - "ScaleDownTimeout":[ - {"Time":"07:00","Value":20}, // Scale down after 20 seconds of inactivity after 07:00 - {"Time":"21:00","Value":10} // Scale down after 10 seconds of inactivity after 21:00 - ] - } + "Timeout": 30, # Timeout in seconds + "Retries": [2,4,8] # Retry pattern } ```` - **SlimFaas/Schedule** : json configuration @@ -400,10 +393,10 @@ spec: { "TimeZoneID":"Europe/Paris", # Time Zone ID can be found here: https://nodatime.org/TimeZones "Default":{ - "WakeUp":["07:00"], // Wake up your infrastructure at 07:00 + "WakeUp":["07:00"], # Wake up your infrastructure at 07:00 "ScaleDownTimeout":[ - {"Time":"07:00","Value":20}, // Scale down after 20 seconds of inactivity after 07:00 - {"Time":"21:00","Value":10} // Scale down after 10 seconds of inactivity after 21:00 + {"Time":"07:00","Value":20}, # Scale down after 20 seconds of inactivity after 07:00 + {"Time":"21:00","Value":10} # Scale down after 10 seconds of inactivity after 21:00 ] } } diff --git a/src/SlimFaas/SendClient.cs b/src/SlimFaas/SendClient.cs index 3cf5d1a6..794afdd5 100644 --- a/src/SlimFaas/SendClient.cs +++ b/src/SlimFaas/SendClient.cs @@ -4,7 +4,7 @@ namespace SlimFaas; public interface ISendClient { - Task SendHttpRequestAsync(CustomRequest customRequest, HttpContext? context = null, string? baseUrl = null); + Task SendHttpRequestAsync(CustomRequest customRequest, int timeout=30, string? baseUrl = null); Task SendHttpRequestSync(HttpContext httpContext, string functionName, string functionPath, string functionQuery, string? baseUrl = null); @@ -19,7 +19,7 @@ public class SendClient(HttpClient httpClient, ILogger logger) : ISe Environment.GetEnvironmentVariable(EnvironmentVariables.Namespace) ?? EnvironmentVariables.NamespaceDefault; public async Task SendHttpRequestAsync(CustomRequest customRequest, - HttpContext? context = null, string? baseUrl = null) + int timeout=30, string? baseUrl = null) { try { @@ -31,14 +31,10 @@ public async Task SendHttpRequestAsync(CustomRequest custom ComputeTargetUrl(functionUrl, customRequestFunctionName, customRequestPath, customRequestQuery, _namespaceSlimFaas); logger.LogDebug("Sending async request to {TargetUrl}", targetUrl); HttpRequestMessage targetRequestMessage = CreateTargetMessage(customRequest, new Uri(targetUrl)); - if (context != null) - { - return await httpClient.SendAsync(targetRequestMessage, - HttpCompletionOption.ResponseHeadersRead, context.RequestAborted); - } + using var cancellationToken = new CancellationTokenSource(timeout); return await httpClient.SendAsync(targetRequestMessage, - HttpCompletionOption.ResponseHeadersRead); + HttpCompletionOption.ResponseHeadersRead, cancellationToken.Token); } catch (Exception e) { diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index c09b6754..c201e55b 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -310,6 +310,7 @@ private async Task BuildPublishResponseAsync(HttpContext context, HistoryHttpMem await InitCustomRequest(context, context.Request, "", functionPath); List tasks = new(); + var queryString = context.Request.QueryString.ToUriComponent(); foreach (DeploymentInformation function in functions) { foreach (var pod in function.Pods) @@ -332,7 +333,7 @@ private async Task BuildPublishResponseAsync(HttpContext context, HistoryHttpMem var baseUrl = SlimDataEndpoint.Get(pod, baseFunctionPodUrl); logger.LogDebug("Sending event {EventName} to {FunctionDeployment} at {BaseUrl} with path {FunctionPath} and query {UriComponent}", eventName, function.Deployment, baseUrl, functionPath, context.Request.QueryString.ToUriComponent()); - Task task = SendRequest(context, sendClient, customRequest with {FunctionName = function.Deployment}, baseUrl, logger, eventName); + Task task = SendRequest(queryString, sendClient, customRequest with {FunctionName = function.Deployment}, baseUrl, logger, eventName); tasks.Add(task); } } @@ -342,7 +343,7 @@ private async Task BuildPublishResponseAsync(HttpContext context, HistoryHttpMem foreach (string baseUrl in slimFaasSubscribeEvent.Value) { logger.LogDebug("Sending event {EventName} to {BaseUrl} with path {FunctionPath} and query {UriComponent}", eventName, baseUrl, functionPath, context.Request.QueryString.ToUriComponent()); - Task task = SendRequest(context, sendClient, customRequest with {FunctionName = ""}, baseUrl, logger, eventName); + Task task = SendRequest(queryString, sendClient, customRequest with {FunctionName = ""}, baseUrl, logger, eventName); tasks.Add(task); } } @@ -366,20 +367,20 @@ private async Task BuildPublishResponseAsync(HttpContext context, HistoryHttpMem context.Response.StatusCode = 204; } - private static async Task SendRequest(HttpContext context, ISendClient sendClient, CustomRequest customRequest, string baseUrl, ILogger logger, string eventName) + private static async Task SendRequest(string queryString, ISendClient sendClient, CustomRequest customRequest, string baseUrl, ILogger logger, string eventName) { try { - using HttpResponseMessage responseMessage = await sendClient.SendHttpRequestAsync(customRequest, context, baseUrl); + using HttpResponseMessage responseMessage = await sendClient.SendHttpRequestAsync(customRequest, 30, baseUrl); logger.LogDebug( "Response from event {EventName} to {FunctionDeployment} at {BaseUrl} with path {FunctionPath} and query {UriComponent} is {StatusCode}", - eventName, customRequest.FunctionName, baseUrl, customRequest.Path, context.Request.QueryString.ToUriComponent(), + eventName, customRequest.FunctionName, baseUrl, customRequest.Path, queryString, responseMessage.StatusCode); } catch (Exception e) { logger.LogError(e, "Error in sending event {EventName} to {FunctionDeployment} at {BaseUrl} with path {FunctionPath} and query {UriComponent}", - eventName, customRequest.FunctionName, baseUrl, customRequest.Path, context.Request.QueryString.ToUriComponent()); + eventName, customRequest.FunctionName, baseUrl, customRequest.Path, queryString); } } diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index e87fa792..6f8bd486 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -89,7 +89,7 @@ internal record SendData(string FunctionName, string Path, string BaseUrl); internal class SendClientMock : ISendClient { public IList SendDatas = new List(); - public Task SendHttpRequestAsync(CustomRequest customRequest, HttpContext? context = null, string? baseUrl = null) + public Task SendHttpRequestAsync(CustomRequest customRequest, int timeout, string? baseUrl = null) { HttpResponseMessage responseMessage = new HttpResponseMessage(); responseMessage.StatusCode = HttpStatusCode.OK; @@ -174,7 +174,7 @@ public async Task CallFunctionInSyncModeAndReturnOk(string path, HttpStatusCode HttpResponseMessage responseMessage = new HttpResponseMessage(); responseMessage.StatusCode = HttpStatusCode.OK; Mock sendClientMock = new Mock(); - sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny())) + sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(responseMessage); using IHost host = await new HostBuilder() diff --git a/tests/SlimFaas.Tests/SlimWorkerShould.cs b/tests/SlimFaas.Tests/SlimWorkerShould.cs index 8f6900fc..efacd559 100644 --- a/tests/SlimFaas.Tests/SlimWorkerShould.cs +++ b/tests/SlimFaas.Tests/SlimWorkerShould.cs @@ -18,7 +18,7 @@ public async Task OnlyCallOneFunctionAsync() responseMessage.StatusCode = HttpStatusCode.OK; Mock sendClientMock = new Mock(); - sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny())) + sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(responseMessage); Mock serviceProvider = new Mock(); @@ -96,7 +96,7 @@ public async Task OnlyCallOneFunctionAsync() await Task.Delay(3000); Assert.True(task.IsCompleted); - sendClientMock.Verify(v => v.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny()), + sendClientMock.Verify(v => v.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } From 8e3511178de9d291f9f22d517676c08ad2e3609a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Thu, 19 Dec 2024 21:54:12 +0100 Subject: [PATCH 105/135] clean --- src/SlimData/Endpoints.cs | 9 ++++---- src/SlimFaas/Database/SlimDataService.cs | 4 ++-- src/SlimFaas/SlimfaasSerializer.cs | 28 ------------------------ 3 files changed, 7 insertions(+), 34 deletions(-) delete mode 100644 src/SlimFaas/SlimfaasSerializer.cs diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index aac110d8..b4a4e623 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -5,7 +5,11 @@ namespace SlimData; - +[MemoryPackable] +public partial record ListLeftPushInput(byte[] Value, byte[] RetryInformation); + +[MemoryPackable] +public partial record RetryInformation(List Retries, int RetryTimeoutSeconds); [MemoryPackable] public partial record QueueItemStatus(string Id="", int HttpCode=0); @@ -160,10 +164,7 @@ public static async Task ListRightPopCommand(SlimPersistentState prov return values; } - - public record ListLeftPushInput(byte[] Value, byte[] RetryInformation); - public record RetryInformation(List Retries, int RetryTimeoutSeconds); public static Task ListLeftPush(HttpContext context) { diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 840379e6..48230ba8 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -114,8 +114,8 @@ public async Task ListLeftPushAsync(string key, byte[] field) private async Task DoListLeftPushAsync(string key, byte[] field) { EndPoint endpoint = await GetAndWaitForLeader(); - Endpoints.RetryInformation retryInformation = new([2, 4, 10], 30); - Endpoints.ListLeftPushInput listLeftPushInput = new(field, MemoryPackSerializer.Serialize(retryInformation)); + RetryInformation retryInformation = new([2, 4, 10], 30); + ListLeftPushInput listLeftPushInput = new(field, MemoryPackSerializer.Serialize(retryInformation)); byte[] serialize = MemoryPackSerializer.Serialize(listLeftPushInput); if (!cluster.LeadershipToken.IsCancellationRequested) { diff --git a/src/SlimFaas/SlimfaasSerializer.cs b/src/SlimFaas/SlimfaasSerializer.cs deleted file mode 100644 index 4239abd1..00000000 --- a/src/SlimFaas/SlimfaasSerializer.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Text.Json; -using MemoryPack; - -namespace SlimFaas; - -public class SlimfaasSerializer -{ - public static byte[] GetBytes(string str) - { - byte[] bytes = new byte[str.Length * sizeof(char)]; - Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); - return bytes; - } - - // Do NOT use on arbitrary bytes; only use on GetBytes's output on the SAME system - public static string GetString(byte[] bytes) - { - char[] chars = new char[bytes.Length / sizeof(char)]; - Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length); - return new string(chars); - } - - public static CustomRequest Deserialize(byte[] data) => - MemoryPackSerializer.Deserialize(data); - - public static byte[] SerializeBin(CustomRequest data) => - MemoryPackSerializer.Serialize(data); -} From de785de9cd3a37af5b20ed152edae602592e56d2 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 20 Dec 2024 12:25:25 +0100 Subject: [PATCH 106/135] update --- src/SlimData/Commands/ListLeftPushCommand.cs | 19 +++++++++-- src/SlimData/Commands/LogSnapshotCommand.cs | 21 ++++++++++-- src/SlimData/Endpoints.cs | 9 +++++ src/SlimData/QueueElementExtensions.cs | 34 +++++++------------ src/SlimData/SlimDataInterpreter.cs | 12 ++++--- .../QueueElementExtentionsTests.cs | 17 +++++----- 6 files changed, 74 insertions(+), 38 deletions(-) diff --git a/src/SlimData/Commands/ListLeftPushCommand.cs b/src/SlimData/Commands/ListLeftPushCommand.cs index 4ca34cb0..faeaac3f 100644 --- a/src/SlimData/Commands/ListLeftPushCommand.cs +++ b/src/SlimData/Commands/ListLeftPushCommand.cs @@ -18,9 +18,11 @@ public struct ListLeftPushCommand : ISerializable public List Retries { get; set; } + public List HttpStatusCodesWorthRetrying { get; set; } + public ReadOnlyMemory Value { get; set; } - long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + Value.Length + Encoding.UTF8.GetByteCount(Identifier) + sizeof(long) + sizeof(int) + Retries.Count * sizeof(int); + long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Key) + Value.Length + Encoding.UTF8.GetByteCount(Identifier) + sizeof(long) + sizeof(int) + Retries.Count * sizeof(int) + sizeof(int) + sizeof(int) + HttpStatusCodesWorthRetrying.Count * sizeof(int); public async ValueTask WriteToAsync(TWriter writer, CancellationToken token) where TWriter : notnull, IAsyncBinaryWriter @@ -38,6 +40,12 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t { await writer.WriteLittleEndianAsync(retry, token).ConfigureAwait(false); } + await writer.WriteLittleEndianAsync(HttpStatusCodesWorthRetrying.Count, token).ConfigureAwait(false); + foreach (var httpStatus in HttpStatusCodesWorthRetrying) + { + await writer.WriteLittleEndianAsync(httpStatus, token).ConfigureAwait(false); + } + } #pragma warning disable CA2252 @@ -56,6 +64,12 @@ public static async ValueTask ReadFromAsync(TReade { retries.Add(await reader.ReadLittleEndianAsync(token).ConfigureAwait(false)); } + var httpStatusCodesWorthRetryingCount = await reader.ReadLittleEndianAsync(token).ConfigureAwait(false); + var httpStatusCodesWorthRetrying = new List(httpStatusCodesWorthRetryingCount); + while (httpStatusCodesWorthRetryingCount-- > 0) + { + httpStatusCodesWorthRetrying.Add(await reader.ReadLittleEndianAsync(token).ConfigureAwait(false)); + } return new ListLeftPushCommand { @@ -64,7 +78,8 @@ public static async ValueTask ReadFromAsync(TReade NowTicks = nowTicks, RetryTimeout = timeout, Retries = retries, - Value = value.Memory.ToArray() + Value = value.Memory.ToArray(), + HttpStatusCodesWorthRetrying = httpStatusCodesWorthRetrying }; } } \ No newline at end of file diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index 3d2a4182..b7269dc1 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -43,6 +43,9 @@ public readonly struct LogSnapshotCommand(Dictionary(TWriter writer, CancellationToken t await writer.WriteLittleEndianAsync(valueRetry, token).ConfigureAwait(false); } - await writer.WriteLittleEndianAsync(value.RetryQueueElements.Count, token).ConfigureAwait(false); foreach (var retryQueueElement in value.RetryQueueElements) { await writer.WriteBigEndianAsync(retryQueueElement.StartTimeStamp, token).ConfigureAwait(false); await writer.WriteBigEndianAsync(retryQueueElement.EndTimeStamp, token).ConfigureAwait(false); await writer.WriteLittleEndianAsync(retryQueueElement.HttpCode, token).ConfigureAwait(false); - }; + } + + await writer.WriteLittleEndianAsync(value.HttpStatusCodesWorthRetrying.Count, token).ConfigureAwait(false); + foreach (var httpStatusCode in value.HttpStatusCodesWorthRetrying) + { + await writer.WriteLittleEndianAsync(httpStatusCode, token).ConfigureAwait(false); + } } } @@ -168,7 +176,14 @@ public static async ValueTask ReadFromAsync(TReader retryQueueElements.Add(new QueueHttpTryElement(startTimestamp, endTimestamp, httpCode)); } - queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, timeout, retries, retryQueueElements)); + var countHttpStatusCodesWorthRetrying = await reader.ReadLittleEndianAsync(token); + var httpStatusCodesWorthRetrying = new List(countHttpStatusCodesWorthRetrying); + while (countHttpStatusCodesWorthRetrying-- > 0) + { + httpStatusCodesWorthRetrying.Add(await reader.ReadLittleEndianAsync(token)); + } + + queue.Add(new QueueElement(value.Memory, id.ToString(), insertTimeStamp, timeout, retries, retryQueueElements, httpStatusCodesWorthRetrying)); } queues.Add(key.ToString(), queue); diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index b4a4e623..6a7dff1e 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -186,6 +186,14 @@ public static Task ListLeftPush(HttpContext context) }); } + public static int[] HttpStatusCodesWorthRetrying = + [ + // 408 , // HttpStatusCode.RequestTimeout, + 500, // HttpStatusCode.InternalServerError, + 502, // HttpStatusCode.BadGateway, + 503, // HttpStatusCode.ServiceUnavailable, + //504, // HttpStatusCode.GatewayTimeout + ]; public static async Task ListLeftPushCommand(SlimPersistentState provider, string key, byte[] value, IRaftCluster cluster, CancellationTokenSource source) { @@ -198,6 +206,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin NowTicks = DateTime.UtcNow.Ticks, Retries = retryInformation.Retries, RetryTimeout = retryInformation.RetryTimeoutSeconds, + HttpStatusCodesWorthRetrying = new List(HttpStatusCodesWorthRetrying) }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index d3e91076..d1f3b416 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -2,18 +2,12 @@ public static class QueueElementExtensions { - public static int[] HttpStatusCodesWorthRetrying = - [ - // 408 , // HttpStatusCode.RequestTimeout, - 500, // HttpStatusCode.InternalServerError, - 502, // HttpStatusCode.BadGateway, - 503, // HttpStatusCode.ServiceUnavailable, - //504, // HttpStatusCode.GatewayTimeout - ]; + - public static bool IsTimeout(this QueueElement element, long nowTicks, int timeout=30) + public static bool IsTimeout(this QueueElement element, long nowTicks) { if (element.RetryQueueElements.Count <= 0) return false; + int timeout=element.Timeout; var retryQueueElement = element.RetryQueueElements[^1]; if (retryQueueElement.EndTimeStamp == 0 && retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) @@ -26,17 +20,16 @@ public static bool IsTimeout(this QueueElement element, long nowTicks, int timeo public static bool IsWaitingForRetry(this QueueElement element, long nowTicks) { List retries= element.Retries; - int timeoutSeconds = element.Timeout; var count = element.RetryQueueElements.Count; if(count == 0 || count > retries.Count ) return false; if(element.IsFinished(nowTicks)) return false; - if(element.IsRunning(nowTicks, timeoutSeconds)) return false; + if(element.IsRunning(nowTicks)) return false; var retryQueueElement = element.RetryQueueElements[^1]; var retryTimeout = retries[count - 1]; - if(element.IsTimeout(nowTicks, timeoutSeconds) && retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(retryTimeout).Ticks <= nowTicks) + if(element.IsTimeout(nowTicks) && retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(retryTimeout).Ticks <= nowTicks) { return true; } @@ -55,17 +48,16 @@ public static bool IsFinished(this QueueElement queueElement, long nowTicks) var count = queueElement.RetryQueueElements.Count; if (count <= 0) return false; List retries= queueElement.Retries; - int timeoutSeconds=queueElement.Timeout; var retryQueueElement = queueElement.RetryQueueElements[^1]; if (retryQueueElement.EndTimeStamp > 0 && - !HttpStatusCodesWorthRetrying.Contains(retryQueueElement.HttpCode)) + !queueElement.HttpStatusCodesWorthRetrying.Contains(retryQueueElement.HttpCode)) { return true; } if (retries.Count < count) { - if (queueElement.IsTimeout(nowTicks, timeoutSeconds) || retryQueueElement.EndTimeStamp > 0) + if (queueElement.IsTimeout(nowTicks) || retryQueueElement.EndTimeStamp > 0) { return true; } @@ -74,24 +66,24 @@ public static bool IsFinished(this QueueElement queueElement, long nowTicks) return false; } - public static bool IsRunning(this QueueElement queueElement, long nowTicks, int timeoutSeconds=30) + public static bool IsRunning(this QueueElement queueElement, long nowTicks) { if (queueElement.RetryQueueElements.Count <= 0) return false; var retryQueueElement = queueElement.RetryQueueElements[^1]; if (retryQueueElement.EndTimeStamp == 0 && - !queueElement.IsTimeout(nowTicks, timeoutSeconds)) + !queueElement.IsTimeout(nowTicks)) { return true; } return false; } - public static List GetQueueTimeoutElement(this List element, long nowTicks, int timeout=30) + public static List GetQueueTimeoutElement(this List element, long nowTicks) { var timeoutElements = new List(); foreach (var queueElement in element) { - if(queueElement.IsTimeout(nowTicks, timeout)) + if(queueElement.IsTimeout(nowTicks)) { timeoutElements.Add(queueElement); } @@ -100,12 +92,12 @@ public static List GetQueueTimeoutElement(this List return timeoutElements; } - public static List GetQueueRunningElement(this List element, long nowTicks, int timeoutSeconds=30) + public static List GetQueueRunningElement(this List element, long nowTicks) { var runningElement = new List(); foreach (var queueElement in element) { - if(queueElement.IsRunning(nowTicks, timeoutSeconds)) + if(queueElement.IsRunning(nowTicks)) { runningElement.Add(queueElement); } diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 87ec0db7..e94e21ff 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -16,7 +16,9 @@ public class QueueElement( long insertTimeStamp, int timeout, List retries, - IList retryQueueElements) + IList retryQueueElements, + List httpStatusCodesWorthRetrying + ) { public ReadOnlyMemory Value { get; } = value; public string Id { get; } = id; @@ -26,6 +28,8 @@ public class QueueElement( public int Timeout { get; } = timeout; public IList RetryQueueElements { get; } = retryQueueElements; + + public List HttpStatusCodesWorthRetrying { get; } = httpStatusCodesWorthRetrying; } public class QueueHttpTryElement(long startTimeStamp=0, long endTimeStamp=0, int httpCode=0) @@ -56,7 +60,7 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm if (queues.TryGetValue(addHashSetCommand.Key, out var queue)) { var nowTicks =addHashSetCommand.NowTicks; - var queueTimeoutElements = queue.GetQueueTimeoutElement(nowTicks, RetryTimeout); + var queueTimeoutElements = queue.GetQueueTimeoutElement(nowTicks); foreach (var queueTimeoutElement in queueTimeoutElements) { var retryQueueElement = queueTimeoutElement.RetryQueueElements[^1]; @@ -105,9 +109,9 @@ public ValueTask ListLeftPushAsync(ListLeftPushCommand addHashSetCommand, Cancel internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCommand, Dictionary> queues) { if (queues.TryGetValue(listLeftPushCommand.Key, out List? value)) - value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List())); + value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List(), listLeftPushCommand.HttpStatusCodesWorthRetrying)); else - queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List())}); + queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List(), listLeftPushCommand.HttpStatusCodesWorthRetrying)}); // print all queue elements Console.WriteLine("DoListLeftPushAsync key " + listLeftPushCommand.Key + " Identifier " + listLeftPushCommand.Identifier); var elements = queues[listLeftPushCommand.Key]; diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index f11fdd9d..6d94d099 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -11,41 +11,42 @@ public static void QueueElementExtensionsGetQueueRunningElement() var timeout = 30; var timeoutSpanTicks = TimeSpan.FromSeconds(31).Ticks; List queueElements = new(); + var httpRetriesCode = new List(Endpoints.HttpStatusCodesWorthRetrying) ; queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks -100, nowTicks, 500), new(nowTicks -50, nowTicks, 500), new(nowTicks -20, nowTicks, 500), new(nowTicks -10, nowTicks, 500), - })); + }, httpRetriesCode)); queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks - timeoutSpanTicks -100, nowTicks, 500), new(nowTicks- timeoutSpanTicks -50, nowTicks, 500), new(nowTicks- timeoutSpanTicks -30, nowTicks, 500), new(nowTicks- timeoutSpanTicks -20, 0, 0), - })); + }, httpRetriesCode)); queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks -100, nowTicks, 200), - })); + }, httpRetriesCode)); queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 200, nowTicks, 500), new(nowTicks- 100, 0, 0), - })); + }, httpRetriesCode)); queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, timeout, SlimDataInterpreter.Retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 400, nowTicks, 500), new(nowTicks- timeoutSpanTicks, 0, 0), - })); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, timeout, SlimDataInterpreter.Retries, new List())); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, SlimDataInterpreter.Retries, new List())); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, SlimDataInterpreter.Retries, new List())); + }, httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, timeout, SlimDataInterpreter.Retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, SlimDataInterpreter.Retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, SlimDataInterpreter.Retries, new List(), httpRetriesCode)); var availableElements = queueElements.GetQueueAvailableElement(nowTicks, 3); From cb585a7a75f4dd17d09fbe71eb5aad996ccff3ff Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 20 Dec 2024 12:50:29 +0100 Subject: [PATCH 107/135] fix --- tests/SlimData.Tests/CommandsTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/SlimData.Tests/CommandsTests.cs b/tests/SlimData.Tests/CommandsTests.cs index e030106d..8cca699c 100644 --- a/tests/SlimData.Tests/CommandsTests.cs +++ b/tests/SlimData.Tests/CommandsTests.cs @@ -17,7 +17,7 @@ public static async Task InterpreterWithPersistentState() { byte[] bytes = RandomBytes(1000); using var wal = new SlimPersistentState(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - var entry1 = wal.CreateLogEntry(new ListLeftPushCommand { Key = "youhou" , Value = bytes, Identifier = "1", RetryTimeout = 100, Retries = new List { 1, 2, 3 }, NowTicks = DateTime.UtcNow.Ticks }); + var entry1 = wal.CreateLogEntry(new ListLeftPushCommand { Key = "youhou" , Value = bytes, Identifier = "1", RetryTimeout = 100, Retries = new List { 1, 2, 3 }, NowTicks = DateTime.UtcNow.Ticks, HttpStatusCodesWorthRetrying = new List() }); await wal.AppendAsync(entry1); Assert.Empty(wal.SlimDataState.Queues); await wal.CommitAsync(CancellationToken.None); From 41ea8dbc16560fe603d9d5faaf4b7f13bd43b6b9 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 20 Dec 2024 22:11:44 +0100 Subject: [PATCH 108/135] update --- README.md | 16 ++++-- demo/deployment-functions.yml | 2 +- demo/deployment-slimfaas.yml | 8 +-- ...tatusCommand.cs => ListCallbackCommand.cs} | 6 +-- src/SlimData/Commands/LogSnapshotCommand.cs | 16 +++--- src/SlimData/Endpoints.cs | 16 +++--- src/SlimData/QueueElementExtensions.cs | 8 +-- src/SlimData/SlimDataInterpreter.cs | 46 ++++++++-------- src/SlimData/Startup.cs | 12 ++--- src/SlimFaas/Database/SlimDataService.cs | 4 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 52 ++++++++++++++++--- .../Kubernetes/MockKubernetesService.cs | 6 ++- src/SlimFaas/SendClient.cs | 8 +-- src/SlimFaas/SlimFaas.csproj | 2 +- src/SlimFaas/SlimWorker.cs | 2 +- .../QueueElementExtentionsTests.cs | 4 +- .../HistorySynchronizationWorkerShould.cs | 4 +- .../ReplicasScaleWorkerShould.cs | 10 ++-- .../ReplicasSynchronizationWorkerShould.cs | 4 +- .../SlimProxyMiddlewareTests.cs | 7 +-- tests/SlimFaas.Tests/SlimWorkerShould.cs | 10 ++-- 21 files changed, 147 insertions(+), 96 deletions(-) rename src/SlimData/Commands/{ListSetQueueItemStatusCommand.cs => ListCallbackCommand.cs} (85%) diff --git a/README.md b/README.md index b2cb0a4d..a2e57c7b 100644 --- a/README.md +++ b/README.md @@ -376,13 +376,21 @@ spec: - **SlimFaas/ExcludeDeploymentsFromVisibilityPrivate** : "" - Comma separated list of deployment names or statefulset names - Message from that pods will be considered as public. It is useful if you want to exclude some pods from the private visibility, for example for a backend for frontend. -- **SlimFaas/Async** : json configuration - - Allows you to define a schedule for your functions. If you want to wake up your infrastructure at 07:00 or for example scale down after 60 seconds of inactivity after 07:00 and scale down after 10 seconds of inactivity after 21:00. Time zones are defined as IANA time zones. The full list is available [here](https://nodatime.org/TimeZones) +- **SlimFaas/Configuration** : json configuration + - Allows you to define a configuration for your functions. For example, you can define a timeout for HTTP calls, a retry pattern for timeouts and HTTP status codes. ````bash { - "Timeout": 30, # Timeout in seconds - "Retries": [2,4,8] # Retry pattern + "DefaultSync":{ + "HttpTimeout": 30, # Timeout in seconds + "TimeoutRetries": [2,4,8] # Retry pattern + "HttpStatusRetries": [500,502,503] # Retry pattern + } + "DefaultAsync":{ + "HttpTimeout": 30, # Timeout in seconds + "TimeoutRetries": [2,4,8] # Retry pattern + "HttpStatusRetries": [500,502,503] # Retry pattern + } } ```` - **SlimFaas/Schedule** : json configuration diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 1fc9f77d..365d2e28 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -76,7 +76,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci2 - image: axaguildev/fibonacci:77-815 + image: axaguildev/fibonacci:77-839 livenessProbe: httpGet: path: /health diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 1ca5e875..ded3fe00 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 1 + replicas: 3 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -137,9 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" - - name: SLIMDATA_CONFIGURATION - value: | - {"coldStart":"true"} + #- name: SLIMDATA_CONFIGURATION + # value: | + # {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"} diff --git a/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs b/src/SlimData/Commands/ListCallbackCommand.cs similarity index 85% rename from src/SlimData/Commands/ListSetQueueItemStatusCommand.cs rename to src/SlimData/Commands/ListCallbackCommand.cs index d6b4ac5f..99534c23 100644 --- a/src/SlimData/Commands/ListSetQueueItemStatusCommand.cs +++ b/src/SlimData/Commands/ListCallbackCommand.cs @@ -5,7 +5,7 @@ namespace SlimData.Commands; -public struct ListSetQueueItemStatusCommand : ISerializable +public struct ListCallbackCommand : ISerializable { public const int Id = 15; @@ -29,12 +29,12 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t long? IDataTransferObject.Length => Encoding.UTF8.GetByteCount(Identifier) + sizeof(int) + Encoding.UTF8.GetByteCount(Key) + sizeof(long); - public static async ValueTask ReadFromAsync(TReader reader, CancellationToken token) where TReader : notnull, IAsyncBinaryReader + public static async ValueTask ReadFromAsync(TReader reader, CancellationToken token) where TReader : notnull, IAsyncBinaryReader { var identifier = await reader.DecodeAsync( new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); var key = await reader.DecodeAsync( new DecodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token: token).ConfigureAwait(false); - return new ListSetQueueItemStatusCommand + return new ListCallbackCommand { Identifier = identifier.ToString(), Key = key.ToString(), diff --git a/src/SlimData/Commands/LogSnapshotCommand.cs b/src/SlimData/Commands/LogSnapshotCommand.cs index b7269dc1..050effe2 100644 --- a/src/SlimData/Commands/LogSnapshotCommand.cs +++ b/src/SlimData/Commands/LogSnapshotCommand.cs @@ -36,7 +36,7 @@ public readonly struct LogSnapshotCommand(Dictionary(TWriter writer, CancellationToken t await writer.WriteAsync(value.Value, LengthFormat.Compressed, token).ConfigureAwait(false); await writer.EncodeAsync(value.Id.AsMemory(), new EncodingContext(Encoding.UTF8, false), LengthFormat.LittleEndian, token).ConfigureAwait(false); await writer.WriteBigEndianAsync(value.InsertTimeStamp, token).ConfigureAwait(false); - await writer.WriteLittleEndianAsync(value.Timeout, token).ConfigureAwait(false); - await writer.WriteLittleEndianAsync(value.Retries.Count, token).ConfigureAwait(false); - foreach (var valueRetry in value.Retries) + await writer.WriteLittleEndianAsync(value.HttpTimeout, token).ConfigureAwait(false); + await writer.WriteLittleEndianAsync(value.TimeoutRetries.Count, token).ConfigureAwait(false); + foreach (var valueRetry in value.TimeoutRetries) { await writer.WriteLittleEndianAsync(valueRetry, token).ConfigureAwait(false); } @@ -102,8 +102,8 @@ public async ValueTask WriteToAsync(TWriter writer, CancellationToken t await writer.WriteLittleEndianAsync(retryQueueElement.HttpCode, token).ConfigureAwait(false); } - await writer.WriteLittleEndianAsync(value.HttpStatusCodesWorthRetrying.Count, token).ConfigureAwait(false); - foreach (var httpStatusCode in value.HttpStatusCodesWorthRetrying) + await writer.WriteLittleEndianAsync(value.HttpStatusRetries.Count, token).ConfigureAwait(false); + foreach (var httpStatusCode in value.HttpStatusRetries) { await writer.WriteLittleEndianAsync(httpStatusCode, token).ConfigureAwait(false); } diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index 6a7dff1e..fca8719c 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -61,7 +61,7 @@ public static async Task DoAsync(HttpContext context, RespondDelegate respondDel } } - public static Task AddHashSet(HttpContext context) + public static Task AddHashSetAsync(HttpContext context) { return DoAsync(context, async (cluster, provider, source) => { @@ -95,7 +95,7 @@ public static async Task AddHashSetCommand(SlimPersistentState provider, string await cluster.ReplicateAsync(logEntry, source.Token); } - public static Task ListRightPop(HttpContext context) + public static Task ListRightPopAsync(HttpContext context) { return DoAsync(context, async (cluster, provider, source) => { @@ -166,7 +166,7 @@ public static async Task ListRightPopCommand(SlimPersistentState prov } - public static Task ListLeftPush(HttpContext context) + public static Task ListLeftPushAsync(HttpContext context) { return DoAsync(context, async (cluster, provider, source) => { @@ -212,7 +212,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin await cluster.ReplicateAsync(logEntry, source.Token); } - public static Task ListSetQueueItemStatus(HttpContext context) + public static Task ListCallbackAsync(HttpContext context) { return DoAsync(context, async (cluster, provider, source) => { @@ -229,11 +229,11 @@ public static Task ListSetQueueItemStatus(HttpContext context) await inputStream.CopyToAsync(memoryStream, source.Token); var value = memoryStream.ToArray(); var list = MemoryPackSerializer.Deserialize(value); - await ListSetQueueItemStatusCommand(provider, key, list, cluster, source); + await ListCallbackCommandAsync(provider, key, list, cluster, source); }); } - public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provider, string key, ListQueueItemStatus list, IRaftCluster cluster, CancellationTokenSource source) + public static async Task ListCallbackCommandAsync(SlimPersistentState provider, string key, ListQueueItemStatus list, IRaftCluster cluster, CancellationTokenSource source) { if (list.Items == null) { @@ -243,7 +243,7 @@ public static async Task ListSetQueueItemStatusCommand(SlimPersistentState provi foreach (var queueItemStatus in list.Items) { var logEntry = - provider.Interpreter.CreateLogEntry(new ListSetQueueItemStatusCommand + provider.Interpreter.CreateLogEntry(new ListCallbackCommand { Identifier = queueItemStatus.Id, Key = key, @@ -270,7 +270,7 @@ private static (string key, string value) GetKeyValue(IFormCollection form) return (key, value); } - public static Task AddKeyValue(HttpContext context) + public static Task AddKeyValueAsync(HttpContext context) { return DoAsync(context, async (cluster, provider, source) => { diff --git a/src/SlimData/QueueElementExtensions.cs b/src/SlimData/QueueElementExtensions.cs index d1f3b416..4a3db50f 100644 --- a/src/SlimData/QueueElementExtensions.cs +++ b/src/SlimData/QueueElementExtensions.cs @@ -7,7 +7,7 @@ public static class QueueElementExtensions public static bool IsTimeout(this QueueElement element, long nowTicks) { if (element.RetryQueueElements.Count <= 0) return false; - int timeout=element.Timeout; + int timeout=element.HttpTimeout; var retryQueueElement = element.RetryQueueElements[^1]; if (retryQueueElement.EndTimeStamp == 0 && retryQueueElement.StartTimeStamp + TimeSpan.FromSeconds(timeout).Ticks <= nowTicks) @@ -19,7 +19,7 @@ public static bool IsTimeout(this QueueElement element, long nowTicks) public static bool IsWaitingForRetry(this QueueElement element, long nowTicks) { - List retries= element.Retries; + List retries= element.TimeoutRetries; var count = element.RetryQueueElements.Count; if(count == 0 || count > retries.Count ) return false; @@ -47,10 +47,10 @@ public static bool IsFinished(this QueueElement queueElement, long nowTicks) { var count = queueElement.RetryQueueElements.Count; if (count <= 0) return false; - List retries= queueElement.Retries; + List retries= queueElement.TimeoutRetries; var retryQueueElement = queueElement.RetryQueueElements[^1]; if (retryQueueElement.EndTimeStamp > 0 && - !queueElement.HttpStatusCodesWorthRetrying.Contains(retryQueueElement.HttpCode)) + !queueElement.HttpStatusRetries.Contains(retryQueueElement.HttpCode)) { return true; } diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index e94e21ff..a4b9b101 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -14,22 +14,22 @@ public class QueueElement( ReadOnlyMemory value, string id, long insertTimeStamp, - int timeout, - List retries, + int httpTimeout, + List timeoutRetries, IList retryQueueElements, - List httpStatusCodesWorthRetrying + List httpStatusRetries ) { public ReadOnlyMemory Value { get; } = value; public string Id { get; } = id; public long InsertTimeStamp { get; } = insertTimeStamp; - public List Retries { get; } = retries; + public List TimeoutRetries { get; } = timeoutRetries; - public int Timeout { get; } = timeout; + public int HttpTimeout { get; } = httpTimeout; public IList RetryQueueElements { get; } = retryQueueElements; - public List HttpStatusCodesWorthRetrying { get; } = httpStatusCodesWorthRetrying; + public List HttpStatusRetries { get; } = httpStatusRetries; } public class QueueHttpTryElement(long startTimeStamp=0, long endTimeStamp=0, int httpCode=0) @@ -131,26 +131,26 @@ internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCo } [CommandHandler] - public ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand addHashSetCommand, CancellationToken token) + public ValueTask ListCallbackAsync(ListCallbackCommand addHashSetCommand, CancellationToken token) { - return DoListSetQueueItemStatusAsync(addHashSetCommand, SlimDataState.Queues); + return DoListCallbackAsync(addHashSetCommand, SlimDataState.Queues); } - internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand listSetQueueItemStatusCommand, Dictionary> queues) + internal static ValueTask DoListCallbackAsync(ListCallbackCommand listCallbackCommand, Dictionary> queues) { - if (!queues.TryGetValue(listSetQueueItemStatusCommand.Key, out List? value)) return default; + if (!queues.TryGetValue(listCallbackCommand.Key, out List? value)) return default; - Console.WriteLine("DoListSetQueueItemStatusAsync QueueKey " + listSetQueueItemStatusCommand.Key + " Identifier " + listSetQueueItemStatusCommand.Identifier); - var queueElement = value.FirstOrDefault(x => x.Id == listSetQueueItemStatusCommand.Identifier); + Console.WriteLine("DoListCallbackAsync QueueKey " + listCallbackCommand.Key + " Identifier " + listCallbackCommand.Identifier); + var queueElement = value.FirstOrDefault(x => x.Id == listCallbackCommand.Identifier); if (queueElement == null) { return default; } var retryQueueElement = queueElement.RetryQueueElements[^1]; - retryQueueElement.EndTimeStamp = listSetQueueItemStatusCommand.NowTicks; - retryQueueElement.HttpCode = listSetQueueItemStatusCommand.HttpCode; + retryQueueElement.EndTimeStamp = listCallbackCommand.NowTicks; + retryQueueElement.HttpCode = listCallbackCommand.HttpCode; - if (queueElement.IsFinished(listSetQueueItemStatusCommand.NowTicks)) + if (queueElement.IsFinished(listCallbackCommand.NowTicks)) { value.Remove(queueElement); } @@ -158,14 +158,14 @@ internal static ValueTask DoListSetQueueItemStatusAsync(ListSetQueueItemStatusCo // print all queue elements foreach (var queueElemen in value) { - Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement Id " + queueElemen.Id); - Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement Value " + queueElemen.Value); - Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); + Console.WriteLine("DoListCallbackAsync QueueElement Id " + queueElemen.Id); + Console.WriteLine("DoListCallbackAsync QueueElement Value " + queueElemen.Value); + Console.WriteLine("DoListCallbackAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); foreach (var retryQueueElemen in queueElemen.RetryQueueElements) { - Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); - Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); - Console.WriteLine("DoListSetQueueItemStatusAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); + Console.WriteLine("DoListCallbackAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); + Console.WriteLine("DoListCallbackAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); + Console.WriteLine("DoListCallbackAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); } } return default; @@ -248,7 +248,7 @@ public static CommandInterpreter InitInterpreter(SlimDataState state) ValueTask ListLeftPushHandler(ListLeftPushCommand command, CancellationToken token) => DoListLeftPushAsync(command, state.Queues); ValueTask AddHashSetHandler(AddHashSetCommand command, CancellationToken token) => DoAddHashSetAsync(command, state.Hashsets); ValueTask AddKeyValueHandler(AddKeyValueCommand command, CancellationToken token) => DoAddKeyValueAsync(command, state.KeyValues); - ValueTask ListSetQueueItemStatusAsync(ListSetQueueItemStatusCommand command, CancellationToken token) => DoListSetQueueItemStatusAsync(command, state.Queues); + ValueTask ListSetQueueItemStatusAsync(ListCallbackCommand command, CancellationToken token) => DoListCallbackAsync(command, state.Queues); ValueTask SnapshotHandler(LogSnapshotCommand command, CancellationToken token) => DoHandleSnapshotAsync(command, state.KeyValues, state.Hashsets, state.Queues); var interpreter = new Builder() @@ -256,7 +256,7 @@ public static CommandInterpreter InitInterpreter(SlimDataState state) .Add(ListLeftPushCommand.Id, (Func)ListLeftPushHandler) .Add(AddHashSetCommand.Id, (Func)AddHashSetHandler) .Add(AddKeyValueCommand.Id, (Func)AddKeyValueHandler) - .Add(ListSetQueueItemStatusCommand.Id, (Func)ListSetQueueItemStatusAsync) + .Add(ListCallbackCommand.Id, (Func)ListSetQueueItemStatusAsync) .Add(LogSnapshotCommand.Id, (Func)SnapshotHandler, true) .Build(); diff --git a/src/SlimData/Startup.cs b/src/SlimData/Startup.cs index cbb712c0..70794123 100644 --- a/src/SlimData/Startup.cs +++ b/src/SlimData/Startup.cs @@ -23,7 +23,7 @@ public void Configure(IApplicationBuilder app) const string ListLeftPushResource = "/SlimData/ListLeftPush"; const string AddKeyValueResource = "/SlimData/AddKeyValue"; const string ListLengthResource = "/SlimData/ListLength"; - const string ListSetQueueItemStatus = "/SlimData/ListSetQueueItemStatus"; + const string ListSetQueueItemStatus = "/SlimData/ListCallback"; const string HealthResource = "/health"; app.UseConsensusProtocolHandler() @@ -39,11 +39,11 @@ public void Configure(IApplicationBuilder app) { endpoints.MapGet(LeaderResource, Endpoints.RedirectToLeaderAsync); endpoints.MapGet(HealthResource, async context => { await context.Response.WriteAsync("OK"); }); - endpoints.MapPost(ListLeftPushResource, Endpoints.ListLeftPush); - endpoints.MapPost(ListRightPopResource, Endpoints.ListRightPop); - endpoints.MapPost(AddHashSetResource, Endpoints.AddHashSet); - endpoints.MapPost(AddKeyValueResource, Endpoints.AddKeyValue); - endpoints.MapPost(ListSetQueueItemStatus, Endpoints.ListSetQueueItemStatus); + endpoints.MapPost(ListLeftPushResource, Endpoints.ListLeftPushAsync); + endpoints.MapPost(ListRightPopResource, Endpoints.ListRightPopAsync); + endpoints.MapPost(AddHashSetResource, Endpoints.AddHashSetAsync); + endpoints.MapPost(AddKeyValueResource, Endpoints.AddKeyValueAsync); + endpoints.MapPost(ListSetQueueItemStatus, Endpoints.ListCallbackAsync); }); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 48230ba8..8647bf06 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -212,11 +212,11 @@ private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queu if (!cluster.LeadershipToken.IsCancellationRequested) { var simplePersistentState = serviceProvider.GetRequiredService(); - await Endpoints.ListSetQueueItemStatusCommand(simplePersistentState, key, queueItemStatus, cluster, new CancellationTokenSource()); + await Endpoints.ListCallbackCommandAsync(simplePersistentState, key, queueItemStatus, cluster, new CancellationTokenSource()); } else { - using HttpRequestMessage request = new(HttpMethod.Post, new Uri($"{endpoint}SlimData/ListSetQueueItemStatus?key={key}")); + using HttpRequestMessage request = new(HttpMethod.Post, new Uri($"{endpoint}SlimData/ListCallback?key={key}")); var field = MemoryPackSerializer.Serialize(queueItemStatus); request.Content = new ByteArrayContent(field); using var httpClient = httpClientFactory.CreateClient(HttpClientName); diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 750b1a6c..4a0b7460 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -32,6 +32,24 @@ public record ScaleDownTimeout [JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] public partial class ScheduleConfigSerializerContext : JsonSerializerContext; +public record SlimFaasConfiguration { + + public SlimFaasDefaultConfiguration DefaultSync { get; init; } = new(); + + public SlimFaasDefaultConfiguration DefaultAsync { get; init; } = new(); + +} + +public record SlimFaasDefaultConfiguration { + + public int HttpTimeout { get; init; } = 30; + public List TimeoutRetries { get; init; } = [2, 4, 8]; + public List HttpStatusRetries { get; init; } = [500, 502, 503]; +} + +[JsonSerializable(typeof(SlimFaasConfiguration))] +[JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +public partial class SlimFaasConfigurationSerializerContext : JsonSerializerContext; public enum FunctionVisibility { @@ -56,7 +74,11 @@ public record DeploymentsInformations(IList Functions, [JsonSourceGenerationOptions(WriteIndented = false, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] public partial class DeploymentsInformationsSerializerContext : JsonSerializerContext; -public record DeploymentInformation(string Deployment, string Namespace, IList Pods, int Replicas, +public record DeploymentInformation(string Deployment, + string Namespace, + IList Pods, + SlimFaasConfiguration Configuration, + int Replicas, int ReplicasAtStart = 1, int ReplicasMin = 0, int TimeoutSecondBeforeSetReplicasMin = 300, @@ -70,8 +92,6 @@ public record DeploymentInformation(string Deployment, string Namespace, IList

? PathsStartWithVisibility = null, IList? ExcludeDeploymentsFromVisibilityPrivate = null, string ResourceVersion = "", - IList? AsynchrounousRetry = null, - IList? SynchrounousRetry = null, bool EndpointReady = false ); @@ -82,6 +102,7 @@ public class KubernetesService : IKubernetesService { private const string ReplicasMin = "SlimFaas/ReplicasMin"; private const string Schedule = "SlimFaas/Schedule"; + private const string Configuration = "SlimFaas/Configuration"; private const string Function = "SlimFaas/Function"; private const string ReplicasAtStart = "SlimFaas/ReplicasAtStart"; private const string DependsOn = "SlimFaas/DependsOn"; @@ -243,12 +264,14 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList var name = deploymentListItem.Metadata.Name; var pods = podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(); ScheduleConfig? scheduleConfig = GetScheduleConfig(annotations, name, logger); + SlimFaasConfiguration configuration = GetConfiguration(annotations, name, logger); bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeploymentInformationList, name, pods); DeploymentInformation deploymentInformation = new( name, kubeNamespace, pods, + configuration, deploymentListItem.Spec.Replicas ?? 0, annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) ? int.Parse(annotationReplicasAtStart) @@ -279,8 +302,6 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList : new List(), annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), deploymentListItem.Metadata.ResourceVersion, - AsynchrounousRetry: ReadRetryAnnotation(annotations), - SynchrounousRetry: ReadRetryAnnotation(annotations), EndpointReady: endpointReady ); deploymentInformationList.Add(deploymentInformation); @@ -344,6 +365,23 @@ private static async Task GetEndpointReady(string kubeNamespace, k8s.Kuber return new ScheduleConfig(); } + private static SlimFaasConfiguration GetConfiguration(IDictionary annotations, string name, ILogger logger) + { + try + { + if (annotations.TryGetValue(Configuration, out string? annotation) && !string.IsNullOrEmpty(annotation.Trim())) + { + return JsonSerializer.Deserialize(annotation, SlimFaasConfigurationSerializerContext.Default.SlimFaasConfiguration) ?? new SlimFaasConfiguration(); + } + } + catch (Exception e) + { + logger.LogError( e, "name: {Name}\\n annotations[Configuration]: {Configuration}", name, annotations[Configuration]); + } + + return new SlimFaasConfiguration(); + } + private static async Task AddStatefulSets(string kubeNamespace, V1StatefulSetList deploymentList, IEnumerable podList, IList deploymentInformationList, ILogger logger, k8s.Kubernetes client , IList previousDeploymentInformationList) { @@ -361,12 +399,14 @@ private static async Task AddStatefulSets(string kubeNamespace, V1StatefulSetLis var name = deploymentListItem.Metadata.Name; var pods = podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(); ScheduleConfig? scheduleConfig = GetScheduleConfig(annotations, name, logger); + SlimFaasConfiguration configuration = GetConfiguration(annotations, name, logger); bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeploymentInformationList, name, pods); DeploymentInformation deploymentInformation = new( name, kubeNamespace, pods, + configuration, deploymentListItem.Spec.Replicas ?? 0, annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) ? int.Parse(annotationReplicasAtStart) @@ -397,8 +437,6 @@ private static async Task AddStatefulSets(string kubeNamespace, V1StatefulSetLis : new List(), annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), deploymentListItem.Metadata.ResourceVersion, - AsynchrounousRetry: ReadRetryAnnotation(annotations), - SynchrounousRetry: ReadRetryAnnotation(annotations), EndpointReady: endpointReady); deploymentInformationList.Add(deploymentInformation); diff --git a/src/SlimFaas/Kubernetes/MockKubernetesService.cs b/src/SlimFaas/Kubernetes/MockKubernetesService.cs index d49c4771..252224ca 100644 --- a/src/SlimFaas/Kubernetes/MockKubernetesService.cs +++ b/src/SlimFaas/Kubernetes/MockKubernetesService.cs @@ -1,4 +1,5 @@ -using System.Diagnostics.CodeAnalysis; +using System.Configuration; +using System.Diagnostics.CodeAnalysis; using System.Text.Json; using System.Text.Json.Serialization; using SlimFaas.Kubernetes; @@ -64,7 +65,8 @@ public MockKubernetesService() Namespace: "default", ReplicasStartAsSoonAsOneFunctionRetrieveARequest: false, NumberParallelRequest: function.NumberParallelRequest, - Pods: new List() { new("", true, true, "", "") } + Pods: new List() { new("", true, true, "", "") }, + Configuration : new SlimFaasConfiguration() ); _deploymentInformations.Functions.Add(deploymentInformation); } diff --git a/src/SlimFaas/SendClient.cs b/src/SlimFaas/SendClient.cs index 794afdd5..67379d6b 100644 --- a/src/SlimFaas/SendClient.cs +++ b/src/SlimFaas/SendClient.cs @@ -4,7 +4,7 @@ namespace SlimFaas; public interface ISendClient { - Task SendHttpRequestAsync(CustomRequest customRequest, int timeout=30, string? baseUrl = null); + Task SendHttpRequestAsync(CustomRequest customRequest, int timeout=30, string? baseUrl = null, CancellationTokenSource? cancellationToken = null); Task SendHttpRequestSync(HttpContext httpContext, string functionName, string functionPath, string functionQuery, string? baseUrl = null); @@ -19,7 +19,7 @@ public class SendClient(HttpClient httpClient, ILogger logger) : ISe Environment.GetEnvironmentVariable(EnvironmentVariables.Namespace) ?? EnvironmentVariables.NamespaceDefault; public async Task SendHttpRequestAsync(CustomRequest customRequest, - int timeout=30, string? baseUrl = null) + int timeout=30, string? baseUrl = null, CancellationTokenSource? cancellationToken = null) { try { @@ -31,10 +31,10 @@ public async Task SendHttpRequestAsync(CustomRequest custom ComputeTargetUrl(functionUrl, customRequestFunctionName, customRequestPath, customRequestQuery, _namespaceSlimFaas); logger.LogDebug("Sending async request to {TargetUrl}", targetUrl); HttpRequestMessage targetRequestMessage = CreateTargetMessage(customRequest, new Uri(targetUrl)); - using var cancellationToken = new CancellationTokenSource(timeout); + httpClient.Timeout = TimeSpan.FromSeconds(timeout); return await httpClient.SendAsync(targetRequestMessage, - HttpCompletionOption.ResponseHeadersRead, cancellationToken.Token); + HttpCompletionOption.ResponseHeadersRead, cancellationToken?.Token ?? CancellationToken.None); } catch (Exception e) { diff --git a/src/SlimFaas/SlimFaas.csproj b/src/SlimFaas/SlimFaas.csproj index dc6aad0a..217a7eee 100644 --- a/src/SlimFaas/SlimFaas.csproj +++ b/src/SlimFaas/SlimFaas.csproj @@ -31,7 +31,7 @@ - + diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 6741925b..a277c0f2 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -191,7 +191,7 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, { queueItemStatusList.Add(new QueueItemStatus(processing.Id, 504)); httpResponseMessagesToDelete.Add(processing); - logger.LogWarning("Request Timeout Error: {Message} {StackTrace}", ex.Message, ex.StackTrace); + logger.LogWarning("Request HttpTimeout Error: {Message} {StackTrace}", ex.Message, ex.StackTrace); historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); } catch (Exception e) diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 6d94d099..d44c7fc1 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -73,7 +73,7 @@ public static void QueueElementExtensionsGetQueueRunningElement2() queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", nowTicks, new List())); queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", nowTicks, new List())); - var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.Retries, nowTicks, 1, 30); + var availableElements = queueElements.GetQueueAvailableElement(SlimDataInterpreter.TimeoutRetries, nowTicks, 1, 30); foreach (QueueElement queueElement in queueElements) { @@ -87,7 +87,7 @@ public static void QueueElementExtensionsGetQueueRunningElement2() Assert.Equal("1", runningElements[0].Id); - var finishedElements = queueElements.GetQueueFinishedElement(nowTicks, SlimDataInterpreter.Retries); + var finishedElements = queueElements.GetQueueFinishedElement(nowTicks, SlimDataInterpreter.TimeoutRetries); Assert.Equal(4, finishedElements.Count); }*/ } diff --git a/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs b/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs index 62dbeec3..d3c8db85 100644 --- a/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs +++ b/tests/SlimFaas.Tests/HistorySynchronizationWorkerShould.cs @@ -17,8 +17,8 @@ public async Task SyncLastTicksBetweenDatabaseAndMemory() DeploymentsInformations deploymentsInformations = new DeploymentsInformations( new List { - new("fibonacci1", "default", Replicas: 1, Pods: new List()), - new("fibonacci2", "default", Replicas: 0, Pods: new List()) + new("fibonacci1", "default", Replicas: 1, Pods: new List(), Configuration: new SlimFaasConfiguration()), + new("fibonacci2", "default", Replicas: 0, Pods: new List(), Configuration: new SlimFaasConfiguration()) }, new SlimFaasDeploymentInformation(1, new List()), new List()); kubernetesService.Setup(k => k.ListFunctionsAsync(It.IsAny(), It.IsAny())).ReturnsAsync(deploymentsInformations); diff --git a/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs b/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs index a5b49861..0500c12e 100644 --- a/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs +++ b/tests/SlimFaas.Tests/ReplicasScaleWorkerShould.cs @@ -22,8 +22,8 @@ public IEnumerator GetEnumerator() new DeploymentsInformations( new List { - new("fibonacci1", "default", Replicas: 1, Pods: new List()), - new("fibonacci2", "default", Replicas: 0, Pods: new List()) + new("fibonacci1", "default", Replicas: 1, Pods: new List(), Configuration: new SlimFaasConfiguration()), + new("fibonacci2", "default", Replicas: 0, Pods: new List(), Configuration: new SlimFaasConfiguration()) }, new SlimFaasDeploymentInformation(1, new List()), new List() @@ -36,8 +36,8 @@ public IEnumerator GetEnumerator() new DeploymentsInformations( new List { - new("fibonacci1", "default", Replicas: 1, Pods: new List() { new PodInformation("fibonacci1", true, true, "localhost", "fibonacci1") }), - new("fibonacci2", "default", Replicas: 0, Pods: new List(), DependsOn: new List { "fibonacci1" }) + new("fibonacci1", "default", Replicas: 1, Pods: new List() { new PodInformation("fibonacci1", true, true, "localhost", "fibonacci1")}, Configuration: new SlimFaasConfiguration()), + new("fibonacci2", "default", Replicas: 0, Pods: new List(), DependsOn: new List { "fibonacci1" }, Configuration: new SlimFaasConfiguration()) }, new SlimFaasDeploymentInformation(1, new List()), new List() @@ -119,6 +119,7 @@ public void GetTimeoutSecondBeforeSetReplicasMin() var deplymentInformation = new DeploymentInformation("fibonacci1", "default", Replicas: 1, + Configuration: new SlimFaasConfiguration(), Pods: new List() { new PodInformation("fibonacci1", true, true, "localhost", "fibonacci1") @@ -152,6 +153,7 @@ public void GetLastTicksFromSchedule() var deploymentInformation = new DeploymentInformation("fibonacci1", "default", Replicas: 1, + Configuration: new SlimFaasConfiguration(), Pods: new List() { new PodInformation("fibonacci1", true, true, "localhost", "fibonacci1") diff --git a/tests/SlimFaas.Tests/ReplicasSynchronizationWorkerShould.cs b/tests/SlimFaas.Tests/ReplicasSynchronizationWorkerShould.cs index 0d72e983..d9441e1b 100644 --- a/tests/SlimFaas.Tests/ReplicasSynchronizationWorkerShould.cs +++ b/tests/SlimFaas.Tests/ReplicasSynchronizationWorkerShould.cs @@ -20,8 +20,8 @@ public IEnumerator GetEnumerator() new DeploymentsInformations( new List { - new("fibonacci1", "default", Replicas: 1, Pods: new List()), - new("fibonacci2", "default", Replicas: 0, Pods: new List()) + new("fibonacci1", "default", Replicas: 1, Pods: new List(), Configuration: new SlimFaasConfiguration()), + new("fibonacci2", "default", Replicas: 0, Pods: new List(), Configuration: new SlimFaasConfiguration()) }, new SlimFaasDeploymentInformation(1, new List()), new List() diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 6f8bd486..1f0ac4d8 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -21,7 +21,7 @@ internal class MemoryReplicasService : IReplicasService new List { new(Replicas: 0, Deployment: "fibonacci", Namespace: "default", - Pods: new List { new("", true, true, "", "") }) + Pods: new List { new("", true, true, "", "") }, Configuration: new SlimFaasConfiguration()) }, new SlimFaasDeploymentInformation(1, new List()), new List()); public Task SyncDeploymentsAsync(string kubeNamespace) => throw new NotImplementedException(); @@ -54,6 +54,7 @@ internal class MemoryReplicas2ReplicasService : IReplicasService "/noprefix", }, Namespace: "default", + Configuration: new SlimFaasConfiguration(), Pods: new List { new("fibonacci-1", true, true, "0", "fibonacci"), new("fibonacci-2", true, true, "0", "fibonacci"), @@ -89,7 +90,7 @@ internal record SendData(string FunctionName, string Path, string BaseUrl); internal class SendClientMock : ISendClient { public IList SendDatas = new List(); - public Task SendHttpRequestAsync(CustomRequest customRequest, int timeout, string? baseUrl = null) + public Task SendHttpRequestAsync(CustomRequest customRequest, int timeout, string? baseUrl = null, CancellationTokenSource? cancellationToken = null) { HttpResponseMessage responseMessage = new HttpResponseMessage(); responseMessage.StatusCode = HttpStatusCode.OK; @@ -174,7 +175,7 @@ public async Task CallFunctionInSyncModeAndReturnOk(string path, HttpStatusCode HttpResponseMessage responseMessage = new HttpResponseMessage(); responseMessage.StatusCode = HttpStatusCode.OK; Mock sendClientMock = new Mock(); - sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny())) + sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(responseMessage); using IHost host = await new HostBuilder() diff --git a/tests/SlimFaas.Tests/SlimWorkerShould.cs b/tests/SlimFaas.Tests/SlimWorkerShould.cs index efacd559..bad3b21f 100644 --- a/tests/SlimFaas.Tests/SlimWorkerShould.cs +++ b/tests/SlimFaas.Tests/SlimWorkerShould.cs @@ -18,7 +18,7 @@ public async Task OnlyCallOneFunctionAsync() responseMessage.StatusCode = HttpStatusCode.OK; Mock sendClientMock = new Mock(); - sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny())) + sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(responseMessage); Mock serviceProvider = new Mock(); @@ -51,14 +51,14 @@ public async Task OnlyCallOneFunctionAsync() { new(Replicas: 1, Deployment: "fibonacci", Namespace: "default", NumberParallelRequest: 1, ReplicasMin: 0, ReplicasAtStart: 1, TimeoutSecondBeforeSetReplicasMin: 300, - ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, + ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, Configuration: new SlimFaasConfiguration(), Pods: new List { new("", true, true, "", "")}, EndpointReady: true), new(Replicas: 1, Deployment: "no-pod-started", Namespace: "default", NumberParallelRequest: 1, ReplicasMin: 0, ReplicasAtStart: 1, TimeoutSecondBeforeSetReplicasMin: 300, - ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, + ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, Configuration: new SlimFaasConfiguration(), Pods: new List { new("", false, false, "", "")}, EndpointReady: true), new(Replicas: 0, Deployment: "no-replicas", Namespace: "default", NumberParallelRequest: 1, - ReplicasMin: 0, ReplicasAtStart: 1, TimeoutSecondBeforeSetReplicasMin: 300, + ReplicasMin: 0, ReplicasAtStart: 1, TimeoutSecondBeforeSetReplicasMin: 300, Configuration: new SlimFaasConfiguration(), ReplicasStartAsSoonAsOneFunctionRetrieveARequest: true, Pods: new List(), EndpointReady: false) }, Pods: new List())); HistoryHttpMemoryService historyHttpService = new HistoryHttpMemoryService(); @@ -96,7 +96,7 @@ public async Task OnlyCallOneFunctionAsync() await Task.Delay(3000); Assert.True(task.IsCompleted); - sendClientMock.Verify(v => v.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny()), + sendClientMock.Verify(v => v.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } From b4b88d226bc63cf6bb53539196004219e01b45a2 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 20 Dec 2024 22:15:59 +0100 Subject: [PATCH 109/135] Update --- src/SlimFaas/Database/DatabaseMockService.cs | 2 +- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 6 +++--- src/SlimFaas/Database/SlimFaasQueue.cs | 2 +- src/SlimFaas/SlimWorker.cs | 2 +- tests/SlimData.Tests/RaftClusterTests.cs | 2 +- tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index c093e1ed..35fd04e5 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -117,7 +117,7 @@ public Task ListCountElementAsync(string key, int maximum = Int32.MaxValue return Task.FromResult(list.Count); } - public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) + public async Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) { await Task.Delay(100); } diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index 191430a4..887624d0 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -12,5 +12,5 @@ public interface IDatabaseService Task?> ListRightPopAsync(string key, int count = 1); Task ListCountAvailableElementAsync(string key, int maximum = int.MaxValue); Task ListCountElementAsync(string key, int maximum = int.MaxValue); - Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus); + Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus); } diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 4fed91e1..8a289d7b 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -6,7 +6,7 @@ public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message); Task?> DequeueAsync(string key, long count = 1); - Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus); + Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus); public Task CountAvailableElementAsync(string key, int maximum = int.MaxValue); public Task CountElementAsync(string key, int maximum = int.MaxValue); } diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 8647bf06..f5588fba 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -201,12 +201,12 @@ private async Task DoListCountElementAsync(string key, int maximum) return 0L; } - public async Task ListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) + public async Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) { - await Retry.Do(() => DoListSetQueueItemStatus(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); + await Retry.Do(() => DoListCallbackAsync(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); } - private async Task DoListSetQueueItemStatus(string key, ListQueueItemStatus queueItemStatus) + private async Task DoListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) { EndPoint endpoint = await GetAndWaitForLeader(); if (!cluster.LeadershipToken.IsCancellationRequested) diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index ba1fb9cf..69c797cc 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -17,7 +17,7 @@ public async Task EnqueueAsync(string key, byte[] data) => return data; } - public async Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => await databaseService.ListSetQueueItemStatus($"{KeyPrefix}{key}", queueItemStatus); + public async Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) => await databaseService.ListCallbackAsync($"{KeyPrefix}{key}", queueItemStatus); public async Task CountAvailableElementAsync(string key, int maximum = int.MaxValue) => await databaseService.ListCountAvailableElementAsync($"{KeyPrefix}{key}", maximum); diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index a277c0f2..97376486 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -210,7 +210,7 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, if (listQueueItemStatus.Items.Count > 0) { - await slimFaasQueue.ListSetQueueItemStatusAsync(functionDeployment, listQueueItemStatus); + await slimFaasQueue.ListCallbackAsync(functionDeployment, listQueueItemStatus); } int numberProcessingTasks = processingTasks[functionDeployment].Count; diff --git a/tests/SlimData.Tests/RaftClusterTests.cs b/tests/SlimData.Tests/RaftClusterTests.cs index 8d7fe182..2c5337b0 100644 --- a/tests/SlimData.Tests/RaftClusterTests.cs +++ b/tests/SlimData.Tests/RaftClusterTests.cs @@ -269,7 +269,7 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", HttpCode = 200, }); } - await databaseServiceSlave.ListSetQueueItemStatus("listKey1", queueItemStatus); + await databaseServiceSlave.ListCallbackAsync("listKey1", queueItemStatus); await GetLocalClusterView(host1).ForceReplicationAsync(); var listLength2 = await databaseServiceSlave.ListCountAvailableElementAsync("listKey1"); diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 1f0ac4d8..906070d7 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -79,7 +79,7 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue public Task CountAvailableElementAsync(string key, int maximum) => throw new NotImplementedException(); public Task CountElementAsync(string key, int maximum) => throw new NotImplementedException(); - public Task ListSetQueueItemStatusAsync(string key, ListQueueItemStatus queueItemStatus) => throw new NotImplementedException(); + public Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) => throw new NotImplementedException(); public async Task EnqueueAsync(string key, byte[] message) => await Task.Delay(100); From 437edbf331ceda5b1244fb8a3a50d348d55ff52e Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 20 Dec 2024 22:24:31 +0100 Subject: [PATCH 110/135] sssss --- src/SlimData/Endpoints.cs | 4 ++-- src/SlimFaas/Database/SlimDataService.cs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index fca8719c..a59530ad 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -9,7 +9,7 @@ namespace SlimData; public partial record ListLeftPushInput(byte[] Value, byte[] RetryInformation); [MemoryPackable] -public partial record RetryInformation(List Retries, int RetryTimeoutSeconds); +public partial record RetryInformation(List Retries, int RetryTimeoutSeconds, List HttpStatusRetries); [MemoryPackable] public partial record QueueItemStatus(string Id="", int HttpCode=0); @@ -206,7 +206,7 @@ public static async Task ListLeftPushCommand(SlimPersistentState provider, strin NowTicks = DateTime.UtcNow.Ticks, Retries = retryInformation.Retries, RetryTimeout = retryInformation.RetryTimeoutSeconds, - HttpStatusCodesWorthRetrying = new List(HttpStatusCodesWorthRetrying) + HttpStatusCodesWorthRetrying = retryInformation.HttpStatusRetries }, cluster.Term); await cluster.ReplicateAsync(logEntry, source.Token); diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index f5588fba..2f947540 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -114,7 +114,7 @@ public async Task ListLeftPushAsync(string key, byte[] field) private async Task DoListLeftPushAsync(string key, byte[] field) { EndPoint endpoint = await GetAndWaitForLeader(); - RetryInformation retryInformation = new([2, 4, 10], 30); + RetryInformation retryInformation = new([2, 4, 10], 30, [500, 502,503]); ListLeftPushInput listLeftPushInput = new(field, MemoryPackSerializer.Serialize(retryInformation)); byte[] serialize = MemoryPackSerializer.Serialize(listLeftPushInput); if (!cluster.LeadershipToken.IsCancellationRequested) From e3e7cdfb9cd32c3db5ae59ce193470626ea4db94 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 21 Dec 2024 22:03:39 +0100 Subject: [PATCH 111/135] Continue --- src/SlimFaas/Database/DatabaseMockService.cs | 2 +- src/SlimFaas/Database/IDatabaseService.cs | 2 +- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimDataService.cs | 7 +++---- src/SlimFaas/Database/SlimFaasQueue.cs | 4 ++-- src/SlimFaas/SlimProxyMiddleware.cs | 4 +++- tests/SlimData.Tests/CommandsTests.cs | 2 +- tests/SlimData.Tests/RaftClusterTests.cs | 2 +- tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs | 2 +- tests/SlimFaas.Tests/SlimWorkerShould.cs | 12 +++++++----- 10 files changed, 21 insertions(+), 18 deletions(-) diff --git a/src/SlimFaas/Database/DatabaseMockService.cs b/src/SlimFaas/Database/DatabaseMockService.cs index 35fd04e5..3b877b5b 100644 --- a/src/SlimFaas/Database/DatabaseMockService.cs +++ b/src/SlimFaas/Database/DatabaseMockService.cs @@ -58,7 +58,7 @@ public Task> HashGetAllAsync(string key) return Task.FromResult>(new Dictionary()); } - public Task ListLeftPushAsync(string key, byte[] field) + public Task ListLeftPushAsync(string key, byte[] field, RetryInformation retryInformation) { List list; if (queue.ContainsKey(key)) diff --git a/src/SlimFaas/Database/IDatabaseService.cs b/src/SlimFaas/Database/IDatabaseService.cs index 887624d0..3da0e754 100644 --- a/src/SlimFaas/Database/IDatabaseService.cs +++ b/src/SlimFaas/Database/IDatabaseService.cs @@ -8,7 +8,7 @@ public interface IDatabaseService Task SetAsync(string key, byte[] value); Task HashSetAsync(string key, IDictionary values); Task> HashGetAllAsync(string key); - Task ListLeftPushAsync(string key, byte[] field); + Task ListLeftPushAsync(string key, byte[] field, RetryInformation retryInformation); Task?> ListRightPopAsync(string key, int count = 1); Task ListCountAvailableElementAsync(string key, int maximum = int.MaxValue); Task ListCountElementAsync(string key, int maximum = int.MaxValue); diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 8a289d7b..2c9c2581 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -4,7 +4,7 @@ namespace SlimFaas.Database; public interface ISlimFaasQueue { - Task EnqueueAsync(string key, byte[] message); + Task EnqueueAsync(string key, byte[] message, RetryInformation retryInformation); Task?> DequeueAsync(string key, long count = 1); Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus); public Task CountAvailableElementAsync(string key, int maximum = int.MaxValue); diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index 2f947540..a0bb3c62 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -106,15 +106,14 @@ private async Task> DoHashGetAllAsync(string key) : new Dictionary(); } - public async Task ListLeftPushAsync(string key, byte[] field) + public async Task ListLeftPushAsync(string key, byte[] field, RetryInformation retryInformation) { - await Retry.Do(() =>DoListLeftPushAsync(key, field), _retryInterval, logger, MaxAttemptCount); + await Retry.Do(() =>DoListLeftPushAsync(key, field, retryInformation), _retryInterval, logger, MaxAttemptCount); } - private async Task DoListLeftPushAsync(string key, byte[] field) + private async Task DoListLeftPushAsync(string key, byte[] field, RetryInformation retryInformation) { EndPoint endpoint = await GetAndWaitForLeader(); - RetryInformation retryInformation = new([2, 4, 10], 30, [500, 502,503]); ListLeftPushInput listLeftPushInput = new(field, MemoryPackSerializer.Serialize(retryInformation)); byte[] serialize = MemoryPackSerializer.Serialize(listLeftPushInput); if (!cluster.LeadershipToken.IsCancellationRequested) diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index 69c797cc..e9362509 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -8,8 +8,8 @@ public class SlimFaasQueue(IDatabaseService databaseService) : ISlimFaasQueue { private const string KeyPrefix = "Queue:"; - public async Task EnqueueAsync(string key, byte[] data) => - await databaseService.ListLeftPushAsync($"{KeyPrefix}{key}", data); + public async Task EnqueueAsync(string key, byte[] data, RetryInformation retryInformation) => + await databaseService.ListLeftPushAsync($"{KeyPrefix}{key}", data, retryInformation); public async Task?> DequeueAsync(string key, long count = 1) { diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index c201e55b..0c3ce095 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -1,5 +1,6 @@ using System.Text.Json.Serialization; using MemoryPack; +using SlimData; using SlimFaas.Database; using SlimFaas.Kubernetes; @@ -286,7 +287,8 @@ private async Task BuildAsyncResponseAsync(ILogger logger, await InitCustomRequest(context, context.Request, functionName, functionPath); var bin = MemoryPackSerializer.Serialize(customRequest); - await slimFaasQueue.EnqueueAsync(functionName, bin); + var defaultAsync = function.Configuration.DefaultAsync; + await slimFaasQueue.EnqueueAsync(functionName, bin, new RetryInformation(defaultAsync.TimeoutRetries, defaultAsync.HttpTimeout, defaultAsync.HttpStatusRetries)); context.Response.StatusCode = 202; } diff --git a/tests/SlimData.Tests/CommandsTests.cs b/tests/SlimData.Tests/CommandsTests.cs index 8cca699c..6cb754c3 100644 --- a/tests/SlimData.Tests/CommandsTests.cs +++ b/tests/SlimData.Tests/CommandsTests.cs @@ -17,7 +17,7 @@ public static async Task InterpreterWithPersistentState() { byte[] bytes = RandomBytes(1000); using var wal = new SlimPersistentState(Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())); - var entry1 = wal.CreateLogEntry(new ListLeftPushCommand { Key = "youhou" , Value = bytes, Identifier = "1", RetryTimeout = 100, Retries = new List { 1, 2, 3 }, NowTicks = DateTime.UtcNow.Ticks, HttpStatusCodesWorthRetrying = new List() }); + var entry1 = wal.CreateLogEntry(new ListLeftPushCommand { Key = "youhou" , Value = bytes, Identifier = "1", RetryTimeout = 100, Retries = new List { 1, 2, 3 }, NowTicks = DateTime.UtcNow.Ticks, HttpStatusCodesWorthRetrying = new List()}); await wal.AppendAsync(entry1); Assert.Empty(wal.SlimDataState.Queues); await wal.CommitAsync(CancellationToken.None); diff --git a/tests/SlimData.Tests/RaftClusterTests.cs b/tests/SlimData.Tests/RaftClusterTests.cs index 2c5337b0..e95c4fd7 100644 --- a/tests/SlimData.Tests/RaftClusterTests.cs +++ b/tests/SlimData.Tests/RaftClusterTests.cs @@ -249,7 +249,7 @@ await databaseServiceSlave.HashSetAsync("hashsetKey1", Assert.Equal("value1", hashGet["field1"]); Assert.Equal("value2", hashGet["field2"]); - await databaseServiceSlave.ListLeftPushAsync("listKey1", MemoryPackSerializer.Serialize("value1")); + await databaseServiceSlave.ListLeftPushAsync("listKey1", MemoryPackSerializer.Serialize("value1"), new RetryInformation([], 30, [])); await GetLocalClusterView(host1).ForceReplicationAsync(); long listLength = await databaseServiceSlave.ListCountAvailableElementAsync("listKey1"); Assert.Equal(1, listLength); diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 906070d7..5a1a3fbe 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -81,7 +81,7 @@ internal class MemorySlimFaasQueue : ISlimFaasQueue public Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) => throw new NotImplementedException(); - public async Task EnqueueAsync(string key, byte[] message) => await Task.Delay(100); + public async Task EnqueueAsync(string key, byte[] message, RetryInformation retryInformation) => await Task.Delay(100); } diff --git a/tests/SlimFaas.Tests/SlimWorkerShould.cs b/tests/SlimFaas.Tests/SlimWorkerShould.cs index bad3b21f..aeecf80e 100644 --- a/tests/SlimFaas.Tests/SlimWorkerShould.cs +++ b/tests/SlimFaas.Tests/SlimWorkerShould.cs @@ -6,6 +6,7 @@ using SlimFaas.Kubernetes; using MemoryPack; using SlimFaas.Database; +using SlimData; namespace SlimFaas.Tests; @@ -64,26 +65,27 @@ public async Task OnlyCallOneFunctionAsync() HistoryHttpMemoryService historyHttpService = new HistoryHttpMemoryService(); Mock> logger = new Mock>(); - SlimFaasQueue redisQueue = new SlimFaasQueue(new DatabaseMockService()); + SlimFaasQueue slimFaasQueue = new SlimFaasQueue(new DatabaseMockService()); CustomRequest customRequest = new CustomRequest(new List { new() { Key = "key", Values = new[] { "value1" } } }, new byte[1], "fibonacci", "/download", "GET", ""); var jsonCustomRequest = MemoryPackSerializer.Serialize(customRequest); - await redisQueue.EnqueueAsync("fibonacci", jsonCustomRequest); + var retryInformation = new RetryInformation([], 30, []); + await slimFaasQueue.EnqueueAsync("fibonacci", jsonCustomRequest, retryInformation); CustomRequest customRequestNoPodStarted = new CustomRequest(new List { new() { Key = "key", Values = new[] { "value1" } } }, new byte[1], "no-pod-started", "/download", "GET", ""); var jsonCustomNoPodStarted = MemoryPackSerializer.Serialize(customRequestNoPodStarted); - await redisQueue.EnqueueAsync("no-pod-started", jsonCustomNoPodStarted); + await slimFaasQueue.EnqueueAsync("no-pod-started", jsonCustomNoPodStarted, retryInformation); CustomRequest customRequestReplicas = new CustomRequest(new List { new() { Key = "key", Values = new[] { "value1" } } }, new byte[1], "no-replicas", "/download", "GET", ""); var jsonCustomNoReplicas = MemoryPackSerializer.Serialize(customRequestReplicas); - await redisQueue.EnqueueAsync("no-replicas", jsonCustomNoReplicas); + await slimFaasQueue.EnqueueAsync("no-replicas", jsonCustomNoReplicas, retryInformation); - SlimWorker service = new SlimWorker(redisQueue, + SlimWorker service = new SlimWorker(slimFaasQueue, replicasService.Object, historyHttpService, logger.Object, From aabe661f00c388b914e610f5474e80ac82a73807 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 27 Dec 2024 21:11:26 +0100 Subject: [PATCH 112/135] youhou --- README.md | 5 +- src/SlimFaas/Database/SlimDataService.cs | 76 +++++++++++++++++------- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index a2e57c7b..2b9ab419 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Why use SlimFaas? - Retry Pattern Configurable: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds - Private and Public functions - Private functions can be accessed only by internal namespace http call from pods -- Synchronous Publish/Subscribe internal events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple you application with SlimFaas**) +- Synchronous Publish/Subscribe internal events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple your application with SlimFaas**) - Mind Changer: REST API that show the status of your functions and allow to wake up your infrastructure (**Couple your application with Slimfaas**) - Very useful to inform end users that your infrastructure is starting - Plug and Play: just deploy a standard pod @@ -28,7 +28,8 @@ To test SlimFaas on your local machine by using kubernetes with Docker Desktop, ```bash git clone https://github.com/AxaFrance/slimfaas.git -cd slimfaas/demo +cd slimfaas +cd demo # Create slimfaas service account and pods kubectl apply -f deployment-slimfaas.yml # Expose SlimFaaS service as NodePort or Ingress diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index a0bb3c62..db623d32 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -13,7 +13,7 @@ public class SlimDataService(IHttpClientFactory httpClientFactory, IServiceProvi { public const string HttpClientName = "SlimDataHttpClient"; private const int MaxAttemptCount = 3; - private readonly TimeSpan _retryInterval = TimeSpan.FromSeconds(1); + private readonly IList _retryInterval = new List { 1, 1, 1 }; private readonly TimeSpan _timeMaxToWaitForLeader = TimeSpan.FromMilliseconds(3000); private ISupplier SimplePersistentState => @@ -21,7 +21,7 @@ public class SlimDataService(IHttpClientFactory httpClientFactory, IServiceProvi public async Task GetAsync(string key) { - return await Retry.Do(() => DoGetAsync(key), _retryInterval, logger, MaxAttemptCount); + return await Retry.DoAsync(() => DoGetAsync(key), logger, _retryInterval); } private async Task DoGetAsync(string key) @@ -34,7 +34,7 @@ public class SlimDataService(IHttpClientFactory httpClientFactory, IServiceProvi public async Task SetAsync(string key, byte[] value) { - await Retry.Do(() =>DoSetAsync(key, value), _retryInterval, logger, MaxAttemptCount); + await Retry.DoAsync(() => DoSetAsync(key, value), logger, _retryInterval); } private async Task DoSetAsync(string key, byte[] value) @@ -61,7 +61,7 @@ private async Task DoSetAsync(string key, byte[] value) public async Task HashSetAsync(string key, IDictionary values) { - await Retry.Do(() =>DoHashSetAsync(key, values), _retryInterval, logger, MaxAttemptCount); + await Retry.DoAsync(() => DoHashSetAsync(key, values), logger, _retryInterval); } private async Task DoHashSetAsync(string key, IDictionary values) @@ -92,7 +92,7 @@ private async Task DoHashSetAsync(string key, IDictionary values public async Task> HashGetAllAsync(string key) { - return await Retry.Do(() =>DoHashGetAllAsync(key), _retryInterval, logger, MaxAttemptCount); + return await Retry.DoAsync(() =>DoHashGetAllAsync(key), logger, _retryInterval); } private async Task> DoHashGetAllAsync(string key) @@ -108,7 +108,7 @@ private async Task> DoHashGetAllAsync(string key) public async Task ListLeftPushAsync(string key, byte[] field, RetryInformation retryInformation) { - await Retry.Do(() =>DoListLeftPushAsync(key, field, retryInformation), _retryInterval, logger, MaxAttemptCount); + await Retry.DoAsync(() =>DoListLeftPushAsync(key, field, retryInformation), logger, _retryInterval); } private async Task DoListLeftPushAsync(string key, byte[] field, RetryInformation retryInformation) @@ -136,7 +136,7 @@ private async Task DoListLeftPushAsync(string key, byte[] field, RetryInformatio public async Task?> ListRightPopAsync(string key, int count = 1) { - return await Retry.Do(() => DoListRightPopAsync(key, count), _retryInterval, logger, MaxAttemptCount); + return await Retry.DoAsync(() => DoListRightPopAsync(key, count), logger, _retryInterval); } private async Task?> DoListRightPopAsync(string key, int count = 1) @@ -178,7 +178,7 @@ private async Task DoListLeftPushAsync(string key, byte[] field, RetryInformatio public Task ListCountElementAsync(string key, int maximum = Int32.MaxValue) { - return Retry.Do(() => DoListCountElementAsync(key, maximum), _retryInterval, logger, MaxAttemptCount); + return Retry.DoAsync(() => DoListCountElementAsync(key, maximum), logger, _retryInterval); } private async Task DoListCountElementAsync(string key, int maximum) @@ -202,7 +202,7 @@ private async Task DoListCountElementAsync(string key, int maximum) public async Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) { - await Retry.Do(() => DoListCallbackAsync(key, queueItemStatus), _retryInterval, logger, MaxAttemptCount); + await Retry.DoAsync(() => DoListCallbackAsync(key, queueItemStatus), logger, _retryInterval); } private async Task DoListCallbackAsync(string key, ListQueueItemStatus queueItemStatus) @@ -229,7 +229,7 @@ private async Task DoListCallbackAsync(string key, ListQueueItemStatus queueItem public async Task ListCountAvailableElementAsync(string key, int maximum) { - return await Retry.Do(() => DoListCountAvailableElementAsync(key, maximum), _retryInterval, logger, MaxAttemptCount); + return await Retry.DoAsync(() => DoListCountAvailableElementAsync(key, maximum), logger, _retryInterval); } private async Task DoListCountAvailableElementAsync(string key, int maximum) @@ -279,30 +279,66 @@ private async Task GetAndWaitForLeader() public static class Retry { - public static T Do( - Func action, - TimeSpan retryInterval, - ILogger logger, - int maxAttemptCount = 3) + public static async Task DoAsync( + Func> action, + ILogger logger, + IList delays + ) + { + var exceptions = new List(); + + for (int attempt = 0; attempt < delays.Count; attempt++) + { + try + { + if (attempt > 0) + { + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); + await Task.Delay((int)delay * 1000); + } + + return await action(); + } + catch (Exception ex) + { + exceptions.Add(ex); + } + } + + throw new AggregateException(exceptions); + } + + public static async Task DoAsync( + Func action, + ILogger logger, + IList delays +) { var exceptions = new List(); - for (int attempted = 0; attempted < maxAttemptCount; attempted++) + for (int attempt = 0; attempt < delays.Count; attempt++) { try { - if (attempted > 0) + if (attempt > 0) { - Task.Delay(retryInterval).Wait(); - logger.LogWarning("SlimDataService Retry number {RetryInterval}", retryInterval); + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); + await Task.Delay((int)delay * 1000); } - return action(); + + // Exécuter la méthode asynchrone + await action(); + return; // Si succès, on sort de la fonction } catch (Exception ex) { exceptions.Add(ex); } } + + // Si toutes les tentatives échouent, lever une AggregateException throw new AggregateException(exceptions); } } From 9f06062d18010c3bf2c174602e968811157d59a6 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Fri, 27 Dec 2024 21:22:24 +0100 Subject: [PATCH 113/135] clean --- README.md | 13 ++-- src/SlimFaas/Database/SlimDataService.cs | 69 +------------------- src/SlimFaas/Kubernetes/KubernetesService.cs | 1 + src/SlimFaas/Retry.cs | 68 +++++++++++++++++++ 4 files changed, 79 insertions(+), 72 deletions(-) create mode 100644 src/SlimFaas/Retry.cs diff --git a/README.md b/README.md index 2b9ab419..02449151 100644 --- a/README.md +++ b/README.md @@ -384,13 +384,18 @@ spec: { "DefaultSync":{ "HttpTimeout": 30, # Timeout in seconds - "TimeoutRetries": [2,4,8] # Retry pattern - "HttpStatusRetries": [500,502,503] # Retry pattern + "TimeoutRetries": [2,4,8] # Retry pattern in seconds + "HttpStatusRetries": [500,502,503] # Retry only for 500,502,503 HTTP status codes } "DefaultAsync":{ "HttpTimeout": 30, # Timeout in seconds - "TimeoutRetries": [2,4,8] # Retry pattern - "HttpStatusRetries": [500,502,503] # Retry pattern + "TimeoutRetries": [2,4,8] # Retry pattern in seconds + "HttpStatusRetries": [500,502,503] # Retry only for 500,502,503 HTTP status codes + }, + "DefaultPublish":{ + "HttpTimeout": 30, # Timeout in seconds + "TimeoutRetries": [2,4,8] # Retry pattern in seconds + "HttpStatusRetries": [500,502,503] # Retry only for 500,502,503 HTTP status codes } } ```` diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index db623d32..c66e0675 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -12,8 +12,7 @@ public class SlimDataService(IHttpClientFactory httpClientFactory, IServiceProvi : IDatabaseService { public const string HttpClientName = "SlimDataHttpClient"; - private const int MaxAttemptCount = 3; - private readonly IList _retryInterval = new List { 1, 1, 1 }; + private readonly IList _retryInterval = new List { 1, 1, 1 }; private readonly TimeSpan _timeMaxToWaitForLeader = TimeSpan.FromMilliseconds(3000); private ISupplier SimplePersistentState => @@ -276,69 +275,3 @@ private async Task GetAndWaitForLeader() } } #pragma warning restore CA2252 -public static class Retry -{ - - public static async Task DoAsync( - Func> action, - ILogger logger, - IList delays - ) - { - var exceptions = new List(); - - for (int attempt = 0; attempt < delays.Count; attempt++) - { - try - { - if (attempt > 0) - { - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); - await Task.Delay((int)delay * 1000); - } - - return await action(); - } - catch (Exception ex) - { - exceptions.Add(ex); - } - } - - throw new AggregateException(exceptions); - } - - public static async Task DoAsync( - Func action, - ILogger logger, - IList delays -) - { - var exceptions = new List(); - - for (int attempt = 0; attempt < delays.Count; attempt++) - { - try - { - if (attempt > 0) - { - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); - await Task.Delay((int)delay * 1000); - } - - // Exécuter la méthode asynchrone - await action(); - return; // Si succès, on sort de la fonction - } - catch (Exception ex) - { - exceptions.Add(ex); - } - } - - // Si toutes les tentatives échouent, lever une AggregateException - throw new AggregateException(exceptions); - } -} diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 4a0b7460..74425110 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -37,6 +37,7 @@ public record SlimFaasConfiguration { public SlimFaasDefaultConfiguration DefaultSync { get; init; } = new(); public SlimFaasDefaultConfiguration DefaultAsync { get; init; } = new(); + public SlimFaasDefaultConfiguration DefaultPublish { get; init; } = new(); } diff --git a/src/SlimFaas/Retry.cs b/src/SlimFaas/Retry.cs new file mode 100644 index 00000000..c8e7af2d --- /dev/null +++ b/src/SlimFaas/Retry.cs @@ -0,0 +1,68 @@ +namespace SlimFaas; + +public static class Retry +{ + + public static async Task DoAsync( + Func> action, + ILogger logger, + IList delays + ) + { + var exceptions = new List(); + + for (int attempt = 0; attempt < delays.Count; attempt++) + { + try + { + if (attempt > 0) + { + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); + await Task.Delay((int)delay * 1000); + } + + return await action(); + } + catch (Exception ex) + { + exceptions.Add(ex); + } + } + + throw new AggregateException(exceptions); + } + + public static async Task DoAsync( + Func action, + ILogger logger, + IList delays + ) + { + var exceptions = new List(); + + for (int attempt = 0; attempt < delays.Count; attempt++) + { + try + { + if (attempt > 0) + { + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); + await Task.Delay((int)delay * 1000); + } + + // Exécuter la méthode asynchrone + await action(); + return; // Si succès, on sort de la fonction + } + catch (Exception ex) + { + exceptions.Add(ex); + } + } + + // Si toutes les tentatives échouent, lever une AggregateException + throw new AggregateException(exceptions); + } +} From 491e5ad7218c44a3bb93df9d41813d619cf89f97 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 28 Dec 2024 15:25:10 +0100 Subject: [PATCH 114/135] clean --- src/SlimFaas/Kubernetes/KubernetesService.cs | 178 ++++++++++--------- 1 file changed, 97 insertions(+), 81 deletions(-) diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 74425110..f373ec0c 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -266,46 +266,52 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList var pods = podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(); ScheduleConfig? scheduleConfig = GetScheduleConfig(annotations, name, logger); SlimFaasConfiguration configuration = GetConfiguration(annotations, name, logger); - bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeploymentInformationList, name, pods); - - DeploymentInformation deploymentInformation = new( - name, - kubeNamespace, - pods, - configuration, - deploymentListItem.Spec.Replicas ?? 0, - annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) - ? int.Parse(annotationReplicasAtStart) - : 1, annotations.TryGetValue(ReplicasMin, out string? annotationReplicaMin) - ? int.Parse(annotationReplicaMin) - : 0, annotations.TryGetValue(TimeoutSecondBeforeSetReplicasMin, - out string? annotationTimeoutSecondBeforeSetReplicasMin) - ? int.Parse(annotationTimeoutSecondBeforeSetReplicasMin) - : 300, annotations.TryGetValue(NumberParallelRequest, - out string? annotationNumberParallelRequest) - ? int.Parse(annotationNumberParallelRequest) - : 10, annotations.ContainsKey( - ReplicasStartAsSoonAsOneFunctionRetrieveARequest) && - annotations[ReplicasStartAsSoonAsOneFunctionRetrieveARequest].ToLower() == "true", - PodType.Deployment, - annotations.TryGetValue(DependsOn, out string? value) - ? value.Split(',').ToList() - : new List(), - scheduleConfig, - annotations.TryGetValue(SubscribeEvents, out string? valueSubscribeEvents) - ? valueSubscribeEvents.Split(',').ToList() - : new List(), - annotations.TryGetValue(DefaultVisibility, out string? visibility) - ? Enum.Parse(visibility) - : FunctionVisibility.Public, - annotations.TryGetValue(PathsStartWithVisibility, out string? valueUrlsStartWithVisibility) - ? valueUrlsStartWithVisibility.Split(',').ToList() - : new List(), - annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), - deploymentListItem.Metadata.ResourceVersion, - EndpointReady: endpointReady + var previousDeployment = previousDeploymentInformationList.FirstOrDefault(d => d.Deployment == name); + bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeployment, name, pods); + var resourceVersion = deploymentListItem.Metadata.ResourceVersion; + if (previousDeployment != null && endpointReady == previousDeployment.EndpointReady && previousDeployment.ResourceVersion == resourceVersion) + { + deploymentInformationList.Add(previousDeployment); + } else { + DeploymentInformation deploymentInformation = new( + name, + kubeNamespace, + pods, + configuration, + deploymentListItem.Spec.Replicas ?? 0, + annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) + ? int.Parse(annotationReplicasAtStart) + : 1, annotations.TryGetValue(ReplicasMin, out string? annotationReplicaMin) + ? int.Parse(annotationReplicaMin) + : 0, annotations.TryGetValue(TimeoutSecondBeforeSetReplicasMin, + out string? annotationTimeoutSecondBeforeSetReplicasMin) + ? int.Parse(annotationTimeoutSecondBeforeSetReplicasMin) + : 300, annotations.TryGetValue(NumberParallelRequest, + out string? annotationNumberParallelRequest) + ? int.Parse(annotationNumberParallelRequest) + : 10, annotations.ContainsKey( + ReplicasStartAsSoonAsOneFunctionRetrieveARequest) && + annotations[ReplicasStartAsSoonAsOneFunctionRetrieveARequest].ToLower() == "true", + PodType.Deployment, + annotations.TryGetValue(DependsOn, out string? value) + ? value.Split(',').ToList() + : new List(), + scheduleConfig, + annotations.TryGetValue(SubscribeEvents, out string? valueSubscribeEvents) + ? valueSubscribeEvents.Split(',').ToList() + : new List(), + annotations.TryGetValue(DefaultVisibility, out string? visibility) + ? Enum.Parse(visibility) + : FunctionVisibility.Public, + annotations.TryGetValue(PathsStartWithVisibility, out string? valueUrlsStartWithVisibility) + ? valueUrlsStartWithVisibility.Split(',').ToList() + : new List(), + annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), + resourceVersion, + EndpointReady: endpointReady ); - deploymentInformationList.Add(deploymentInformation); + deploymentInformationList.Add(deploymentInformation); + } } catch (Exception e) { @@ -315,7 +321,7 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList } private static async Task GetEndpointReady(string kubeNamespace, k8s.Kubernetes client, - IList previousDeploymentInformationList, string name, List pods) + DeploymentInformation? previousDeployment, string name, List pods) { try { @@ -324,7 +330,6 @@ private static async Task GetEndpointReady(string kubeNamespace, k8s.Kuber return false; } - var previousDeployment = previousDeploymentInformationList.FirstOrDefault(d => d.Deployment == name); if (previousDeployment is not { EndpointReady: false } || pods.Count != 1) { return previousDeployment is { EndpointReady: true }; @@ -401,46 +406,57 @@ private static async Task AddStatefulSets(string kubeNamespace, V1StatefulSetLis var pods = podList.Where(p => p.DeploymentName.StartsWith(name)).ToList(); ScheduleConfig? scheduleConfig = GetScheduleConfig(annotations, name, logger); SlimFaasConfiguration configuration = GetConfiguration(annotations, name, logger); - bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeploymentInformationList, name, pods); - - DeploymentInformation deploymentInformation = new( - name, - kubeNamespace, - pods, - configuration, - deploymentListItem.Spec.Replicas ?? 0, - annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) - ? int.Parse(annotationReplicasAtStart) - : 1, annotations.TryGetValue(ReplicasMin, out string? annotationReplicasMin) - ? int.Parse(annotationReplicasMin) - : 0, annotations.TryGetValue(TimeoutSecondBeforeSetReplicasMin, - out string? annotationTimeoutSecondBeforeSetReplicasMin) - ? int.Parse(annotationTimeoutSecondBeforeSetReplicasMin) - : 300, annotations.TryGetValue(NumberParallelRequest, - out string? annotationNumberParallelRequest) - ? int.Parse(annotationNumberParallelRequest) - : 10, annotations.ContainsKey( - ReplicasStartAsSoonAsOneFunctionRetrieveARequest) && - annotations[ReplicasStartAsSoonAsOneFunctionRetrieveARequest].ToLower() == "true", - PodType.StatefulSet, - annotations.TryGetValue(DependsOn, out string? value) - ? value.Split(',').ToList() - : new List(), - scheduleConfig, - annotations.TryGetValue(SubscribeEvents, out string? valueSubscribeEvents) - ? valueSubscribeEvents.Split(',').ToList() - : new List(), - annotations.TryGetValue(DefaultVisibility, out string? visibility) - ? Enum.Parse(visibility) - : FunctionVisibility.Public, - annotations.TryGetValue(PathsStartWithVisibility, out string? valueUrlsStartWithVisibility) - ? valueUrlsStartWithVisibility.Split(',').ToList() - : new List(), - annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, out string? valueExcludeDeploymentsFromVisibilityPrivate) ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() : new List(), - deploymentListItem.Metadata.ResourceVersion, - EndpointReady: endpointReady); - - deploymentInformationList.Add(deploymentInformation); + var previousDeployment = previousDeploymentInformationList.FirstOrDefault(d => d.Deployment == name); + bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeployment, name, pods); + var resourceVersion = deploymentListItem.Metadata.ResourceVersion; + if (previousDeployment != null && endpointReady == previousDeployment.EndpointReady && previousDeployment.ResourceVersion == resourceVersion) + { + deploymentInformationList.Add(previousDeployment); + } + else + { + DeploymentInformation deploymentInformation = new( + name, + kubeNamespace, + pods, + configuration, + deploymentListItem.Spec.Replicas ?? 0, + annotations.TryGetValue(ReplicasAtStart, out string? annotationReplicasAtStart) + ? int.Parse(annotationReplicasAtStart) + : 1, annotations.TryGetValue(ReplicasMin, out string? annotationReplicasMin) + ? int.Parse(annotationReplicasMin) + : 0, annotations.TryGetValue(TimeoutSecondBeforeSetReplicasMin, + out string? annotationTimeoutSecondBeforeSetReplicasMin) + ? int.Parse(annotationTimeoutSecondBeforeSetReplicasMin) + : 300, annotations.TryGetValue(NumberParallelRequest, + out string? annotationNumberParallelRequest) + ? int.Parse(annotationNumberParallelRequest) + : 10, annotations.ContainsKey( + ReplicasStartAsSoonAsOneFunctionRetrieveARequest) && + annotations[ReplicasStartAsSoonAsOneFunctionRetrieveARequest].ToLower() == "true", + PodType.StatefulSet, + annotations.TryGetValue(DependsOn, out string? value) + ? value.Split(',').ToList() + : new List(), + scheduleConfig, + annotations.TryGetValue(SubscribeEvents, out string? valueSubscribeEvents) + ? valueSubscribeEvents.Split(',').ToList() + : new List(), + annotations.TryGetValue(DefaultVisibility, out string? visibility) + ? Enum.Parse(visibility) + : FunctionVisibility.Public, + annotations.TryGetValue(PathsStartWithVisibility, out string? valueUrlsStartWithVisibility) + ? valueUrlsStartWithVisibility.Split(',').ToList() + : new List(), + annotations.TryGetValue(ExcludeDeploymentsFromVisibilityPrivate, + out string? valueExcludeDeploymentsFromVisibilityPrivate) + ? valueExcludeDeploymentsFromVisibilityPrivate.Split(',').ToList() + : new List(), + resourceVersion, + EndpointReady: endpointReady); + + deploymentInformationList.Add(deploymentInformation); + } } catch (Exception e) { From 2f9ae9666b8cb6f0bc9b97910d1a66a1390b961a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Sat, 28 Dec 2024 21:27:58 +0100 Subject: [PATCH 115/135] clean :) --- src/SlimFaas/Retry.cs | 56 ++++++++++++++++--- src/SlimFaas/SendClient.cs | 23 +++++--- src/SlimFaas/SlimProxyMiddleware.cs | 10 ++-- src/SlimFaas/SlimWorker.cs | 13 ++++- tests/SlimFaas.Tests/SendClientShould.cs | 7 ++- .../SlimProxyMiddlewareTests.cs | 7 ++- tests/SlimFaas.Tests/SlimWorkerShould.cs | 4 +- 7 files changed, 88 insertions(+), 32 deletions(-) diff --git a/src/SlimFaas/Retry.cs b/src/SlimFaas/Retry.cs index c8e7af2d..82f43b09 100644 --- a/src/SlimFaas/Retry.cs +++ b/src/SlimFaas/Retry.cs @@ -15,13 +15,15 @@ IList delays { try { - if (attempt > 0) + if (attempt <= 0) { - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); - await Task.Delay((int)delay * 1000); + return await action(); } + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); + await Task.Delay((int)delay * 1000); + return await action(); } catch (Exception ex) @@ -49,12 +51,11 @@ IList delays { var delay = delays[attempt]; logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); - await Task.Delay((int)delay * 1000); + await Task.Delay(delay * 1000); } - // Exécuter la méthode asynchrone await action(); - return; // Si succès, on sort de la fonction + return; } catch (Exception ex) { @@ -62,7 +63,46 @@ IList delays } } - // Si toutes les tentatives échouent, lever une AggregateException + throw new AggregateException(exceptions); + } + + public static async Task DoRequestAsync( + Func> action, + ILogger logger, + IList delays, + IList httpStatusRetries + ) + { + var exceptions = new List(); + + for (int attempt = 0; attempt < delays.Count; attempt++) + { + try + { + if (attempt <= 0) + { + return await action(); + } + + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); + await Task.Delay(delay * 1000); + + var responseMessage = await action(); + var statusCode = (int)responseMessage.StatusCode; + if (!httpStatusRetries.Contains(statusCode)) + { + return responseMessage; + } + responseMessage.Dispose(); + exceptions.Add(new Exception($"Received code Http {statusCode}")); + } + catch (HttpRequestException ex) + { + exceptions.Add(ex); + } + } + throw new AggregateException(exceptions); } } diff --git a/src/SlimFaas/SendClient.cs b/src/SlimFaas/SendClient.cs index 67379d6b..56b95f1d 100644 --- a/src/SlimFaas/SendClient.cs +++ b/src/SlimFaas/SendClient.cs @@ -1,13 +1,14 @@ using Microsoft.Extensions.Primitives; +using SlimFaas.Kubernetes; namespace SlimFaas; public interface ISendClient { - Task SendHttpRequestAsync(CustomRequest customRequest, int timeout=30, string? baseUrl = null, CancellationTokenSource? cancellationToken = null); + Task SendHttpRequestAsync(CustomRequest customRequest, SlimFaasDefaultConfiguration slimFaasDefaultConfiguration, string? baseUrl = null, CancellationTokenSource? cancellationToken = null); Task SendHttpRequestSync(HttpContext httpContext, string functionName, string functionPath, - string functionQuery, string? baseUrl = null); + string functionQuery, SlimFaasDefaultConfiguration slimFaasDefaultConfiguration, string? baseUrl = null); } public class SendClient(HttpClient httpClient, ILogger logger) : ISendClient @@ -19,7 +20,7 @@ public class SendClient(HttpClient httpClient, ILogger logger) : ISe Environment.GetEnvironmentVariable(EnvironmentVariables.Namespace) ?? EnvironmentVariables.NamespaceDefault; public async Task SendHttpRequestAsync(CustomRequest customRequest, - int timeout=30, string? baseUrl = null, CancellationTokenSource? cancellationToken = null) + SlimFaasDefaultConfiguration slimFaasDefaultConfiguration, string? baseUrl = null, CancellationTokenSource? cancellationToken = null) { try { @@ -32,9 +33,11 @@ public async Task SendHttpRequestAsync(CustomRequest custom logger.LogDebug("Sending async request to {TargetUrl}", targetUrl); HttpRequestMessage targetRequestMessage = CreateTargetMessage(customRequest, new Uri(targetUrl)); - httpClient.Timeout = TimeSpan.FromSeconds(timeout); - return await httpClient.SendAsync(targetRequestMessage, - HttpCompletionOption.ResponseHeadersRead, cancellationToken?.Token ?? CancellationToken.None); + httpClient.Timeout = TimeSpan.FromSeconds(slimFaasDefaultConfiguration.HttpTimeout); + return await Retry.DoRequestAsync(() => httpClient.SendAsync(targetRequestMessage, + HttpCompletionOption.ResponseHeadersRead, cancellationToken?.Token ?? CancellationToken.None), + logger, slimFaasDefaultConfiguration.TimeoutRetries, slimFaasDefaultConfiguration.HttpStatusRetries) + .ConfigureAwait(false); } catch (Exception e) { @@ -44,15 +47,17 @@ public async Task SendHttpRequestAsync(CustomRequest custom } public async Task SendHttpRequestSync(HttpContext context, string functionName, - string functionPath, string functionQuery, string? baseUrl = null) + string functionPath, string functionQuery, SlimFaasDefaultConfiguration slimFaasDefaultConfiguration, string? baseUrl = null) { try { string targetUrl = ComputeTargetUrl(baseUrl ?? _baseFunctionUrl, functionName, functionPath, functionQuery, _namespaceSlimFaas); logger.LogDebug("Sending sync request to {TargetUrl}", targetUrl); HttpRequestMessage targetRequestMessage = CreateTargetMessage(context, new Uri(targetUrl)); - HttpResponseMessage responseMessage = await httpClient.SendAsync(targetRequestMessage, - HttpCompletionOption.ResponseHeadersRead, context.RequestAborted); + httpClient.Timeout = TimeSpan.FromSeconds(slimFaasDefaultConfiguration.HttpTimeout); + HttpResponseMessage responseMessage = await Retry.DoRequestAsync(() => httpClient.SendAsync(targetRequestMessage, + HttpCompletionOption.ResponseHeadersRead, context.RequestAborted), + logger, slimFaasDefaultConfiguration.TimeoutRetries, slimFaasDefaultConfiguration.HttpStatusRetries).ConfigureAwait(false); return responseMessage; } catch (Exception e) diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index 0c3ce095..9264b938 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -335,7 +335,7 @@ private async Task BuildPublishResponseAsync(HttpContext context, HistoryHttpMem var baseUrl = SlimDataEndpoint.Get(pod, baseFunctionPodUrl); logger.LogDebug("Sending event {EventName} to {FunctionDeployment} at {BaseUrl} with path {FunctionPath} and query {UriComponent}", eventName, function.Deployment, baseUrl, functionPath, context.Request.QueryString.ToUriComponent()); - Task task = SendRequest(queryString, sendClient, customRequest with {FunctionName = function.Deployment}, baseUrl, logger, eventName); + Task task = SendRequest(queryString, sendClient, customRequest with {FunctionName = function.Deployment}, baseUrl, logger, eventName, function.Configuration.DefaultPublish); tasks.Add(task); } } @@ -345,7 +345,7 @@ private async Task BuildPublishResponseAsync(HttpContext context, HistoryHttpMem foreach (string baseUrl in slimFaasSubscribeEvent.Value) { logger.LogDebug("Sending event {EventName} to {BaseUrl} with path {FunctionPath} and query {UriComponent}", eventName, baseUrl, functionPath, context.Request.QueryString.ToUriComponent()); - Task task = SendRequest(queryString, sendClient, customRequest with {FunctionName = ""}, baseUrl, logger, eventName); + Task task = SendRequest(queryString, sendClient, customRequest with {FunctionName = ""}, baseUrl, logger, eventName, new SlimFaasDefaultConfiguration()); tasks.Add(task); } } @@ -369,11 +369,11 @@ private async Task BuildPublishResponseAsync(HttpContext context, HistoryHttpMem context.Response.StatusCode = 204; } - private static async Task SendRequest(string queryString, ISendClient sendClient, CustomRequest customRequest, string baseUrl, ILogger logger, string eventName) + private static async Task SendRequest(string queryString, ISendClient sendClient, CustomRequest customRequest, string baseUrl, ILogger logger, string eventName, SlimFaasDefaultConfiguration slimFaasDefaultConfiguration) { try { - using HttpResponseMessage responseMessage = await sendClient.SendHttpRequestAsync(customRequest, 30, baseUrl); + using HttpResponseMessage responseMessage = await sendClient.SendHttpRequestAsync(customRequest, slimFaasDefaultConfiguration, baseUrl); logger.LogDebug( "Response from event {EventName} to {FunctionDeployment} at {BaseUrl} with path {FunctionPath} and query {UriComponent} is {StatusCode}", eventName, customRequest.FunctionName, baseUrl, customRequest.Path, queryString, @@ -407,7 +407,7 @@ private async Task BuildSyncResponseAsync(HttpContext context, HistoryHttpMemory await WaitForAnyPodStartedAsync(context, historyHttpService, replicasService, functionName); Task responseMessagePromise = sendClient.SendHttpRequestSync(context, functionName, - functionPath, context.Request.QueryString.ToUriComponent()); + functionPath, context.Request.QueryString.ToUriComponent(), function.Configuration.DefaultSync); long lastSetTicks = DateTime.UtcNow.Ticks; historyHttpService.SetTickLastCall(functionName, lastSetTicks); diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 97376486..f639f599 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -73,7 +73,7 @@ private async Task DoOneCycle(CancellationToken stoppingToken, } await SendHttpRequestToFunction(processingTasks, numberLimitProcessingTasks, numberProcessingTasks, - functionDeployment); + function); } } catch (Exception e) @@ -84,8 +84,9 @@ await SendHttpRequestToFunction(processingTasks, numberLimitProcessingTasks, num private async Task SendHttpRequestToFunction(Dictionary> processingTasks, int numberLimitProcessingTasks, int numberProcessingTasks, - string functionDeployment) + DeploymentInformation function) { + string functionDeployment = function.Deployment; int numberTasksToDequeue = numberLimitProcessingTasks - numberProcessingTasks; var jsons = await slimFaasQueue.DequeueAsync(functionDeployment, numberTasksToDequeue); if (jsons == null) @@ -101,8 +102,14 @@ private async Task SendHttpRequestToFunction(Dictionary taskResponse = scope.ServiceProvider.GetRequiredService() - .SendHttpRequestAsync(customRequest); + .SendHttpRequestAsync(customRequest, slimfaasDefaultConfiguration); processingTasks[functionDeployment].Add(new RequestToWait(taskResponse, customRequest, requestJson.Id)); } } diff --git a/tests/SlimFaas.Tests/SendClientShould.cs b/tests/SlimFaas.Tests/SendClientShould.cs index 175289c1..2380a177 100644 --- a/tests/SlimFaas.Tests/SendClientShould.cs +++ b/tests/SlimFaas.Tests/SendClientShould.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Moq; +using SlimFaas.Kubernetes; namespace SlimFaas.Tests; @@ -36,7 +37,7 @@ public async Task CallFunctionAsync(string httpMethod) CustomRequest customRequest = new CustomRequest(new List { new() { Key = "key", Values = new[] { "value1" } } }, new byte[1], "fibonacci", "health", httpMethod, ""); - HttpResponseMessage response = await sendClient.SendHttpRequestAsync(customRequest); + HttpResponseMessage response = await sendClient.SendHttpRequestAsync(customRequest, new SlimFaasDefaultConfiguration()); Uri expectedUri = new Uri("http://fibonacci:8080/health"); Assert.Equal(HttpStatusCode.OK, response.StatusCode); @@ -83,7 +84,9 @@ public async Task CallFunctionSync(string httpMethod) httpContextRequest.ContentLength = 1; httpContextRequest.ContentType = "application/json"; - HttpResponseMessage response = await sendClient.SendHttpRequestSync(httpContext, "fibonacci", "health", ""); + SlimFaasDefaultConfiguration slimFaasDefaultConfiguration = new(); + + HttpResponseMessage response = await sendClient.SendHttpRequestSync(httpContext, "fibonacci", "health", "", slimFaasDefaultConfiguration); Uri expectedUri = new Uri("http://fibonacci:8080/health"); Assert.NotNull(sendedRequest); diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 5a1a3fbe..77b0944c 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -90,7 +90,7 @@ internal record SendData(string FunctionName, string Path, string BaseUrl); internal class SendClientMock : ISendClient { public IList SendDatas = new List(); - public Task SendHttpRequestAsync(CustomRequest customRequest, int timeout, string? baseUrl = null, CancellationTokenSource? cancellationToken = null) + public Task SendHttpRequestAsync(CustomRequest customRequest, SlimFaasDefaultConfiguration slimFaasDefaultConfiguration, string? baseUrl = null, CancellationTokenSource? cancellationToken = null) { HttpResponseMessage responseMessage = new HttpResponseMessage(); responseMessage.StatusCode = HttpStatusCode.OK; @@ -100,7 +100,7 @@ public Task SendHttpRequestAsync(CustomRequest customReques } public Task SendHttpRequestSync(HttpContext httpContext, string functionName, - string functionPath, string functionQuery, string? baseUrl = null) + string functionPath, string functionQuery, SlimFaasDefaultConfiguration slimFaasDefaultConfiguration, string? baseUrl = null) { HttpResponseMessage responseMessage = new HttpResponseMessage(); responseMessage.StatusCode = HttpStatusCode.OK; @@ -175,7 +175,8 @@ public async Task CallFunctionInSyncModeAndReturnOk(string path, HttpStatusCode HttpResponseMessage responseMessage = new HttpResponseMessage(); responseMessage.StatusCode = HttpStatusCode.OK; Mock sendClientMock = new Mock(); - sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), + It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(responseMessage); using IHost host = await new HostBuilder() diff --git a/tests/SlimFaas.Tests/SlimWorkerShould.cs b/tests/SlimFaas.Tests/SlimWorkerShould.cs index aeecf80e..8d1f6f19 100644 --- a/tests/SlimFaas.Tests/SlimWorkerShould.cs +++ b/tests/SlimFaas.Tests/SlimWorkerShould.cs @@ -19,7 +19,7 @@ public async Task OnlyCallOneFunctionAsync() responseMessage.StatusCode = HttpStatusCode.OK; Mock sendClientMock = new Mock(); - sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + sendClientMock.Setup(s => s.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(responseMessage); Mock serviceProvider = new Mock(); @@ -98,7 +98,7 @@ public async Task OnlyCallOneFunctionAsync() await Task.Delay(3000); Assert.True(task.IsCompleted); - sendClientMock.Verify(v => v.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), + sendClientMock.Verify(v => v.SendHttpRequestAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny()), Times.Once()); } From 717f1970b16c52d7800d6264a1d603da0f46e037 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 11:09:31 +0100 Subject: [PATCH 116/135] test --- demo/deployment-slimfaas.yml | 10 +++++----- src/SlimFaas/ReplicasService.cs | 8 +++++--- src/SlimFaas/Retry.cs | 24 ++++++++++++++---------- src/SlimFaas/SendClient.cs | 4 ++-- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index ded3fe00..ebb3e763 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 3 + replicas: 1 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-834 + image: axaguildev/slimfaas:pr-77-847 livenessProbe: httpGet: path: /health @@ -137,9 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" - #- name: SLIMDATA_CONFIGURATION - # value: | - # {"coldStart":"true"} + - name: SLIMDATA_CONFIGURATION + value: | + {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"} diff --git a/src/SlimFaas/ReplicasService.cs b/src/SlimFaas/ReplicasService.cs index 0c4d4146..d16e0f54 100644 --- a/src/SlimFaas/ReplicasService.cs +++ b/src/SlimFaas/ReplicasService.cs @@ -1,4 +1,5 @@ -using SlimFaas.Kubernetes; +using System.Text.Json; +using SlimFaas.Kubernetes; using NodaTime; using NodaTime.TimeZones; @@ -72,12 +73,13 @@ public async Task SyncDeploymentsAsync(string kubeNames "with {ResourceVersion} resource version \n"+ "with {NumberParallelRequest} number parallel request \n" + "with dependOn {DependsOn} \n" + - "with {EndpointReady} endpoint ready \n", + "with {EndpointReady} endpoint ready \n" + + "with {Configuration} configuration \n", deploymentInformation.Deployment, deploymentInformation.Replicas, deploymentInformation.ReplicasAtStart, deploymentInformation.ReplicasMin, deploymentInformation.ReplicasStartAsSoonAsOneFunctionRetrieveARequest, deploymentInformation.TimeoutSecondBeforeSetReplicasMin, deploymentInformation.PodType, deploymentInformation.ResourceVersion, deploymentInformation.NumberParallelRequest, deploymentInformation.DependsOn, - deploymentInformation.EndpointReady); + deploymentInformation.EndpointReady, JsonSerializer.Serialize(deploymentInformation.Configuration, SlimFaasConfigurationSerializerContext.Default.SlimFaasConfiguration)); } } } diff --git a/src/SlimFaas/Retry.cs b/src/SlimFaas/Retry.cs index 82f43b09..156391fe 100644 --- a/src/SlimFaas/Retry.cs +++ b/src/SlimFaas/Retry.cs @@ -11,18 +11,18 @@ IList delays { var exceptions = new List(); - for (int attempt = 0; attempt < delays.Count; attempt++) + for (int attempt = -1; attempt < delays.Count; attempt++) { try { - if (attempt <= 0) + if (attempt < 0) { return await action(); } var delay = delays[attempt]; logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); - await Task.Delay((int)delay * 1000); + await Task.Delay(delay * 1000); return await action(); } @@ -43,17 +43,21 @@ IList delays { var exceptions = new List(); - for (int attempt = 0; attempt < delays.Count; attempt++) + for (int attempt = -1; attempt < delays.Count; attempt++) { try { - if (attempt > 0) + + if (attempt < 0) { - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); - await Task.Delay(delay * 1000); + await action(); + return; } + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); + await Task.Delay(delay * 1000); + await action(); return; } @@ -75,11 +79,11 @@ IList httpStatusRetries { var exceptions = new List(); - for (int attempt = 0; attempt < delays.Count; attempt++) + for (int attempt = -1; attempt < delays.Count; attempt++) { try { - if (attempt <= 0) + if (attempt < 0) { return await action(); } diff --git a/src/SlimFaas/SendClient.cs b/src/SlimFaas/SendClient.cs index 56b95f1d..d97e405c 100644 --- a/src/SlimFaas/SendClient.cs +++ b/src/SlimFaas/SendClient.cs @@ -41,7 +41,7 @@ public async Task SendHttpRequestAsync(CustomRequest custom } catch (Exception e) { - logger.LogError(e, "Error in SendHttpRequestAsync to {FunctionName} to {FunctionPath} ", customRequest.FunctionName, customRequest.FunctionName); + logger.LogError(e, "Error in SendHttpRequestAsync to {FunctionName} to {FunctionPath} ", customRequest.FunctionName, customRequest.Path); throw; } } @@ -55,7 +55,7 @@ public async Task SendHttpRequestSync(HttpContext context, logger.LogDebug("Sending sync request to {TargetUrl}", targetUrl); HttpRequestMessage targetRequestMessage = CreateTargetMessage(context, new Uri(targetUrl)); httpClient.Timeout = TimeSpan.FromSeconds(slimFaasDefaultConfiguration.HttpTimeout); - HttpResponseMessage responseMessage = await Retry.DoRequestAsync(() => httpClient.SendAsync(targetRequestMessage, + HttpResponseMessage responseMessage = await Retry.DoRequestAsync(() => httpClient.SendAsync(targetRequestMessage, HttpCompletionOption.ResponseHeadersRead, context.RequestAborted), logger, slimFaasDefaultConfiguration.TimeoutRetries, slimFaasDefaultConfiguration.HttpStatusRetries).ConfigureAwait(false); return responseMessage; From b5a270083778283698e0b6e5022deffa6b52d5bb Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 14:34:07 +0100 Subject: [PATCH 117/135] test --- README.md | 2 +- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Retry.cs | 33 ++++++++++++--------------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 02449151..b15f865b 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ kubectl apply -f deployment-functions.yml # Install MySql kubectl apply -f deployment-mysql.yml # to run Single Page webapp demo (optional) on http://localhost:8000 -docker run -p 8000:8000 --rm axaguildev/fibonacci-webapp:latest +docker run -d -p 8000:8000 --rm axaguildev/fibonacci-webapp:latest kubectl port-forward svc/slimfaas-nodeport 30021:5000 -n slimfaas-demo ``` diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index ebb3e763..a39bbdfa 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-847 + image: axaguildev/slimfaas:pr-77-848 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Retry.cs b/src/SlimFaas/Retry.cs index 156391fe..9592fb66 100644 --- a/src/SlimFaas/Retry.cs +++ b/src/SlimFaas/Retry.cs @@ -15,15 +15,13 @@ IList delays { try { - if (attempt < 0) + if (attempt >= 0) { - return await action(); + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); + await Task.Delay(delay * 1000); } - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); - await Task.Delay(delay * 1000); - return await action(); } catch (Exception ex) @@ -47,17 +45,12 @@ IList delays { try { - - if (attempt < 0) + if (attempt >= 0) { - await action(); - return; + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); + await Task.Delay(delay * 1000); } - - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait numnber {Delay} second", attempt, delay); - await Task.Delay(delay * 1000); - await action(); return; } @@ -83,15 +76,13 @@ IList httpStatusRetries { try { - if (attempt < 0) + if (attempt >= 0) { - return await action(); + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); + await Task.Delay(delay * 1000); } - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); - await Task.Delay(delay * 1000); - var responseMessage = await action(); var statusCode = (int)responseMessage.StatusCode; if (!httpStatusRetries.Contains(statusCode)) From 6edf95fc8042ac9977dd129563bb9c55575e2d89 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 14:44:39 +0100 Subject: [PATCH 118/135] test --- src/SlimData/SlimDataInterpreter.cs | 2 -- src/SlimFaas/SlimWorker.cs | 2 +- .../QueueElementExtentionsTests.cs | 18 ++++++++++-------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index a4b9b101..280c3901 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -51,8 +51,6 @@ public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, Cancel return DoListRightPopAsync(addHashSetCommand, SlimDataState.Queues); } - public static readonly List Retries = [2, 6, 10]; - public static readonly int RetryTimeout = 30; internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetCommand, Dictionary> queues) { diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index f639f599..5b516e5c 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -186,7 +186,7 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, HttpResponseMessage httpResponseMessage = processing.Task.Result; var statusCode = (int)httpResponseMessage.StatusCode; logger.LogDebug( - "{CustomRequestMethod}: /async-function/{CustomRequestPath}{CustomRequestQuery} {StatusCode}", + "{CustomRequestMethod}: /async-function{CustomRequestPath}{CustomRequestQuery} {StatusCode}", processing.CustomRequest.Method, processing.CustomRequest.Path, processing.CustomRequest.Query, httpResponseMessage.StatusCode); httpResponseMessagesToDelete.Add(processing); diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index d44c7fc1..5818df18 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -7,46 +7,48 @@ public static void QueueElementExtensionsGetQueueRunningElement() { // I want a test which text my extention var nowTicks = DateTime.UtcNow.Ticks; + List Retries = [2, 6, 10]; + int RetryTimeout = 30; var timeout = 30; var timeoutSpanTicks = TimeSpan.FromSeconds(31).Ticks; List queueElements = new(); var httpRetriesCode = new List(Endpoints.HttpStatusCodesWorthRetrying) ; - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, timeout, SlimDataInterpreter.Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, timeout, Retries, new List() { new(nowTicks -100, nowTicks, 500), new(nowTicks -50, nowTicks, 500), new(nowTicks -20, nowTicks, 500), new(nowTicks -10, nowTicks, 500), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, timeout, SlimDataInterpreter.Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, timeout, Retries, new List() { new(nowTicks - timeoutSpanTicks -100, nowTicks, 500), new(nowTicks- timeoutSpanTicks -50, nowTicks, 500), new(nowTicks- timeoutSpanTicks -30, nowTicks, 500), new(nowTicks- timeoutSpanTicks -20, 0, 0), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, timeout, SlimDataInterpreter.Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, timeout, Retries, new List() { new(nowTicks -100, nowTicks, 200), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, timeout, SlimDataInterpreter.Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, timeout, Retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 200, nowTicks, 500), new(nowTicks- 100, 0, 0), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, timeout, SlimDataInterpreter.Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, timeout, Retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 400, nowTicks, 500), new(nowTicks- timeoutSpanTicks, 0, 0), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, timeout, SlimDataInterpreter.Retries, new List(), httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, SlimDataInterpreter.Retries, new List(), httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, SlimDataInterpreter.Retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, timeout, Retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, Retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, Retries, new List(), httpRetriesCode)); var availableElements = queueElements.GetQueueAvailableElement(nowTicks, 3); From b3202edbd08713a4da4a38c18e83f48b1905750e Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 16:11:51 +0100 Subject: [PATCH 119/135] update --- README.md | 8 ++- src/SlimFaas/Kubernetes/KubernetesService.cs | 2 +- src/SlimFaas/Retry.cs | 56 +++++++++++++------- src/SlimFaas/SlimWorker.cs | 9 ---- 4 files changed, 42 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index b15f865b..701245e3 100644 --- a/README.md +++ b/README.md @@ -168,8 +168,6 @@ spec: SlimFaas/SubscribeEvents: "Public:my-event-name1,Private:my-event-name2,my-event-name3" # comma separated list of event names SlimFaas/DefaultVisibility: "Public" # Public or Private (private can be accessed only by internal namespace https call from pods) SlimFaas/UrlsPathStartWithVisibility: "Private:/mypath/subPath,Private:/mysecondpath" # Public or Private (private can be accessed only by internal namespace https call from pods) - SlimFaas/SynchrounousRetry: "2;4;8" - SlimFaas/AsynchrounousRetry: "2;4;8" spec: serviceAccountName: default containers: @@ -383,17 +381,17 @@ spec: ````bash { "DefaultSync":{ - "HttpTimeout": 30, # Timeout in seconds + "HttpTimeout": 120, # Timeout in seconds "TimeoutRetries": [2,4,8] # Retry pattern in seconds "HttpStatusRetries": [500,502,503] # Retry only for 500,502,503 HTTP status codes } "DefaultAsync":{ - "HttpTimeout": 30, # Timeout in seconds + "HttpTimeout": 120, # Timeout in seconds "TimeoutRetries": [2,4,8] # Retry pattern in seconds "HttpStatusRetries": [500,502,503] # Retry only for 500,502,503 HTTP status codes }, "DefaultPublish":{ - "HttpTimeout": 30, # Timeout in seconds + "HttpTimeout": 120, # Timeout in seconds "TimeoutRetries": [2,4,8] # Retry pattern in seconds "HttpStatusRetries": [500,502,503] # Retry only for 500,502,503 HTTP status codes } diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index f373ec0c..9466ef1e 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -43,7 +43,7 @@ public record SlimFaasConfiguration { public record SlimFaasDefaultConfiguration { - public int HttpTimeout { get; init; } = 30; + public int HttpTimeout { get; init; } = 120; public List TimeoutRetries { get; init; } = [2, 4, 8]; public List HttpStatusRetries { get; init; } = [500, 502, 503]; } diff --git a/src/SlimFaas/Retry.cs b/src/SlimFaas/Retry.cs index 9592fb66..615b4979 100644 --- a/src/SlimFaas/Retry.cs +++ b/src/SlimFaas/Retry.cs @@ -74,30 +74,50 @@ IList httpStatusRetries for (int attempt = -1; attempt < delays.Count; attempt++) { - try + if (attempt >= 0) { - if (attempt >= 0) - { - var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); - await Task.Delay(delay * 1000); - } - - var responseMessage = await action(); - var statusCode = (int)responseMessage.StatusCode; - if (!httpStatusRetries.Contains(statusCode)) - { - return responseMessage; - } - responseMessage.Dispose(); - exceptions.Add(new Exception($"Received code Http {statusCode}")); + var delay = delays[attempt]; + logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); + await Task.Delay(delay * 1000); } - catch (HttpRequestException ex) + + var responseMessage = await WrapRequestAction(action); + var statusCode = (int)responseMessage.StatusCode; + if (!httpStatusRetries.Contains(statusCode)) { - exceptions.Add(ex); + return responseMessage; } + responseMessage.Dispose(); + exceptions.Add(new Exception($"Received code Http {statusCode}")); } throw new AggregateException(exceptions); } + + private static async Task WrapRequestAction(Func> action) + { + try + { + return await action(); + } + catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) + { + var fallbackResponse = new HttpResponseMessage(System.Net.HttpStatusCode.GatewayTimeout) + { + Content = new StringContent("Error 504 simulated due to a timeout") + }; + return fallbackResponse; + } + catch (HttpRequestException ex) + { + Console.WriteLine($"Network exception : {ex.Message}"); + + var fallbackResponse = new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError) + { + Content = new StringContent("Error 500 simulated due to a network problem") + }; + return fallbackResponse; + } + } + } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 5b516e5c..ee33c790 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -193,20 +193,11 @@ private async Task ManageProcessingTasksAsync(ISlimFaasQueue slimFaasQueue, queueItemStatusList.Add(new QueueItemStatus(processing.Id, statusCode)); httpResponseMessage.Dispose(); } - // Filter by InnerException. - catch (TaskCanceledException ex) when (ex.InnerException is TimeoutException) - { - queueItemStatusList.Add(new QueueItemStatus(processing.Id, 504)); - httpResponseMessagesToDelete.Add(processing); - logger.LogWarning("Request HttpTimeout Error: {Message} {StackTrace}", ex.Message, ex.StackTrace); - historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); - } catch (Exception e) { queueItemStatusList.Add(new QueueItemStatus(processing.Id, 500)); httpResponseMessagesToDelete.Add(processing); logger.LogWarning("Request Error: {Message} {StackTrace}", e.Message, e.StackTrace); - historyHttpService.SetTickLastCall(functionDeployment, DateTime.UtcNow.Ticks); } } From 83ab0b0de6a654d988879e8924a2633dda0fa91d Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 16:44:09 +0100 Subject: [PATCH 120/135] last fix --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/SendClient.cs | 20 ++++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index a39bbdfa..a56beabe 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-848 + image: axaguildev/slimfaas:pr-77-850 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/SendClient.cs b/src/SlimFaas/SendClient.cs index d97e405c..85d570a9 100644 --- a/src/SlimFaas/SendClient.cs +++ b/src/SlimFaas/SendClient.cs @@ -31,11 +31,16 @@ public async Task SendHttpRequestAsync(CustomRequest custom string targetUrl = ComputeTargetUrl(functionUrl, customRequestFunctionName, customRequestPath, customRequestQuery, _namespaceSlimFaas); logger.LogDebug("Sending async request to {TargetUrl}", targetUrl); - HttpRequestMessage targetRequestMessage = CreateTargetMessage(customRequest, new Uri(targetUrl)); + httpClient.Timeout = TimeSpan.FromSeconds(slimFaasDefaultConfiguration.HttpTimeout); - return await Retry.DoRequestAsync(() => httpClient.SendAsync(targetRequestMessage, - HttpCompletionOption.ResponseHeadersRead, cancellationToken?.Token ?? CancellationToken.None), + return await Retry.DoRequestAsync(() => + { + HttpRequestMessage targetRequestMessage = CreateTargetMessage(customRequest, new Uri(targetUrl)); + return httpClient.SendAsync(targetRequestMessage, + HttpCompletionOption.ResponseHeadersRead, + cancellationToken?.Token ?? CancellationToken.None); + }, logger, slimFaasDefaultConfiguration.TimeoutRetries, slimFaasDefaultConfiguration.HttpStatusRetries) .ConfigureAwait(false); } @@ -53,10 +58,13 @@ public async Task SendHttpRequestSync(HttpContext context, { string targetUrl = ComputeTargetUrl(baseUrl ?? _baseFunctionUrl, functionName, functionPath, functionQuery, _namespaceSlimFaas); logger.LogDebug("Sending sync request to {TargetUrl}", targetUrl); - HttpRequestMessage targetRequestMessage = CreateTargetMessage(context, new Uri(targetUrl)); httpClient.Timeout = TimeSpan.FromSeconds(slimFaasDefaultConfiguration.HttpTimeout); - HttpResponseMessage responseMessage = await Retry.DoRequestAsync(() => httpClient.SendAsync(targetRequestMessage, - HttpCompletionOption.ResponseHeadersRead, context.RequestAborted), + HttpResponseMessage responseMessage = await Retry.DoRequestAsync(() => + { + HttpRequestMessage targetRequestMessage = CreateTargetMessage(context, new Uri(targetUrl)); + return httpClient.SendAsync(targetRequestMessage, + HttpCompletionOption.ResponseHeadersRead, context.RequestAborted); + }, logger, slimFaasDefaultConfiguration.TimeoutRetries, slimFaasDefaultConfiguration.HttpStatusRetries).ConfigureAwait(false); return responseMessage; } From a9492fbb7d17afb8e5d7eb2b92829f5bbcb3c476 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 17:27:55 +0100 Subject: [PATCH 121/135] clen --- demo/deployment-slimfaas.yml | 10 +-- src/SlimData/Endpoints.cs | 11 +--- src/SlimData/SlimDataInterpreter.cs | 65 +------------------ src/SlimFaas/Database/SlimDataService.cs | 8 --- src/SlimFaas/Retry.cs | 4 +- .../QueueElementExtentionsTests.cs | 10 ++- 6 files changed, 18 insertions(+), 90 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index a56beabe..5eda7091 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 1 + replicas: 3 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-850 + image: axaguildev/slimfaas:pr-77-851 livenessProbe: httpGet: path: /health @@ -137,9 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" - - name: SLIMDATA_CONFIGURATION - value: | - {"coldStart":"true"} + # - name: SLIMDATA_CONFIGURATION + # value: | + # {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"} diff --git a/src/SlimData/Endpoints.cs b/src/SlimData/Endpoints.cs index a59530ad..c3fd0a63 100644 --- a/src/SlimData/Endpoints.cs +++ b/src/SlimData/Endpoints.cs @@ -146,7 +146,6 @@ public static async Task ListRightPopCommand(SlimPersistentState prov var queueElements = queue.GetQueueAvailableElement(nowTicks, count); foreach (var queueElement in queueElements) { - Console.WriteLine("Endpoint ListRightPopCommand " + queueElement.Id); values.Items.Add(new QueueData(queueElement.Id ,queueElement.Value.ToArray())); } @@ -185,15 +184,7 @@ public static Task ListLeftPushAsync(HttpContext context) await ListLeftPushCommand(provider, key, value, cluster, source); }); } - - public static int[] HttpStatusCodesWorthRetrying = - [ - // 408 , // HttpStatusCode.RequestTimeout, - 500, // HttpStatusCode.InternalServerError, - 502, // HttpStatusCode.BadGateway, - 503, // HttpStatusCode.ServiceUnavailable, - //504, // HttpStatusCode.GatewayTimeout - ]; + public static async Task ListLeftPushCommand(SlimPersistentState provider, string key, byte[] value, IRaftCluster cluster, CancellationTokenSource source) { diff --git a/src/SlimData/SlimDataInterpreter.cs b/src/SlimData/SlimDataInterpreter.cs index 280c3901..d69b0ae7 100644 --- a/src/SlimData/SlimDataInterpreter.cs +++ b/src/SlimData/SlimDataInterpreter.cs @@ -54,7 +54,6 @@ public ValueTask ListRightPopAsync(ListRightPopCommand addHashSetCommand, Cancel internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetCommand, Dictionary> queues) { - Console.WriteLine("DoListRightPopAsync Key " + addHashSetCommand.Key); if (queues.TryGetValue(addHashSetCommand.Key, out var queue)) { var nowTicks =addHashSetCommand.NowTicks; @@ -78,23 +77,8 @@ internal static ValueTask DoListRightPopAsync(ListRightPopCommand addHashSetComm queueAvailableElement.RetryQueueElements.Add(new QueueHttpTryElement(nowTicks)); } - // print all queue elements - foreach (var queueElemen in queue) - { - Console.WriteLine("DoListRightPopAsync QueueElement Id " + queueElemen.Id); - Console.WriteLine("DoListRightPopAsync QueueElement Value " + queueElemen.Value); - Console.WriteLine("DoListRightPopAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); - foreach (var retryQueueElemen in queueElemen.RetryQueueElements) - { - Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); - Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); - Console.WriteLine("DoListRightPopAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); - } - } } - - return default; } @@ -110,21 +94,6 @@ internal static ValueTask DoListLeftPushAsync(ListLeftPushCommand listLeftPushCo value.Add(new QueueElement(listLeftPushCommand.Value, listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List(), listLeftPushCommand.HttpStatusCodesWorthRetrying)); else queues.Add(listLeftPushCommand.Key, new List() {new(listLeftPushCommand.Value,listLeftPushCommand.Identifier, listLeftPushCommand.NowTicks, listLeftPushCommand.RetryTimeout, listLeftPushCommand.Retries,new List(), listLeftPushCommand.HttpStatusCodesWorthRetrying)}); - // print all queue elements - Console.WriteLine("DoListLeftPushAsync key " + listLeftPushCommand.Key + " Identifier " + listLeftPushCommand.Identifier); - var elements = queues[listLeftPushCommand.Key]; - foreach (var queueElemen in elements) - { - Console.WriteLine("DoListLeftPushAsync QueueElement Id " + queueElemen.Id); - Console.WriteLine("DoListLeftPushAsync QueueElement Value " + queueElemen.Value); - Console.WriteLine("DoListLeftPushAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); - foreach (var retryQueueElemen in queueElemen.RetryQueueElements) - { - Console.WriteLine("DoListLeftPushAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); - Console.WriteLine("DoListLeftPushAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); - Console.WriteLine("DoListLeftPushAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); - } - } return default; } @@ -137,8 +106,7 @@ public ValueTask ListCallbackAsync(ListCallbackCommand addHashSetCommand, Cancel internal static ValueTask DoListCallbackAsync(ListCallbackCommand listCallbackCommand, Dictionary> queues) { if (!queues.TryGetValue(listCallbackCommand.Key, out List? value)) return default; - - Console.WriteLine("DoListCallbackAsync QueueKey " + listCallbackCommand.Key + " Identifier " + listCallbackCommand.Identifier); + var queueElement = value.FirstOrDefault(x => x.Id == listCallbackCommand.Identifier); if (queueElement == null) { @@ -153,19 +121,6 @@ internal static ValueTask DoListCallbackAsync(ListCallbackCommand listCallbackCo value.Remove(queueElement); } - // print all queue elements - foreach (var queueElemen in value) - { - Console.WriteLine("DoListCallbackAsync QueueElement Id " + queueElemen.Id); - Console.WriteLine("DoListCallbackAsync QueueElement Value " + queueElemen.Value); - Console.WriteLine("DoListCallbackAsync QueueElement InsertTimeStamp " + queueElemen.InsertTimeStamp); - foreach (var retryQueueElemen in queueElemen.RetryQueueElements) - { - Console.WriteLine("DoListCallbackAsync QueueElement RetryQueueElement StartTimeStamp " + retryQueueElemen.StartTimeStamp); - Console.WriteLine("DoListCallbackAsync QueueElement RetryQueueElement EndTimeStamp " + retryQueueElemen.EndTimeStamp); - Console.WriteLine("DoListCallbackAsync QueueElement RetryQueueElement HttpCode " + retryQueueElemen.HttpCode); - } - } return default; } @@ -207,24 +162,6 @@ internal static ValueTask DoHandleSnapshotAsync(LogSnapshotCommand command, Dict { keyValues[keyValue.Key] = keyValue.Value; } - // Print all data from queues - foreach (var queue in command.queues) - { - Console.WriteLine("SnapshotCommand Queue Key " + queue.Key); - foreach (var element in queue.Value) - { - Console.WriteLine("SnapshotCommand QueueElement Id " + element.Id); - Console.WriteLine("SnapshotCommand QueueElement Value " + element.Value); - Console.WriteLine("SnapshotCommand QueueElement InsertTimeStamp " + element.InsertTimeStamp); - foreach (var retryQueueElement in element.RetryQueueElements) - { - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement StartTimeStamp " + retryQueueElement.StartTimeStamp); - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement EndTimeStamp " + retryQueueElement.EndTimeStamp); - Console.WriteLine("SnapshotCommand QueueElement RetryQueueElement HttpCode " + retryQueueElement.HttpCode); - } - } - } - queues.Clear(); foreach (var queue in command.queues) diff --git a/src/SlimFaas/Database/SlimDataService.cs b/src/SlimFaas/Database/SlimDataService.cs index c66e0675..a374f65a 100644 --- a/src/SlimFaas/Database/SlimDataService.cs +++ b/src/SlimFaas/Database/SlimDataService.cs @@ -163,14 +163,6 @@ private async Task DoListLeftPushAsync(string key, byte[] field, RetryInformatio var bin = await response.Content.ReadAsByteArrayAsync(); ListItems? result = MemoryPackSerializer.Deserialize(bin); - if(result != null && result.Items != null) - { - foreach (var listItem in result.Items) - { - Console.WriteLine($"DoListRightPopAsync: Id: {listItem.Id}"); - } - } - return result?.Items ?? new List(); } } diff --git a/src/SlimFaas/Retry.cs b/src/SlimFaas/Retry.cs index 615b4979..ecdbf1a2 100644 --- a/src/SlimFaas/Retry.cs +++ b/src/SlimFaas/Retry.cs @@ -77,7 +77,7 @@ IList httpStatusRetries if (attempt >= 0) { var delay = delays[attempt]; - logger.LogWarning("Try {Attempt} : wait number {Delay} second", attempt, delay); + logger.LogWarning("DoRequestAsync Try {Attempt} : wait number {Delay} second", attempt+1, delay); await Task.Delay(delay * 1000); } @@ -88,7 +88,7 @@ IList httpStatusRetries return responseMessage; } responseMessage.Dispose(); - exceptions.Add(new Exception($"Received code Http {statusCode}")); + exceptions.Add(new Exception($"DoRequestAsync received code Http {statusCode}")); } throw new AggregateException(exceptions); diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index 5818df18..c910eb7a 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -9,11 +9,19 @@ public static void QueueElementExtensionsGetQueueRunningElement() var nowTicks = DateTime.UtcNow.Ticks; List Retries = [2, 6, 10]; int RetryTimeout = 30; + int[] HttpStatusCodesWorthRetrying = + [ + // 408 , // HttpStatusCode.RequestTimeout, + 500, // HttpStatusCode.InternalServerError, + 502, // HttpStatusCode.BadGateway, + 503, // HttpStatusCode.ServiceUnavailable, + //504, // HttpStatusCode.GatewayTimeout + ]; var timeout = 30; var timeoutSpanTicks = TimeSpan.FromSeconds(31).Ticks; List queueElements = new(); - var httpRetriesCode = new List(Endpoints.HttpStatusCodesWorthRetrying) ; + var httpRetriesCode = new List(HttpStatusCodesWorthRetrying) ; queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, timeout, Retries, new List() { new(nowTicks -100, nowTicks, 500), From b0a878141acefc62b49e673baa0916f02232d5ad Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 17:36:15 +0100 Subject: [PATCH 122/135] update --- src/SlimData/SlimData.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SlimData/SlimData.csproj b/src/SlimData/SlimData.csproj index 276514e4..9fd072f5 100644 --- a/src/SlimData/SlimData.csproj +++ b/src/SlimData/SlimData.csproj @@ -13,7 +13,7 @@ - + From cbb102d879a3872edfcd06765f4632e984098649 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 17:47:10 +0100 Subject: [PATCH 123/135] upgrade libraies --- .../QueueElementExtentionsTests.cs | 24 +++++++++---------- tests/SlimData.Tests/SlimData.Tests.csproj | 10 ++++---- tests/SlimFaas.Tests/ProgramShould.cs | 2 -- tests/SlimFaas.Tests/SlimFaas.Tests.csproj | 12 +++++----- 4 files changed, 23 insertions(+), 25 deletions(-) diff --git a/tests/SlimData.Tests/QueueElementExtentionsTests.cs b/tests/SlimData.Tests/QueueElementExtentionsTests.cs index c910eb7a..ae4fbe38 100644 --- a/tests/SlimData.Tests/QueueElementExtentionsTests.cs +++ b/tests/SlimData.Tests/QueueElementExtentionsTests.cs @@ -7,9 +7,9 @@ public static void QueueElementExtensionsGetQueueRunningElement() { // I want a test which text my extention var nowTicks = DateTime.UtcNow.Ticks; - List Retries = [2, 6, 10]; - int RetryTimeout = 30; - int[] HttpStatusCodesWorthRetrying = + List retries = [2, 6, 10]; + int retryTimeout = 30; + int[] httpStatusCodesWorthRetrying = [ // 408 , // HttpStatusCode.RequestTimeout, 500, // HttpStatusCode.InternalServerError, @@ -21,42 +21,42 @@ public static void QueueElementExtensionsGetQueueRunningElement() var timeout = 30; var timeoutSpanTicks = TimeSpan.FromSeconds(31).Ticks; List queueElements = new(); - var httpRetriesCode = new List(HttpStatusCodesWorthRetrying) ; - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, timeout, Retries, new List() + var httpRetriesCode = new List(httpStatusCodesWorthRetrying) ; + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "-1", 090902, timeout, retries, new List() { new(nowTicks -100, nowTicks, 500), new(nowTicks -50, nowTicks, 500), new(nowTicks -20, nowTicks, 500), new(nowTicks -10, nowTicks, 500), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, timeout, Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0", 090902, timeout, retries, new List() { new(nowTicks - timeoutSpanTicks -100, nowTicks, 500), new(nowTicks- timeoutSpanTicks -50, nowTicks, 500), new(nowTicks- timeoutSpanTicks -30, nowTicks, 500), new(nowTicks- timeoutSpanTicks -20, 0, 0), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, timeout, Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "0-ok", 090902, timeout, retries, new List() { new(nowTicks -100, nowTicks, 200), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, timeout, Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1", 090902, timeout, retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 200, nowTicks, 500), new(nowTicks- 100, 0, 0), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, timeout, Retries, new List() + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "1timeout", 090902, timeout, retries, new List() { new(nowTicks - 1000, nowTicks, 500), new(nowTicks- 500, nowTicks, 500), new(nowTicks- 400, nowTicks, 500), new(nowTicks- timeoutSpanTicks, 0, 0), }, httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, timeout, Retries, new List(), httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, Retries, new List(), httpRetriesCode)); - queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, Retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "2", 090902, timeout, retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "3", 090902, timeout, retries, new List(), httpRetriesCode)); + queueElements.Add(new QueueElement(new ReadOnlyMemory([1]), "4", 090902, timeout, retries, new List(), httpRetriesCode)); var availableElements = queueElements.GetQueueAvailableElement(nowTicks, 3); diff --git a/tests/SlimData.Tests/SlimData.Tests.csproj b/tests/SlimData.Tests/SlimData.Tests.csproj index 7a885d0c..89c99cb2 100644 --- a/tests/SlimData.Tests/SlimData.Tests.csproj +++ b/tests/SlimData.Tests/SlimData.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable @@ -13,13 +13,13 @@ - + - - + + - + runtime; build; native; contentfiles; analyzers; buildtransitive all diff --git a/tests/SlimFaas.Tests/ProgramShould.cs b/tests/SlimFaas.Tests/ProgramShould.cs index bea1efd4..8ca51276 100644 --- a/tests/SlimFaas.Tests/ProgramShould.cs +++ b/tests/SlimFaas.Tests/ProgramShould.cs @@ -11,9 +11,7 @@ public async Task TestRootEndpoint() Environment.SetEnvironmentVariable(EnvironmentVariables.SlimDataConfiguration, "{\"coldStart\":\"true\"}"); Environment.SetEnvironmentVariable(EnvironmentVariables.MockKubernetesFunctions, "{\"Functions\":[{\"Name\":\"fibonacci1\",\"NumberParallelRequest\":1},{\"Name\":\"fibonacci2\",\"NumberParallelRequest\":1}],\"Slimfaas\":[{\"Name\":\"slimfaas-1\"}]}"); -#pragma warning disable CA2252 await using WebApplicationFactory application = new(); -#pragma warning restore CA2252 using HttpClient client = application.CreateClient(); string response = await client.GetStringAsync("http://localhost:5000/health"); diff --git a/tests/SlimFaas.Tests/SlimFaas.Tests.csproj b/tests/SlimFaas.Tests/SlimFaas.Tests.csproj index 48b56da3..4eba54c5 100644 --- a/tests/SlimFaas.Tests/SlimFaas.Tests.csproj +++ b/tests/SlimFaas.Tests/SlimFaas.Tests.csproj @@ -1,7 +1,7 @@ - net8.0 + net9.0 enable enable @@ -14,13 +14,13 @@ - - - - + + + + - + runtime; build; native; contentfiles; analyzers; buildtransitive all From 4943cfdc902fdf578ecc2e0f201fb552fcf730bf Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 18:14:21 +0100 Subject: [PATCH 124/135] clean --- README.md | 6 +++--- demo/deployment-functions.yml | 2 +- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/SlimWorker.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 701245e3..14bfe084 100644 --- a/README.md +++ b/README.md @@ -6,14 +6,14 @@ Why use SlimFaas? - Scale to 0 after a period of inactivity (work with deployment and statefulset) -- Scale up : compatible with HPA (Horizontal Auto Scaler) and Keda +- Scale up : compatible with HPA (Horizontal Auto Scaler) and Keda (SlimFaas integrated autonomous Scale Up coming soon) - Synchronous HTTP calls - Asynchronous HTTP calls - Allows you to limit the number of parallel HTTP requests for each underlying function -- Retry Pattern Configurable: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds +- Retry Pattern fully Configurable: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds - Private and Public functions - Private functions can be accessed only by internal namespace http call from pods -- Synchronous Publish/Subscribe internal events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple your application with SlimFaas**) +- Synchronous Publish/Subscribe internal events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple your application with SlimFaas**) - Mind Changer: REST API that show the status of your functions and allow to wake up your infrastructure (**Couple your application with Slimfaas**) - Very useful to inform end users that your infrastructure is starting - Plug and Play: just deploy a standard pod diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 365d2e28..ec549b49 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -15,7 +15,7 @@ spec: annotations: SlimFaas/Function: "true" SlimFaas/TimeoutSecondBeforeSetReplicasMin: "5" - SlimFaas/NumberParallelRequest : "1" + SlimFaas/NumberParallelRequest : "10" spec: serviceAccountName: default automountServiceAccountToken: false diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 5eda7091..9075a915 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-851 + image: axaguildev/slimfaas:pr-77-854 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index ee33c790..21a31111 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -65,7 +65,7 @@ private async Task DoOneCycle(CancellationToken stoppingToken, { continue; } - logger.LogDebug("Function {FunctionDeployment} is ready", functionDeployment); + logger.LogDebug("Function {FunctionDeployment} is ready,NumberLimitProcessingTasks {NumberLimitProcessingTasks}, QueueLength {QueueLength} ", functionDeployment, numberProcessingTasks, queueLength); if (numberProcessingTasks >= numberLimitProcessingTasks) { From 04b47f70d507c9b93a317789e4b597b975436c60 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 18:18:21 +0100 Subject: [PATCH 125/135] u^date --- src/SlimFaas/SlimWorker.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index 21a31111..bc3efa0b 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -65,7 +65,10 @@ private async Task DoOneCycle(CancellationToken stoppingToken, { continue; } - logger.LogDebug("Function {FunctionDeployment} is ready,NumberLimitProcessingTasks {NumberLimitProcessingTasks}, QueueLength {QueueLength} ", functionDeployment, numberProcessingTasks, queueLength); + logger.LogDebug("Function {FunctionDeployment} is ready, " + + "NumberProcessingTasks {NumberProcessingTasks}, " + + "NumberLimitProcessingTasks {NumberLimitProcessingTasks}, " + + "QueueLength {QueueLength} ", functionDeployment, numberProcessingTasks, numberProcessingTasks, queueLength); if (numberProcessingTasks >= numberLimitProcessingTasks) { From 5b4c501af0a655f2270a2d3a467bbd57f77a461a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Mon, 30 Dec 2024 22:41:02 +0100 Subject: [PATCH 126/135] dddd --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/SlimWorker.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 9075a915..02e8d32f 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-854 + image: axaguildev/slimfaas:pr-77-855 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index bc3efa0b..ce561de1 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -68,7 +68,7 @@ private async Task DoOneCycle(CancellationToken stoppingToken, logger.LogDebug("Function {FunctionDeployment} is ready, " + "NumberProcessingTasks {NumberProcessingTasks}, " + "NumberLimitProcessingTasks {NumberLimitProcessingTasks}, " + - "QueueLength {QueueLength} ", functionDeployment, numberProcessingTasks, numberProcessingTasks, queueLength); + "QueueLength {QueueLength} ", functionDeployment, numberProcessingTasks, numberLimitProcessingTasks, queueLength); if (numberProcessingTasks >= numberLimitProcessingTasks) { From 2c33dd17f261cdb82f89ff679c6b2f4d7632bd23 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 10:47:38 +0100 Subject: [PATCH 127/135] fix --- demo/deployment-slimfaas.yml | 10 +++++----- src/SlimFaas/Database/ISlimFaasQueue.cs | 2 +- src/SlimFaas/Database/SlimFaasQueue.cs | 4 ++-- src/SlimFaas/SlimWorker.cs | 7 +++---- tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs | 2 +- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 02e8d32f..1a91fbbb 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 3 + replicas: 1 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-855 + image: axaguildev/slimfaas:pr-77-856 livenessProbe: httpGet: path: /health @@ -137,9 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" - # - name: SLIMDATA_CONFIGURATION - # value: | - # {"coldStart":"true"} + - name: SLIMDATA_CONFIGURATION + value: | + {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"} diff --git a/src/SlimFaas/Database/ISlimFaasQueue.cs b/src/SlimFaas/Database/ISlimFaasQueue.cs index 2c9c2581..5db699db 100644 --- a/src/SlimFaas/Database/ISlimFaasQueue.cs +++ b/src/SlimFaas/Database/ISlimFaasQueue.cs @@ -5,7 +5,7 @@ namespace SlimFaas.Database; public interface ISlimFaasQueue { Task EnqueueAsync(string key, byte[] message, RetryInformation retryInformation); - Task?> DequeueAsync(string key, long count = 1); + Task?> DequeueAsync(string key, int count = 1); Task ListCallbackAsync(string key, ListQueueItemStatus queueItemStatus); public Task CountAvailableElementAsync(string key, int maximum = int.MaxValue); public Task CountElementAsync(string key, int maximum = int.MaxValue); diff --git a/src/SlimFaas/Database/SlimFaasQueue.cs b/src/SlimFaas/Database/SlimFaasQueue.cs index e9362509..9c998190 100644 --- a/src/SlimFaas/Database/SlimFaasQueue.cs +++ b/src/SlimFaas/Database/SlimFaasQueue.cs @@ -11,9 +11,9 @@ public class SlimFaasQueue(IDatabaseService databaseService) : ISlimFaasQueue public async Task EnqueueAsync(string key, byte[] data, RetryInformation retryInformation) => await databaseService.ListLeftPushAsync($"{KeyPrefix}{key}", data, retryInformation); - public async Task?> DequeueAsync(string key, long count = 1) + public async Task?> DequeueAsync(string key, int count = 1) { - var data = await databaseService.ListRightPopAsync($"{KeyPrefix}{key}"); + var data = await databaseService.ListRightPopAsync($"{KeyPrefix}{key}", count); return data; } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index ce561de1..a2fac87a 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -75,7 +75,7 @@ private async Task DoOneCycle(CancellationToken stoppingToken, continue; } - await SendHttpRequestToFunction(processingTasks, numberLimitProcessingTasks, numberProcessingTasks, + await SendHttpRequestToFunction(processingTasks, numberLimitProcessingTasks, function); } } @@ -86,12 +86,11 @@ await SendHttpRequestToFunction(processingTasks, numberLimitProcessingTasks, num } private async Task SendHttpRequestToFunction(Dictionary> processingTasks, - int numberLimitProcessingTasks, int numberProcessingTasks, + int numberLimitProcessingTasks, DeploymentInformation function) { string functionDeployment = function.Deployment; - int numberTasksToDequeue = numberLimitProcessingTasks - numberProcessingTasks; - var jsons = await slimFaasQueue.DequeueAsync(functionDeployment, numberTasksToDequeue); + var jsons = await slimFaasQueue.DequeueAsync(functionDeployment, numberLimitProcessingTasks); if (jsons == null) { return; diff --git a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs index 77b0944c..624f7df2 100644 --- a/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs +++ b/tests/SlimFaas.Tests/SlimProxyMiddlewareTests.cs @@ -74,7 +74,7 @@ public async Task SyncDeploymentsFromSlimData(DeploymentsInformations deployment internal class MemorySlimFaasQueue : ISlimFaasQueue { - public Task?> DequeueAsync(string key, long count = 1) => throw new NotImplementedException(); + public Task?> DequeueAsync(string key, int count = 1) => throw new NotImplementedException(); public Task CountAvailableElementAsync(string key, int maximum) => throw new NotImplementedException(); public Task CountElementAsync(string key, int maximum) => throw new NotImplementedException(); From 06f37503f8a0e2e9e703ff5a24773f4532b9cb0a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 12:02:46 +0100 Subject: [PATCH 128/135] clean --- README.md | 4 ++-- demo/deployment-functions.yml | 4 ++-- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/Kubernetes/KubernetesService.cs | 8 ++++---- src/SlimFaas/ReplicasService.cs | 17 ++++++++++++++--- src/SlimFaas/SlimWorker.cs | 4 ---- 6 files changed, 23 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 14bfe084..dbbf1cd3 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Why use SlimFaas? - Synchronous HTTP calls - Asynchronous HTTP calls - Allows you to limit the number of parallel HTTP requests for each underlying function -- Retry Pattern fully Configurable: 3 times with graduation: 2 seconds, 4 seconds, 8 seconds +- Retry Pattern configurable - Private and Public functions - Private functions can be accessed only by internal namespace http call from pods - Synchronous Publish/Subscribe internal events via HTTP calls to every replicas via HTTP without any use of specific drivers/libraries (**Couple your application with SlimFaas**) @@ -375,7 +375,7 @@ spec: - **SlimFaas/ExcludeDeploymentsFromVisibilityPrivate** : "" - Comma separated list of deployment names or statefulset names - Message from that pods will be considered as public. It is useful if you want to exclude some pods from the private visibility, for example for a backend for frontend. -- **SlimFaas/Configuration** : json configuration +- **SlimFaas/Configuration** : json configuration default values displayed below - Allows you to define a configuration for your functions. For example, you can define a timeout for HTTP calls, a retry pattern for timeouts and HTTP status codes. ````bash diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index ec549b49..72919d6d 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -15,7 +15,7 @@ spec: annotations: SlimFaas/Function: "true" SlimFaas/TimeoutSecondBeforeSetReplicasMin: "5" - SlimFaas/NumberParallelRequest : "10" + SlimFaas/NumberParallelRequest : "1" spec: serviceAccountName: default automountServiceAccountToken: false @@ -76,7 +76,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci2 - image: axaguildev/fibonacci:77-839 + image: axaguildev/fibonacci:pr-77-815 livenessProbe: httpGet: path: /health diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 1a91fbbb..51181efe 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-856 + image: axaguildev/slimfaas:pr-77-857 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/Kubernetes/KubernetesService.cs b/src/SlimFaas/Kubernetes/KubernetesService.cs index 9466ef1e..d9351372 100644 --- a/src/SlimFaas/Kubernetes/KubernetesService.cs +++ b/src/SlimFaas/Kubernetes/KubernetesService.cs @@ -268,8 +268,8 @@ private static async Task AddDeployments(string kubeNamespace, V1DeploymentList SlimFaasConfiguration configuration = GetConfiguration(annotations, name, logger); var previousDeployment = previousDeploymentInformationList.FirstOrDefault(d => d.Deployment == name); bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeployment, name, pods); - var resourceVersion = deploymentListItem.Metadata.ResourceVersion; - if (previousDeployment != null && endpointReady == previousDeployment.EndpointReady && previousDeployment.ResourceVersion == resourceVersion) + var resourceVersion = $"{deploymentListItem.Metadata.ResourceVersion}-{endpointReady}"; + if (previousDeployment != null && previousDeployment.ResourceVersion == resourceVersion) { deploymentInformationList.Add(previousDeployment); } else { @@ -408,8 +408,8 @@ private static async Task AddStatefulSets(string kubeNamespace, V1StatefulSetLis SlimFaasConfiguration configuration = GetConfiguration(annotations, name, logger); var previousDeployment = previousDeploymentInformationList.FirstOrDefault(d => d.Deployment == name); bool endpointReady = await GetEndpointReady(kubeNamespace, client, previousDeployment, name, pods); - var resourceVersion = deploymentListItem.Metadata.ResourceVersion; - if (previousDeployment != null && endpointReady == previousDeployment.EndpointReady && previousDeployment.ResourceVersion == resourceVersion) + var resourceVersion = $"{deploymentListItem.Metadata.ResourceVersion}-{endpointReady}"; + if (previousDeployment != null && previousDeployment.ResourceVersion == resourceVersion) { deploymentInformationList.Add(previousDeployment); } diff --git a/src/SlimFaas/ReplicasService.cs b/src/SlimFaas/ReplicasService.cs index d16e0f54..9b2bf7c6 100644 --- a/src/SlimFaas/ReplicasService.cs +++ b/src/SlimFaas/ReplicasService.cs @@ -62,6 +62,12 @@ public async Task SyncDeploymentsAsync(string kubeNames f.ResourceVersion == deploymentInformation.ResourceVersion); if (currentDeployment == null) { + + string podsInformationString = ""; + foreach (PodInformation deploymentInformationPod in deploymentInformation.Pods) + { + podsInformationString += deploymentInformationPod.Name + " " + deploymentInformationPod.Ready + " " + deploymentInformationPod.Started + " " + deploymentInformationPod.Ip + " " + deploymentInformationPod.DeploymentName + "\n"; + } // Un log information avec toutes les informations de toutes les propriété de la fonction logger.LogInformation("New deployment {Deployment} \n" + "with {Replicas} replicas \n" + @@ -74,12 +80,15 @@ public async Task SyncDeploymentsAsync(string kubeNames "with {NumberParallelRequest} number parallel request \n" + "with dependOn {DependsOn} \n" + "with {EndpointReady} endpoint ready \n" + - "with {Configuration} configuration \n", + "with {Configuration} configuration \n" + + "with pods {Pods}", deploymentInformation.Deployment, deploymentInformation.Replicas, deploymentInformation.ReplicasAtStart, deploymentInformation.ReplicasMin, deploymentInformation.ReplicasStartAsSoonAsOneFunctionRetrieveARequest, deploymentInformation.TimeoutSecondBeforeSetReplicasMin, deploymentInformation.PodType, deploymentInformation.ResourceVersion, deploymentInformation.NumberParallelRequest, deploymentInformation.DependsOn, - deploymentInformation.EndpointReady, JsonSerializer.Serialize(deploymentInformation.Configuration, SlimFaasConfigurationSerializerContext.Default.SlimFaasConfiguration)); + deploymentInformation.EndpointReady, + JsonSerializer.Serialize(deploymentInformation.Configuration, SlimFaasConfigurationSerializerContext.Default.SlimFaasConfiguration), + podsInformationString); } } } @@ -146,7 +155,9 @@ public async Task CheckScaleAsync(string kubeNamespace) if (currentScale == deploymentInformation.ReplicasMin) { continue; - } else if(currentScale < deploymentInformation.ReplicasMin) + } + + if(currentScale < deploymentInformation.ReplicasMin) { logger.LogInformation("Scale up {Deployment} from {CurrentScale} to {ReplicaAtStart}", deploymentInformation.Deployment, currentScale, deploymentInformation.ReplicasAtStart); } diff --git a/src/SlimFaas/SlimWorker.cs b/src/SlimFaas/SlimWorker.cs index a2fac87a..6af6e4b0 100644 --- a/src/SlimFaas/SlimWorker.cs +++ b/src/SlimFaas/SlimWorker.cs @@ -65,10 +65,6 @@ private async Task DoOneCycle(CancellationToken stoppingToken, { continue; } - logger.LogDebug("Function {FunctionDeployment} is ready, " + - "NumberProcessingTasks {NumberProcessingTasks}, " + - "NumberLimitProcessingTasks {NumberLimitProcessingTasks}, " + - "QueueLength {QueueLength} ", functionDeployment, numberProcessingTasks, numberLimitProcessingTasks, queueLength); if (numberProcessingTasks >= numberLimitProcessingTasks) { From cbc27fea17d8239e7679d8246497273b93915eca Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 12:10:19 +0100 Subject: [PATCH 129/135] fix --- src/SlimFaas/SlimProxyMiddleware.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index 9264b938..39625500 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -440,7 +440,7 @@ private async Task WaitForAnyPodStartedAsync(HttpContext context, HistoryHttpMem while (numberLoop > 0) { bool isAnyContainerStarted = replicasService.Deployments.Functions.Any(f => - f is { Replicas: > 0, EndpointReady: true } && f.Pods.Any(p => p.Ready.HasValue && p.Ready.Value)); + f is { Replicas: > 0, EndpointReady: true } && f.Pods.Any(p => p.Ready.HasValue && p.Ready.Value && p.DeploymentName == functionName)); if (!isAnyContainerStarted && !context.RequestAborted.IsCancellationRequested) { numberLoop--; From 69a2b7b30809c0b18d23f6ea3799af356a963d0e Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 12:18:07 +0100 Subject: [PATCH 130/135] update --- demo/deployment-functions.yml | 8 ++++---- demo/deployment-slimfaas.yml | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/demo/deployment-functions.yml b/demo/deployment-functions.yml index 72919d6d..a77f0e7e 100644 --- a/demo/deployment-functions.yml +++ b/demo/deployment-functions.yml @@ -21,7 +21,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci1 - image: axaguildev/fibonacci:pr-77-815 + image: axaguildev/fibonacci:latest livenessProbe: httpGet: path: /health @@ -76,7 +76,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci2 - image: axaguildev/fibonacci:pr-77-815 + image: axaguildev/fibonacci:latest livenessProbe: httpGet: path: /health @@ -129,7 +129,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci3 - image: axaguildev/fibonacci:pr-77-815 + image: axaguildev/fibonacci:latest livenessProbe: httpGet: path: /health @@ -187,7 +187,7 @@ spec: automountServiceAccountToken: false containers: - name: fibonacci4 - image: axaguildev/fibonacci:pr-77-815 + image: axaguildev/fibonacci:latest livenessProbe: httpGet: path: /health diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 51181efe..88f6eedd 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 1 + replicas: 3 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-857 + image: axaguildev/slimfaas:latest livenessProbe: httpGet: path: /health @@ -137,9 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" - - name: SLIMDATA_CONFIGURATION - value: | - {"coldStart":"true"} + #- name: SLIMDATA_CONFIGURATION + # value: | + # {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"} From 2668d2f3cb13cb5a5d57e1e8bb8e249f6af845f6 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 13:47:28 +0100 Subject: [PATCH 131/135] test --- src/SlimFaas/SlimProxyMiddleware.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index 39625500..203e2610 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -439,8 +439,8 @@ private async Task WaitForAnyPodStartedAsync(HttpContext context, HistoryHttpMem historyHttpService.SetTickLastCall(functionName, lastSetTicks); while (numberLoop > 0) { - bool isAnyContainerStarted = replicasService.Deployments.Functions.Any(f => - f is { Replicas: > 0, EndpointReady: true } && f.Pods.Any(p => p.Ready.HasValue && p.Ready.Value && p.DeploymentName == functionName)); + bool isAnyContainerStarted = replicasService.Deployments.Functions.Where(d => d.Deployment == functionName).Any(f => + f is { Replicas: > 0, EndpointReady: true } && f.Pods.Any(p => p.Ready.HasValue && p.Ready.Value)); if (!isAnyContainerStarted && !context.RequestAborted.IsCancellationRequested) { numberLoop--; From e28a15280e447db657c95aa60cb59bfcbeab9630 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 14:19:37 +0100 Subject: [PATCH 132/135] test --- demo/deployment-slimfaas.yml | 10 +++++----- src/SlimFaas/SlimProxyMiddleware.cs | 11 ++++++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 88f6eedd..6e58eea2 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 3 + replicas: 1 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:latest + image: axaguildev/slimfaas:pr-77-861 livenessProbe: httpGet: path: /health @@ -137,9 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" - #- name: SLIMDATA_CONFIGURATION - # value: | - # {"coldStart":"true"} + - name: SLIMDATA_CONFIGURATION + value: | + {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"} diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index 203e2610..e5113219 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -439,9 +439,14 @@ private async Task WaitForAnyPodStartedAsync(HttpContext context, HistoryHttpMem historyHttpService.SetTickLastCall(functionName, lastSetTicks); while (numberLoop > 0) { - bool isAnyContainerStarted = replicasService.Deployments.Functions.Where(d => d.Deployment == functionName).Any(f => - f is { Replicas: > 0, EndpointReady: true } && f.Pods.Any(p => p.Ready.HasValue && p.Ready.Value)); - if (!isAnyContainerStarted && !context.RequestAborted.IsCancellationRequested) + DeploymentInformation? function = SearchFunction(replicasService, functionName); + if(function == null) + { + continue; + } + bool? isAnyContainerStarted = function.Pods.Any(p => p.Ready.HasValue && p.Ready.Value); + bool notReady = !isAnyContainerStarted.Value || !function.EndpointReady; + if (notReady && !context.RequestAborted.IsCancellationRequested) { numberLoop--; await Task.Delay(10, context.RequestAborted); From 9bb522830bbb211f7e675380b5f350c41bc21dfc Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 16:27:28 +0100 Subject: [PATCH 133/135] test --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/EnvironmentVariables.cs | 2 +- src/SlimFaas/SlimProxyMiddleware.cs | 9 +++++---- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 6e58eea2..4f77b909 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-861 + image: axaguildev/slimfaas:pr-77-862 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/EnvironmentVariables.cs b/src/SlimFaas/EnvironmentVariables.cs index 3c536d85..0807046c 100644 --- a/src/SlimFaas/EnvironmentVariables.cs +++ b/src/SlimFaas/EnvironmentVariables.cs @@ -22,7 +22,7 @@ public static class EnvironmentVariables public const string BaseSlimDataUrlDefault = "http://{pod_name}.slimfaas.default.svc.cluster.local:3262/"; - public const int SlimProxyMiddlewareTimeoutWaitWakeSyncFunctionMilliSecondsDefault = 10000; + public const int SlimProxyMiddlewareTimeoutWaitWakeSyncFunctionMilliSecondsDefault = 20000; public const string TimeMaximumWaitForAtLeastOnePodStartedForSyncFunction = "TIME_MAXIMUM_WAIT_FOR_AT_LEAST_ONE_POD_STARTED_FOR_SYNC_FUNCTION"; diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index e5113219..4ceaddee 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -404,7 +404,7 @@ private async Task BuildSyncResponseAsync(HttpContext context, HistoryHttpMemory return; } - await WaitForAnyPodStartedAsync(context, historyHttpService, replicasService, functionName); + await WaitForAnyPodStartedAsync(logger, context, historyHttpService, replicasService, functionName); Task responseMessagePromise = sendClient.SendHttpRequestSync(context, functionName, functionPath, context.Request.QueryString.ToUriComponent(), function.Configuration.DefaultSync); @@ -431,7 +431,7 @@ private async Task BuildSyncResponseAsync(HttpContext context, HistoryHttpMemory await responseMessage.Content.CopyToAsync(context.Response.Body); } - private async Task WaitForAnyPodStartedAsync(HttpContext context, HistoryHttpMemoryService historyHttpService, + private async Task WaitForAnyPodStartedAsync(ILogger logger, HttpContext context, HistoryHttpMemoryService historyHttpService, IReplicasService replicasService, string functionName) { int numberLoop = _timeoutMaximumWaitWakeSyncFunctionMilliSecond / 10; @@ -445,8 +445,9 @@ private async Task WaitForAnyPodStartedAsync(HttpContext context, HistoryHttpMem continue; } bool? isAnyContainerStarted = function.Pods.Any(p => p.Ready.HasValue && p.Ready.Value); - bool notReady = !isAnyContainerStarted.Value || !function.EndpointReady; - if (notReady && !context.RequestAborted.IsCancellationRequested) + logger.LogDebug("WaitForAnyPodStartedAsync {FunctionName} isAnyContainerStarted: {IsAnyContainerStarted} EndpointReady: {EndpointReady}", functionName, isAnyContainerStarted, function.EndpointReady); + bool isReady = isAnyContainerStarted.Value && function.EndpointReady; + if (!isReady && !context.RequestAborted.IsCancellationRequested) { numberLoop--; await Task.Delay(10, context.RequestAborted); From a72b51dddf2726b13bd798e121edb9862764c8e4 Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 16:40:15 +0100 Subject: [PATCH 134/135] update --- demo/deployment-slimfaas.yml | 2 +- src/SlimFaas/EnvironmentVariables.cs | 2 +- src/SlimFaas/SlimProxyMiddleware.cs | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index 4f77b909..e9d773b3 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-862 + image: axaguildev/slimfaas:pr-77-863 livenessProbe: httpGet: path: /health diff --git a/src/SlimFaas/EnvironmentVariables.cs b/src/SlimFaas/EnvironmentVariables.cs index 0807046c..3f39c03f 100644 --- a/src/SlimFaas/EnvironmentVariables.cs +++ b/src/SlimFaas/EnvironmentVariables.cs @@ -22,7 +22,7 @@ public static class EnvironmentVariables public const string BaseSlimDataUrlDefault = "http://{pod_name}.slimfaas.default.svc.cluster.local:3262/"; - public const int SlimProxyMiddlewareTimeoutWaitWakeSyncFunctionMilliSecondsDefault = 20000; + public const int SlimProxyMiddlewareTimeoutWaitWakeSyncFunctionMilliSecondsDefault = 30000; public const string TimeMaximumWaitForAtLeastOnePodStartedForSyncFunction = "TIME_MAXIMUM_WAIT_FOR_AT_LEAST_ONE_POD_STARTED_FOR_SYNC_FUNCTION"; diff --git a/src/SlimFaas/SlimProxyMiddleware.cs b/src/SlimFaas/SlimProxyMiddleware.cs index 4ceaddee..ef99504e 100644 --- a/src/SlimFaas/SlimProxyMiddleware.cs +++ b/src/SlimFaas/SlimProxyMiddleware.cs @@ -445,7 +445,6 @@ private async Task WaitForAnyPodStartedAsync(ILogger logger continue; } bool? isAnyContainerStarted = function.Pods.Any(p => p.Ready.HasValue && p.Ready.Value); - logger.LogDebug("WaitForAnyPodStartedAsync {FunctionName} isAnyContainerStarted: {IsAnyContainerStarted} EndpointReady: {EndpointReady}", functionName, isAnyContainerStarted, function.EndpointReady); bool isReady = isAnyContainerStarted.Value && function.EndpointReady; if (!isReady && !context.RequestAborted.IsCancellationRequested) { From b0f76a25189c638061159478616f37c47708e42a Mon Sep 17 00:00:00 2001 From: Guillaume Chervet Date: Tue, 31 Dec 2024 16:49:05 +0100 Subject: [PATCH 135/135] last clean --- demo/deployment-slimfaas.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/demo/deployment-slimfaas.yml b/demo/deployment-slimfaas.yml index e9d773b3..88f6eedd 100644 --- a/demo/deployment-slimfaas.yml +++ b/demo/deployment-slimfaas.yml @@ -91,7 +91,7 @@ metadata: name: slimfaas namespace: slimfaas-demo spec: - replicas: 1 + replicas: 3 podManagementPolicy: Parallel serviceName: slimfaas selector: @@ -109,7 +109,7 @@ spec: serviceAccountName: slimfaas containers: - name: slimfaas - image: axaguildev/slimfaas:pr-77-863 + image: axaguildev/slimfaas:latest livenessProbe: httpGet: path: /health @@ -137,9 +137,9 @@ spec: value: "1" - name: Logging__LogLevel__SlimFaas value: "Debug" - - name: SLIMDATA_CONFIGURATION - value: | - {"coldStart":"true"} + #- name: SLIMDATA_CONFIGURATION + # value: | + # {"coldStart":"true"} #- name: SLIMDATA_CONFIGURATION # value: | # {"lowerElectionTimeout":"500","upperElectionTimeout":"1000","requestTimeout":"00:01:20.0000000","rpcTimeout":"00:00:40.0000000","heartbeatThreshold":"0.5"}