Skip to content

Commit

Permalink
Implement a caching client pool to save on the initial handshake.
Browse files Browse the repository at this point in the history
  • Loading branch information
osery committed Sep 29, 2022
1 parent c6a3042 commit 7eb07d4
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ require (
github.com/eyetowers/gowsdl v0.0.0-20220927164314-b28274961972
github.com/golangci/golangci-lint v1.49.0
github.com/ivanpirog/coloredcobra v1.0.1
github.com/jellydator/ttlcache/v3 v3.0.0
github.com/motemen/go-loghttp v0.0.0-20170804080138-974ac5ceac27
github.com/spf13/cobra v1.5.0
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
)

require (
Expand Down Expand Up @@ -165,7 +167,6 @@ require (
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.12 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/ivanpirog/coloredcobra v1.0.1 h1:aURSdEmlR90/tSiWS0dMjdwOvCVUeYLfltLfbgNxrN4=
github.com/ivanpirog/coloredcobra v1.0.1/go.mod h1:iho4nEKcnwZFiniGSdcgdvRgZNjxm+h20acv8vqmN6Q=
github.com/jellydator/ttlcache/v3 v3.0.0 h1:zmFhqrB/4sKiEiJHhtseJsNRE32IMVmJSs4++4gaQO4=
github.com/jellydator/ttlcache/v3 v3.0.0/go.mod h1:WwTaEmcXQ3MTjOm4bsZoDFiCu/hMvNWLO1w67RXz6h4=
github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM=
github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
Expand Down Expand Up @@ -565,6 +567,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
Expand Down Expand Up @@ -606,6 +609,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
Expand Down
84 changes: 84 additions & 0 deletions pkg/gonvif/pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package gonvif

import (
"fmt"
"strings"
"time"

"github.com/jellydator/ttlcache/v3"
"golang.org/x/sync/singleflight"
)

type ClientPool interface {
GetClient(baseURL, username, password string, verbose bool) (Client, error)
}

func NewPool(ttl time.Duration) ClientPool {
cache := ttlcache.New(
ttlcache.WithTTL[key, Client](ttl),
)
go cache.Start()

return &pool{
cache: cache,
}
}

type key struct {
baseURL string
username string
password string
verbose bool
}

type pool struct {
cache *ttlcache.Cache[key, Client]
group singleflight.Group
}

func (p *pool) GetClient(baseURL, username, password string, verbose bool) (Client, error) {
k := key{
baseURL: baseURL,
username: username,
password: password,
verbose: verbose,
}
item := p.cache.Get(k)

if item != nil {
return item.Value(), nil
}

return p.newClientSynced(k)
}

func (p *pool) newClientSynced(k key) (Client, error) {
v, err, _ := p.group.Do(k.String(), func() (any, error) {
return p.newClient(k)
})
if err != nil {
return nil, err
}
return v.(Client), nil
}

func (p *pool) newClient(k key) (Client, error) {
client, err := New(k.baseURL, k.username, k.password, k.verbose)
if err != nil {
p.cache.Set(k, client, ttlcache.DefaultTTL)
}
return client, err
}

var escaper = strings.NewReplacer(
"\\", "\\\\",
"|", "\\|",
)

func (k key) String() string {
return fmt.Sprintf("%s|%s|%s|%v",
escaper.Replace(k.baseURL),
escaper.Replace(k.password),
escaper.Replace(k.username),
k.verbose)
}

0 comments on commit 7eb07d4

Please sign in to comment.