Update Coherence driver to add near cache option

This commit is contained in:
Tim Middleton
2024-03-08 15:39:04 +08:00
parent fc05d5dc68
commit 21a2ad89f2
6 changed files with 77 additions and 19 deletions

View File

@@ -18,16 +18,17 @@ jobs:
- 1.19.x - 1.19.x
- 1.20.x - 1.20.x
- 1.21.x - 1.21.x
- 1.22.x
steps: steps:
- name: Fetch Repository - name: Fetch Repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Startup Coherence - name: Startup Coherence
run: | run: |
docker run -d -p 1408:1408 -p 30000:30000 ghcr.io/oracle/coherence-ce:22.06.5 docker run -d -p 1408:1408 -p 30000:30000 ghcr.io/oracle/coherence-ce:22.06.7
sleep 30 sleep 30
- name: Install Go - name: Install Go
uses: actions/setup-go@v5 uses: actions/setup-go@v5
with: with:
go-version: '${{ matrix.go-version }}' go-version: '${{ matrix.go-version }}'
- name: Run Test - name: Run Test
run: cd ./coherence && go clean -testcache && go test ./... -v run: cd ./coherence && go clean -testcache && go test ./... -v -race

View File

@@ -35,7 +35,7 @@ necessary for the client to operate correctly.
To start a Coherence cluster using Docker, issue the following: To start a Coherence cluster using Docker, issue the following:
```bash ```bash
docker run -d -p 1408:1408 ghcr.io/oracle/coherence-ce:22.06.5 docker run -d -p 1408:1408 ghcr.io/oracle/coherence-ce:22.06.7
``` ```
See the documentation [here](https://pkg.go.dev/github.com/oracle/coherence-go-client/coherence#hdr-Obtaining_a_Session) on connection options See the documentation [here](https://pkg.go.dev/github.com/oracle/coherence-go-client/coherence#hdr-Obtaining_a_Session) on connection options
@@ -52,9 +52,10 @@ You can use the following possibilities to create a storage:
// Initialize default config, to connect to localhost:1408 using plain text // Initialize default config, to connect to localhost:1408 using plain text
store, err := coherence.New() store, err := coherence.New()
// Initialize custom config to connect to a different host/port and use plaint ext. // Initialize custom config to connect to a different host/port and use plain text and expiry of 5 minutes.
store, err := coherence.New(coherence.Config{ store, err := coherence.New(coherence.Config{
Address: "my-host:myport", Address: "my-host:myport",
Expiration: time.Duration(300) * time.Second, // 5 minutes
}) })
// Initialize to connect with TLS enabled with your own tls.Config // Initialize to connect with TLS enabled with your own tls.Config
@@ -66,13 +67,38 @@ store, err := coherence.New(coherence.Config{
}) })
``` ```
> Note: If you create two stores using `coherence.New()` they will effectivity be idential. > Note: If you create two stores using `coherence.New()` they will effectivity be identical.
> If you wish to have two separate stores, then you can use: > If you wish to have two separate stores, then you can use:
> ```go > ```go
> store1, err := coherence.New(Config{ScopeName: "scope1"}) > store1, err := coherence.New(Config{ScopeName: "scope1"})
> store2, err := coherence.New(Config{ScopeName: "scope2"}) > store2, err := coherence.New(Config{ScopeName: "scope2"})
> ``` > ```
**Near Caches**
The latest version of the Coherence Go client introduces near cache support
to cache frequently accessed data in the Go client to avoid sending requests across the network.
This is particularly useful if you are using sticky sessions via a LBR as this will cache
the session in the Go process and the `Get()` operations will be much quicker.
When the session is expired on the server it will automatically be removed from the near cache.
To enable this for you session, you can set the `NearCacheTimeout` to a duration less than the expiry.
```go
// Initialize default config, to connect to localhost:1408 using plain text
store, err := coherence.New()
// Use plain text with default expiry of 5 minutes, and a near cache expiry of 2 minutes
store, err := coherence.New(coherence.Config{
Address: "my-host:myport",
Expiration: time.Duration(300) * time.Second, // 5 minutes
NearCacheTimeout: time.Duration(120) * time.Second, // 2 minutes
})
```
> Note: You must ensure your near cache timeout is less that the session timeout.
### Config ### Config
```go ```go
@@ -92,6 +118,11 @@ type Config struct {
// TLSConfig specifies tls.Config to use when connecting, if nil then plain text is used // TLSConfig specifies tls.Config to use when connecting, if nil then plain text is used
TLSConfig *tls.Config TLSConfig *tls.Config
// NearCacheTimeout defines the timeout for a near cache. Is this is set, then a near cache
// with the timeout is created. Note: this must be less than the session timeout or any timeout you specify
// when using Set().
NearCacheTimeout time.Duration
} }
``` ```
@@ -99,8 +130,9 @@ type Config struct {
```go ```go
var DefaultConfig = Config{ var DefaultConfig = Config{
Address: "localhost:1408", Address: "localhost:1408",
Timeout: time.Duration(30) * time.Millisecond, Timeout: time.Duration(120) * time.Seconds,
ScopeName: defaultScopeName, ScopeName: defaultScopeName,
Reset: false, Reset: false,
NearCacheTimeout: time.Duration(60) * time.Seconds,
} }
``` ```

View File

@@ -1,11 +1,12 @@
package coherence package coherence
/* /*
* Copyright © 2023, Oracle and/or its affiliates. * Copyright © 2023, 2024 Oracle and/or its affiliates.
*/ */
import ( import (
"context" "context"
"crypto/tls" "crypto/tls"
"fmt"
coh "github.com/oracle/coherence-go-client/coherence" coh "github.com/oracle/coherence-go-client/coherence"
"time" "time"
) )
@@ -39,6 +40,11 @@ type Config struct {
// TLSConfig specifies tls.Config to use when connecting, if nil then plain text is used // TLSConfig specifies tls.Config to use when connecting, if nil then plain text is used
TLSConfig *tls.Config TLSConfig *tls.Config
// NearCacheTimeout defines the timeout for a near cache. Is this is set, then a near cache
// with the timeout is created. Note: this must be less than the session timeout or any timeout you specify
// when using Set().
NearCacheTimeout time.Duration
} }
// DefaultConfig defines default options. // DefaultConfig defines default options.
@@ -51,9 +57,10 @@ var DefaultConfig = Config{
// New returns a new [Storage] given a [Config]. // New returns a new [Storage] given a [Config].
func New(config ...Config) (*Storage, error) { func New(config ...Config) (*Storage, error) {
cfg := setupConfig(config...) var (
cfg = setupConfig(config...)
options := make([]func(session *coh.SessionOptions), 0) options = make([]func(session *coh.SessionOptions), 0)
)
// apply any config values as Coherence options // apply any config values as Coherence options
options = append(options, coh.WithAddress(cfg.Address)) options = append(options, coh.WithAddress(cfg.Address))
@@ -66,13 +73,21 @@ func New(config ...Config) (*Storage, error) {
options = append(options, coh.WithRequestTimeout(cfg.Timeout)) options = append(options, coh.WithRequestTimeout(cfg.Timeout))
// validate near cache options
if cfg.NearCacheTimeout != 0 {
if cfg.NearCacheTimeout > cfg.Timeout {
return nil, fmt.Errorf("you cannot set the near cache timeout (%v) to less than session timeout (%v)",
cfg.NearCacheTimeout, cfg.Timeout)
}
}
// create the Coherence session // create the Coherence session
session, err := coh.NewSession(context.Background(), options...) session, err := coh.NewSession(context.Background(), options...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
store, err := newCoherenceStorage(session, cfg.ScopeName) store, err := newCoherenceStorage(session, cfg.ScopeName, cfg.NearCacheTimeout)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -109,8 +124,16 @@ func setupConfig(config ...Config) Config {
} }
// newCoherenceStorage returns a new Coherence [Storage]. // newCoherenceStorage returns a new Coherence [Storage].
func newCoherenceStorage(session *coh.Session, cacheName string) (*Storage, error) { func newCoherenceStorage(session *coh.Session, cacheName string, nearCacheTimeout time.Duration) (*Storage, error) {
nc, err := coh.GetNamedCache[string, []byte](session, "fiber$"+cacheName) cacheOptions := make([]func(cache *coh.CacheOptions), 0)
// configure a near cache if the nearCacheTimeout is set
if nearCacheTimeout != 0 {
nearCacheOptions := coh.NearCacheOptions{TTL: nearCacheTimeout}
cacheOptions = append(cacheOptions, coh.WithNearCache(&nearCacheOptions))
}
nc, err := coh.GetNamedCache[string, []byte](session, "fiber$"+cacheName, cacheOptions...)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -1,7 +1,7 @@
package coherence package coherence
/* /*
* Copyright © 2023, Oracle and/or its affiliates. * Copyright © 2023, 2024 Oracle and/or its affiliates.
*/ */
import ( import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
@@ -22,7 +22,8 @@ var testStore *Storage
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
testStore, _ = New(Config{ testStore, _ = New(Config{
Reset: true, Reset: true,
NearCacheTimeout: time.Duration(20) * time.Second,
}) })
code := m.Run() code := m.Run()
@@ -34,8 +35,9 @@ func TestMain(m *testing.M) {
// newTestStore returns a new Coherence Store and ensures it is reset. // newTestStore returns a new Coherence Store and ensures it is reset.
func newTestStore(t testing.TB, config ...Config) (*Storage, error) { func newTestStore(t testing.TB, config ...Config) (*Storage, error) {
t.Helper() t.Helper()
var err error
testStore, err := New(config...) testStore, err = New(config...)
require.NoError(t, err) require.NoError(t, err)
err = testStore.Reset() err = testStore.Reset()

View File

@@ -3,7 +3,7 @@ module github.com/gofiber/storage/coherence
go 1.19 go 1.19
require ( require (
github.com/oracle/coherence-go-client v1.0.3 github.com/oracle/coherence-go-client v1.1.0
github.com/stretchr/testify v1.9.0 github.com/stretchr/testify v1.9.0
) )

View File

@@ -12,8 +12,8 @@ github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/oracle/coherence-go-client v1.0.3 h1:P8Rzgo21BAaJsKzemzMCFY9I27PdKBpr5ZqrHhZ7zPg= github.com/oracle/coherence-go-client v1.1.0 h1:Hra1R6xcszzHfTbhzsfLkI5xn2/kxoLBHagvE+2jiUU=
github.com/oracle/coherence-go-client v1.0.3/go.mod h1:IAk8etsxzhUK6YaGzbInR1LYlh+1fiG85bGpyvzY0QY= github.com/oracle/coherence-go-client v1.1.0/go.mod h1:IAk8etsxzhUK6YaGzbInR1LYlh+1fiG85bGpyvzY0QY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=