Skip to content

Compatibility Issue with Medallion.Threading.Redis and Garnet #1098

@xsoheilalizadeh

Description

@xsoheilalizadeh

Describe the bug

We attempted to use Garnet as a Redis replacement for our distributed locking mechanism using Medallion.Threading.Redis (version 1.0.3). However, we encountered an issue when trying to acquire a lock.

The same code works fine when using Redis, but fails when using Garnet.

NuGet Packages Used:

  • DistributedLock.Redis 1.0.3
  • StackExchange.Redis latest stable version

Observed Behavior (Error Logs)

14:13:03.2434: Connecting (sync) on .NET 9.0.2 (StackExchange.Redis: v2.7.27.49176)
14:13:03.2559: localhost
14:13:03.2587: localhost:6379/Interactive: Connecting...
14:13:03.2634: localhost:6379: BeginConnectAsync
14:13:03.2680: 1 unique nodes specified (with tiebreaker)
14:13:03.2688: localhost:6379: OnConnectedAsync init (State=Connecting)
14:13:03.2698: Allowing 1 endpoint(s) 00:00:05 to respond...
14:13:03.2711: Awaiting 1 available task completion(s) for 5000ms, IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=3,Free=32764,Min=16,Max=32767), POOL: (Threads=5,QueuedItems=0,CompletedItems=5,Timers=0)
14:13:03.2720: localhost:6379/Interactive: Connected 
14:13:03.2737: localhost:6379: Server handshake
14:13:03.2798: localhost:6379: Setting client name: Mac-FXGL266(SE.Redis-v2.7.27.49176)
14:13:03.2878: localhost:6379: Setting client lib/ver
14:13:03.2894: localhost:6379: Auto-configuring...
14:13:03.2902: localhost:6379: Requesting tie-break (Key="__Booksleeve_TieBreak")...
14:13:03.2909: localhost:6379/Interactive: Writing: GET __Booksleeve_TieBreak
14:13:03.2911: localhost:6379: Sending critical tracer (handshake): ECHO
14:13:03.2911: localhost:6379/Interactive: Writing: ECHO
14:13:03.2911: localhost:6379: Flushing outbound buffer
14:13:03.2912: localhost:6379: OnEstablishingAsync complete
14:13:03.2912: localhost:6379: Starting read
14:13:03.2961: localhost:6379: Auto-configured (CLIENT) connection-id: 38
14:13:03.2996: localhost:6379: Auto-configured (CONFIG) read-only replica: false
14:13:03.2997: localhost:6379: Auto-configured (CONFIG) databases: 1
14:13:03.3001: localhost:6379: Auto-configured (INFO) role: primary
14:13:03.3006: localhost:6379: Auto-configured (INFO) version: 7.2.5
14:13:03.3012: localhost:6379: Auto-configured (INFO) server-type: Standalone
14:13:03.3013: Response from localhost:6379/Interactive / GET __Booksleeve_TieBreak: (null)
14:13:03.3015: Response from localhost:6379/Interactive / ECHO: BulkString: 16 bytes
14:13:03.3017: localhost:6379: OnConnectedAsync completed (From command: ECHO)
14:13:03.3021: All 1 available tasks completed cleanly, IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=3,Free=32764,Min=16,Max=32767), POOL: (Threads=7,QueuedItems=0,CompletedItems=53,Timers=0)
14:13:03.3022: Endpoint summary:
14:13:03.3027:   localhost:6379: Endpoint is (Interactive: ConnectedEstablished, Subscription: ConnectedEstablished)
14:13:03.3027: Task summary:
14:13:03.3028:   localhost:6379: Returned with success as Standalone primary (Source: From command: ECHO)
14:13:03.3036: Election summary:
14:13:03.3037:   Election: localhost:6379 had no tiebreaker set
14:13:03.3037:   Election: Single primary detected: localhost:6379
14:13:03.3037: localhost:6379: Clearing as RedundantPrimary
14:13:03.3039: Endpoint Summary:
14:13:03.3043:   localhost:6379: Standalone v7.2.5, primary; 1 databases; keep-alive: 00:01:00; int: ConnectedEstablished; sub: ConnectedEstablished, 1 active
14:13:03.3054:   localhost:6379: int ops=13, qu=0, qs=0, qc=0, wr=0, socks=1; sub ops=6, qu=0, qs=0, qc=0, wr=0, subs=1, socks=1
14:13:03.3123:   localhost:6379: Circular op-count snapshot; int: 0+13=13 (1,30 ops/s; spans 10s); sub: 0+6=6 (0,60 ops/s; spans 10s)
14:13:03.3127: Sync timeouts: 0; async timeouts: 0; fire and forget: 0; last heartbeat: -1s ago
14:13:03.3129: Starting heartbeat...
14:13:03.3134: Total connect time: 70 ms
Lock acquired
Unhandled exception. System.AggregateException: One or more errors occurred. (Timeout performing EVAL (5000ms), next: SCRIPT, inst: 0, qu: 0, qs: 2, aw: False, bw: Inactive, rs: ReadAsync, ws: Idle, in: 0, in-pipe: 0, out-pipe: 0, last-in: 2, cur-in: 0, sync-ops: 2, async-ops: 0, serverEndpoint: localhost:6379, conn-sec: 5,09, aoc: 1, mc: 1/1/0, clientName: Mac-FXGL266(SE.Redis-v2.7.27.49176), IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=1,Free=32766,Min=16,Max=32767), POOL: (Threads=7,QueuedItems=0,CompletedItems=75,Timers=1), v: 2.7.27.49176 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts))
 ---> StackExchange.Redis.RedisTimeoutException: Timeout performing EVAL (5000ms), next: SCRIPT, inst: 0, qu: 0, qs: 2, aw: False, bw: Inactive, rs: ReadAsync, ws: Idle, in: 0, in-pipe: 0, out-pipe: 0, last-in: 2, cur-in: 0, sync-ops: 2, async-ops: 0, serverEndpoint: localhost:6379, conn-sec: 5,09, aoc: 1, mc: 1/1/0, clientName: Mac-FXGL266(SE.Redis-v2.7.27.49176), IOCP: (Busy=0,Free=1000,Min=1,Max=1000), WORKER: (Busy=1,Free=32766,Min=16,Max=32767), POOL: (Threads=7,QueuedItems=0,CompletedItems=75,Timers=1), v: 2.7.27.49176 (Please take a look at this article for some common client-side issues that can cause timeouts: https://stackexchange.github.io/StackExchange.Redis/Timeouts)
   at StackExchange.Redis.ConnectionMultiplexer.ExecuteSyncImpl[T](Message message, ResultProcessor`1 processor, ServerEndPoint server, T defaultValue) in /_/src/StackExchange.Redis/ConnectionMultiplexer.cs:line 2105
   at StackExchange.Redis.RedisBase.ExecuteSync[T](Message message, ResultProcessor`1 processor, ServerEndPoint server, T defaultValue) in /_/src/StackExchange.Redis/RedisBase.cs:line 62
   at StackExchange.Redis.RedisDatabase.ScriptEvaluate(String script, RedisKey[] keys, RedisValue[] values, CommandFlags flags) in /_/src/StackExchange.Redis/RedisDatabase.cs:line 1519
   at StackExchange.Redis.LuaScript.Evaluate(IDatabase db, Object ps, Nullable`1 withKeyPrefix, CommandFlags flags) in /_/src/StackExchange.Redis/LuaScript.cs:line 151
   at StackExchange.Redis.RedisDatabase.ScriptEvaluate(LuaScript script, Object parameters, CommandFlags flags) in /_/src/StackExchange.Redis/RedisDatabase.cs:line 1536
   at Medallion.Threading.Redis.Primitives.RedisScript`1.Execute(IDatabase database, TArgument argument, Boolean fireAndForget) in /_/src/DistributedLock.Redis/Primitives/RedisScript.cs:line 13
   at Medallion.Threading.Redis.Primitives.RedisMutexPrimitive.Release(IDatabase database, Boolean fireAndForget) in /_/src/DistributedLock.Redis/Primitives/RedisMutexPrimitive.cs:line 30
   at Medallion.Threading.Redis.RedLock.RedLockRelease.ReleaseAsync() in /_/src/DistributedLock.Redis/RedLock/RedLockRelease.cs:line 56
   --- End of inner exception stack trace ---
   at Medallion.Threading.Redis.RedLock.RedLockRelease.ReleaseAsync() in /_/src/DistributedLock.Redis/RedLock/RedLockRelease.cs:line 66
   at Medallion.Threading.Redis.RedLock.RedLockHandle.DisposeAsync() in /_/src/DistributedLock.Redis/RedLock/RedLockHandle.cs:line 46
   at Medallion.Threading.Internal.SyncViaAsync.<>c__3`1.<<Run>b__3_0>d.MoveNext() in /_/src/DistributedLock.Core/Internal/SyncViaAsync.cs:line 31
--- End of stack trace from previous location ---
   at Medallion.Threading.Internal.SyncViaAsync.Run[TState,TResult](Func`2 action, TState state) in /_/src/DistributedLock.Core/Internal/SyncViaAsync.cs:line 61
   at Medallion.Threading.Internal.SyncViaAsync.Run[TState](Func`2 action, TState state) in /_/src/DistributedLock.Core/Internal/SyncViaAsync.cs:line 28
   at Medallion.Threading.Internal.SyncViaAsync.DisposeSyncViaAsync[TDisposable](TDisposable disposable) in /_/src/DistributedLock.Core/Internal/SyncViaAsync.cs:line 100
   at Medallion.Threading.Redis.RedLock.RedLockHandle.Dispose() in /_/src/DistributedLock.Redis/RedLock/RedLockHandle.cs:line 35
   at Medallion.Threading.Redis.RedisDistributedLockHandle.Dispose() in /_/src/DistributedLock.Redis/RedisDistributedLockHandle.cs:line 26

Steps to reproduce the bug

Garnet Configuration

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: garnet
  namespace: garnet
spec:
  interval: 5m
  chart:
    spec:
      chart: garnet
      version: '0.2.0'
      sourceRef:
        kind: HelmRepository
        name: garnet
        namespace: flux-system
      interval: 60m
  values:
    image:
      tag: 1
    config:
      garnetConf: |
        {
          "EnableLua": true,
        }

Client

using Medallion.Threading;
using Medallion.Threading.Redis;
using StackExchange.Redis;

var config = ConfigurationOptions.Parse("localhost");
config.SocketManager = SocketManager.ThreadPool;

var connection = ConnectionMultiplexer.Connect(config, Console.Out);
var db = connection.GetDatabase();

var dLock = new RedisDistributedSynchronizationProvider(db);

var aLock = dLock.AcquireLock("123_lock");

Console.WriteLine("Lock acquired");

aLock.Dispose();

Console.WriteLine("Lock released");

Console.ReadKey();

Garnet Version

Garnet 1.0.59

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions