From ed7f7183ad65911d024ccf28ab4bbe6b0af58d4b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delucchi?= Date: Mon, 3 Jun 2024 16:57:25 +0200 Subject: [PATCH 1/7] =?UTF-8?q?refactor(db):=20retire=20le=20syst=C3=A8me?= =?UTF-8?q?=20de=20nettoyage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Server/Database.cs | 15 +-------------- src/Server/Program.cs | 2 +- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/src/Server/Database.cs b/src/Server/Database.cs index e5616c1..328471f 100644 --- a/src/Server/Database.cs +++ b/src/Server/Database.cs @@ -5,13 +5,7 @@ public class Database private ConcurrentDictionary _data = new(); private ConcurrentDictionary _ex = new(); - public Database(long cleanupInterval = 1000) - { - System.Timers.Timer timer = new(cleanupInterval); - timer.Elapsed += (sender, e) => Clean(); - timer.AutoReset = true; - timer.Start(); - } + public Database() { } public void Set(string key, string value) { @@ -44,11 +38,4 @@ public void Del(string key) return _data.TryGetValue(key, out var value) ? value : null; } - - private void Clean() - { - foreach (var (key, expire) in _ex) - if (expire < DateTimeOffset.UtcNow) - Del(key); - } } \ No newline at end of file diff --git a/src/Server/Program.cs b/src/Server/Program.cs index b329bee..328c3d6 100644 --- a/src/Server/Program.cs +++ b/src/Server/Program.cs @@ -2,6 +2,6 @@ if (args.Length > 0) port = int.Parse(args[0]); -var database = new Database(15000); +var database = new Database(); var server = new Server(port, database); server.Run(); \ No newline at end of file From d35e45e6ad87725ac335e686c9a89824bd6483b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delucchi?= Date: Mon, 3 Jun 2024 17:02:40 +0200 Subject: [PATCH 2/7] fix(db): rend readonly _data et _ex --- src/Server/Database.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Server/Database.cs b/src/Server/Database.cs index 328471f..a827605 100644 --- a/src/Server/Database.cs +++ b/src/Server/Database.cs @@ -2,8 +2,8 @@ public class Database { - private ConcurrentDictionary _data = new(); - private ConcurrentDictionary _ex = new(); + private readonly ConcurrentDictionary _data = new(); + private readonly ConcurrentDictionary _ex = new(); public Database() { } From 3332875a86f36083ad0a31856390c302f1702e44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delucchi?= Date: Mon, 3 Jun 2024 17:08:58 +0200 Subject: [PATCH 3/7] =?UTF-8?q?feat(db):=20ajoute=20un=20m=C3=A9canisme=20?= =?UTF-8?q?de=20verrou=20pour=20la=20synchronisation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Server/Database.cs | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/Server/Database.cs b/src/Server/Database.cs index a827605..e43aa4e 100644 --- a/src/Server/Database.cs +++ b/src/Server/Database.cs @@ -4,38 +4,54 @@ public class Database { private readonly ConcurrentDictionary _data = new(); private readonly ConcurrentDictionary _ex = new(); + private readonly object _lock = new(); public Database() { } public void Set(string key, string value) { - _data[key] = value; - _ex.Remove(key, out _); + lock (_lock) + { + _data[key] = value; + _ex.Remove(key, out _); + } } public void Set(string key, string value, long ex) { - _data[key] = value; - _ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex); + lock (_lock) + { + _data[key] = value; + _ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex); + } } public void Set(string key, long ex) { - if (_data.ContainsKey(key)) - _ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex); + lock (_lock) + { + if (_data.ContainsKey(key)) + _ex[key] = DateTimeOffset.UtcNow.AddMilliseconds(ex); + } } public void Del(string key) { - _data.Remove(key, out _); - _ex.Remove(key, out _); + lock (_lock) + { + _data.Remove(key, out _); + _ex.Remove(key, out _); + } } public string? Get(string key) { - if (_ex.TryGetValue(key, out var expire) && expire < DateTimeOffset.UtcNow) - Del(key); + lock (_lock) + { + if (_ex.TryGetValue(key, out var expire) && expire < DateTimeOffset.UtcNow) + Del(key); - return _data.TryGetValue(key, out var value) ? value : null; + return _data.TryGetValue(key, out var value) ? value : null; + } } } \ No newline at end of file From 1b19f2b8bcdc18d855c9745604b4a2d2819925fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delucchi?= Date: Mon, 3 Jun 2024 17:20:29 +0200 Subject: [PATCH 4/7] fix(db): corrige l'appel au constructeur de Database --- tests/Server.UnitTests/Database.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Server.UnitTests/Database.cs b/tests/Server.UnitTests/Database.cs index 5e8e27f..bc599ac 100644 --- a/tests/Server.UnitTests/Database.cs +++ b/tests/Server.UnitTests/Database.cs @@ -37,7 +37,7 @@ public void SetGetEx(string key, string value, long ex) [Fact] public void AutoClean() { - var db = new Database(10); + var db = new Database(); db.Set("key1", "value"); db.Set("key2", "value", 50); db.Set("key3", "value", 20); From 46199a222143979f5d932156ff90d473984b0212 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delucchi?= Date: Mon, 3 Jun 2024 17:21:31 +0200 Subject: [PATCH 5/7] =?UTF-8?q?feat(db):=20ajoute=20le=20m=C3=A9canisme=20?= =?UTF-8?q?de=20nettoyage=20en=20arri=C3=A8re=20plan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Server/Database.cs | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/Server/Database.cs b/src/Server/Database.cs index e43aa4e..42f689e 100644 --- a/src/Server/Database.cs +++ b/src/Server/Database.cs @@ -1,12 +1,17 @@ using System.Collections.Concurrent; -public class Database +public class Database : IDisposable { private readonly ConcurrentDictionary _data = new(); private readonly ConcurrentDictionary _ex = new(); private readonly object _lock = new(); + private readonly object _cleanLock = new(); + private CancellationTokenSource _cts = new(); - public Database() { } + public Database() + { + _ = Task.Run(Clean); + } public void Set(string key, string value) { @@ -54,4 +59,21 @@ public void Del(string key) return _data.TryGetValue(key, out var value) ? value : null; } } + + private void Clean() + { + while (!_cts.Token.IsCancellationRequested) + { + foreach (var (key, expire) in _ex) + { + if (expire < DateTimeOffset.UtcNow) + lock (_cleanLock) Del(key); + } + } + } + + public void Dispose() + { + _cts.Cancel(); + } } \ No newline at end of file From 5aeff75123b37b0b572598a1c88ba4fc9fb6dbe9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delucchi?= Date: Mon, 3 Jun 2024 17:23:15 +0200 Subject: [PATCH 6/7] =?UTF-8?q?feat(db):=20ajoute=20les=20m=C3=A9thode=20L?= =?UTF-8?q?ock=20et=20Unlock?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Server/Database.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Server/Database.cs b/src/Server/Database.cs index 42f689e..eda6044 100644 --- a/src/Server/Database.cs +++ b/src/Server/Database.cs @@ -60,6 +60,10 @@ public void Del(string key) } } + public void Lock() => Monitor.Enter(_cleanLock); + + public void Unlock() => Monitor.Exit(_cleanLock); + private void Clean() { while (!_cts.Token.IsCancellationRequested) From c72c7cce85a026af7e478649327a58f1f902153b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delucchi?= Date: Mon, 3 Jun 2024 18:43:01 +0200 Subject: [PATCH 7/7] =?UTF-8?q?fix(db):=20am=C3=A9liore=20Database.Dispose?= =?UTF-8?q?()=20et=20utilise=20using?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Server/Database.cs | 4 ++++ tests/Server.UnitTests/Database.cs | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Server/Database.cs b/src/Server/Database.cs index eda6044..5c73269 100644 --- a/src/Server/Database.cs +++ b/src/Server/Database.cs @@ -79,5 +79,9 @@ private void Clean() public void Dispose() { _cts.Cancel(); + _cts.Dispose(); + _data.Clear(); + _ex.Clear(); + GC.SuppressFinalize(this); } } \ No newline at end of file diff --git a/tests/Server.UnitTests/Database.cs b/tests/Server.UnitTests/Database.cs index bc599ac..88a315b 100644 --- a/tests/Server.UnitTests/Database.cs +++ b/tests/Server.UnitTests/Database.cs @@ -12,7 +12,7 @@ public class DatabaseTests [InlineData("", "")] public void SetGet(string key, string value) { - var db = new Database(); + using var db = new Database(); db.Set(key, value); var result = db.Get(key); Assert.Equal(value, result); @@ -23,7 +23,7 @@ public void SetGet(string key, string value) [InlineData("key2", "value", 10)] public void SetGetEx(string key, string value, long ex) { - var db = new Database(); + using var db = new Database(); db.Set(key, value, ex); var result = db.Get(key); Assert.Equal(value, result); @@ -37,7 +37,7 @@ public void SetGetEx(string key, string value, long ex) [Fact] public void AutoClean() { - var db = new Database(); + using var db = new Database(); db.Set("key1", "value"); db.Set("key2", "value", 50); db.Set("key3", "value", 20);