1

Do I get lots of errors when working with radishes.

It`s my config:

container.Register<IRedisClientsManager>(c => new PooledRedisClientManager("localhost:6379"));
container.Register(c => c.Resolve<IRedisClientsManager>().GetCacheClient());

container.Register(new GameDispatchService(container.Resolve<IRedisClientsManager>()));

It`s class which changes the data in radis

public class GameDispatchService {
        private readonly IRedisClientsManager redisManager;
        private Timer mTimer;

        public GameDispatchService(IRedisClientsManager redisManager) {
            this.redisManager = redisManager;

            mTimer = new Timer();

            mTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
            mTimer.Interval = 1000;
            mTimer.Enabled = true;
        }

        private void OnTimedEvent(object sender, ElapsedEventArgs e) {
            mTimer.Stop();

            try {
                using (IRedisClient cacheClient = redisManager.GetClient()) {
                    var sessionPattern = "game:Created*";
                    var tSessionKeys = cacheClient.GetKeysStartingWith(sessionPattern).ToList();

                    if (!tSessionKeys.IsNullOrEmpty()) {
                        var list = cacheClient.GetAll<GameCachModel>(tSessionKeys);

                        foreach (var item in list) {
                            var lastKey = item.Key;
                            var newKey = $"game:{GameStatuses.Waiting}:{item.Value.GameNumber}";
                            item.Value.Status = GameStatuses.Waiting;

                            cacheClient.Remove(lastKey);
                            cacheClient.Add(newKey, item.Value);
                        }
                    }
                }
            } catch (Exception ex) {
                 var t = ex.Message;
                t.PrintDump();
            } finally {
                mTimer.Start();
            }

        }

        .......
    }

and so I receive the data from the redis

    List<GameRetModel> gamesList = new List<GameRetModel>();

                try {
                    using (var cacheClient = this.GetCacheClient()) {
                        var sessionPattern = "game:Waiting*";
                        var tSessionKeys = cacheClient.GetKeysStartingWith(sessionPattern)?.ToList();

                        if (!tSessionKeys.IsNullOrEmpty()) {
                            var list = cacheClient.GetAll<GameCachModel>(tSessionKeys);

                            foreach (var item in list.Values) {
                                if (item.Rate >= request.MinVal && item.Rate <= request.MaxVal) {
                                    gamesList.Add(new GameRetModel {
                                        Author = item.Author,
                                        Avatar = item.Avatar,
                                        GameNumber = item.GameNumber,
                                        Count = item.Users.Count,
                                        Rate = item.Rate
                                    });
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    e.Message.PrintDump();
                    return new { error = true };
                }

                return new { error = false, gamesList = gamesList };
}

and I get many errors, I searched the Internet and I understand that the problem with the multiple threads, but I can't solve the problem.

Please help if you know how to do it right.

ServiceStack version 4.5.5 Redis 3.0.501

Thanks!

I get the following error:

1 .Message: Protocol error: expected '$', got 'C'

Trace:

в ServiceStack.Redis.RedisNativeClient.ReadDeeplyNestedMultiDataItem()
   в ServiceStack.Redis.RedisNativeClient.ReadDeeplyNestedMultiData()
   в ServiceStack.Redis.RedisNativeClient.SendReceive[T](Byte[][] cmdWithBinaryArgs, Func`1 fn, Action`1 completePipelineFn, Boolean sendWithoutRead)
   в ServiceStack.Redis.RedisNativeClient.SendExpectDeeplyNestedMultiData(Byte[][] cmdWithBinaryArgs)
   в ServiceStack.Redis.RedisNativeClient.SendExpectScanResult(Byte[] cmd, Byte[][] args)
   в ServiceStack.Redis.RedisNativeClient.Scan(UInt64 cursor, Int32 count, String match)
   в ServiceStack.Redis.RedisClient.<ScanAllKeys>d__159.MoveNext()
   в System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   в System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   в loto.ServiceInterface.LotoServices.Post(GetGames request) в D:\Documents\Visual Studio 2015\Projects\loto\loto\loto.ServiceInterface\LotoServices.cs:строка 144
  1. Message: Unexpected reply: *2

Trace:

в ServiceStack.Redis.RedisNativeClient.ParseSingleLine(String r)
   в ServiceStack.Redis.RedisNativeClient.ReadData()
   в ServiceStack.Redis.RedisNativeClient.SendReceive[T](Byte[][] cmdWithBinaryArgs, Func`1 fn, Action`1 completePipelineFn, Boolean sendWithoutRead)
   в ServiceStack.Redis.RedisNativeClient.SendExpectData(Byte[][] cmdWithBinaryArgs)
   в ServiceStack.Redis.RedisNativeClient.Set(String key, Byte[] value, Boolean exists, Int32 expirySeconds, Int64 expiryMs)
   в ServiceStack.Redis.RedisClient.<>c__DisplayClass21_0`1.<Add>b__0(RedisClient r)
   в ServiceStack.Redis.RedisClient.Exec[T](Func`2 action)
   в ServiceStack.Redis.RedisClient.Add[T](String key, T value)
   в ServiceStack.Redis.RedisClientManagerCacheClient.Add[T](String key, T value)
   в loto.ServiceInterface.LotoServices.Post(CreateGame request) в D:\Documents\Visual Studio 2015\Projects\loto\loto\loto.ServiceInterface\LotoServices.cs:строка 42
  1. Message: Unknown reply on integer response: 422

Trace:

 в ServiceStack.Redis.RedisNativeClient.ReadLong()
   в ServiceStack.Redis.RedisNativeClient.SendReceive[T](Byte[][] cmdWithBinaryArgs, Func`1 fn, Action`1 completePipelineFn, Boolean sendWithoutRead)
   в ServiceStack.Redis.RedisNativeClient.SendExpectLong(Byte[][] cmdWithBinaryArgs)
   в ServiceStack.Redis.RedisNativeClient.Del(Byte[] key)
   в ServiceStack.Redis.RedisClient.Remove(String key)
   в ServiceStack.Redis.RedisClientManagerCacheClient.Remove(String key)
   в loto.ServiceInterface.GameDispatchService.OnTimedEvent(Object sender, ElapsedEventArgs e) в D:\Documents\Visual Studio 2015\Projects\loto\loto\loto.ServiceInterface\GameDispatchService.cs:строка 67

I have different data so many mistakes

enter image description here

Mher Arsh
  • 588
  • 4
  • 21

1 Answers1

1

The ICacheClient is a singleton, it shouldn't be disposed so you shouldn't put it in a using, i.e:

using (var cacheClient = this.GetCacheClient()) {

Since it's registered as a ICacheClient you can instead resolve it with:

var cacheClient = HostContext.Cache;

Which is just a wrapper for:

var cacheClient = HostContext.TryResolve<ICacheClient>();
mythz
  • 141,670
  • 29
  • 246
  • 390
  • I did as You showed but it does not work, please look here: http://stackoverflow.com/a/41502093/7015077 – Mher Arsh Jan 06 '17 at 08:59
  • @MherArsh don't put it in a using statement, it's a singleton – mythz Jan 06 '17 at 10:47
  • it seems that with multi-threading, the редис has problems :(, I have one thread changing the data while others read them, but in the flow of the reading they some time do not change and I get a lot of errors, for example: "Unknown reply on multi-request". I'm trying to create a small game, but such restrictions are hindering me, what do you think ? if I use the "Memcached" in ServiceStack will not be such problems? because "Memcached" is multi-threaded. Thanks. – Mher Arsh Jan 06 '17 at 18:01
  • @MherArsh sharing the same Redis client instance across multiple threads would generate this error. You need to make sure you resolve a new IRedisClient and dispose of it within the same thread and not share the instance. It's not clear where your race condition is, but it may be somewhere other than the code provided (I.e where the Exception is thrown does not indicate where the race condition is as it happened somewhere before then) – mythz Jan 06 '17 at 18:09
  • @ mythz 1.https://github.com/MherX/test/blob/master/loto/loto/AppHost.cs#L52-L53 2. https://github.com/MherX/test/blob/master/loto/loto/AppHost.cs#L112 and all cаlls: https://github.com/MherX/test/blob/master/loto/loto.ServiceInterface/GameDispatchService.cs#L21 https://github.com/MherX/test/blob/master/loto/loto.ServiceInterface/LotoServices.cs#L39 https://github.com/MherX/test/blob/master/loto/loto.ServiceInterface/LotoServices.cs#L125. Аll as discussed today, but somewhere something is not right, I would be very grateful if you look. – Mher Arsh Jan 06 '17 at 19:19
  • @myhtz it's my full project :) – Mher Arsh Jan 06 '17 at 22:54
  • @MherArsh can't see the issue from browsing the source code, can you update your question to post the full StackTrace of the Exception that you're receiving. – mythz Jan 07 '17 at 01:45
  • @myhtz thanks for the feedback, I update question, added error and trace – Mher Arsh Jan 07 '17 at 08:56
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/132555/discussion-between-mher-arsh-and-mythz). – Mher Arsh Jan 07 '17 at 09:13
  • @MherArsh thx for the StackTrace, the issue is potentially in the Redis ICacheClient wrapper which returns an open cursor that's read after the Redis client is disposed and returned back into the pool which can cause the same client instance to be used in multiple threads. This should now be prevented in [this commit](https://github.com/ServiceStack/ServiceStack.Redis/commit/d7b3df85ec4eba0f0e3098917dad4ecb4ff67bee) which is available from v4.5.5+ on MyGet. Can you try [clearing your NuGet cache](http://docs.servicestack.net/myget#redownloading-myget-packages) then downloading packages again? – mythz Jan 07 '17 at 11:02
  • @MherArsh Note an alternative to using `ICacheClient` is to use the Redis Client directly. The [Redis ICacheClient wrapper](https://github.com/ServiceStack/ServiceStack.Redis/blob/master/src/ServiceStack.Redis/RedisClientManagerCacheClient.cs) just resolves and disposes a Redis Client after each operation. – mythz Jan 07 '17 at 11:04
  • @myhtz thanks, after clearing NuGet cache the error is gone, but strangely, I clearing cache 2 days ago, if the problem will happen again I'll let you know, thanks again. – Mher Arsh Jan 07 '17 at 12:49