BeetleX.Redis
BeetleX.Redis copied to clipboard
Deadlock on Set
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() });
}
}
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)}");
}
}
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?
RedisDB internal is using connection pool access redis, you can define an instance to operate in multiple threads.