Skip to content
This repository was archived by the owner on Feb 12, 2024. It is now read-only.

Commit d17a9fa

Browse files
DayFanavdva
authored andcommitted
added consul wrapper (#39)
* added consul wrapper * rename test function * tmp. added verbose flag * - hiding error removed from the constructor - added interface for update TTL - added dummy consul client * removed verbose flag from test runner * update change log
1 parent 2ac2f2e commit d17a9fa

10 files changed

Lines changed: 230 additions & 4 deletions

File tree

.travis.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
language: go
22
go:
33
- 1.11.2
4-
4+
55
script:
66
- go test ./...
77

@@ -10,8 +10,13 @@ services:
1010
- postgresql
1111
- rabbitmq
1212

13+
env:
14+
- CONSUL_VERSION=1.4.2
15+
1316
before_install:
1417
- mysql -e 'CREATE DATABASE IF NOT EXISTS db_test;'
18+
- curl -sLo consul.zip https://releases.hashicorp.com/consul/${CONSUL_VERSION}/consul_${CONSUL_VERSION}_linux_amd64.zip
19+
- unzip consul.zip -d $HOME/bin
1520

1621
before_script:
1722
- psql -c 'CREATE DATABASE db_test;' -U postgres

CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Changelog
22

3+
## [2.4.0] - 2019-02-11
4+
### Add
5+
- Consul client
36

47
## [2.3.0] - 2019-02-08
58
### Change
@@ -24,7 +27,7 @@
2427

2528
## [1.1.1] - 2018-11-23
2629
- add amqp-kit close method
27-
- fix amqp-kit data race serve() method
30+
- fix amqp-kit data race serve() method
2831

2932
## [1.0.0] - 2018-11-13
3033
### Added

README.md

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
10. [json_formatter.go](#formatter)
1616
11. [messagebus.go](#messagebus)
1717
12. [amqp-kit](#amqp-kit)
18+
13. [consul](#consul)
1819

1920
<a name="debug" />
2021

@@ -146,4 +147,11 @@ func main() {
146147

147148
AMQP wrapper in go-kit style
148149

149-
see test example for use: [publisher_test.go](https://github.com/space307/go-utils/blob/master/amqp-kit/publisher_test.go)
150+
see test example for use: [publisher_test.go](https://github.com/space307/go-utils/blob/master/amqp-kit/publisher_test.go)
151+
152+
153+
<a name="consul" />
154+
155+
### 13. consul
156+
157+
Consul package contains a wrapper for Consul API for simplicity registration a service in the local agent.

config/config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
app:
2+
opt1: opt1
3+
opt2: 2
4+
app2:
5+
opt1: 2
6+
opt2: opt2

consul/consul.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package consul
2+
3+
import (
4+
"github.com/hashicorp/consul/api"
5+
)
6+
7+
// TTLUpdater is an interface to update the TTL of service
8+
type TTLUpdater interface {
9+
UpdateTTL(checkID, status, output string) error
10+
}
11+
12+
// Client provides a client to functions of Consul API
13+
// for one serivce
14+
type Client struct {
15+
clientAPI *api.Client
16+
srvID string
17+
}
18+
19+
// NewDefaultClient is the most default constructor for Consul agent for one serivce.
20+
// It initializes HTTP client for a local agent and register service on it.
21+
// srvName sets for ID, Name and CheckID of service.
22+
func NewDefaultClient(srvName, localIP string, svcPort int, checkTTL string) (*Client, error) {
23+
var err error
24+
25+
client := &Client{srvID: srvName}
26+
27+
client.clientAPI, err = api.NewClient(api.DefaultConfig())
28+
if err != nil {
29+
return nil, err
30+
}
31+
32+
srvRegInfo := &api.AgentServiceRegistration{
33+
ID: srvName,
34+
Name: srvName,
35+
Address: localIP,
36+
Port: svcPort,
37+
Check: &api.AgentServiceCheck{
38+
CheckID: srvName,
39+
TTL: checkTTL,
40+
},
41+
}
42+
43+
if err = client.Register(srvRegInfo); err != nil {
44+
return nil, err
45+
}
46+
47+
return client, nil
48+
}
49+
50+
// Agent returns a handle to the agent endpoints
51+
func (c *Client) Agent() *api.Agent {
52+
return c.clientAPI.Agent()
53+
}
54+
55+
// IsReachable check whether we can reach the agent
56+
func (c *Client) IsReachable() bool {
57+
_, err := c.clientAPI.Agent().Self()
58+
59+
return err == nil
60+
}
61+
62+
// Register is used to register a new service with given ID
63+
func (c *Client) Register(srvInfo *api.AgentServiceRegistration) error {
64+
c.srvID = srvInfo.ID
65+
return c.clientAPI.Agent().ServiceRegister(srvInfo)
66+
}
67+
68+
// Deregister is used to deregister a service
69+
func (c *Client) Deregister() error {
70+
return c.clientAPI.Agent().ServiceDeregister(c.srvID)
71+
}
72+
73+
// PassingTTL is used to update the TTL of a default check
74+
// with status 'passing'
75+
func (c *Client) PassingTTL(output string) error {
76+
return c.UpdateTTL(c.srvID, api.HealthPassing, output)
77+
}
78+
79+
// CriticalTTL is used to update the TTL of a default check
80+
// with status 'critical'
81+
func (c *Client) CriticalTTL(output string) error {
82+
return c.UpdateTTL(c.srvID, api.HealthCritical, output)
83+
}
84+
85+
// WarningTTL is used to update the TTL of a default check
86+
// with status 'warning'
87+
func (c *Client) WarningTTL(output string) error {
88+
return c.UpdateTTL(c.srvID, api.HealthWarning, output)
89+
}
90+
91+
// UpdateTTL is used to update the TTL of a check
92+
func (c *Client) UpdateTTL(checkID, status, output string) error {
93+
return c.clientAPI.Agent().UpdateTTL(checkID, output, status)
94+
}

consul/consul_test.go

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package consul
2+
3+
import (
4+
"testing"
5+
6+
"github.com/hashicorp/consul/testutil"
7+
"github.com/stretchr/testify/assert"
8+
)
9+
10+
func TestConsulWrapper(t *testing.T) {
11+
srv1, err := testutil.NewTestServerConfig(func(c *testutil.TestServerConfig) {
12+
c.Ports.HTTP = 8500
13+
})
14+
if err != nil {
15+
t.Fatal(err)
16+
}
17+
18+
serviceName := "testService"
19+
client, err := NewDefaultClient(serviceName, `127.0.0.1`, 8080, "10m")
20+
assert.NoError(t, err)
21+
assert.Implements(t, (*TTLUpdater)(nil), client)
22+
23+
consulAgent := client.Agent()
24+
25+
assert.NoError(t, client.PassingTTL(testutil.HealthPassing))
26+
27+
status, info, err := consulAgent.AgentHealthServiceByID(serviceName)
28+
assert.NoError(t, err)
29+
assert.Equal(t, testutil.HealthPassing, info.Checks[0].Output)
30+
assert.Equal(t, testutil.HealthPassing, status)
31+
32+
assert.NoError(t, client.WarningTTL(testutil.HealthWarning))
33+
34+
status, info, err = consulAgent.AgentHealthServiceByID(serviceName)
35+
assert.NoError(t, err)
36+
assert.Equal(t, testutil.HealthWarning, info.Checks[0].Output)
37+
assert.Equal(t, testutil.HealthWarning, status)
38+
39+
assert.NoError(t, client.CriticalTTL(testutil.HealthCritical))
40+
41+
status, info, err = consulAgent.AgentHealthServiceByID(serviceName)
42+
assert.NoError(t, err)
43+
assert.Equal(t, testutil.HealthCritical, info.Checks[0].Output)
44+
assert.Equal(t, testutil.HealthCritical, status)
45+
46+
assert.NoError(t, client.UpdateTTL(serviceName, testutil.HealthPassing, testutil.HealthPassing))
47+
48+
status, info, err = consulAgent.AgentHealthServiceByID(serviceName)
49+
assert.NoError(t, err)
50+
assert.Equal(t, testutil.HealthPassing, info.Checks[0].Output)
51+
assert.Equal(t, testutil.HealthPassing, status)
52+
53+
assert.NoError(t, client.Deregister())
54+
55+
status, _, _ = consulAgent.AgentHealthServiceByID(serviceName)
56+
assert.Equal(t, testutil.HealthCritical, status)
57+
58+
srv1.Stop()
59+
60+
assert.False(t, client.IsReachable())
61+
62+
client, err = NewDefaultClient(serviceName, `127.0.0.1`, 8080, "10m")
63+
assert.Error(t, err)
64+
assert.Nil(t, client)
65+
}

consul/dummy.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package consul
2+
3+
// Dummy is struct for implements TTLUpdater interface
4+
type Dummy struct{}
5+
6+
// NewDummyClient return initialized struct Dummy
7+
func NewDummyClient() *Dummy {
8+
return &Dummy{}
9+
}
10+
11+
// UpdateTTL implements TTLUpdater interface.
12+
// Return always nil.
13+
func (c *Dummy) UpdateTTL(checkID, status, output string) error {
14+
return nil
15+
}

consul/dummy_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package consul
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestDummyConsulWrapper(t *testing.T) {
10+
client := NewDummyClient()
11+
assert.Implements(t, (*TTLUpdater)(nil), client)
12+
13+
assert.NoError(t, client.UpdateTTL("", "", ""))
14+
}

go.mod

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ require (
55
github.com/Azure/azure-sdk-for-go v25.0.0+incompatible // indirect
66
github.com/Azure/go-autorest v11.4.0+incompatible // indirect
77
github.com/SAP/go-hdb v0.13.2 // indirect
8+
github.com/SermoDigital/jose v0.9.2-0.20161205224733-f6df55f235c2 // indirect
89
github.com/VividCortex/gohistogram v1.0.0 // indirect
910
github.com/aliyun/alibaba-cloud-sdk-go v0.0.0-20190203032130-408505a5fba8 // indirect
1011
github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61 // indirect
@@ -46,15 +47,18 @@ require (
4647
github.com/gorilla/websocket v1.4.0 // indirect
4748
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0 // indirect
4849
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
49-
github.com/hashicorp/consul v1.4.2 // indirect
50+
github.com/hashicorp/consul v1.4.2
5051
github.com/hashicorp/go-gcp-common v0.0.0-20180425173946-763e39302965 // indirect
5152
github.com/hashicorp/go-hclog v0.0.0-20190109152822-4783caec6f2e // indirect
5253
github.com/hashicorp/go-plugin v0.0.0-20190129155509-362c99b11937 // indirect
5354
github.com/hashicorp/go-retryablehttp v0.5.2 // indirect
5455
github.com/hashicorp/go-rootcerts v1.0.0 // indirect
5556
github.com/hashicorp/go-sockaddr v1.0.1 // indirect
5657
github.com/hashicorp/go-version v1.1.0 // indirect
58+
github.com/hashicorp/hil v0.0.0-20190129155652-59d7c1fee952 // indirect
59+
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 // indirect
5760
github.com/hashicorp/nomad v0.8.7 // indirect
61+
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea // indirect
5862
github.com/hashicorp/serf v0.8.2 // indirect
5963
github.com/hashicorp/vault v1.0.2
6064
github.com/hashicorp/vault-plugin-auth-alicloud v0.0.0-20181109180636-f278a59ca3e8 // indirect

go.sum

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX
1212
github.com/Azure/go-autorest v11.4.0+incompatible h1:z3Yr6KYqs0nhSNwqGXEBpWK977hxVqsLv2n9PVYcixY=
1313
github.com/Azure/go-autorest v11.4.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
1414
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
15+
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895 h1:dmc/C8bpE5VkQn65PNbbyACDC8xw8Hpp/NEurdPmQDQ=
1516
github.com/DataDog/datadog-go v0.0.0-20180822151419-281ae9f2d895/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
1617
github.com/Jeffail/gabs v1.1.1 h1:V0uzR08Hj22EX8+8QMhyI9sX2hwRu+/RJhJUmnwda/E=
1718
github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc=
@@ -28,6 +29,7 @@ github.com/RoaringBitmap/roaring v0.4.16/go.mod h1:8khRDP4HmeXns4xIj9oGrKSz7XTQi
2829
github.com/SAP/go-hdb v0.13.1/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0=
2930
github.com/SAP/go-hdb v0.13.2 h1:19+oZb2RGKCJpSZjFN/dcdOuSACSWGJlinHwgVyvUnM=
3031
github.com/SAP/go-hdb v0.13.2/go.mod h1:etBT+FAi1t5k3K3tf5vQTnosgYmhDkRi8jEnQqCnxF0=
32+
github.com/SermoDigital/jose v0.9.1/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
3133
github.com/SermoDigital/jose v0.9.2-0.20161205224733-f6df55f235c2 h1:koK7z0nSsRiRiBWwa+E714Puh+DO+ZRdIyAXiXzL+lg=
3234
github.com/SermoDigital/jose v0.9.2-0.20161205224733-f6df55f235c2/go.mod h1:ARgCUhI1MHQH+ONky/PAtmVHQrP5JlGY0F3poXOp/fA=
3335
github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE=
@@ -67,6 +69,7 @@ github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCS
6769
github.com/blakesmith/ar v0.0.0-20150311145944-8bd4349a67f2/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
6870
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY=
6971
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4=
72+
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
7073
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
7174
github.com/boombuler/barcode v1.0.0 h1:s1TvRnXwL2xJRaccrdcBQMZxq6X7DvsMogtmJeHDdrc=
7275
github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
@@ -86,7 +89,9 @@ github.com/centrify/cloud-golang-sdk v0.0.0-20180119173102-7c97cc6fde16/go.mod h
8689
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
8790
github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0 h1:CWU8piLyqoi9qXEUwzOh5KFKGgmSU5ZhktJyYcq6ryQ=
8891
github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0/go.mod h1:5d8DqS60xkj9k3aXfL3+mXBH0DPYO0FQjcKosxl+b/Q=
92+
github.com/circonus-labs/circonus-gometrics v2.2.5+incompatible h1:KsuY3ogbxgVv3FNhbLUoT+SE9znoWEUIuChSIT4HukI=
8993
github.com/circonus-labs/circonus-gometrics v2.2.5+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag=
94+
github.com/circonus-labs/circonusllhist v0.1.3 h1:TJH+oke8D16535+jHExHj4nQvzlZrj7ug5D7I/orNUA=
9095
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I=
9196
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
9297
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w=
@@ -271,15 +276,21 @@ github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCO
271276
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
272277
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
273278
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
279+
github.com/hashicorp/hil v0.0.0-20190129155652-59d7c1fee952 h1:2touDRqIeu/4eKrg7WHcH+WZwpW97r0NKOHDixzroJg=
280+
github.com/hashicorp/hil v0.0.0-20190129155652-59d7c1fee952/go.mod h1:n2TSygSNwsLJ76m8qFXTSc7beTb+auJxYdqrnoqwZWE=
274281
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
275282
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
276283
github.com/hashicorp/memberlist v0.1.0/go.mod h1:ncdBp14cuox2iFOq3kDiquKU6fqsTBc3W6JvZwjxxsE=
277284
github.com/hashicorp/memberlist v0.1.3 h1:EmmoJme1matNzb+hMpDuR/0sbJSUisxyqBGG676r31M=
278285
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
286+
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69 h1:lc3c72qGlIMDqQpQH82Y4vaglRMMFdJbziYWriR4UcE=
287+
github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q=
279288
github.com/hashicorp/nomad v0.8.7 h1:jOrmJdAoWcyhKgoG4OxHQhG5SU6RniXFjfwKg6a492U=
280289
github.com/hashicorp/nomad v0.8.7/go.mod h1:WRaKjdO1G2iqi86TvTjIYtKTyxg4pl7NLr9InxtWaI0=
281290
github.com/hashicorp/raft v1.0.0 h1:htBVktAOtGs4Le5Z7K8SF5H2+oWsQFYVmOgH5loro7Y=
282291
github.com/hashicorp/raft v1.0.0/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI=
292+
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea h1:xykPFhrBAS2J0VBzVa5e80b5ZtYuNQtgXjN40qBZlD4=
293+
github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk=
283294
github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE=
284295
github.com/hashicorp/serf v0.8.2 h1:YZ7UKsJv+hKjqGVUUbtE3HNj79Eln2oQ75tniF6iPt0=
285296
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
@@ -526,6 +537,7 @@ github.com/testcontainers/testcontainer-go v0.0.0-20181115231424-8e868ca12c0f/go
526537
github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE=
527538
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5 h1:LnC5Kc/wtumK+WB441p7ynQJzVuNRJiqddSIE3IlSEQ=
528539
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
540+
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926 h1:G3dpKMzFDjgEh2q1Z7zUUtKa8ViPtH+ocF0bE0g00O8=
529541
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
530542
github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II=
531543
github.com/uber-go/atomic v1.3.2 h1:Azu9lPBWRNKzYXSIwRfgRuDuS0YKsK4NFhiQv98gkxo=

0 commit comments

Comments
 (0)