Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deadlock on Set #14

Open
BertusVanZyl opened this issue May 20, 2020 · 3 comments
Open

Deadlock on Set #14

BertusVanZyl opened this issue May 20, 2020 · 3 comments

Comments

@BertusVanZyl
Copy link

I am experiencing some kind of deadlock. I am doing some basic proof of concept testing in an attempt to use redis as a distributed concurrency management scheme.

When the Set command is inside the nested await, it appears to lock.

Here is a sample (a simple console app) :

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="BeetleX.Redis" Version="0.9.5" />
  </ItemGroup>

</Project>
class Program
    {
        static async Task Main(string[] args)
        {
			RedisDB DB = new RedisDB(1);
            DB.Host.AddWriteHost("xxxxx", 6379, false);
            var resultList = new List<string>();
            await DB.Del("aaa");
            var list = new List<ValueTask<string>>();
            for (int i = 0; i < 1; i++)
            {
                await DoTest(10);
            }
            foreach (var l in list)
            {
                resultList.Add(await l);
            }
            var result = resultList.GroupBy(x => x).Select(x => new { V = x.Key, C = x.Count() });
		}

        public static async Task DoTest(int count)
        {
            RedisDB DB = new RedisDB(1);
            DB.Host.AddWriteHost("xxxxxx", 6379, false);
            var resultList = new List<string>();

            var list = new List<ValueTask<string>>();
            for (int i = 0; i < count; i++)
            {
                var r = await DB.Set("aaa", 1, seconds: null, nx: true);
                resultList.Add(r);
            }
            foreach (var l in list)
            {
                resultList.Add(await l);
            }
            var result = resultList.GroupBy(x => x).Select(x => new { V = x.Key, C = x.Count() });
        }
    }
@beetlex-io
Copy link
Owner

RedisDB is thread safe, can be defined as a static variable. modify the code to run successfully

    class Program
    {
        static RedisDB DB = new RedisDB(1);

        static async Task Main(string[] args)
        {
            DB.Host.AddWriteHost("192.168.2.19", 6379, false);
            var resultList = new List<string>();
            await DB.Del("aaa");
            var list = new List<ValueTask<string>>();
            for (int i = 0; i < 1; i++)
            {
                await DoTest(10);
            }
            foreach (var l in list)
            {
                resultList.Add(await l);
            }
            var result = resultList.GroupBy(x => x).Select(x => new { V = x.Key, C = x.Count() });
            Console.WriteLine("completed!");
            Console.Read();
        }

        public static async Task DoTest(int count)
        {
            var resultList = new List<string>();
            var list = new List<ValueTask<string>>();
            for (int i = 0; i < count; i++)
            {
                var r = DB.Set("aaa", 1, seconds: null, nx: true);
                list.Add(r);
            }
            foreach (var l in list)
            {
                resultList.Add(await l);
            }

            foreach (var item in resultList)
                Console.WriteLine($"{(item == null ? "null" : item)}");
        }
    }

image

@BertusVanZyl
Copy link
Author

Changing the code like you suiggested removes the deadlock problem. However, I want to test concurrencly from different processes, and for that I need to create more than one connection. The moment I create another connection, and attempt to call SET on it, it locks up.

I would I create more than one RedisDB, to simulate connections from different processes?

@beetlex-io
Copy link
Owner

RedisDB internal is using connection pool access redis, you can define an instance to operate in multiple threads.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants