Forum

Redis ISubscriber.Subscribe method is not properly called in VL

Hey guys. I have a very specialized question, but anyways I’ll try my luck here. I’m basically trying to implement Stackexchange.Redis into VL by writing a c# wrapper, and I’m stuck

VL seems to ignore the whole Subscribe method of Stackexchange.Redis lib. On the other hand it does everything else, e.g. it connects to the server, interacts with database and publishes messages, but as soon as I start trying to subscribe to messages nothing happens.

I’ve built a small console app without VL to just check if I’m doing everything right and Stackexchange.Redis did its work from pure .net core, so my guess is that VL is doing something wrong. Maybe. At least VL doesn’t give me any errors, but just ignores calls to the method.

I put Stackexchange.Redis source code here to get an idea what it’s doing. I’m just calling ISubscriber.Subscribe method from VL wrapper. Don’t think that attaching any of my patches and c# bits would help because you’ll find only really basic stuff there and it’s pointless without the whole redis infrastracture. So maybe this bit of code could give you some clues. There are also some classes involved, which I’m not posting here, but my main question is why VL is not doing the same thing as console .net app does?

void ISubscriber.Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handler, CommandFlags flags) => Subscribe(channel, handler, null, flags);

public void Subscribe(RedisChannel channel, Action<RedisChannel, RedisValue> handler, ChannelMessageQueue queue, CommandFlags flags)
{
var task = SubscribeAsync(channel, handler, queue, flags);
if ((flags & CommandFlags.FireAndForget) == 0) Wait(task);
}

Task ISubscriber.SubscribeAsync(RedisChannel channel, Action<RedisChannel, RedisValue> handler, CommandFlags flags) => SubscribeAsync(channel, handler, null, flags);

public Task SubscribeAsync(in RedisChannel channel, Action<RedisChannel, RedisValue> handler, ChannelMessageQueue queue, CommandFlags flags)
{
if (channel.IsNullOrEmpty) throw new ArgumentNullException(nameof(channel));
return multiplexer.AddSubscription(channel, handler, queue, flags, asyncState);
}

internal Task AddSubscription(in RedisChannel channel, Action<RedisChannel, RedisValue> handler, ChannelMessageQueue queue, CommandFlags flags, object asyncState)
{
Task task = null;
if (handler != null | queue != null)
{
    lock (subscriptions)
    {
        if (!subscriptions.TryGetValue(channel, out Subscription sub))
             {
                   sub = new Subscription();
                   subscriptions.Add(channel, sub);
                   task = sub.SubscribeToServer(this, channel, flags, asyncState, false);
              }
        sub.Add(handler, queue);
    }
}
return task ?? CompletedTask<bool>.Default(asyncState);
}

Any help would be appreciated. Maybe at least you have some ideas what to check and how to debug that type of stuff.

how does the subscription in vl look like? how do you wait for the asyc task to finish?

My code here is simple. I have a subscriber, which is the same object I use to publish messages.

subscriber.Subscribe(new RedisChannel(channelName, RedisChannel.PatternMode.Literal), WhatIWantToDoOnMessageReceive);

WhatIWantToDoOnMessageReceive is an action delegate.

To your second question. I’m not doing anything special to handle async task. Should I?

Do you also have a screenshot of the patch?

Ok, I ran through my code once again and found one try catch region, that prevented me from seeing the error. The problem was specifically with System.Threading.Channels, that I needed to add to VL doc as a dependenciy manually from nuget. Now everything works

Thanx for being with me

XX

2 Likes