Skip to content

ConnectionGroupMember.Multiplexer is internal, so ServerMaintenanceEvent subscribers cannot attribute a notification to a group member #3249

Description

@cosmin-staicu

Summary

A subscriber to IConnectionGroup.ServerMaintenanceEvent cannot tell which group member a notification came from, because the one link it needs — ConnectionGroupMember.Multiplexer — is internal.

Detail

MultiGroupMultiplexer forwards the event by attaching the subscriber's own delegate to every member:

add
{
    if (AddHandler(ref _serverMaintenanceEvent, value))
    {
        foreach (var member in _members)
        {
            member.Multiplexer.ServerMaintenanceEvent += value;
        }
    }
}

So the sender the subscriber receives is the child ConnectionMultiplexer, not the group. The group layer itself does not react to maintenance notifications — selection is driven by health checks, circuit-breaker failures and TryFailoverTo — so deciding whether a notification concerns the connection currently carrying commands is left to the subscriber.

IConnectionGroup.ActiveMember is public and ConnectionGroupMember is a public type, but ConnectionGroupMember.Multiplexer is internal, so there is no supported way to complete the comparison:

// what a subscriber wants to write, and cannot
if (muxer is IConnectionGroup group && group.ActiveMember?.Multiplexer != sender)
{
    return;
}

Why it matters

This is most acute for MOVING. It is scoped to the connection it arrived on, it names that connection's replacement, and the server does not replay it. A subscriber that cannot attribute it has two options, both wrong in one direction:

  • filter on sender identity against the multiplexer it subscribed to, and silently drop every MOVING on a group connection, losing a notice that never comes again;
  • forward everything, and act on a MOVING describing a member the cache is not currently using.

Comparing PushMaintenanceEvent.EndPoint against GetEndPoints() is the only public alternative, and it is fragile — IPEndPoint versus DnsEndPoint and normalisation differences make a mismatch drop the notification rather than over-forward it.

Suggested fix

Make ConnectionGroupMember.Multiplexer public. It is a one-line accessibility change on a type that is already public, and it makes the attribution exact without exposing anything new about the group's internals.

An alternative would be for MultiGroupMultiplexer to re-raise ServerMaintenanceEvent with itself as sender, but that loses which member the notification described, which is the information the subscriber actually needs.

Workaround in use

Reading ConnectionGroupMember.Multiplexer reflectively, with the check skipped whenever the
lookup fails so an upstream rename costs a redundant notification rather than a lost one. It works,
but it pins a library's internals from outside, which is what this issue asks to avoid.

Version

StackExchange.Redis 3.3.0.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    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