lettuce icon indicating copy to clipboard operation
lettuce copied to clipboard

expose a method for get socket address of connection

Open jjz921024 opened this issue 2 years ago • 4 comments

Feature Request

Is your feature request related to a problem? Please describe

In my scenario, I use EventBus to subscribe latency metrics for each connection.

CommandLatencyId identify a connection with local/remote address tuple of SocketAddress.

like that:

clientResources.eventBus().get()
            .filter(event -> event instanceof CommandLatencyEvent)
            .cast(CommandLatencyEvent.class)
            .map(CommandLatencyEvent::getLatencies)
            .subscribe(latencyMetricsMap -> {
                isolationConnection.clear();
                for (Map.Entry<CommandLatencyId, CommandMetrics> entry : latencyMetricsMap.entrySet()) {
                         CommandLatencyId latencyId = entry.getKey();
                         SocketAddress remoteAddress = latencyId.remoteAddress();
                         SocketAddress localAddress = latencyId.localAddress();
                         // do something...
                }
            });

But, I can not get socket address from a connection, so metrics cannot be associated with a connection

Describe the solution you'd like

Add a method to expose SocketAddress on DefaultEndpoint

public SocketAddress getLocalAddress() {
        if (channel == null) {
            return null;
        }
        return channel.localAddress();
    }
    
    public SocketAddress getRemoteAddress() {
        if (channel == null) {
            return null;
        }
        return channel.remoteAddress();
    }

Describe alternatives you've considered

A clear and concise description of any alternative solutions or features you've considered.

Teachability, Documentation, Adoption, Migration Strategy

If you can, explain how users will be able to use this and possibly write out a version the docs. Maybe a screenshot or design?

jjz921024 avatar Mar 21 '22 01:03 jjz921024

Lettuce connections are a facade on top of a potentially connected channel. The StatefulRedisConnection may have a Channel. During a disconnect, the Channel is gone and we cannot provide a SocketAddress until the connection is re-established.

Additionally, a cluster connection consists of multiple TCP connections (and multiple StatefulRedisConnection objects).

mp911de avatar Mar 21 '22 09:03 mp911de

I know a Clinet may maintain multiple Connection. but just for a Connection, its tcp four tuple should be provided so that the user can identify it.

It is useful if user need to connect multiple redis instances, and collect metrice for each connection using EventBus that mentioned above.

Otherwise, user need to manually maintain the relationship between connections and addresses,like

Map<StatefulRedisConnection, IpAndPort> connectionPool

even if, the user can only know the remote address.

During a disconect, null or a special placehold can be provided ?

jjz921024 avatar Mar 22 '22 16:03 jjz921024

You can register RedisConnectionStateListener that is called with onRedisConnected(RedisChannelHandler<?, ?> connection, SocketAddress socketAddress) where RedisChannelHandler is a StatefulConnection. Does that help?

mp911de avatar Mar 23 '22 07:03 mp911de

I have tried this way, but still only get the remote address of the connection. This is not enough to identify a connection.

When i use event to collect metrics for each connection. Command latencies are transported using Events on the EventBus. And the key of latencies info is CommandLatencyId object that contain a remote address and a local address field, but i only have remote address for a connection.

So, i can not know which metric belongs to which connection.

jjz921024 avatar Mar 23 '22 08:03 jjz921024

This is all we can provide at the time being. We don't intend to expose more details.

mp911de avatar Nov 22 '22 13:11 mp911de