diff --git a/go.mod b/go.mod index 9284786..80a7e23 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module github.com/kotalco/crossover-cache go 1.21 -require github.com/kotalco/resp v0.0.0-20240310155233-e8ffa70a7031 +require github.com/kotalco/resp v0.0.0-20240311131414-34be1adf83d2 diff --git a/go.sum b/go.sum index 7ffc9f0..481fd69 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -github.com/kotalco/resp v0.0.0-20240310155233-e8ffa70a7031 h1:F1VO30pQBmIo3Vmw2LtcjM6qd8ocxatXiUc8SFxAv2Y= -github.com/kotalco/resp v0.0.0-20240310155233-e8ffa70a7031/go.mod h1:+7+oV/yGtCk7K98vCqoFkkhG0gzoyfp/zNMtuSyxn08= +github.com/kotalco/resp v0.0.0-20240311131414-34be1adf83d2 h1:w1zVyA8V5eB3ndBdfrCFTtzh2ViuHz/BQa3djmS/ek0= +github.com/kotalco/resp v0.0.0-20240311131414-34be1adf83d2/go.mod h1:+7+oV/yGtCk7K98vCqoFkkhG0gzoyfp/zNMtuSyxn08= diff --git a/plugin.go b/plugin.go index 26a75d0..34179fb 100644 --- a/plugin.go +++ b/plugin.go @@ -10,8 +10,7 @@ import ( ) const ( - DefaultRedisPoolSize = 10 - DefaultCacheExpiry = 15 + DefaultCacheExpiry = 15 ) type CachedResponse struct { @@ -21,10 +20,9 @@ type CachedResponse struct { } type Config struct { - RedisAddress string - RedisAuth string - RedisPoolSize int - CacheExpiry int //in seconds + RedisAddress string + RedisAuth string + CacheExpiry int //in seconds } // CreateConfig creates the default plugin configuration. @@ -33,45 +31,43 @@ func CreateConfig() *Config { } type Cache struct { - next http.Handler - name string - resp resp.IClient - redisAuth string - redisAddress string - redisPoolSize int - cacheExpiry int + next http.Handler + name string + redisAuth string + redisAddress string + cacheExpiry int } func New(ctx context.Context, next http.Handler, config *Config, name string) (http.Handler, error) { - if config.RedisPoolSize == 0 { - config.RedisPoolSize = DefaultRedisPoolSize - } if config.CacheExpiry == 0 { config.CacheExpiry = DefaultCacheExpiry } gob.Register(CachedResponse{}) - //ignore error check to run the plugin with Yaegi - respClient, _ := resp.NewRedisClient(config.RedisAddress, config.RedisPoolSize, config.RedisAuth) - handler := &Cache{ - next: next, - name: name, - resp: respClient, - redisAddress: config.RedisAddress, - redisAuth: config.RedisAuth, - redisPoolSize: config.RedisPoolSize, - cacheExpiry: config.CacheExpiry, + next: next, + name: name, + redisAddress: config.RedisAddress, + redisAuth: config.RedisAuth, + cacheExpiry: config.CacheExpiry, } return handler, nil } func (c *Cache) ServeHTTP(rw http.ResponseWriter, req *http.Request) { + respClient, err := resp.NewRedisClient(c.redisAddress, c.redisAuth) + if err != nil { + rw.WriteHeader(http.StatusInternalServerError) + log.Printf("Failed to create Redis Connection %s", err.Error()) + rw.Write([]byte("something went wrong")) + return + } + defer respClient.Close() // cache key based on the request cacheKey := req.URL.Path // retrieve the cached response - cachedData, err := c.resp.Get(req.Context(), cacheKey) + cachedData, err := respClient.Get(req.Context(), cacheKey) if err == nil && cachedData != "" { // Cache hit - parse the cached response and write it to the original ResponseWriter var cachedResponse CachedResponse @@ -88,7 +84,7 @@ func (c *Cache) ServeHTTP(rw http.ResponseWriter, req *http.Request) { return } log.Printf("Failed to serialize response for caching: %s", err.Error()) - _ = c.resp.Delete(req.Context(), cacheKey) + _ = respClient.Delete(req.Context(), cacheKey) } // Cache miss - record the response @@ -108,7 +104,7 @@ func (c *Cache) ServeHTTP(rw http.ResponseWriter, req *http.Request) { } // Store the serialized response in Redis as a string with an expiration time - if err := c.resp.SetWithTTL(req.Context(), cacheKey, buffer.String(), c.cacheExpiry); err != nil { + if err := respClient.SetWithTTL(req.Context(), cacheKey, buffer.String(), c.cacheExpiry); err != nil { log.Println("Failed to cache response in Redis:", err) } diff --git a/vendor/github.com/kotalco/resp/client.go b/vendor/github.com/kotalco/resp/client.go index 7893fdc..07b479a 100644 --- a/vendor/github.com/kotalco/resp/client.go +++ b/vendor/github.com/kotalco/resp/client.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "log" "strconv" "sync" ) @@ -20,8 +19,6 @@ const ( ) type IClient interface { - GetConnection() (IConnection, error) - ReleaseConnection(conn IConnection) Do(ctx context.Context, command string) (string, error) Ping(ctx context.Context) (string, error) Set(ctx context.Context, key string, value string) error @@ -30,94 +27,45 @@ type IClient interface { Delete(ctx context.Context, key string) error Incr(ctx context.Context, key string) (int, error) Expire(ctx context.Context, key string, seconds int) (bool, error) - Pool() chan IConnection - PoolSize() int - Close() + Close() error } type Client struct { - pool chan IConnection - address string - poolSize int - mu sync.Mutex - auth string - dialer IDialer + conn IConnection + address string + mu sync.Mutex + auth string + dialer IDialer } -func NewRedisClient(address string, poolSize int, auth string) (IClient, error) { +func NewRedisClient(address string, auth string) (IClient, error) { client := &Client{ - pool: make(chan IConnection, poolSize), - address: address, - poolSize: poolSize, - auth: auth, - dialer: NewDialer(), - } - // pre-populate the pool with connections , authenticated and ready to be used - for i := 0; i < poolSize; i++ { - conn, err := NewRedisConnection(client.dialer, address, auth) - if err != nil { - log.Println(err.Error()) - continue - } - client.pool <- conn - } - if len(client.pool) == 0 { - return nil, errors.New("can't create redis connection") + address: address, + auth: auth, + dialer: NewDialer(), } - return client, nil -} - -func (client *Client) GetConnection() (IConnection, error) { - // make sure that the access to the client.pool is synchronized among concurrent goroutines, make the operation atomic to prevent race conditions - client.mu.Lock() - defer client.mu.Unlock() - - select { - case conn := <-client.pool: - return conn, nil - default: - // pool is empty now all connection are being used , create a new connection till some connections get released - conn, err := NewRedisConnection(client.dialer, client.address, client.auth) - if err != nil { - return nil, err - } - return conn, nil + conn, err := NewRedisConnection(client.dialer, address, auth) + if err != nil { + return nil, errors.New("can't create redis connection") } -} -func (client *Client) ReleaseConnection(conn IConnection) { - client.mu.Lock() - defer client.mu.Unlock() + client.conn = conn - err := conn.Ping(context.Background()) - if len(client.pool) >= client.poolSize || err != nil { - err := conn.Close() - if err != nil { - return - } //if the pool is full the new conn is closed and discarded - } else { - client.pool <- conn //if there is room put into the pool for future use - } + return client, nil } func (client *Client) Do(ctx context.Context, command string) (string, error) { - conn, err := client.GetConnection() - if err != nil { - return "", err - } - defer client.ReleaseConnection(conn) - errChan := make(chan error, 1) replyChan := make(chan string, 1) go func() { - err := conn.Send(ctx, command) + err := client.conn.Send(ctx, command) if err != nil { errChan <- err return } - reply, err := conn.Receive(ctx) + reply, err := client.conn.Receive(ctx) if err != nil { errChan <- err } else { @@ -229,20 +177,8 @@ func (client *Client) Delete(ctx context.Context, key string) error { return nil } -func (client *Client) Close() { +func (client *Client) Close() error { client.mu.Lock() defer client.mu.Unlock() - for len(client.pool) > 0 { - conn := <-client.pool - _ = conn.Close() - } - close(client.pool) - -} - -func (client *Client) Pool() chan IConnection { - return client.pool -} -func (client *Client) PoolSize() int { - return client.poolSize + return client.conn.Close() } diff --git a/vendor/modules.txt b/vendor/modules.txt index c6f39c7..6b5a3c1 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,3 +1,3 @@ -# github.com/kotalco/resp v0.0.0-20240310155233-e8ffa70a7031 +# github.com/kotalco/resp v0.0.0-20240311131414-34be1adf83d2 ## explicit; go 1.21 github.com/kotalco/resp