Skip to content

Commit

Permalink
Cleanup docs (#30)
Browse files Browse the repository at this point in the history
* unify(get): unify get command of resp2 & resp3

give same signature

* unify(setex): add setex to the unified client

* add delete commands

* chore(docs): cleanup the docs

* fix test
  • Loading branch information
iwanbk authored May 17, 2022
1 parent 3dfa98d commit 0b0ec3b
Show file tree
Hide file tree
Showing 11 changed files with 105 additions and 232 deletions.
52 changes: 43 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# rimcu - Redis server-assisted client side caching Go library

![Test and Linter](https://github.com/github/docs/actions/workflows/test_lint.yml/badge.svg)
![build workflow](https://github.com/iwanbk/rimcu/actions/workflows/test_lint.yml/badge.svg)
[![PkgGoDev](https://pkg.go.dev/badge/github.com/iwanbk/rimcu)](https://pkg.go.dev/github.com/iwanbk/rimcu)
[![codecov](https://codecov.io/gh/iwanbk/rimcu/branch/master/graph/badge.svg)](https://codecov.io/gh/iwanbk/rimcu)
[![Maintainability](https://api.codeclimate.com/v1/badges/edbfa2013d2a8d2b74ce/maintainability)](https://codeclimate.com/github/iwanbk/rimcu/maintainability)
Expand All @@ -10,7 +10,7 @@ In other words, it is a combination of Redis cient library and in memory cache l

## System Requirements

Redis 6, with it's client side caching feature
Redis 6 or newer, with it's client side caching feature

## How it works

Expand All @@ -19,7 +19,34 @@ So you don't need to always ask the Redis server to get your cache data.

It supports two kind of Redis protocols:
- RESP2: it is the default one
- RESP3: still under development
- RESP3: not fully tested yet

## Examples

```go

```
## Features

| Features | Status | Description |
|------------------|--------------|-----------------------------|
| Metrics Client | :x: :wrench: | Configurable metrics client |
| Password Support | :x: :wrench: | |
| Strings | :x: :wrench: | redis strings data type |
| list | :x: :wrench: | redis list data type |
| hash | :x: :wrench: | redis hash data type |



Connection Pool

| Features | Status | Description |
|-------------------------------------|--- |--------------------------------------|
| Single Pool | :x: :wrench: | Single conn pool for all cache types |
| Max Number of Connections | :white_check_mark: | |
| Waiting for connection with timeout | :white_check_mark: | |
| Idle connection checking | :x: :wrench: | |
| Healthcheck | :x: :wrench: | |

## Caches
We categorize the cache based on the Redis data types mention in https://redis.io/docs/manual/data-types/.
Expand Down Expand Up @@ -55,13 +82,20 @@ Implemented commands:
- [ ]...
```

## TODO

improve the connection pool:
- [x] maximum number of connections
- [x] waiting for connection with timeout
- [ ] idle connection checking
- [ ] health checking
# Development
Local Test
```bash
export TEST_REDIS_ADDRESS=127.0.0.1:6379 # replace with your redis 6 server
go test ./...
```

TODO

| Features | Status | Description |
|-------------------|--------------|----------------------------------------------------|
| Unify inmem cache | :x: :wrench: | resp2 & resp3 currently using two different memcache lib |



# CREDITS
Expand Down
156 changes: 0 additions & 156 deletions internal/crc/crc64.go

This file was deleted.

2 changes: 0 additions & 2 deletions internal/resp3pool/conn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"testing"
"time"

"github.com/iwanbk/rimcu/internal/crc"
"github.com/stretchr/testify/require"
)

Expand Down Expand Up @@ -48,7 +47,6 @@ func TestConn(t *testing.T) {
val1 = "val_1"
val2 = "val_2"
)
log.Printf("key crc = %v", crc.RedisCrc([]byte(key1)))

err = c1.setex(key1, val1, exp)
require.NoError(t, err)
Expand Down
14 changes: 11 additions & 3 deletions resp2/string_result.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (

// StringResult represents result of the strings cache read operation
type StringResult struct {
val interface{}
val interface{}
fromLocalCache bool
}

func newStringResult(val interface{}) *StringResult {
func newStringResult(val interface{}, fromLocalCache bool) *StringResult {
return &StringResult{
val: val,
val: val,
fromLocalCache: fromLocalCache,
}
}

Expand All @@ -24,3 +26,9 @@ func (sr *StringResult) Bool() (bool, error) {
func (sr *StringResult) String() (string, error) {
return redis.String(sr.val, nil)
}

// FromLocalCache returns true if this result was coming from
// the local inmemory cache
func (sr *StringResult) FromLocalCache() bool {
return sr.fromLocalCache
}
16 changes: 11 additions & 5 deletions resp2/strings.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package resp2
import (
"context"
"errors"

"github.com/iwanbk/rimcu/result"

"github.com/iwanbk/rimcu/internal/redigo/redis"
Expand Down Expand Up @@ -30,6 +31,8 @@ type StringsCacheConfig struct {
// inmem cache max size
CacheSize int

// inmem cache TTL
CacheTTL int
// Logger for this lib, if nil will use Go log package which only print log on error
Logger logger.Logger
}
Expand All @@ -41,6 +44,8 @@ func NewStringsCache(cfg StringsCacheConfig) (*StringsCache, error) {
cfg.Logger = logger.NewDefault()
}

cfg.Logger.Debugf("cfg:%#v", cfg)

sc := &StringsCache{
logger: cfg.Logger,
cc: newCache(cfg.CacheSize),
Expand Down Expand Up @@ -86,7 +91,8 @@ func (sc *StringsCache) Setex(ctx context.Context, key string, val interface{},
return err
}

sc.cc.Set(key, val, conn.ClientID(), expSecond)
//sc.cc.Set(key, val, conn.ClientID(), expSecond)
sc.cc.Del(key)
return nil
}

Expand All @@ -99,13 +105,13 @@ func (sc *StringsCache) Get(ctx context.Context, key string, expSecond int) (res
val, ok := sc.getMemCache(key)
if ok {
sc.logger.Debugf("GET: already in memcache")
return newStringResult(val), nil
return newStringResult(val, true), nil
}

// get from redis
conn, err := sc.getConn(ctx)
if err != nil {
return newStringResult(nil), err
return newStringResult(nil, false), err
}
defer conn.Close()

Expand All @@ -115,13 +121,13 @@ func (sc *StringsCache) Get(ctx context.Context, key string, expSecond int) (res
if err == redis.ErrNil {
err = ErrNotFound
}
return newStringResult(val), err
return newStringResult(val, false), err
}

// set to in-mem cache
sc.cc.Set(key, val, conn.ClientID(), expSecond)

return newStringResult(val), nil
return newStringResult(val, false), nil
}

// Del deletes the key in both memory cache and redis server
Expand Down
42 changes: 0 additions & 42 deletions resp2/strings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,48 +17,6 @@ var (
syncTimeWait = 1 * time.Second
)

// Test Set initiate in memory cache
func TestStringsCache_Set_InitInMem(t *testing.T) {
clis, cleanup := createStringsCacheClient(t, 1)
defer cleanup()

var (
cli1 = clis[0]
key1 = generateRandomKey()
val1 = "val1"
expSecond = 100
ctx = context.Background()
)

// Test Init
{

}

// make sure initial condition
{
val, ok := cli1.getMemCache(key1)
require.False(t, ok)
require.Empty(t, val)
}

// do action
{
// - set from client1
err := cli1.Setex(ctx, key1, val1, expSecond)
require.NoError(t, err)

}

// check expected condition
{
val, ok := cli1.getMemCache(key1)
require.True(t, ok)
require.Equal(t, val1, val)
}

}

// Test that Set will invalidate memcache in other nodes
func TestStringsCache_Set_Invalidate(t *testing.T) {
ctx := context.Background()
Expand Down
Loading

0 comments on commit 0b0ec3b

Please sign in to comment.