mirror of
https://github.com/gofiber/storage.git
synced 2025-10-06 00:57:38 +08:00
Update Coherence driver to add near cache option
This commit is contained in:
5
.github/workflows/test-coherence.yml
vendored
5
.github/workflows/test-coherence.yml
vendored
@@ -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
|
||||||
|
@@ -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,
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
|
@@ -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()
|
||||||
|
@@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -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=
|
||||||
|
Reference in New Issue
Block a user