From 32bf8b05370b43052dbce2ad08c770238ce098a3 Mon Sep 17 00:00:00 2001 From: Hendrik De Vloed Date: Mon, 23 Sep 2024 18:58:23 +0200 Subject: [PATCH 1/2] Properly translate null etags --- .../Storage/RedisGrainStorage.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs b/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs index ae3fd3c3b2..b22e0830e3 100644 --- a/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs +++ b/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Diagnostics; using System.Globalization; using System.Linq; @@ -225,7 +225,6 @@ public async Task ClearStateAsync(string grainType, GrainId grainId, IGrainSt { try { - RedisValue etag = grainState.ETag ?? ""; RedisResult response; string newETag; var key = _getKeyFunc(grainType, grainId); @@ -241,7 +240,8 @@ public async Task ClearStateAsync(string grainType, GrainId grainId, IGrainSt return -1 end """; - response = await _db.ScriptEvaluateAsync(DeleteScript, keys: new[] { key }, values: new[] { etag }).ConfigureAwait(false); + RedisValue[] values = grainState.ETag is null ? [] : [grainState.ETag]; + response = await _db.ScriptEvaluateAsync(DeleteScript, keys: [key], values: values).ConfigureAwait(false); newETag = null; } else @@ -257,7 +257,8 @@ public async Task ClearStateAsync(string grainType, GrainId grainId, IGrainSt end """; newETag = Guid.NewGuid().ToString("N"); - response = await _db.ScriptEvaluateAsync(ClearScript, keys: new[] { key }, values: new RedisValue[] { etag, newETag }).ConfigureAwait(false); + RedisValue[] values = grainState.ETag is null ? [] : [grainState.ETag, newETag]; + response = await _db.ScriptEvaluateAsync(ClearScript, keys: [key], values: values).ConfigureAwait(false); } if (response is not null && (int)response == -1) @@ -282,4 +283,4 @@ private async Task Close(CancellationToken cancellationToken) _connection.Dispose(); } } -} \ No newline at end of file +} From b769aeea06dfddaa08b14775f833b706b092870f Mon Sep 17 00:00:00 2001 From: Hendrik De Vloed Date: Wed, 25 Sep 2024 09:40:07 +0200 Subject: [PATCH 2/2] Handle nulls on the LUA side --- .../Storage/RedisGrainStorage.cs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs b/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs index b22e0830e3..e224ab87a6 100644 --- a/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs +++ b/src/Redis/Orleans.Persistence.Redis/Storage/RedisGrainStorage.cs @@ -149,7 +149,7 @@ public async Task WriteStateAsync(string grainType, GrainId grainId, IGrainSt const string WriteScript = """ local etag = redis.call('HGET', KEYS[1], 'etag') - if (not etag and (ARGV[1] == nil or ARGV[1] == '')) or etag == ARGV[1] then + if ((not etag or etag == '') and (not ARGV[1] or ARGV[1] == '')) or etag == ARGV[1] then redis.call('HMSET', KEYS[1], 'etag', ARGV[2], 'data', ARGV[3]) if ARGV[4] ~= '-1' then redis.call('EXPIRE', KEYS[1], ARGV[4]) @@ -225,6 +225,7 @@ public async Task ClearStateAsync(string grainType, GrainId grainId, IGrainSt { try { + RedisValue etag = grainState.ETag ?? ""; RedisResult response; string newETag; var key = _getKeyFunc(grainType, grainId); @@ -233,15 +234,14 @@ public async Task ClearStateAsync(string grainType, GrainId grainId, IGrainSt const string DeleteScript = """ local etag = redis.call('HGET', KEYS[1], 'etag') - if (not etag and not ARGV[1]) or etag == ARGV[1] then + if ((not etag or etag == '') and (not ARGV[1] or ARGV[1] == '')) or etag == ARGV[1] then redis.call('DEL', KEYS[1]) return 0 else return -1 end """; - RedisValue[] values = grainState.ETag is null ? [] : [grainState.ETag]; - response = await _db.ScriptEvaluateAsync(DeleteScript, keys: [key], values: values).ConfigureAwait(false); + response = await _db.ScriptEvaluateAsync(DeleteScript, keys: new[] { key }, values: new[] { etag }).ConfigureAwait(false); newETag = null; } else @@ -249,7 +249,7 @@ public async Task ClearStateAsync(string grainType, GrainId grainId, IGrainSt const string ClearScript = """ local etag = redis.call('HGET', KEYS[1], 'etag') - if (not etag and not ARGV[1]) or etag == ARGV[1] then + if ((not etag or etag == '') and (not ARGV[1] or ARGV[1] == '')) or etag == ARGV[1] then redis.call('HMSET', KEYS[1], 'etag', ARGV[2], 'data', '') return 0 else @@ -257,8 +257,7 @@ public async Task ClearStateAsync(string grainType, GrainId grainId, IGrainSt end """; newETag = Guid.NewGuid().ToString("N"); - RedisValue[] values = grainState.ETag is null ? [] : [grainState.ETag, newETag]; - response = await _db.ScriptEvaluateAsync(ClearScript, keys: [key], values: values).ConfigureAwait(false); + response = await _db.ScriptEvaluateAsync(ClearScript, keys: new[] { key }, values: new RedisValue[] { etag, newETag }).ConfigureAwait(false); } if (response is not null && (int)response == -1)