mirror of
https://github.com/gogf/gf.git
synced 2025-04-05 03:05:05 +08:00
feat(contrib/registry/etcd): add retry machenism when keepalive lease expires (#4035)
This commit is contained in:
parent
e3e82c7351
commit
ac53170884
84
.github/workflows/ci-main.sh
vendored
84
.github/workflows/ci-main.sh
vendored
@ -1,5 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Define the latest Go version requirement
|
||||
LATEST_GO_VERSION="1.23"
|
||||
|
||||
coverage=$1
|
||||
|
||||
# find all path that contains go.mod.
|
||||
@ -13,82 +16,39 @@ for file in `find . -name go.mod`; do
|
||||
continue 1
|
||||
fi
|
||||
|
||||
if [[ $file =~ "/testdata/" ]]; then
|
||||
echo "ignore testdata path $file"
|
||||
continue 1
|
||||
fi
|
||||
|
||||
# package kuhecm was moved to sub ci procedure.
|
||||
if [ "kubecm" = $(basename $dirpath) ]; then
|
||||
continue 1
|
||||
fi
|
||||
|
||||
# package consul needs golang >= v1.19
|
||||
if [ "consul" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -qE "go1.[2-9][0-9]"; then
|
||||
echo "ignore consul as go version: $(go version)"
|
||||
continue 1
|
||||
# Check if it's a contrib directory or example directory
|
||||
if [[ $dirpath =~ "/contrib/" ]] || [ "example" = $(basename $dirpath) ]; then
|
||||
# Check if go version meets the requirement
|
||||
if ! go version | grep -qE "go${LATEST_GO_VERSION}"; then
|
||||
echo "ignore path $dirpath as go version is not ${LATEST_GO_VERSION}: $(go version)"
|
||||
continue 1
|
||||
fi
|
||||
# If it's example directory, only build without tests
|
||||
if [ "example" = $(basename $dirpath) ]; then
|
||||
echo "the example directory only needs to be built, not unit tests and coverage tests."
|
||||
cd $dirpath
|
||||
go mod tidy
|
||||
go build ./...
|
||||
cd -
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# package etcd needs golang >= v1.19
|
||||
if [ "etcd" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -qE "go1.[2-9][0-9]"; then
|
||||
echo "ignore etcd as go version: $(go version)"
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# package polaris needs golang >= v1.19
|
||||
if [ "polaris" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -qE "go1.[2-9][0-9]"; then
|
||||
echo "ignore polaris as go version: $(go version)"
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# package example needs golang >= v1.20
|
||||
if [ "example" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -qE "go1.[2-9][1-9]"; then
|
||||
echo "ignore example as go version: $(go version)"
|
||||
continue 1
|
||||
fi
|
||||
echo "the example directory only needs to be built, not unit tests and coverage tests."
|
||||
cd $dirpath
|
||||
go mod tidy
|
||||
go build ./...
|
||||
cd -
|
||||
if [[ $file =~ "/testdata/" ]]; then
|
||||
echo "ignore testdata path $file"
|
||||
continue 1
|
||||
fi
|
||||
|
||||
# package otlpgrpc needs golang >= v1.20
|
||||
if [ "otlpgrpc" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -qE "go1.[2-9][0-9]"; then
|
||||
echo "ignore otlpgrpc as go version: $(go version)"
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# package otlphttp needs golang >= v1.20
|
||||
if [ "otlphttp" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -qE "go1.[2-9][0-9]"; then
|
||||
echo "ignore otlphttp as go version: $(go version)"
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# package otelmetric needs golang >= v1.20
|
||||
if [ "otelmetric" = $(basename $dirpath) ]; then
|
||||
if ! go version|grep -qE "go1.[2-9][0-9]"; then
|
||||
echo "ignore otelmetric as go version: $(go version)"
|
||||
continue 1
|
||||
fi
|
||||
fi
|
||||
|
||||
cd $dirpath
|
||||
go mod tidy
|
||||
go build ./...
|
||||
# check coverage
|
||||
|
||||
# test with coverage
|
||||
if [ "${coverage}" = "coverage" ]; then
|
||||
go test ./... -race -coverprofile=coverage.out -covermode=atomic -coverpkg=./...,github.com/gogf/gf/... || exit 1
|
||||
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/container/gpool"
|
||||
"github.com/gogf/gf/v2/container/gtype"
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/test/gtest"
|
||||
)
|
||||
@ -20,10 +21,10 @@ var nf gpool.NewFunc = func() (i interface{}, e error) {
|
||||
return "hello", nil
|
||||
}
|
||||
|
||||
var assertIndex int = 0
|
||||
var assertIndex = gtype.NewInt(0)
|
||||
|
||||
var ef gpool.ExpireFunc = func(i interface{}) {
|
||||
assertIndex++
|
||||
assertIndex.Add(1)
|
||||
gtest.Assert(i, assertIndex)
|
||||
}
|
||||
|
||||
@ -83,7 +84,7 @@ func Test_Gpool(t *testing.T) {
|
||||
v2, err2 = p2.Get()
|
||||
t.Assert(err2, nil)
|
||||
t.Assert(v2, 0)
|
||||
assertIndex = 0
|
||||
assertIndex.Set(0)
|
||||
p2.Close()
|
||||
time.Sleep(3 * time.Second)
|
||||
t.AssertNE(p2.Put(1), nil)
|
||||
|
@ -295,7 +295,7 @@ func Test_DB_Tables(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err := db.Tables(ctx)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
|
@ -34,7 +34,7 @@ func TestTables(t *testing.T) {
|
||||
}
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.Tables(ctx)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
@ -48,7 +48,7 @@ func TestTables(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err = dblink.Tables(ctx)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
for j := 0; j < len(result); j++ {
|
||||
@ -95,7 +95,7 @@ func TestTableFields(t *testing.T) {
|
||||
gtest.AssertNE(err, nil)
|
||||
|
||||
res, err := db.TableFields(ctx, tables)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
@ -205,7 +205,7 @@ func TestModelInsert(t *testing.T) {
|
||||
}
|
||||
// _, err := db.Schema(TestDBName).Model(table).Data(data).Insert()
|
||||
_, err := db.Model(table).Insert(&data)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
})
|
||||
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
@ -220,7 +220,7 @@ func TestModelInsert(t *testing.T) {
|
||||
}
|
||||
// _, err := db.Schema(TestDBName).Model(table).Data(data).Insert()
|
||||
_, err := db.Model(table).Data(&data).Insert()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
@ -238,7 +238,7 @@ func TestDBInsert(t *testing.T) {
|
||||
"UPDATED_TIME": gtime.Now(),
|
||||
}
|
||||
_, err := db.Insert(ctx, table, &data)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -173,7 +173,7 @@ func createInitTable(table ...string) (name string) {
|
||||
})
|
||||
}
|
||||
result, err := db.Schema(TestDBName).Insert(context.Background(), name, array.Slice())
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
n, e := result.RowsAffected()
|
||||
gtest.Assert(e, nil)
|
||||
|
@ -29,7 +29,7 @@ func TestTables(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err := db.Tables(context.Background())
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
@ -43,7 +43,7 @@ func TestTables(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err = db.Tables(context.Background(), "test")
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
for j := 0; j < len(result); j++ {
|
||||
@ -74,7 +74,7 @@ func TestTableFields(t *testing.T) {
|
||||
}
|
||||
|
||||
res, err := db.TableFields(context.Background(), "t_user")
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
@ -89,7 +89,7 @@ func TestTableFields(t *testing.T) {
|
||||
}
|
||||
|
||||
res, err = db.TableFields(context.Background(), "t_user", "test")
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
@ -124,7 +124,7 @@ func TestDoInsert(t *testing.T) {
|
||||
"create_time": gtime.Now(),
|
||||
}
|
||||
_, err := db.Insert(context.Background(), "t_user", data)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
})
|
||||
|
||||
|
@ -61,7 +61,8 @@ func init() {
|
||||
|
||||
nodeErr := gdb.ConfigNode{
|
||||
Type: "mssql",
|
||||
Link: fmt.Sprintf("user id=%s;password=%s;server=%s;port=%s;database=%s;encrypt=disable",
|
||||
Link: fmt.Sprintf(
|
||||
"mssql:%s:%s@tcp(%s:%s)/%s?encrypt=disable",
|
||||
node.User, "node.Pass", node.Host, node.Port, node.Name),
|
||||
}
|
||||
|
||||
@ -130,7 +131,7 @@ func createInitTable(table ...string) (name string) {
|
||||
})
|
||||
}
|
||||
result, err := db.Insert(context.Background(), name, array.Slice())
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
n, e := result.RowsAffected()
|
||||
gtest.Assert(e, nil)
|
||||
|
@ -26,30 +26,32 @@ import (
|
||||
func Test_Page(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
// db.SetDebug(true)
|
||||
result, err := db.Model(table).Page(1, 2).Order("id").All()
|
||||
gtest.Assert(err, nil)
|
||||
fmt.Println("page:1--------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 1)
|
||||
gtest.Assert(result[1]["ID"], 2)
|
||||
gtest.C(t, func(t *gtest.T) {
|
||||
result, err := db.Model(table).Page(1, 2).Order("id").All()
|
||||
t.AssertNil(err)
|
||||
fmt.Println("page:1--------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 1)
|
||||
gtest.Assert(result[1]["ID"], 2)
|
||||
|
||||
result, err = db.Model(table).Page(2, 2).Order("id").All()
|
||||
gtest.Assert(err, nil)
|
||||
fmt.Println("page: 2--------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 3)
|
||||
gtest.Assert(result[1]["ID"], 4)
|
||||
result, err = db.Model(table).Page(2, 2).Order("id").All()
|
||||
t.AssertNil(err)
|
||||
fmt.Println("page: 2--------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 3)
|
||||
gtest.Assert(result[1]["ID"], 4)
|
||||
|
||||
result, err = db.Model(table).Page(3, 2).Order("id").All()
|
||||
gtest.Assert(err, nil)
|
||||
fmt.Println("page:3 --------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 5)
|
||||
result, err = db.Model(table).Page(3, 2).Order("id").All()
|
||||
t.AssertNil(err)
|
||||
fmt.Println("page:3 --------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 5)
|
||||
|
||||
result, err = db.Model(table).Page(2, 3).All()
|
||||
t.AssertNil(err)
|
||||
gtest.Assert(len(result), 3)
|
||||
})
|
||||
|
||||
result, err = db.Model(table).Page(2, 3).All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.Assert(len(result), 3)
|
||||
}
|
||||
|
||||
func Test_Model_Insert(t *testing.T) {
|
||||
|
@ -27,7 +27,7 @@ func Test_Tables(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err := db.Tables(ctx)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
@ -41,7 +41,7 @@ func Test_Tables(t *testing.T) {
|
||||
}
|
||||
|
||||
result, err = db.Tables(ctx, TestSchema)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
for j := 0; j < len(result); j++ {
|
||||
@ -76,7 +76,7 @@ func Test_Table_Fields(t *testing.T) {
|
||||
gtest.AssertNE(err, nil)
|
||||
|
||||
res, err := db.TableFields(ctx, "t_user")
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
@ -88,7 +88,7 @@ func Test_Table_Fields(t *testing.T) {
|
||||
}
|
||||
|
||||
res, err = db.TableFields(ctx, "t_user", TestSchema)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
@ -121,7 +121,7 @@ func Test_Do_Insert(t *testing.T) {
|
||||
"CREATE_TIME": gtime.Now().String(),
|
||||
}
|
||||
_, err := db.Insert(ctx, "t_user", data)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
})
|
||||
|
||||
|
@ -143,7 +143,7 @@ func createInitTable(table ...string) (name string) {
|
||||
})
|
||||
}
|
||||
result, err := db.Insert(context.Background(), name, array.Slice())
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
n, e := result.RowsAffected()
|
||||
gtest.Assert(e, nil)
|
||||
|
@ -132,27 +132,27 @@ func Test_Page(t *testing.T) {
|
||||
table := createInitTable()
|
||||
defer dropTable(table)
|
||||
result, err := db.Model(table).Page(1, 2).Order("ID").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
fmt.Println("page:1--------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 1)
|
||||
gtest.Assert(result[1]["ID"], 2)
|
||||
|
||||
result, err = db.Model(table).Page(2, 2).Order("ID").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
fmt.Println("page: 2--------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 3)
|
||||
gtest.Assert(result[1]["ID"], 4)
|
||||
|
||||
result, err = db.Model(table).Page(3, 2).Order("ID").All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
fmt.Println("page:3 --------", result)
|
||||
gtest.Assert(len(result), 2)
|
||||
gtest.Assert(result[0]["ID"], 5)
|
||||
|
||||
result, err = db.Model(table).Page(2, 3).All()
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
gtest.Assert(len(result), 3)
|
||||
gtest.Assert(result[0]["ID"], 4)
|
||||
gtest.Assert(result[1]["ID"], 5)
|
||||
|
@ -282,7 +282,7 @@ func Test_DB_Tables(t *testing.T) {
|
||||
createTable(v)
|
||||
}
|
||||
result, err := db.Tables(ctx)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
for i := 0; i < len(tables); i++ {
|
||||
find := false
|
||||
for j := 0; j < len(result); j++ {
|
||||
@ -312,7 +312,7 @@ func Test_DB_TableFields(t *testing.T) {
|
||||
}
|
||||
|
||||
res, err := db.TableFields(ctx, table)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
|
@ -1553,7 +1553,7 @@ func Test_TableFields(t *testing.T) {
|
||||
}
|
||||
|
||||
res, err := db.TableFields(context.Background(), tableName)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
|
@ -1553,7 +1553,7 @@ func Test_TableFields(t *testing.T) {
|
||||
}
|
||||
|
||||
res, err := db.TableFields(context.Background(), tableName)
|
||||
gtest.Assert(err, nil)
|
||||
gtest.AssertNil(err)
|
||||
|
||||
for k, v := range expect {
|
||||
_, ok := res[k]
|
||||
|
@ -33,6 +33,7 @@ type Registry struct {
|
||||
lease etcd3.Lease
|
||||
keepaliveTTL time.Duration
|
||||
logger glog.ILogger
|
||||
etcdConfig etcd3.Config
|
||||
}
|
||||
|
||||
// Option is the option for the etcd registry.
|
||||
@ -59,7 +60,7 @@ const (
|
||||
|
||||
// New creates and returns a new etcd registry.
|
||||
// Support Etcd Address format: ip:port,ip:port...,ip:port@username:password
|
||||
func New(address string, option ...Option) gsvc.Registry {
|
||||
func New(address string, option ...Option) *Registry {
|
||||
if address == "" {
|
||||
panic(gerror.NewCode(gcode.CodeInvalidParameter, `invalid etcd address ""`))
|
||||
}
|
||||
@ -110,7 +111,9 @@ func New(address string, option ...Option) gsvc.Registry {
|
||||
if err != nil {
|
||||
panic(gerror.Wrap(err, `create etcd client failed`))
|
||||
}
|
||||
return NewWithClient(client, option...)
|
||||
r := NewWithClient(client, option...)
|
||||
r.etcdConfig = cfg
|
||||
return r
|
||||
}
|
||||
|
||||
// NewWithClient creates and returns a new etcd registry with the given client.
|
||||
|
@ -58,5 +58,5 @@ func (r *Registry) Search(ctx context.Context, in gsvc.SearchInput) ([]gsvc.Serv
|
||||
// Watch watches specified condition changes.
|
||||
// The `key` is the prefix of service key.
|
||||
func (r *Registry) Watch(ctx context.Context, key string) (gsvc.Watcher, error) {
|
||||
return newWatcher(key, r.client)
|
||||
return newWatcher(key, r.client, r.etcdConfig.DialTimeout)
|
||||
}
|
||||
|
@ -8,21 +8,34 @@ package etcd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
etcd3 "go.etcd.io/etcd/client/v3"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/gsvc"
|
||||
"github.com/gogf/gf/v2/util/grand"
|
||||
)
|
||||
|
||||
// Register registers `service` to Registry.
|
||||
// Note that it returns a new Service if it changes the input Service with custom one.
|
||||
func (r *Registry) Register(ctx context.Context, service gsvc.Service) (gsvc.Service, error) {
|
||||
service = NewService(service)
|
||||
if err := r.doRegisterLease(ctx, service); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return service, nil
|
||||
}
|
||||
|
||||
func (r *Registry) doRegisterLease(ctx context.Context, service gsvc.Service) error {
|
||||
r.lease = etcd3.NewLease(r.client)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), r.etcdConfig.DialTimeout)
|
||||
defer cancel()
|
||||
|
||||
grant, err := r.lease.Grant(ctx, int64(r.keepaliveTTL.Seconds()))
|
||||
if err != nil {
|
||||
return nil, gerror.Wrapf(err, `etcd grant failed with keepalive ttl "%s"`, r.keepaliveTTL)
|
||||
return gerror.Wrapf(err, `etcd grant failed with keepalive ttl "%s"`, r.keepaliveTTL)
|
||||
}
|
||||
var (
|
||||
key = service.GetKey()
|
||||
@ -30,7 +43,7 @@ func (r *Registry) Register(ctx context.Context, service gsvc.Service) (gsvc.Ser
|
||||
)
|
||||
_, err = r.client.Put(ctx, key, value, etcd3.WithLease(grant.ID))
|
||||
if err != nil {
|
||||
return nil, gerror.Wrapf(
|
||||
return gerror.Wrapf(
|
||||
err,
|
||||
`etcd put failed with key "%s", value "%s", lease "%d"`,
|
||||
key, value, grant.ID,
|
||||
@ -43,10 +56,10 @@ func (r *Registry) Register(ctx context.Context, service gsvc.Service) (gsvc.Ser
|
||||
)
|
||||
keepAliceCh, err := r.client.KeepAlive(context.Background(), grant.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return err
|
||||
}
|
||||
go r.doKeepAlive(grant.ID, keepAliceCh)
|
||||
return service, nil
|
||||
go r.doKeepAlive(service, grant.ID, keepAliceCh)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Deregister off-lines and removes `service` from the Registry.
|
||||
@ -59,12 +72,14 @@ func (r *Registry) Deregister(ctx context.Context, service gsvc.Service) error {
|
||||
}
|
||||
|
||||
// doKeepAlive continuously keeps alive the lease from ETCD.
|
||||
func (r *Registry) doKeepAlive(leaseID etcd3.LeaseID, keepAliceCh <-chan *etcd3.LeaseKeepAliveResponse) {
|
||||
func (r *Registry) doKeepAlive(
|
||||
service gsvc.Service, leaseID etcd3.LeaseID, keepAliceCh <-chan *etcd3.LeaseKeepAliveResponse,
|
||||
) {
|
||||
var ctx = context.Background()
|
||||
for {
|
||||
select {
|
||||
case <-r.client.Ctx().Done():
|
||||
r.logger.Noticef(ctx, "keepalive done for lease id: %d", leaseID)
|
||||
r.logger.Infof(ctx, "keepalive done for lease id: %d", leaseID)
|
||||
return
|
||||
|
||||
case res, ok := <-keepAliceCh:
|
||||
@ -72,7 +87,21 @@ func (r *Registry) doKeepAlive(leaseID etcd3.LeaseID, keepAliceCh <-chan *etcd3.
|
||||
// r.logger.Debugf(ctx, `keepalive loop: %v, %s`, ok, res.String())
|
||||
}
|
||||
if !ok {
|
||||
r.logger.Noticef(ctx, `keepalive exit, lease id: %d`, leaseID)
|
||||
r.logger.Warningf(ctx, `keepalive exit, lease id: %d, retry register`, leaseID)
|
||||
// Re-register the service.
|
||||
for {
|
||||
if err := r.doRegisterLease(ctx, service); err != nil {
|
||||
retryDuration := grand.D(time.Second, time.Second*3)
|
||||
r.logger.Errorf(
|
||||
ctx,
|
||||
`keepalive retry register failed, will retry in %s: %+v`,
|
||||
retryDuration, err,
|
||||
)
|
||||
time.Sleep(retryDuration)
|
||||
continue
|
||||
}
|
||||
break
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,12 @@ package etcd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
etcd3 "go.etcd.io/etcd/client/v3"
|
||||
|
||||
"github.com/gogf/gf/v2/errors/gcode"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/net/gsvc"
|
||||
)
|
||||
|
||||
@ -27,17 +30,31 @@ type watcher struct {
|
||||
kv etcd3.KV
|
||||
}
|
||||
|
||||
func newWatcher(key string, client *etcd3.Client) (*watcher, error) {
|
||||
func newWatcher(key string, client *etcd3.Client, dialTimeout time.Duration) (*watcher, error) {
|
||||
w := &watcher{
|
||||
key: key,
|
||||
watcher: etcd3.NewWatcher(client),
|
||||
kv: etcd3.NewKV(client),
|
||||
}
|
||||
|
||||
// Create context with timeout
|
||||
ctx, cancel := context.WithTimeout(context.Background(), dialTimeout)
|
||||
defer cancel()
|
||||
|
||||
// Test connection first.
|
||||
if _, err := client.Get(ctx, "ping"); err != nil {
|
||||
return nil, gerror.WrapCode(gcode.CodeOperationFailed, err, "failed to connect to etcd")
|
||||
}
|
||||
|
||||
w.ctx, w.cancel = context.WithCancel(context.Background())
|
||||
w.watchChan = w.watcher.Watch(w.ctx, key, etcd3.WithPrefix(), etcd3.WithRev(0))
|
||||
|
||||
if err := w.watcher.RequestProgress(context.Background()); err != nil {
|
||||
return nil, err
|
||||
// Clean up
|
||||
w.cancel()
|
||||
return nil, gerror.WrapCode(gcode.CodeOperationFailed, err, "failed to establish watch connection")
|
||||
}
|
||||
|
||||
return w, nil
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
module github.com/gogf/gf/contrib/registry/etcd/v2
|
||||
|
||||
go 1.20
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/gogf/gf/v2 v2.8.2
|
||||
go.etcd.io/etcd/client/v3 v3.5.7
|
||||
go.etcd.io/etcd/client/v3 v3.5.17
|
||||
google.golang.org/grpc v1.59.0
|
||||
)
|
||||
|
||||
@ -19,7 +19,7 @@ require (
|
||||
github.com/go-logr/logr v1.4.2 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/protobuf v1.5.4 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 // indirect
|
||||
github.com/magiconair/properties v1.8.9 // indirect
|
||||
@ -28,8 +28,8 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/olekukonko/tablewriter v0.0.5 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.17 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||
|
@ -23,11 +23,10 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grokify/html-strip-tags-go v0.1.0 h1:03UrQLjAny8xci+R+qjCce/MYnpNXCtgzltlQbOBae4=
|
||||
@ -56,15 +55,16 @@ github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUc
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY=
|
||||
go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY=
|
||||
go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4=
|
||||
go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw=
|
||||
go.etcd.io/etcd/api/v3 v3.5.17 h1:cQB8eb8bxwuxOilBpMJAEo8fAONyrdXTHUNcMd8yT1w=
|
||||
go.etcd.io/etcd/api/v3 v3.5.17/go.mod h1:d1hvkRuXkts6PmaYk2Vrgqbv7H4ADfAKhyJqHNLJCB4=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17 h1:XxnDXAWq2pnxqx76ljWwiQ9jylbpC4rvkAeRVOUKKVw=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17/go.mod h1:4DqK1TKacp/86nJk4FLQqo6Mn2vvQFBmruW3pP14H/w=
|
||||
go.etcd.io/etcd/client/v3 v3.5.17 h1:o48sINNeWz5+pjy/Z0+HKpj/xSnBkuVhVvXkjEXbqZY=
|
||||
go.etcd.io/etcd/client/v3 v3.5.17/go.mod h1:j2d4eXTHWkT2ClBgnnEPm/Wuu7jsqku41v9DZ3OtjQo=
|
||||
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||
@ -120,14 +120,13 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
|
||||
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
|
@ -1,6 +1,6 @@
|
||||
module github.com/gogf/gf/example
|
||||
|
||||
go 1.21
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/gogf/gf/contrib/config/apollo/v2 v2.8.2
|
||||
@ -32,7 +32,7 @@ require (
|
||||
go.opentelemetry.io/otel/exporters/prometheus v0.46.0
|
||||
go.opentelemetry.io/otel/sdk v1.29.0
|
||||
golang.org/x/time v0.6.0
|
||||
google.golang.org/grpc v1.67.1
|
||||
google.golang.org/grpc v1.68.1
|
||||
google.golang.org/protobuf v1.34.2
|
||||
k8s.io/client-go v0.27.4
|
||||
)
|
||||
@ -125,9 +125,9 @@ require (
|
||||
github.com/spf13/viper v1.8.1 // indirect
|
||||
github.com/subosito/gotenv v1.2.0 // indirect
|
||||
github.com/tjfoc/gmsm v1.4.1 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.7 // indirect
|
||||
go.etcd.io/etcd/api/v3 v3.5.17 // indirect
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17 // indirect
|
||||
go.etcd.io/etcd/client/v3 v3.5.17 // indirect
|
||||
go.opentelemetry.io/contrib/instrumentation/runtime v0.49.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.29.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk/metric v1.24.0 // indirect
|
||||
@ -138,7 +138,7 @@ require (
|
||||
golang.org/x/crypto v0.30.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/net v0.32.0 // indirect
|
||||
golang.org/x/oauth2 v0.22.0 // indirect
|
||||
golang.org/x/oauth2 v0.23.0 // indirect
|
||||
golang.org/x/sync v0.10.0 // indirect
|
||||
golang.org/x/sys v0.28.0 // indirect
|
||||
golang.org/x/term v0.27.0 // indirect
|
||||
|
@ -731,14 +731,14 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
|
||||
go.etcd.io/etcd/api/v3 v3.5.7 h1:sbcmosSVesNrWOJ58ZQFitHMdncusIifYcrBfwrlJSY=
|
||||
go.etcd.io/etcd/api/v3 v3.5.7/go.mod h1:9qew1gCdDDLu+VwmeG+iFpL+QlpHTo7iubavdVDgCAA=
|
||||
go.etcd.io/etcd/api/v3 v3.5.17 h1:cQB8eb8bxwuxOilBpMJAEo8fAONyrdXTHUNcMd8yT1w=
|
||||
go.etcd.io/etcd/api/v3 v3.5.17/go.mod h1:d1hvkRuXkts6PmaYk2Vrgqbv7H4ADfAKhyJqHNLJCB4=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.7 h1:y3kf5Gbp4e4q7egZdn5T7W9TSHUvkClN6u+Rq9mEOmg=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.7/go.mod h1:o0Abi1MK86iad3YrWhgUsbGx1pmTS+hrORWc2CamuhY=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17 h1:XxnDXAWq2pnxqx76ljWwiQ9jylbpC4rvkAeRVOUKKVw=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.17/go.mod h1:4DqK1TKacp/86nJk4FLQqo6Mn2vvQFBmruW3pP14H/w=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v3 v3.5.7 h1:u/OhpiuCgYY8awOHlhIhmGIGpxfBU/GZBUP3m/3/Iz4=
|
||||
go.etcd.io/etcd/client/v3 v3.5.7/go.mod h1:sOWmj9DZUMyAngS7QQwCyAXXAL6WhgTOPLNS/NabQgw=
|
||||
go.etcd.io/etcd/client/v3 v3.5.17 h1:o48sINNeWz5+pjy/Z0+HKpj/xSnBkuVhVvXkjEXbqZY=
|
||||
go.etcd.io/etcd/client/v3 v3.5.17/go.mod h1:j2d4eXTHWkT2ClBgnnEPm/Wuu7jsqku41v9DZ3OtjQo=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
|
||||
go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=
|
||||
@ -928,8 +928,8 @@ golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7Lm
|
||||
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE=
|
||||
golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg=
|
||||
golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA=
|
||||
golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs=
|
||||
golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@ -1334,8 +1334,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu
|
||||
google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
|
||||
google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww=
|
||||
google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E=
|
||||
google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA=
|
||||
google.golang.org/grpc v1.68.1 h1:oI5oTa11+ng8r8XMMN7jAOmWfPZWbYpCFaMUTACxkM0=
|
||||
google.golang.org/grpc v1.68.1/go.mod h1:+q1XYFJjShcqn0QZHvCyeR4CXPA+llXIeUIfIe00waw=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
|
@ -7,8 +7,10 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/gogf/gf/v2/frame/g"
|
||||
"github.com/gogf/gf/v2/os/gctx"
|
||||
|
||||
"github.com/gogf/gf/contrib/registry/etcd/v2"
|
||||
"github.com/gogf/gf/contrib/rpc/grpcx/v2"
|
||||
@ -20,14 +22,23 @@ func main() {
|
||||
grpcx.Resolver.Register(etcd.New("127.0.0.1:2379"))
|
||||
|
||||
var (
|
||||
ctx = gctx.New()
|
||||
conn = grpcx.Client.MustNewGrpcClientConn("demo")
|
||||
client = protobuf.NewGreeterClient(conn)
|
||||
)
|
||||
res, err := client.SayHello(ctx, &protobuf.HelloRequest{Name: "World"})
|
||||
if err != nil {
|
||||
g.Log().Error(ctx, err)
|
||||
return
|
||||
|
||||
for {
|
||||
func() {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second*3)
|
||||
defer cancel()
|
||||
res, err := client.SayHello(ctx, &protobuf.HelloRequest{Name: "World"})
|
||||
if err != nil {
|
||||
g.Log().Errorf(ctx, `%+v`, err)
|
||||
} else {
|
||||
g.Log().Debug(ctx, "Response:", res.Message)
|
||||
}
|
||||
}()
|
||||
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
g.Log().Debug(ctx, "Response:", res.Message)
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user