Skip to content

Commit 7eb07d4

Browse files
committed
Implement a caching client pool to save on the initial handshake.
1 parent c6a3042 commit 7eb07d4

File tree

3 files changed

+90
-1
lines changed

3 files changed

+90
-1
lines changed

go.mod

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ require (
66
github.com/eyetowers/gowsdl v0.0.0-20220927164314-b28274961972
77
github.com/golangci/golangci-lint v1.49.0
88
github.com/ivanpirog/coloredcobra v1.0.1
9+
github.com/jellydator/ttlcache/v3 v3.0.0
910
github.com/motemen/go-loghttp v0.0.0-20170804080138-974ac5ceac27
1011
github.com/spf13/cobra v1.5.0
12+
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4
1113
)
1214

1315
require (
@@ -165,7 +167,6 @@ require (
165167
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
166168
golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect
167169
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
168-
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
169170
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
170171
golang.org/x/text v0.3.7 // indirect
171172
golang.org/x/tools v0.1.12 // indirect

go.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH
294294
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
295295
github.com/ivanpirog/coloredcobra v1.0.1 h1:aURSdEmlR90/tSiWS0dMjdwOvCVUeYLfltLfbgNxrN4=
296296
github.com/ivanpirog/coloredcobra v1.0.1/go.mod h1:iho4nEKcnwZFiniGSdcgdvRgZNjxm+h20acv8vqmN6Q=
297+
github.com/jellydator/ttlcache/v3 v3.0.0 h1:zmFhqrB/4sKiEiJHhtseJsNRE32IMVmJSs4++4gaQO4=
298+
github.com/jellydator/ttlcache/v3 v3.0.0/go.mod h1:WwTaEmcXQ3MTjOm4bsZoDFiCu/hMvNWLO1w67RXz6h4=
297299
github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM=
298300
github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
299301
github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs=
@@ -565,6 +567,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
565567
go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk=
566568
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
567569
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
570+
go.uber.org/goleak v1.1.10 h1:z+mqJhf6ss6BSfSM671tgKyZBFPTTJM+HLxnhPC3wu0=
568571
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
569572
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
570573
go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U=
@@ -606,6 +609,7 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu
606609
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
607610
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
608611
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
612+
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug=
609613
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
610614
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
611615
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=

pkg/gonvif/pool.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package gonvif
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
"time"
7+
8+
"github.com/jellydator/ttlcache/v3"
9+
"golang.org/x/sync/singleflight"
10+
)
11+
12+
type ClientPool interface {
13+
GetClient(baseURL, username, password string, verbose bool) (Client, error)
14+
}
15+
16+
func NewPool(ttl time.Duration) ClientPool {
17+
cache := ttlcache.New(
18+
ttlcache.WithTTL[key, Client](ttl),
19+
)
20+
go cache.Start()
21+
22+
return &pool{
23+
cache: cache,
24+
}
25+
}
26+
27+
type key struct {
28+
baseURL string
29+
username string
30+
password string
31+
verbose bool
32+
}
33+
34+
type pool struct {
35+
cache *ttlcache.Cache[key, Client]
36+
group singleflight.Group
37+
}
38+
39+
func (p *pool) GetClient(baseURL, username, password string, verbose bool) (Client, error) {
40+
k := key{
41+
baseURL: baseURL,
42+
username: username,
43+
password: password,
44+
verbose: verbose,
45+
}
46+
item := p.cache.Get(k)
47+
48+
if item != nil {
49+
return item.Value(), nil
50+
}
51+
52+
return p.newClientSynced(k)
53+
}
54+
55+
func (p *pool) newClientSynced(k key) (Client, error) {
56+
v, err, _ := p.group.Do(k.String(), func() (any, error) {
57+
return p.newClient(k)
58+
})
59+
if err != nil {
60+
return nil, err
61+
}
62+
return v.(Client), nil
63+
}
64+
65+
func (p *pool) newClient(k key) (Client, error) {
66+
client, err := New(k.baseURL, k.username, k.password, k.verbose)
67+
if err != nil {
68+
p.cache.Set(k, client, ttlcache.DefaultTTL)
69+
}
70+
return client, err
71+
}
72+
73+
var escaper = strings.NewReplacer(
74+
"\\", "\\\\",
75+
"|", "\\|",
76+
)
77+
78+
func (k key) String() string {
79+
return fmt.Sprintf("%s|%s|%s|%v",
80+
escaper.Replace(k.baseURL),
81+
escaper.Replace(k.password),
82+
escaper.Replace(k.username),
83+
k.verbose)
84+
}

0 commit comments

Comments
 (0)