redis / go-redis

Redis Go client
https://redis.uptrace.dev
BSD 2-Clause "Simplified" License
19.81k stars 2.34k forks source link

cannot listen for when TCP connection closes #2845

Open ORESoftware opened 8 months ago

ORESoftware commented 8 months ago

There seems to be zero way to listen for when the connection closes...I am looking for something like:

    c := make(chan interface{})
    client.notifyClose(c);
       go func() {
         for {
           v := <-c
           if v != nil {

           }
         }
      }()

even better if you could provide a state string/enum that tells us the state of the connection:

if client.state == client.CLOSED {
  ///
}

having both of these features would be very useful for real-world code. Thanks for listening.

ORESoftware commented 8 months ago

I understand that there might be a goroutine pool beneath the client. but I will still would like to find a way to listen for close events.

rfyiamcool commented 8 months ago

the case is about go-redis ?

ORESoftware commented 8 months ago

yessir this library

rfyiamcool commented 8 months ago

can you provide runable example ? 😁

ORESoftware commented 5 months ago

well I cannot provide the example because it doesn't exist yet, but here is what I mean: https://chat.openai.com/share/1f680748-6874-41f4-9f7e-f1f6f0942e1b

there should be a boolean that tells users if the connection (or connection pool) is open or closed. that would be really useful instead of having to using PING/PONG which is expensive for a check.

For a more direct approach to determine if a Redis connection is open or closed in the `go-redis` library, there isn't a straightforward method like a `IsConnected` function that you can call. This is largely because the library manages connections in a pool and handles opening and closing connections as needed, abstracting these details away from the user.

However, you can perform a simple operation such as a `PING` command to check if the connection is active. This is a lightweight and common practice to test connectivity with the Redis server. If the `PING` command succeeds, you can assume the connection is open; if it fails, the connection might be closed or there could be a network issue.

Here is a simple example of how to use the `PING` command to check for connectivity:

```go
package main

import (
    "context"
    "fmt"
    "github.com/go-redis/redis/v8"
)

func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr: "localhost:6379", // Redis server address
    })

    // Using context.Background() for simplicity,
    // but you should use a proper context in real applications.
    pong, err := rdb.Ping(context.Background()).Result()
    if err != nil {
        fmt.Println("Connection to Redis failed:", err)
    } else {
        fmt.Println("Connection to Redis is open:", pong)
    }
}

If the connection to Redis is open and healthy, the PING command will return a PONG response, and you'll see the output "Connection to Redis is open: PONG". If the connection is closed or there's a network issue preventing the command from reaching the Redis server, you'll get an error.

This method is effective for a quick check but keep in mind that connection status can change immediately after the check. If you're performing critical operations, always include error handling around those operations to catch and appropriately handle any connectivity issues.