mirror of
https://github.com/go-kratos/kratos.git
synced 2025-03-19 21:18:07 +02:00
doc and example (#267)
* add doc and example * rm deprecated ecode.Equal
This commit is contained in:
parent
0160db5832
commit
d9cee15ef6
@ -180,7 +180,7 @@ func (d *Dao) DemoIncrbys(c context.Context, pid int) (err error) {
|
|||||||
|
|
||||||
## 返回值转换
|
## 返回值转换
|
||||||
|
|
||||||
与[memcache包](cache-mc.md)类似地,kratos/pkg/cache/redis包中也提供了Scan方法将redis server的返回值转换为golang类型。
|
kratos/pkg/cache/redis包中也提供了Scan方法将redis server的返回值转换为golang类型。
|
||||||
|
|
||||||
除此之外,kratos/pkg/cache/redis包提供了大量返回值转换的快捷方式:
|
除此之外,kratos/pkg/cache/redis包提供了大量返回值转换的快捷方式:
|
||||||
|
|
||||||
|
81
doc/wiki-cn/database-mysql-orm.md
Normal file
81
doc/wiki-cn/database-mysql-orm.md
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
# 准备工作
|
||||||
|
|
||||||
|
推荐使用[kratos工具](kratos-tool.md)快速生成项目,如我们生成一个叫`kratos-demo`的项目。目录结构如下:
|
||||||
|
|
||||||
|
```
|
||||||
|
├── CHANGELOG.md
|
||||||
|
├── CONTRIBUTORS.md
|
||||||
|
├── LICENSE
|
||||||
|
├── README.md
|
||||||
|
├── cmd
|
||||||
|
│ ├── cmd
|
||||||
|
│ └── main.go
|
||||||
|
├── configs
|
||||||
|
│ ├── application.toml
|
||||||
|
│ ├── grpc.toml
|
||||||
|
│ ├── http.toml
|
||||||
|
│ ├── log.toml
|
||||||
|
│ ├── memcache.toml
|
||||||
|
│ ├── mysql.toml
|
||||||
|
│ └── redis.toml
|
||||||
|
├── go.mod
|
||||||
|
├── go.sum
|
||||||
|
└── internal
|
||||||
|
├── dao
|
||||||
|
│ └── dao.go
|
||||||
|
├── model
|
||||||
|
│ └── model.go
|
||||||
|
├── server
|
||||||
|
│ └── http
|
||||||
|
│ └── http.go
|
||||||
|
└── service
|
||||||
|
└── service.go
|
||||||
|
```
|
||||||
|
|
||||||
|
# 开始使用
|
||||||
|
|
||||||
|
## 配置
|
||||||
|
|
||||||
|
创建项目成功后,进入项目中的configs目录,mysql.toml,我们可以看到:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[demo]
|
||||||
|
addr = "127.0.0.1:3306"
|
||||||
|
dsn = "{user}:{password}@tcp(127.0.0.1:3306)/{database}?timeout=1s&readTimeout=1s&writeTimeout=1s&parseTime=true&loc=Local&charset=utf8mb4,utf8"
|
||||||
|
readDSN = ["{user}:{password}@tcp(127.0.0.2:3306)/{database}?timeout=1s&readTimeout=1s&writeTimeout=1s&parseTime=true&loc=Local&charset=utf8mb4,utf8","{user}:{password}@tcp(127.0.0.3:3306)/{database}?timeout=1s&readTimeout=1s&writeTimeout=1s&parseTime=true&loc=Local&charset=utf8,utf8mb4"]
|
||||||
|
active = 20
|
||||||
|
idle = 10
|
||||||
|
idleTimeout ="4h"
|
||||||
|
queryTimeout = "200ms"
|
||||||
|
execTimeout = "300ms"
|
||||||
|
tranTimeout = "400ms"
|
||||||
|
```
|
||||||
|
|
||||||
|
在该配置文件中我们可以配置mysql的读和写的dsn、连接地址addr、连接池的闲置连接数idle、最大连接数active以及各类超时。
|
||||||
|
|
||||||
|
如果配置了readDSN,在进行读操作的时候会优先使用readDSN的连接。
|
||||||
|
|
||||||
|
## 初始化
|
||||||
|
|
||||||
|
进入项目的internal/dao目录,打开dao.go,其中:
|
||||||
|
|
||||||
|
```go
|
||||||
|
var (
|
||||||
|
dc struct {
|
||||||
|
Demo *sql.Config
|
||||||
|
}
|
||||||
|
)
|
||||||
|
checkErr(paladin.Get("mysql.toml").UnmarshalTOML(&dc))
|
||||||
|
```
|
||||||
|
使用paladin配置管理工具将上文中的mysql.toml中的配置解析为我们需要使用mysql的相关配置。
|
||||||
|
|
||||||
|
# TODO:补充常用方法
|
||||||
|
|
||||||
|
# 扩展阅读
|
||||||
|
|
||||||
|
[tidb模块说明](database-tidb.md)
|
||||||
|
[hbase模块说明](database-hbase.md)
|
||||||
|
|
||||||
|
-------------
|
||||||
|
|
||||||
|
[文档目录树](summary.md)
|
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
## MySQL
|
## MySQL
|
||||||
MySQL数据库驱动,支持读写分离、context、timeout、trace和统计功能,以及错误熔断防止数据库雪崩。
|
MySQL数据库驱动,支持读写分离、context、timeout、trace和统计功能,以及错误熔断防止数据库雪崩。
|
||||||
[mysql client](database-mysql.md)
|
[mysql client](database-mysql.md)
|
||||||
|
[mysql client orm](database-mysql-orm.md)
|
||||||
|
|
||||||
## HBase
|
## HBase
|
||||||
HBase客户端,支持trace、slowlog和统计功能。
|
HBase客户端,支持trace、slowlog和统计功能。
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
> 缓存回源代码生成
|
> 缓存回源代码生成
|
||||||
|
|
||||||
在internal/dao/dao.go中添加mc缓存interface定义,可以指定对应的[注解参数](../../tool/kratos-gen-mc/README.md);
|
在internal/dao/dao.go中添加mc缓存interface定义,可以指定对应的[注解参数](../../tool/kratos-gen-bts/README.md);
|
||||||
并且在接口前面添加`go:generate kratos tool genbts`;
|
并且在接口前面添加`go:generate kratos tool genbts`;
|
||||||
然后在当前目录执行`go generate`,可以看到自动生成的dao.bts.go代码。
|
然后在当前目录执行`go generate`,可以看到自动生成的dao.bts.go代码。
|
||||||
|
|
||||||
|
@ -11,17 +11,17 @@ kratos 借鉴了 Sentinel 项目的自适应限流系统,通过综合分析服
|
|||||||
|
|
||||||
## 限流规则
|
## 限流规则
|
||||||
|
|
||||||
1,指标介绍
|
### 指标介绍
|
||||||
|
|
||||||
|指标名称|指标含义|
|
| 指标名称 | 指标含义 |
|
||||||
|---|---|
|
| -------- | ------------------------------------------------------------- |
|
||||||
|cpu|最近 1s 的 CPU 使用率均值,使用滑动平均计算,采样周期是 250ms|
|
| cpu | 最近 1s 的 CPU 使用率均值,使用滑动平均计算,采样周期是 250ms |
|
||||||
|inflight|当前处理中正在处理的请求数量|
|
| inflight | 当前处理中正在处理的请求数量 |
|
||||||
|pass|请求处理成功的量|
|
| pass | 请求处理成功的量 |
|
||||||
|rt|请求成功的响应耗时|
|
| rt | 请求成功的响应耗时 |
|
||||||
|
|
||||||
|
|
||||||
2,滑动窗口
|
### 滑动窗口
|
||||||
|
|
||||||
在自适应限流保护中,采集到的指标的时效性非常强,系统只需要采集最近一小段时间内的 qps、rt 即可,对于较老的数据,会自动丢弃。为了实现这个效果,kratos 使用了滑动窗口来保存采样数据。
|
在自适应限流保护中,采集到的指标的时效性非常强,系统只需要采集最近一小段时间内的 qps、rt 即可,对于较老的数据,会自动丢弃。为了实现这个效果,kratos 使用了滑动窗口来保存采样数据。
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ kratos 借鉴了 Sentinel 项目的自适应限流系统,通过综合分析服
|
|||||||
当时间流动之后,过期的桶会自动被新桶的数据覆盖掉,在图中,在 1000-1500ms 时,bucket 1 的数据因为过期而被丢弃,之后 bucket 3 的数据填到了窗口的头部。
|
当时间流动之后,过期的桶会自动被新桶的数据覆盖掉,在图中,在 1000-1500ms 时,bucket 1 的数据因为过期而被丢弃,之后 bucket 3 的数据填到了窗口的头部。
|
||||||
|
|
||||||
|
|
||||||
3,限流公式
|
### 限流公式
|
||||||
|
|
||||||
判断是否丢弃当前请求的算法如下:
|
判断是否丢弃当前请求的算法如下:
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ windows 表示一秒内采样窗口的数量,默认配置中是 5s 50 个采
|
|||||||
可以看到,没有限流的场景里,系统在 700qps 时开始抖动,在 1k qps 时被拖垮,几乎没有新的请求能被放行,然而在使用限流之后,系统请求能够稳定在 600 qps 左右,rt 没有暴增,服务也没有被打垮,可见,限流有效的保护了服务。
|
可以看到,没有限流的场景里,系统在 700qps 时开始抖动,在 1k qps 时被拖垮,几乎没有新的请求能被放行,然而在使用限流之后,系统请求能够稳定在 600 qps 左右,rt 没有暴增,服务也没有被打垮,可见,限流有效的保护了服务。
|
||||||
|
|
||||||
|
|
||||||
参考资料:
|
## 参考资料
|
||||||
|
|
||||||
[Sentinel 系统自适应限流](https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81)
|
[Sentinel 系统自适应限流](https://github.com/alibaba/Sentinel/wiki/%E7%B3%BB%E7%BB%9F%E8%87%AA%E9%80%82%E5%BA%94%E9%99%90%E6%B5%81)
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
* [log-agent](log-agent.md)
|
* [log-agent](log-agent.md)
|
||||||
* [database](database.md)
|
* [database](database.md)
|
||||||
* [mysql](database-mysql.md)
|
* [mysql](database-mysql.md)
|
||||||
|
* [mysql-orm](database-mysql-orm.md)
|
||||||
* [hbase](database-hbase.md)
|
* [hbase](database-hbase.md)
|
||||||
* [tidb](database-tidb.md)
|
* [tidb](database-tidb.md)
|
||||||
* [cache](cache.md)
|
* [cache](cache.md)
|
||||||
|
@ -4,7 +4,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
bm "github.com/bilibili/kratos/pkg/net/http/blademaster"
|
bm "github.com/bilibili/kratos/pkg/net/http/blademaster"
|
||||||
"github.com/bilibili/kratos/pkg/net/http/blademaster/middleware/auth"
|
"github.com/bilibili/kratos/example/blademaster/middleware/auth"
|
||||||
"github.com/bilibili/kratos/pkg/net/metadata"
|
"github.com/bilibili/kratos/pkg/net/metadata"
|
||||||
)
|
)
|
||||||
|
|
@ -196,7 +196,7 @@ func (db *DB) Prepared(query string) (stmt *Stmt) {
|
|||||||
func (db *DB) Query(c context.Context, query string, args ...interface{}) (rows *Rows, err error) {
|
func (db *DB) Query(c context.Context, query string, args ...interface{}) (rows *Rows, err error) {
|
||||||
idx := db.readIndex()
|
idx := db.readIndex()
|
||||||
for i := range db.read {
|
for i := range db.read {
|
||||||
if rows, err = db.read[(idx+i)%len(db.read)].query(c, query, args...); !ecode.ServiceUnavailable.Equal(err) {
|
if rows, err = db.read[(idx+i)%len(db.read)].query(c, query, args...); !ecode.EqualError(ecode.ServiceUnavailable, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ func (db *DB) Query(c context.Context, query string, args ...interface{}) (rows
|
|||||||
func (db *DB) QueryRow(c context.Context, query string, args ...interface{}) *Row {
|
func (db *DB) QueryRow(c context.Context, query string, args ...interface{}) *Row {
|
||||||
idx := db.readIndex()
|
idx := db.readIndex()
|
||||||
for i := range db.read {
|
for i := range db.read {
|
||||||
if row := db.read[(idx+i)%len(db.read)].queryRow(c, query, args...); !ecode.ServiceUnavailable.Equal(row.err) {
|
if row := db.read[(idx+i)%len(db.read)].queryRow(c, query, args...); !ecode.EqualError(ecode.ServiceUnavailable, row.err) {
|
||||||
return row
|
return row
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
_messages atomic.Value // NOTE: stored map[string]map[int]string
|
_messages atomic.Value // NOTE: stored map[int]string
|
||||||
_codes = map[int]struct{}{} // register codes.
|
_codes = map[int]struct{}{} // register codes.
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -71,10 +71,6 @@ func (e Code) Message() string {
|
|||||||
// Details return details.
|
// Details return details.
|
||||||
func (e Code) Details() []interface{} { return nil }
|
func (e Code) Details() []interface{} { return nil }
|
||||||
|
|
||||||
// Equal for compatible.
|
|
||||||
// Deprecated: please use ecode.EqualError.
|
|
||||||
func (e Code) Equal(err error) bool { return EqualError(e, err) }
|
|
||||||
|
|
||||||
// Int parse code int to error.
|
// Int parse code int to error.
|
||||||
func Int(i int) Code { return Code(i) }
|
func Int(i int) Code { return Code(i) }
|
||||||
|
|
||||||
|
@ -74,12 +74,6 @@ func (s *Status) WithDetails(pbs ...proto.Message) (*Status, error) {
|
|||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equal for compatible.
|
|
||||||
// Deprecated: please use ecode.EqualError.
|
|
||||||
func (s *Status) Equal(err error) bool {
|
|
||||||
return EqualError(s, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Proto return origin protobuf message
|
// Proto return origin protobuf message
|
||||||
func (s *Status) Proto() *types.Status {
|
func (s *Status) Proto() *types.Status {
|
||||||
return s.s
|
return s.s
|
||||||
|
@ -16,9 +16,6 @@ func TestEqual(t *testing.T) {
|
|||||||
err2 = Errorf(RequestErr, "test")
|
err2 = Errorf(RequestErr, "test")
|
||||||
)
|
)
|
||||||
assert.Equal(t, err1, err2)
|
assert.Equal(t, err1, err2)
|
||||||
assert.True(t, OK.Equal(nil))
|
|
||||||
assert.True(t, err1.Equal(err2))
|
|
||||||
assert.False(t, err1.Equal(nil))
|
|
||||||
assert.True(t, Equal(nil, nil))
|
assert.True(t, Equal(nil, nil))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -338,7 +338,7 @@ func (d *Discovery) Register(ctx context.Context, ins *naming.Instance) (cancelF
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
if err := d.renew(ctx, ins); err != nil && ecode.NothingFound.Equal(err) {
|
if err := d.renew(ctx, ins); err != nil && ecode.EqualError(ecode.NothingFound, err) {
|
||||||
_ = d.register(ctx, ins)
|
_ = d.register(ctx, ins)
|
||||||
}
|
}
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@ -380,7 +380,7 @@ func (d *Discovery) register(ctx context.Context, ins *naming.Instance) (err err
|
|||||||
uri, c.Zone, c.Env, ins.AppID, ins.Addrs, err)
|
uri, c.Zone, c.Env, ins.AppID, ins.Addrs, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ec := ecode.Int(res.Code); !ec.Equal(ecode.OK) {
|
if ec := ecode.Int(res.Code); !ecode.Equal(ecode.OK, ec) {
|
||||||
log.Warn("discovery: register client.Get(%v) env(%s) appid(%s) addrs(%v) code(%v)", uri, c.Env, ins.AppID, ins.Addrs, res.Code)
|
log.Warn("discovery: register client.Get(%v) env(%s) appid(%s) addrs(%v) code(%v)", uri, c.Env, ins.AppID, ins.Addrs, res.Code)
|
||||||
err = ec
|
err = ec
|
||||||
return
|
return
|
||||||
@ -408,9 +408,9 @@ func (d *Discovery) renew(ctx context.Context, ins *naming.Instance) (err error)
|
|||||||
uri, c.Env, ins.AppID, c.Host, err)
|
uri, c.Env, ins.AppID, c.Host, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ec := ecode.Int(res.Code); !ec.Equal(ecode.OK) {
|
if ec := ecode.Int(res.Code); !ecode.Equal(ecode.OK, ec) {
|
||||||
err = ec
|
err = ec
|
||||||
if ec.Equal(ecode.NothingFound) {
|
if ecode.Equal(ecode.NothingFound, ec) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Error("discovery: renew client.Get(%v) env(%s) appid(%s) hostname(%s) code(%v)",
|
log.Error("discovery: renew client.Get(%v) env(%s) appid(%s) hostname(%s) code(%v)",
|
||||||
@ -440,7 +440,7 @@ func (d *Discovery) cancel(ins *naming.Instance) (err error) {
|
|||||||
uri, c.Env, ins.AppID, c.Host, err)
|
uri, c.Env, ins.AppID, c.Host, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ec := ecode.Int(res.Code); !ec.Equal(ecode.OK) {
|
if ec := ecode.Int(res.Code); !ecode.Equal(ecode.OK, ec) {
|
||||||
log.Warn("discovery cancel client.Get(%v) env(%s) appid(%s) hostname(%s) code(%v)",
|
log.Warn("discovery cancel client.Get(%v) env(%s) appid(%s) hostname(%s) code(%v)",
|
||||||
uri, c.Env, ins.AppID, c.Host, res.Code)
|
uri, c.Env, ins.AppID, c.Host, res.Code)
|
||||||
err = ec
|
err = ec
|
||||||
@ -484,7 +484,7 @@ func (d *Discovery) set(ctx context.Context, ins *naming.Instance) (err error) {
|
|||||||
uri, conf.Zone, conf.Env, ins.AppID, ins.Addrs, err)
|
uri, conf.Zone, conf.Env, ins.AppID, ins.Addrs, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ec := ecode.Int(res.Code); !ec.Equal(ecode.OK) {
|
if ec := ecode.Int(res.Code); !ecode.Equal(ecode.OK, ec) {
|
||||||
log.Warn("discovery: set client.Get(%v) env(%s) appid(%s) addrs(%v) code(%v)",
|
log.Warn("discovery: set client.Get(%v) env(%s) appid(%s) addrs(%v) code(%v)",
|
||||||
uri, conf.Env, ins.AppID, ins.Addrs, res.Code)
|
uri, conf.Env, ins.AppID, ins.Addrs, res.Code)
|
||||||
err = ec
|
err = ec
|
||||||
@ -587,8 +587,8 @@ func (d *Discovery) polls(ctx context.Context) (apps map[string]*naming.Instance
|
|||||||
log.Error("discovery: client.Get(%s) error(%+v)", uri+"?"+params.Encode(), err)
|
log.Error("discovery: client.Get(%s) error(%+v)", uri+"?"+params.Encode(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if ec := ecode.Int(res.Code); !ec.Equal(ecode.OK) {
|
if ec := ecode.Int(res.Code); !ecode.Equal(ecode.OK, ec) {
|
||||||
if !ec.Equal(ecode.NotModified) {
|
if !ecode.Equal(ecode.NotModified, ec) {
|
||||||
log.Error("discovery: client.Get(%s) get error code(%d)", uri+"?"+params.Encode(), res.Code)
|
log.Error("discovery: client.Get(%s) get error code(%d)", uri+"?"+params.Encode(), res.Code)
|
||||||
err = ec
|
err = ec
|
||||||
}
|
}
|
||||||
@ -611,7 +611,7 @@ func (d *Discovery) broadcast(apps map[string]*naming.InstancesInfo) {
|
|||||||
for appID, v := range apps {
|
for appID, v := range apps {
|
||||||
var count int
|
var count int
|
||||||
// v maybe nil in old version(less than v1.1) discovery,check incase of panic
|
// v maybe nil in old version(less than v1.1) discovery,check incase of panic
|
||||||
if v==nil {
|
if v == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for zone, ins := range v.Instances {
|
for zone, ins := range v.Instances {
|
||||||
|
@ -3,8 +3,6 @@ package warden
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/bilibili/kratos/pkg/net/rpc/warden/resolver"
|
|
||||||
"github.com/bilibili/kratos/pkg/net/rpc/warden/resolver/direct"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -12,6 +10,9 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/bilibili/kratos/pkg/net/rpc/warden/resolver"
|
||||||
|
"github.com/bilibili/kratos/pkg/net/rpc/warden/resolver/direct"
|
||||||
|
|
||||||
"github.com/bilibili/kratos/pkg/conf/env"
|
"github.com/bilibili/kratos/pkg/conf/env"
|
||||||
"github.com/bilibili/kratos/pkg/conf/flagvar"
|
"github.com/bilibili/kratos/pkg/conf/flagvar"
|
||||||
"github.com/bilibili/kratos/pkg/ecode"
|
"github.com/bilibili/kratos/pkg/ecode"
|
||||||
@ -84,14 +85,15 @@ type Client struct {
|
|||||||
handlers []grpc.UnaryClientInterceptor
|
handlers []grpc.UnaryClientInterceptor
|
||||||
}
|
}
|
||||||
|
|
||||||
type TimeOutCallOption struct {
|
// TimeoutCallOption timeout option.
|
||||||
|
type TimeoutCallOption struct {
|
||||||
*grpc.EmptyCallOption
|
*grpc.EmptyCallOption
|
||||||
Timeout time.Duration
|
Timeout time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithTimeoutCallOption can override the timeout in ctx and the timeout in the configuration file
|
// WithTimeoutCallOption can override the timeout in ctx and the timeout in the configuration file
|
||||||
func WithTimeoutCallOption(timeout time.Duration) *TimeOutCallOption {
|
func WithTimeoutCallOption(timeout time.Duration) *TimeoutCallOption {
|
||||||
return &TimeOutCallOption{&grpc.EmptyCallOption{}, timeout}
|
return &TimeoutCallOption{&grpc.EmptyCallOption{}, timeout}
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle returns a new unary client interceptor for OpenTracing\Logging\LinkTimeout.
|
// handle returns a new unary client interceptor for OpenTracing\Logging\LinkTimeout.
|
||||||
@ -127,10 +129,10 @@ func (c *Client) handle() grpc.UnaryClientInterceptor {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer onBreaker(brk, &err)
|
defer onBreaker(brk, &err)
|
||||||
var timeOpt *TimeOutCallOption
|
var timeOpt *TimeoutCallOption
|
||||||
for _, opt := range opts {
|
for _, opt := range opts {
|
||||||
var tok bool
|
var tok bool
|
||||||
timeOpt, tok = opt.(*TimeOutCallOption)
|
timeOpt, tok = opt.(*TimeoutCallOption)
|
||||||
if tok {
|
if tok {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -173,9 +175,10 @@ func (c *Client) handle() grpc.UnaryClientInterceptor {
|
|||||||
|
|
||||||
func onBreaker(breaker breaker.Breaker, err *error) {
|
func onBreaker(breaker breaker.Breaker, err *error) {
|
||||||
if err != nil && *err != nil {
|
if err != nil && *err != nil {
|
||||||
if ecode.ServerErr.Equal(*err) || ecode.ServiceUnavailable.Equal(*err) || ecode.Deadline.Equal(*err) || ecode.LimitExceed.Equal(*err) {
|
if ecode.EqualError(ecode.ServerErr, *err) || ecode.EqualError(ecode.ServiceUnavailable, *err) || ecode.EqualError(ecode.Deadline, *err) || ecode.EqualError(ecode.LimitExceed, *err) {
|
||||||
breaker.MarkFailed()
|
breaker.MarkFailed()
|
||||||
return
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
breaker.MarkSuccess()
|
breaker.MarkSuccess()
|
||||||
|
@ -220,7 +220,7 @@ func Test_Warden(t *testing.T) {
|
|||||||
|
|
||||||
func testValidation(t *testing.T) {
|
func testValidation(t *testing.T) {
|
||||||
_, err := runClient(context.Background(), &clientConfig, t, "", 0)
|
_, err := runClient(context.Background(), &clientConfig, t, "", 0)
|
||||||
if !ecode.RequestErr.Equal(err) {
|
if !ecode.EqualError(ecode.RequestErr, err) {
|
||||||
t.Fatalf("testValidation should return ecode.RequestErr,but is %v", err)
|
t.Fatalf("testValidation should return ecode.RequestErr,but is %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +296,7 @@ func testBreaker(t *testing.T) {
|
|||||||
for i := 0; i < 50; i++ {
|
for i := 0; i < 50; i++ {
|
||||||
_, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "breaker_test"})
|
_, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: "breaker_test"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ecode.ServiceUnavailable.Equal(err) {
|
if ecode.EqualError(ecode.ServiceUnavailable, err) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -334,7 +334,7 @@ func testLinkTimeout(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("testLinkTimeout must return error")
|
t.Fatalf("testLinkTimeout must return error")
|
||||||
}
|
}
|
||||||
if !ecode.Deadline.Equal(err) {
|
if !ecode.EqualError(ecode.Deadline, err) {
|
||||||
t.Fatalf("testLinkTimeout must return error RPCDeadline,err:%v", err)
|
t.Fatalf("testLinkTimeout must return error RPCDeadline,err:%v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +344,7 @@ func testClientConfig(t *testing.T) {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("testLinkTimeout must return error")
|
t.Fatalf("testLinkTimeout must return error")
|
||||||
}
|
}
|
||||||
if !ecode.Deadline.Equal(err) {
|
if !ecode.EqualError(ecode.Deadline, err) {
|
||||||
t.Fatalf("testLinkTimeout must return error RPCDeadline,err:%v", err)
|
t.Fatalf("testLinkTimeout must return error RPCDeadline,err:%v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,7 +397,7 @@ func testClientRecovery(t *testing.T) {
|
|||||||
t.Fatalf("recovery must return ecode error")
|
t.Fatalf("recovery must return ecode error")
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ecode.ServerErr.Equal(e) {
|
if !ecode.EqualError(ecode.ServerErr, e) {
|
||||||
t.Fatalf("recovery must return ecode.RPCClientErr")
|
t.Fatalf("recovery must return ecode.RPCClientErr")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user