From e0824b81943528783a8924ff0b3839472eea2309 Mon Sep 17 00:00:00 2001 From: lixiaoshuang <644968328@qq.com> Date: Mon, 20 Dec 2021 12:23:09 +0800 Subject: [PATCH 001/124] add test --- dtmsvr/api_http_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 dtmsvr/api_http_test.go diff --git a/dtmsvr/api_http_test.go b/dtmsvr/api_http_test.go new file mode 100644 index 0000000..48ebb39 --- /dev/null +++ b/dtmsvr/api_http_test.go @@ -0,0 +1,19 @@ +package dtmsvr + +import ( + "github.com/stretchr/testify/assert" + "github.com/yedf/dtm/common" + "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" + "testing" +) + +func TestDtmMetrics(t *testing.T) { + common.MustLoadConfig() + dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) + PopulateDB(true) + StartSvr() + rest, err := dtmimp.RestyClient.R().Get("http://localhost:36789/api/metrics") + assert.Nil(t, err) + assert.Equal(t, rest.StatusCode(), 200) +} From 3e685aa39ef516a62c8c56b71e3938ebc93cfb26 Mon Sep 17 00:00:00 2001 From: lixiaoshuang <644968328@qq.com> Date: Mon, 20 Dec 2021 12:38:24 +0800 Subject: [PATCH 002/124] add test --- {dtmsvr => test}/api_http_test.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) rename {dtmsvr => test}/api_http_test.go (59%) diff --git a/dtmsvr/api_http_test.go b/test/api_http_test.go similarity index 59% rename from dtmsvr/api_http_test.go rename to test/api_http_test.go index 48ebb39..a545ba8 100644 --- a/dtmsvr/api_http_test.go +++ b/test/api_http_test.go @@ -1,18 +1,12 @@ -package dtmsvr +package test import ( "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" "testing" ) func TestDtmMetrics(t *testing.T) { - common.MustLoadConfig() - dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) - PopulateDB(true) - StartSvr() rest, err := dtmimp.RestyClient.R().Get("http://localhost:36789/api/metrics") assert.Nil(t, err) assert.Equal(t, rest.StatusCode(), 200) From 0f68545ba9ad2e1c22250fd30f4ea97bb66c121f Mon Sep 17 00:00:00 2001 From: lixiaoshuang <644968328@qq.com> Date: Mon, 20 Dec 2021 16:11:58 +0800 Subject: [PATCH 003/124] =?UTF-8?q?=E8=BF=81=E7=A7=BBtest?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/api_http_test.go | 13 ------------- test/api_test.go | 6 ++++++ 2 files changed, 6 insertions(+), 13 deletions(-) delete mode 100644 test/api_http_test.go diff --git a/test/api_http_test.go b/test/api_http_test.go deleted file mode 100644 index a545ba8..0000000 --- a/test/api_http_test.go +++ /dev/null @@ -1,13 +0,0 @@ -package test - -import ( - "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" - "testing" -) - -func TestDtmMetrics(t *testing.T) { - rest, err := dtmimp.RestyClient.R().Get("http://localhost:36789/api/metrics") - assert.Nil(t, err) - assert.Equal(t, rest.StatusCode(), 200) -} diff --git a/test/api_test.go b/test/api_test.go index e44ed14..de79daa 100644 --- a/test/api_test.go +++ b/test/api_test.go @@ -73,3 +73,9 @@ func TestAPIAll(t *testing.T) { nextPos3 := m["next_position"].(string) assert.Equal(t, "", nextPos3) } + +func TestDtmMetrics(t *testing.T) { + rest, err := dtmimp.RestyClient.R().Get("http://localhost:36789/api/metrics") + assert.Nil(t, err) + assert.Equal(t, rest.StatusCode(), 200) +} From 32cb6c8f7d349214432fc0760ca5faba76ee922e Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 08:19:21 +0800 Subject: [PATCH 004/124] default to cn --- README.md | 166 +++++++++++++++++++++++++++++------------------------- 1 file changed, 88 insertions(+), 78 deletions(-) diff --git a/README.md b/README.md index 4f547b9..8f866fc 100644 --- a/README.md +++ b/README.md @@ -5,124 +5,134 @@ [![Go Reference](https://pkg.go.dev/badge/github.com/yedf/dtm.svg)](https://pkg.go.dev/github.com/yedf/dtm) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#database) -# [中文文档](http://dtm.pub) +# [English Docs](https://en.dtm.pub) +# 跨语言分布式事务管理器 -# A Cross Language Distributed Transaction Manager +DTM是一款golang开发的分布式事务管理器,解决了跨数据库、跨服务、跨语言栈更新数据的一致性问题。 -## Who's using DTM +他优雅的解决了幂等、空补偿、悬挂等分布式事务难题,提供了简单易用、高性能、易水平扩展的解决方案。 -[Tencent](https://www.tencent.com/) +作者受邀参加中国数据库大会分享[多语言环境下分布式事务实践](http://dtcc.it168.com/yicheng.html#b9) -[Ivydad](https://ivydad.com) +## 谁在使用dtm +[Tencent 腾讯](https://www.tencent.com/) -[Eglass](https://epeijing.cn) +[Ivydad 常青藤爸爸](https://ivydad.com) -[Jiou](http://jiou.me) +[Eglass 视咖镜小二](https://epeijing.cn) -[GoldenData]() +[极欧科技](http://jiou.me) -## What is DTM +[金数智联]() -DTM is the first distributed transaction management framework in Golang. Unlike other frameworks, DTM provides extremely easy access interfaces of HTTP and gRPC, supports multiple language bindings, and handles tricky problems of unordered sub-transactions at the framework level. +## 亮点 -## Features +* 极易接入 + - 支持HTTP,提供非常简单的接口,极大降低上手分布式事务的难度,新手也能快速接入 +* 使用简单 + - 开发者不再担心悬挂、空补偿、幂等各类问题,框架层代为处理 +* 跨语言 + - 可适合多语言栈的公司使用。方便go、python、php、nodejs、ruby、c# 各类语言使用。 +* 易部署、易扩展 + - 仅依赖mysql,部署简单,易集群化,易水平扩展 +* 多种分布式事务协议支持 + - TCC、SAGA、XA、事务消息 -* Extremely easy to adapt - - Support HTTP and gRPC, provide easy-to-use programming interfaces, lower substantially the barrier of getting started with distributed transactions. Newcomers can adapt quickly. +## 与其他框架对比 -* Easy to use - - Relieving developers from worrying about suspension, null compensation, idempotent transaction, and other tricky problems, the framework layer handles them all. +目前开源的分布式事务框架,Java的框架较多,有大厂开源的SEATA、ServiceComb-Pack,shardingsphere,以及个人开源的himly,tcc-transaction,ByteTCC等等,其中以Seata的应用最为广泛。 -* Language-agnostic - - Suit for companies with multiple-language stacks. - Easy to write bindings for Go, Python, PHP, Node.js, Ruby, and other languages. +非Java语言类的,暂未看到除dtm之外的成熟框架,因此这里仅将DTM和Java中最成熟的Seata对比: -* Easy to deploy, easy to extend - - DTM depends only on MySQL, easy to deploy, cluster, and scale horizontally. +| 特性| DTM | SEATA |备注| +|:-----:|:----:|:----:|:----:| +| 支持语言 |Go、Java、python、php、c#...|Java|dtm可轻松接入一门新语言| +|异常处理| [子事务屏障自动处理](https://zhuanlan.zhihu.com/p/388444465) |手动处理 |dtm解决了幂等、悬挂、空补偿| +| TCC事务| ||| +| XA事务|||| +|AT事务|建议使用XA||AT与XA类似,性能更好,但有脏回滚| +| SAGA事务 |支持并发 |状态机模式 || +|事务消息|||dtm提供类似rocketmq的事务消息| +|单服务多数据源|||| +|通信协议|HTTP、gRPC、go-zero|dubbo等协议|dtm对云原生更加友好| +|star数量|github stars|github stars|dtm从20210604发布0.1,发展快| -* Support for multiple distributed transaction protocol - - TCC, SAGA, XA, Transactional messages. +从上面对比的特性来看,如果您的语言栈包含了Java之外的语言,那么dtm是您的首选。如果您的语言栈是Java,您也可以选择接入dtm,使用子事务屏障技术,简化您的业务编写。 -## DTM vs. others +## [性能测试报告](https://dtm.pub/other/performance.html) -There is no mature open-source distributed transaction framework for non-Java languages. -Mature open-source distributed transaction frameworks for Java language include Ali's Seata, Huawei's ServiceComb-Pack, Jingdong's shardingsphere, himly, tcc-transaction, ByteTCC, and so on, of which Seata is most widely used. +## [教程与文档](https://dtm.pub) -The following is a comparison of the main features of dtm and Seata. +## [各语言客户端及示例](https://dtm.pub/summary/code.html#go) +## 微服务框架支持 +- [go-zero](https://github.com/zeromicro/go-zero):一开源就非常火爆的微服务框架,首家接入dtm的微服务框架。感谢go-zero作者[kevwan](https://github.com/kevwan)的大力支持 +- [polaris](https://github.com/polarismesh/polaris): 腾讯开源的注册发现组件,以及在其上构建的微服务框架。感谢腾讯同学[ychensha](https://github.com/ychensha)的PR +- 其他:看用户需求量,择机接入 -| Features | DTM | Seata | Remarks | -| :-----: | :----: | :----: | :----: | -| Supported languages | Golang, Python, PHP, and others | Java | dtm allows easy access from a new language | -| Exception handling | [Sub-transaction barrier](https://zhuanlan.zhihu.com/p/388444465) | manual | dtm solves idempotent transaction, hanging, null compensation | -| TCC | | | | -| XA | | | | -| AT | suggest XA | | AT is similar to XA with better performance but with dirty rollback | -| SAGA | support concurrency | complicated state-machine mode | dtm's state-machine mode is being planned | -| Transactional Messaging | | | dtm provides Transactional Messaging similar to RocketMQ | -| Multiple DBs in a service |||| -| Communication protocols | HTTP, gRPC | Dubbo, no HTTP | | -| Star count | github stars | github stars | dtm 0.1 is released from 20210604 and under fast development | +具体微服务接入使用,参见[微服务支持](https://dtm.pub/protocol/intro.html) +## 快速开始 -From the features' comparison above, if your language stack includes languages other than Java, then dtm is the one for you. -If your language stack is Java, you can also choose to access dtm and use sub-transaction barrier technology to simplify your business development. +### 获取代码 -## [Cook Book](https://en.dtm.pub) +`git clone https://github.com/yedf/dtm && cd dtm` -# Quick start +### dtm依赖于mysql -### Install +安装[docker 20.04+](https://docs.docker.com/get-docker/)之后 -`git clone https://github.com/yedf/dtm` +`docker-compose -f helper/compose.mysql.yml up` -### Configure Mysql +> 您也可以配置使用现有的mysql,需要高级权限,允许dtm创建数据库 +> +> `cp conf.sample.yml conf.yml # 修改conf.yml` -`cp conf.sample.yml conf.yml # Modify conf.yml` +### 启动并运行saga示例 +`go run app/main.go qs` -### Start the example -`go run app/main.go` +## 开始使用 -# Code - -### Use -``` go - // business micro-service address +### 使用 +``` GO + // 具体业务微服务地址 const qsBusi = "http://localhost:8081/api/busi_saga" - // The address where DtmServer serves DTM, which is a url + req := &gin.H{"amount": 30} // 微服务的载荷 + // DtmServer为DTM服务的地址,是一个url DtmServer := "http://localhost:36789/api/dtmsvr" - req := &gin.H{"amount": 30} // micro-service payload - // DtmServer is the address of DTM micro-service - saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). - // add a TransOut subtraction,forward operation with url: qsBusi+"/TransOut", reverse compensation operation with url: qsBusi+"/TransOutCompensate" - Add(qsBusi+"/TransOut", qsBusi+"/TransOutCompensate", req). - // add a TransIn subtraction, forward operation with url: qsBusi+"/TransIn", reverse compensation operation with url: qsBusi+"/TransInCompensate" - Add(qsBusi+"/TransIn", qsBusi+"/TransInCompensate", req) - // submit the created saga transaction,dtm ensures all subtractions either complete or get revoked - err := saga.Submit() + saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). + // 添加一个TransOut的子事务,正向操作为url: qsBusi+"/TransOut", 补偿操作为url: qsBusi+"/TransOutCompensate" + Add(qsBusi+"/TransOut", qsBusi+"/TransOutCompensate", req). + // 添加一个TransIn的子事务,正向操作为url: qsBusi+"/TransIn", 补偿操作为url: qsBusi+"/TransInCompensate" + Add(qsBusi+"/TransIn", qsBusi+"/TransInCompensate", req) + // 提交saga事务,dtm会完成所有的子事务/回滚所有的子事务 + err := saga.Submit() ``` -### Complete example -Refer to [examples/quick_start.go](./examples/quick_start.go). +成功运行后,可以看到TransOut、TransIn依次被调用,完成了整个分布式事务 -### Slack +### 时序图 -You can join the [DTM slack channel here](https://join.slack.com/t/dtm-w6k9662/shared_invite/zt-vkrph4k1-eFqEFnMkbmlXqfUo5GWHWw). +上述saga分布式事务的时序图如下: -### Wechat + -Add wechat friend with id yedf2008, or scan the OR code. Fill in dtm as verification. +### 完整示例 +参考[examples/quick_start.go](./examples/quick_start.go) -![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) +## 公众号 +您可以关注公众号:分布式事务,及时跟踪dtm的最新内容 +## 交流群 +请加 yedf2008 好友或者扫码加好友,验证回复 dtm 按照指引进群 -### Give a star! ⭐ +![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) -If you think this project is good, or helpful to you, please give a star! +欢迎使用[dtm](https://github.com/yedf/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 -### Who is using +## 谁在使用
- Tencent - Ivydad - Eglass - Jiou - GoldenData + 腾讯 + 常青藤爸爸 + 镜小二 + 极欧科技 + 金数智联
From c156b09619c992f45592a82126db984f3a6f3531 Mon Sep 17 00:00:00 2001 From: tynam Date: Fri, 24 Dec 2021 10:14:53 +0800 Subject: [PATCH 005/124] Update config.go https://github.com/yedf/dtm/issues/94 --- common/config.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/common/config.go b/common/config.go index f39eaa0..afc5852 100644 --- a/common/config.go +++ b/common/config.go @@ -102,10 +102,10 @@ func checkConfig() error { if Config.TimeoutToFail < Config.RetryInterval { return errors.New("TimeoutToFail should not be less than RetryInterval") } - if Config.Store.Driver == BoltDb { + switch Config.Store.Driver { + case BoltDb: return nil - } - if Config.Store.Driver == Mysql { + case Mysql: if Config.Store.Host == "" { return errors.New("Db host not valid ") } @@ -115,6 +115,13 @@ func checkConfig() error { if Config.Store.User == "" { return errors.New("Db user not valid ") } + case Redis: + if Config.Store.Host == "" { + return errors.New("Redis host not valid ") + } + if Config.Store.Port == 0 { + return errors.New("Redis port not valid ") + } } return nil } From 73fff1876ecae1ceab64342e6d051770775c06ef Mon Sep 17 00:00:00 2001 From: lsytj0413 <511121939@qq.com> Date: Fri, 24 Dec 2021 10:27:57 +0800 Subject: [PATCH 006/124] refactor(*): split storage with sql/redis package --- dtmsvr/storage/{ => redis}/redis.go | 48 ++++++++++++++----------- dtmsvr/storage/registry/registry.go | 8 +++-- dtmsvr/storage/{ => sql}/sql.go | 56 ++++++++++++++++++----------- dtmsvr/storage/store.go | 10 ------ dtmsvr/storage/utils.go | 16 --------- 5 files changed, 69 insertions(+), 69 deletions(-) rename dtmsvr/storage/{ => redis}/redis.go (81%) rename dtmsvr/storage/{ => sql}/sql.go (71%) delete mode 100644 dtmsvr/storage/utils.go diff --git a/dtmsvr/storage/redis.go b/dtmsvr/storage/redis/redis.go similarity index 81% rename from dtmsvr/storage/redis.go rename to dtmsvr/storage/redis/redis.go index dcaed8a..348e572 100644 --- a/dtmsvr/storage/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -1,4 +1,4 @@ -package storage +package redis import ( "context" @@ -6,11 +6,15 @@ import ( "time" "github.com/go-redis/redis/v8" + "gorm.io/gorm" + "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli/dtmimp" - "gorm.io/gorm" + "github.com/yedf/dtm/dtmsvr/storage" ) +var config = &common.Config + var ctx context.Context = context.Background() type RedisStore struct { @@ -26,30 +30,30 @@ func (s *RedisStore) PopulateData(skipDrop bool) { dtmimp.PanicIf(err != nil, err) } -func (s *RedisStore) FindTransGlobalStore(gid string) *TransGlobalStore { +func (s *RedisStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { r, err := redisGet().Get(ctx, config.Store.RedisPrefix+"_g_"+gid).Result() if err == redis.Nil { return nil } dtmimp.E2P(err) - trans := &TransGlobalStore{} + trans := &storage.TransGlobalStore{} dtmimp.MustUnmarshalString(r, trans) return trans } -func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []TransGlobalStore { +func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { lid := uint64(0) if *position != "" { lid = uint64(dtmimp.MustAtoi(*position)) } keys, cursor, err := redisGet().Scan(ctx, lid, config.Store.RedisPrefix+"_g_*", limit).Result() dtmimp.E2P(err) - globals := []TransGlobalStore{} + globals := []storage.TransGlobalStore{} if len(keys) > 0 { values, err := redisGet().MGet(ctx, keys...).Result() dtmimp.E2P(err) for _, v := range values { - global := TransGlobalStore{} + global := storage.TransGlobalStore{} dtmimp.MustUnmarshalString(v.(string), &global) globals = append(globals, global) } @@ -62,17 +66,17 @@ func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []Tran return globals } -func (s *RedisStore) FindBranches(gid string) []TransBranchStore { +func (s *RedisStore) FindBranches(gid string) []storage.TransBranchStore { sa, err := redisGet().LRange(ctx, config.Store.RedisPrefix+"_b_"+gid, 0, -1).Result() dtmimp.E2P(err) - branches := make([]TransBranchStore, len(sa)) + branches := make([]storage.TransBranchStore, len(sa)) for k, v := range sa { dtmimp.MustUnmarshalString(v, &branches[k]) } return branches } -func (s *RedisStore) UpdateBranchesSql(branches []TransBranchStore, updates []string) *gorm.DB { +func (s *RedisStore) UpdateBranchesSql(branches []storage.TransBranchStore, updates []string) *gorm.DB { return nil // not implemented } @@ -102,7 +106,7 @@ func (a *argList) AppendObject(v interface{}) *argList { return a.AppendRaw(dtmimp.MustMarshalString(v)) } -func (a *argList) AppendBranches(branches []TransBranchStore) *argList { +func (a *argList) AppendBranches(branches []storage.TransBranchStore) *argList { for _, b := range branches { a.AppendRaw(dtmimp.MustMarshalString(b)) } @@ -116,8 +120,8 @@ func handleRedisResult(ret interface{}, err error) (string, error) { } s, _ := ret.(string) err = map[string]error{ - "NOT_FOUND": ErrNotFound, - "UNIQUE_CONFLICT": ErrUniqueConflict, + "NOT_FOUND": storage.ErrNotFound, + "UNIQUE_CONFLICT": storage.ErrUniqueConflict, }[s] return s, err } @@ -128,7 +132,7 @@ func callLua(a *argList, lua string) (string, error) { return handleRedisResult(ret, err) } -func (s *RedisStore) MaySaveNewTrans(global *TransGlobalStore, branches []TransBranchStore) error { +func (s *RedisStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { a := newArgList(). AppendGid(global.Gid). AppendObject(global). @@ -153,10 +157,10 @@ redis.call('EXPIRE', KEYS[2], ARGV[2]) return err } -func (s *RedisStore) LockGlobalSaveBranches(gid string, status string, branches []TransBranchStore, branchStart int) { +func (s *RedisStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { args := newArgList(). AppendGid(gid). - AppendObject(&TransGlobalStore{Gid: gid, Status: status}). + AppendObject(&storage.TransGlobalStore{Gid: gid, Status: status}). AppendRaw(branchStart). AppendBranches(branches) _, err := callLua(args, ` @@ -182,7 +186,7 @@ redis.call('EXPIRE', KEYS[2], ARGV[2]) dtmimp.E2P(err) } -func (s *RedisStore) ChangeGlobalStatus(global *TransGlobalStore, newStatus string, updates []string, finished bool) { +func (s *RedisStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus args := newArgList().AppendGid(global.Gid).AppendObject(global).AppendRaw(old).AppendRaw(finished) @@ -205,7 +209,7 @@ end dtmimp.E2P(err) } -func (s *RedisStore) LockOneGlobalTrans(expireIn time.Duration) *TransGlobalStore { +func (s *RedisStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { expired := time.Now().Add(expireIn).Unix() next := time.Now().Add(time.Duration(config.RetryInterval) * time.Second).Unix() args := newArgList().AppendGid("").AppendRaw(expired).AppendRaw(next) @@ -224,7 +228,7 @@ return gid ` for { r, err := callLua(args, lua) - if err == ErrNotFound { + if err == storage.ErrNotFound { return nil } dtmimp.E2P(err) @@ -235,7 +239,7 @@ return gid } } -func (s *RedisStore) TouchCronTime(global *TransGlobalStore, nextCronInterval int64) { +func (s *RedisStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { global.NextCronTime = common.GetNextTime(nextCronInterval) global.UpdateTime = common.GetNextTime(0) global.NextCronInterval = nextCronInterval @@ -255,3 +259,7 @@ redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) `) dtmimp.E2P(err) } + +func redisGet() *redis.Client { + return common.RedisGet() +} diff --git a/dtmsvr/storage/registry/registry.go b/dtmsvr/storage/registry/registry.go index 250ffe2..e0fbe93 100644 --- a/dtmsvr/storage/registry/registry.go +++ b/dtmsvr/storage/registry/registry.go @@ -6,14 +6,16 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmsvr/storage" "github.com/yedf/dtm/dtmsvr/storage/boltdb" + "github.com/yedf/dtm/dtmsvr/storage/redis" + "github.com/yedf/dtm/dtmsvr/storage/sql" ) var config = &common.Config var stores map[string]storage.Store = map[string]storage.Store{ - "redis": &storage.RedisStore{}, - "mysql": &storage.SqlStore{}, - "postgres": &storage.SqlStore{}, + "redis": &redis.RedisStore{}, + "mysql": &sql.SqlStore{}, + "postgres": &sql.SqlStore{}, "boltdb": &boltdb.BoltdbStore{}, } diff --git a/dtmsvr/storage/sql.go b/dtmsvr/storage/sql/sql.go similarity index 71% rename from dtmsvr/storage/sql.go rename to dtmsvr/storage/sql/sql.go index 40a399f..db4ad26 100644 --- a/dtmsvr/storage/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -1,4 +1,4 @@ -package storage +package sql import ( "fmt" @@ -6,12 +6,16 @@ import ( "time" "github.com/google/uuid" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/dtmimp" "gorm.io/gorm" "gorm.io/gorm/clause" + + "github.com/yedf/dtm/common" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmsvr/storage" ) +var config = &common.Config + type SqlStore struct { } @@ -27,8 +31,8 @@ func (s *SqlStore) PopulateData(skipDrop bool) { common.RunSQLScript(config.Store.GetDBConf(), file, skipDrop) } -func (s *SqlStore) FindTransGlobalStore(gid string) *TransGlobalStore { - trans := &TransGlobalStore{} +func (s *SqlStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { + trans := &storage.TransGlobalStore{} dbr := dbGet().Model(trans).Where("gid=?", gid).First(trans) if dbr.Error == gorm.ErrRecordNotFound { return nil @@ -37,8 +41,8 @@ func (s *SqlStore) FindTransGlobalStore(gid string) *TransGlobalStore { return trans } -func (s *SqlStore) ScanTransGlobalStores(position *string, limit int64) []TransGlobalStore { - globals := []TransGlobalStore{} +func (s *SqlStore) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { + globals := []storage.TransGlobalStore{} lid := math.MaxInt64 if *position != "" { lid = dtmimp.MustAtoi(*position) @@ -52,22 +56,22 @@ func (s *SqlStore) ScanTransGlobalStores(position *string, limit int64) []TransG return globals } -func (s *SqlStore) FindBranches(gid string) []TransBranchStore { - branches := []TransBranchStore{} +func (s *SqlStore) FindBranches(gid string) []storage.TransBranchStore { + branches := []storage.TransBranchStore{} dbGet().Must().Where("gid=?", gid).Order("id asc").Find(&branches) return branches } -func (s *SqlStore) UpdateBranchesSql(branches []TransBranchStore, updates []string) *gorm.DB { +func (s *SqlStore) UpdateBranchesSql(branches []storage.TransBranchStore, updates []string) *gorm.DB { return dbGet().Clauses(clause.OnConflict{ OnConstraint: "trans_branch_op_pkey", DoUpdates: clause.AssignmentColumns(updates), }).Create(branches) } -func (s *SqlStore) LockGlobalSaveBranches(gid string, status string, branches []TransBranchStore, branchStart int) { +func (s *SqlStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { err := dbGet().Transaction(func(tx *gorm.DB) error { - g := &TransGlobalStore{} + g := &storage.TransGlobalStore{} dbr := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Model(g).Where("gid=? and status=?", gid, status).First(g) if dbr.Error == nil { dbr = tx.Save(branches) @@ -77,14 +81,14 @@ func (s *SqlStore) LockGlobalSaveBranches(gid string, status string, branches [] dtmimp.E2P(err) } -func (s *SqlStore) MaySaveNewTrans(global *TransGlobalStore, branches []TransBranchStore) error { +func (s *SqlStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { return dbGet().Transaction(func(db1 *gorm.DB) error { db := &common.DB{DB: db1} dbr := db.Must().Clauses(clause.OnConflict{ DoNothing: true, }).Create(global) if dbr.RowsAffected <= 0 { // 如果这个不是新事务,返回错误 - return ErrUniqueConflict + return storage.ErrUniqueConflict } if len(branches) > 0 { db.Must().Clauses(clause.OnConflict{ @@ -95,16 +99,16 @@ func (s *SqlStore) MaySaveNewTrans(global *TransGlobalStore, branches []TransBra }) } -func (s *SqlStore) ChangeGlobalStatus(global *TransGlobalStore, newStatus string, updates []string, finished bool) { +func (s *SqlStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus dbr := dbGet().Must().Model(global).Where("status=? and gid=?", old, global.Gid).Select(updates).Updates(global) if dbr.RowsAffected == 0 { - dtmimp.E2P(ErrNotFound) + dtmimp.E2P(storage.ErrNotFound) } } -func (s *SqlStore) TouchCronTime(global *TransGlobalStore, nextCronInterval int64) { +func (s *SqlStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { global.NextCronTime = common.GetNextTime(nextCronInterval) global.UpdateTime = common.GetNextTime(0) global.NextCronInterval = nextCronInterval @@ -112,7 +116,7 @@ func (s *SqlStore) TouchCronTime(global *TransGlobalStore, nextCronInterval int6 Select([]string{"next_cron_time", "update_time", "next_cron_interval"}).Updates(global) } -func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *TransGlobalStore { +func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { db := dbGet() getTime := func(second int) string { return map[string]string{ @@ -123,12 +127,12 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *TransGlobalStore expire := int(expireIn / time.Second) whereTime := fmt.Sprintf("next_cron_time < %s", getTime(expire)) owner := uuid.NewString() - global := &TransGlobalStore{} + global := &storage.TransGlobalStore{} dbr := db.Must().Model(global). Where(whereTime + "and status in ('prepared', 'aborting', 'submitted')"). Limit(1). Select([]string{"owner", "next_cron_time"}). - Updates(&TransGlobalStore{ + Updates(&storage.TransGlobalStore{ Owner: owner, NextCronTime: common.GetNextTime(common.Config.RetryInterval), }) @@ -138,3 +142,15 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *TransGlobalStore dbr = db.Must().Where("owner=?", owner).First(global) return global } + +func dbGet() *common.DB { + return common.DbGet(config.Store.GetDBConf()) +} + +func wrapError(err error) error { + if err == gorm.ErrRecordNotFound { + return storage.ErrNotFound + } + dtmimp.E2P(err) + return err +} diff --git a/dtmsvr/storage/store.go b/dtmsvr/storage/store.go index d68b1a4..54a40f9 100644 --- a/dtmsvr/storage/store.go +++ b/dtmsvr/storage/store.go @@ -4,8 +4,6 @@ import ( "errors" "time" - "github.com/go-redis/redis/v8" - "github.com/yedf/dtm/dtmcli/dtmimp" "gorm.io/gorm" ) @@ -25,11 +23,3 @@ type Store interface { TouchCronTime(global *TransGlobalStore, nextCronInterval int64) LockOneGlobalTrans(expireIn time.Duration) *TransGlobalStore } - -func wrapError(err error) error { - if err == gorm.ErrRecordNotFound || err == redis.Nil { - return ErrNotFound - } - dtmimp.E2P(err) - return err -} diff --git a/dtmsvr/storage/utils.go b/dtmsvr/storage/utils.go deleted file mode 100644 index d2d73d1..0000000 --- a/dtmsvr/storage/utils.go +++ /dev/null @@ -1,16 +0,0 @@ -package storage - -import ( - "github.com/go-redis/redis/v8" - "github.com/yedf/dtm/common" -) - -var config = &common.Config - -func dbGet() *common.DB { - return common.DbGet(config.Store.GetDBConf()) -} - -func redisGet() *redis.Client { - return common.RedisGet() -} From 9cef2484ea96254881aea4ea49a899c4f64f1f8e Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 14:04:00 +0800 Subject: [PATCH 007/124] use codecov --- .github/workflows/tests.yml | 45 ++++ .gitignore | 5 +- .travis.yml | 18 -- dtmgrpc/dtmgimp/grpc_clients.go | 12 +- dtmgrpc/dtmgimp/utils.go | 5 +- dtmgrpc/{dtmgimp => dtmgpb}/dtmgimp.pb.go | 219 +++++++++--------- dtmgrpc/{dtmgimp => dtmgpb}/dtmgimp.proto | 2 +- .../{dtmgimp => dtmgpb}/dtmgimp_grpc.pb.go | 10 +- dtmgrpc/tcc.go | 5 +- dtmgrpc/xa.go | 7 +- dtmsvr/api_grpc.go | 6 +- dtmsvr/svr.go | 3 +- dtmsvr/trans_class.go | 6 +- examples/base_grpc.go | 5 +- go.sum | 1 + helper/test-cover.sh | 13 ++ 16 files changed, 199 insertions(+), 163 deletions(-) create mode 100644 .github/workflows/tests.yml delete mode 100644 .travis.yml rename dtmgrpc/{dtmgimp => dtmgpb}/dtmgimp.pb.go (54%) rename dtmgrpc/{dtmgimp => dtmgpb}/dtmgimp.proto (96%) rename dtmgrpc/{dtmgimp => dtmgpb}/dtmgimp_grpc.pb.go (97%) create mode 100644 helper/test-cover.sh diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..2282245 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,45 @@ +name: Tests +on: + push: + branches-ignore: + - 'tmp-*' + pull_request: + branches-ignore: + - 'tmp-*' + +jobs: + tests: + name: CI + runs-on: ubuntu-latest + services: + mysql: + image: 'mysql:5.7' + env: + MYSQL_ALLOW_EMPTY_PASSWORD: 1 + volumes: + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + ports: + - 3306:3306 + reids: + image: 'redis' + volumes: + - /etc/localtime:/etc/localtime:ro + - /etc/timezone:/etc/timezone:ro + ports: + - 6379:6379 + steps: + - name: Set up Go 1.15 + uses: actions/setup-go@v2 + with: + go-version: '1.15' + + - name: Check out code + uses: actions/checkout@v2 + + - name: Install dependencies + run: | + go mod download + + - name: Run test cover + run: sh helper/test-cover.sh diff --git a/.gitignore b/.gitignore index ca6b347..771c69c 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,6 @@ default.etcd */**/*.bolt # Output file of unit test coverage -coverage.out -coverage.out.tmp \ No newline at end of file +coverage.* +profile.* +test.sh \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5fde38f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: go -go: - - 1.15.x -env: - - GO111MODULE=on -branches: - only: - - master - - main - - alpha -services: - - mysql - - redis-server -before_install: - - go get -t -v ./... - - go get github.com/yedf2/goveralls -script: - - $GOPATH/bin/goveralls -envs=TEST_STORE=redis,TEST_STORE=mysql,TEST_STORE=boltdb -flags '-gcflags=-l' -service=travis-ci -ignore="examples/*,dtmgrpc/dtmgimp/*.pb.go,bench/*,test/*" diff --git a/dtmgrpc/dtmgimp/grpc_clients.go b/dtmgrpc/dtmgimp/grpc_clients.go index 917f322..17c7b54 100644 --- a/dtmgrpc/dtmgimp/grpc_clients.go +++ b/dtmgrpc/dtmgimp/grpc_clients.go @@ -8,9 +8,11 @@ package dtmgimp import ( "fmt" + "sync" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgpb" grpc "google.golang.org/grpc" - "sync" ) type rawCodec struct{} @@ -33,13 +35,13 @@ func (cb rawCodec) Name() string { return "dtm_raw" } var normalClients, rawClients sync.Map // MustGetDtmClient 1 -func MustGetDtmClient(grpcServer string) DtmClient { - return NewDtmClient(MustGetGrpcConn(grpcServer, false)) +func MustGetDtmClient(grpcServer string) dtmgpb.DtmClient { + return dtmgpb.NewDtmClient(MustGetGrpcConn(grpcServer, false)) } // MustGetRawDtmClient must get raw codec grpc conn -func MustGetRawDtmClient(grpcServer string) DtmClient { - return NewDtmClient(MustGetGrpcConn(grpcServer, true)) +func MustGetRawDtmClient(grpcServer string) dtmgpb.DtmClient { + return dtmgpb.NewDtmClient(MustGetGrpcConn(grpcServer, true)) } // GetGrpcConn 1 diff --git a/dtmgrpc/dtmgimp/utils.go b/dtmgrpc/dtmgimp/utils.go index ba2e08e..357d0c7 100644 --- a/dtmgrpc/dtmgimp/utils.go +++ b/dtmgrpc/dtmgimp/utils.go @@ -10,6 +10,7 @@ import ( context "context" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgpb" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -25,10 +26,10 @@ func MustProtoMarshal(msg proto.Message) []byte { // DtmGrpcCall make a convenient call to dtm func DtmGrpcCall(s *dtmimp.TransBase, operation string) error { reply := emptypb.Empty{} - return MustGetGrpcConn(s.Dtm, false).Invoke(context.Background(), "/dtmgimp.Dtm/"+operation, &DtmRequest{ + return MustGetGrpcConn(s.Dtm, false).Invoke(context.Background(), "/dtmgimp.Dtm/"+operation, &dtmgpb.DtmRequest{ Gid: s.Gid, TransType: s.TransType, - TransOptions: &DtmTransOptions{ + TransOptions: &dtmgpb.DtmTransOptions{ WaitResult: s.WaitResult, TimeoutToFail: s.TimeoutToFail, RetryInterval: s.RetryInterval, diff --git a/dtmgrpc/dtmgimp/dtmgimp.pb.go b/dtmgrpc/dtmgpb/dtmgimp.pb.go similarity index 54% rename from dtmgrpc/dtmgimp/dtmgimp.pb.go rename to dtmgrpc/dtmgpb/dtmgimp.pb.go index 3b28c14..89a2526 100644 --- a/dtmgrpc/dtmgimp/dtmgimp.pb.go +++ b/dtmgrpc/dtmgpb/dtmgimp.pb.go @@ -1,16 +1,10 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.27.1 // protoc v3.17.3 -// source: dtmgrpc/dtmgimp/dtmgimp.proto +// source: dtmgrpc/dtmgpb/dtmgimp.proto -package dtmgimp +package dtmgpb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" @@ -40,7 +34,7 @@ type DtmTransOptions struct { func (x *DtmTransOptions) Reset() { *x = DtmTransOptions{} if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[0] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[0] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -53,7 +47,7 @@ func (x *DtmTransOptions) String() string { func (*DtmTransOptions) ProtoMessage() {} func (x *DtmTransOptions) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[0] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[0] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -66,7 +60,7 @@ func (x *DtmTransOptions) ProtoReflect() protoreflect.Message { // Deprecated: Use DtmTransOptions.ProtoReflect.Descriptor instead. func (*DtmTransOptions) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{0} + return file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescGZIP(), []int{0} } func (x *DtmTransOptions) GetWaitResult() bool { @@ -108,7 +102,7 @@ type DtmRequest struct { func (x *DtmRequest) Reset() { *x = DtmRequest{} if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[1] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[1] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -121,7 +115,7 @@ func (x *DtmRequest) String() string { func (*DtmRequest) ProtoMessage() {} func (x *DtmRequest) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[1] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[1] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -134,7 +128,7 @@ func (x *DtmRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DtmRequest.ProtoReflect.Descriptor instead. func (*DtmRequest) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{1} + return file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescGZIP(), []int{1} } func (x *DtmRequest) GetGid() string { @@ -197,7 +191,7 @@ type DtmGidReply struct { func (x *DtmGidReply) Reset() { *x = DtmGidReply{} if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[2] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[2] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -210,7 +204,7 @@ func (x *DtmGidReply) String() string { func (*DtmGidReply) ProtoMessage() {} func (x *DtmGidReply) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[2] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[2] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -223,7 +217,7 @@ func (x *DtmGidReply) ProtoReflect() protoreflect.Message { // Deprecated: Use DtmGidReply.ProtoReflect.Descriptor instead. func (*DtmGidReply) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{2} + return file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescGZIP(), []int{2} } func (x *DtmGidReply) GetGid() string { @@ -249,7 +243,7 @@ type DtmBranchRequest struct { func (x *DtmBranchRequest) Reset() { *x = DtmBranchRequest{} if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[3] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -262,7 +256,7 @@ func (x *DtmBranchRequest) String() string { func (*DtmBranchRequest) ProtoMessage() {} func (x *DtmBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[3] + mi := &file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -275,7 +269,7 @@ func (x *DtmBranchRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use DtmBranchRequest.ProtoReflect.Descriptor instead. func (*DtmBranchRequest) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{3} + return file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescGZIP(), []int{3} } func (x *DtmBranchRequest) GetGid() string { @@ -320,93 +314,92 @@ func (x *DtmBranchRequest) GetBusiPayload() []byte { return nil } -var File_dtmgrpc_dtmgimp_dtmgimp_proto protoreflect.FileDescriptor - -var file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc = []byte{ - 0x0a, 0x1d, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, - 0x70, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, - 0x07, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7d, 0x0a, 0x0f, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x57, 0x61, 0x69, 0x74, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x57, 0x61, - 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, - 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x12, 0x24, - 0x0a, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, - 0x72, 0x76, 0x61, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x0a, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, - 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, - 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x74, 0x6d, 0x67, - 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x52, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, - 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x64, 0x44, 0x61, 0x74, - 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, - 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6c, - 0x6f, 0x61, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x69, 0x6e, 0x50, - 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, - 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, - 0x05, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, - 0x65, 0x70, 0x73, 0x22, 0x1f, 0x0a, 0x0b, 0x44, 0x74, 0x6d, 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x47, 0x69, 0x64, 0x22, 0x82, 0x02, 0x0a, 0x10, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x4f, 0x70, 0x12, 0x37, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, - 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, - 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, - 0x0a, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, - 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xb1, 0x02, 0x0a, 0x03, 0x44, 0x74, - 0x6d, 0x12, 0x38, 0x0a, 0x06, 0x4e, 0x65, 0x77, 0x47, 0x69, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, - 0x6d, 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x53, - 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, - 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, +var File_dtmgrpc_dtmgpb_dtmgimp_proto protoreflect.FileDescriptor + +var file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDesc = []byte{ + 0x0a, 0x1c, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x70, 0x62, + 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, + 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7d, 0x0a, 0x0f, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x57, 0x61, 0x69, 0x74, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x57, 0x61, 0x69, + 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, + 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x12, 0x24, 0x0a, + 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, + 0x76, 0x61, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x0a, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, + 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, + 0x6e, 0x73, 0x52, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x64, + 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x69, 0x6e, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x51, + 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, + 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, 0x65, + 0x70, 0x73, 0x22, 0x1f, 0x0a, 0x0b, 0x44, 0x74, 0x6d, 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x47, 0x69, 0x64, 0x22, 0x82, 0x02, 0x0a, 0x10, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x02, 0x4f, 0x70, 0x12, 0x37, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, + 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, + 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, + 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, + 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, + 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, + 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xb1, 0x02, 0x0a, 0x03, 0x44, 0x74, 0x6d, + 0x12, 0x38, 0x0a, 0x06, 0x4e, 0x65, 0x77, 0x47, 0x69, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, - 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, - 0x0a, 0x05, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, - 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, - 0x65, 0x72, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x19, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, - 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, + 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x53, 0x75, + 0x62, 0x6d, 0x69, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, + 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x13, + 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x0b, 0x5a, - 0x09, 0x2e, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x33, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, + 0x05, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, + 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, + 0x72, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x19, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, + 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, + 0x2e, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescOnce sync.Once - file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData = file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc + file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescOnce sync.Once + file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescData = file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDesc ) -func file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP() []byte { - file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescOnce.Do(func() { - file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData = protoimpl.X.CompressGZIP(file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData) +func file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescGZIP() []byte { + file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescOnce.Do(func() { + file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescData = protoimpl.X.CompressGZIP(file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescData) }) - return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData + return file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescData } -var file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes = make([]protoimpl.MessageInfo, 5) -var file_dtmgrpc_dtmgimp_dtmgimp_proto_goTypes = []interface{}{ +var file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_dtmgrpc_dtmgpb_dtmgimp_proto_goTypes = []interface{}{ (*DtmTransOptions)(nil), // 0: dtmgimp.DtmTransOptions (*DtmRequest)(nil), // 1: dtmgimp.DtmRequest (*DtmGidReply)(nil), // 2: dtmgimp.DtmGidReply @@ -414,7 +407,7 @@ var file_dtmgrpc_dtmgimp_dtmgimp_proto_goTypes = []interface{}{ nil, // 4: dtmgimp.DtmBranchRequest.DataEntry (*emptypb.Empty)(nil), // 5: google.protobuf.Empty } -var file_dtmgrpc_dtmgimp_dtmgimp_proto_depIdxs = []int32{ +var file_dtmgrpc_dtmgpb_dtmgimp_proto_depIdxs = []int32{ 0, // 0: dtmgimp.DtmRequest.TransOptions:type_name -> dtmgimp.DtmTransOptions 4, // 1: dtmgimp.DtmBranchRequest.Data:type_name -> dtmgimp.DtmBranchRequest.DataEntry 5, // 2: dtmgimp.Dtm.NewGid:input_type -> google.protobuf.Empty @@ -434,13 +427,13 @@ var file_dtmgrpc_dtmgimp_dtmgimp_proto_depIdxs = []int32{ 0, // [0:2] is the sub-list for field type_name } -func init() { file_dtmgrpc_dtmgimp_dtmgimp_proto_init() } -func file_dtmgrpc_dtmgimp_dtmgimp_proto_init() { - if File_dtmgrpc_dtmgimp_dtmgimp_proto != nil { +func init() { file_dtmgrpc_dtmgpb_dtmgimp_proto_init() } +func file_dtmgrpc_dtmgpb_dtmgimp_proto_init() { + if File_dtmgrpc_dtmgpb_dtmgimp_proto != nil { return } if !protoimpl.UnsafeEnabled { - file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DtmTransOptions); i { case 0: return &v.state @@ -452,7 +445,7 @@ func file_dtmgrpc_dtmgimp_dtmgimp_proto_init() { return nil } } - file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DtmRequest); i { case 0: return &v.state @@ -464,7 +457,7 @@ func file_dtmgrpc_dtmgimp_dtmgimp_proto_init() { return nil } } - file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DtmGidReply); i { case 0: return &v.state @@ -476,7 +469,7 @@ func file_dtmgrpc_dtmgimp_dtmgimp_proto_init() { return nil } } - file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*DtmBranchRequest); i { case 0: return &v.state @@ -493,18 +486,18 @@ func file_dtmgrpc_dtmgimp_dtmgimp_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc, + RawDescriptor: file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDesc, NumEnums: 0, NumMessages: 5, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_dtmgrpc_dtmgimp_dtmgimp_proto_goTypes, - DependencyIndexes: file_dtmgrpc_dtmgimp_dtmgimp_proto_depIdxs, - MessageInfos: file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes, + GoTypes: file_dtmgrpc_dtmgpb_dtmgimp_proto_goTypes, + DependencyIndexes: file_dtmgrpc_dtmgpb_dtmgimp_proto_depIdxs, + MessageInfos: file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes, }.Build() - File_dtmgrpc_dtmgimp_dtmgimp_proto = out.File - file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc = nil - file_dtmgrpc_dtmgimp_dtmgimp_proto_goTypes = nil - file_dtmgrpc_dtmgimp_dtmgimp_proto_depIdxs = nil + File_dtmgrpc_dtmgpb_dtmgimp_proto = out.File + file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDesc = nil + file_dtmgrpc_dtmgpb_dtmgimp_proto_goTypes = nil + file_dtmgrpc_dtmgpb_dtmgimp_proto_depIdxs = nil } diff --git a/dtmgrpc/dtmgimp/dtmgimp.proto b/dtmgrpc/dtmgpb/dtmgimp.proto similarity index 96% rename from dtmgrpc/dtmgimp/dtmgimp.proto rename to dtmgrpc/dtmgpb/dtmgimp.proto index a6ef5e6..84e3105 100644 --- a/dtmgrpc/dtmgimp/dtmgimp.proto +++ b/dtmgrpc/dtmgpb/dtmgimp.proto @@ -1,6 +1,6 @@ syntax = "proto3"; -option go_package = "./dtmgimp"; +option go_package = "./dtmgpb"; import "google/protobuf/empty.proto"; package dtmgimp; diff --git a/dtmgrpc/dtmgimp/dtmgimp_grpc.pb.go b/dtmgrpc/dtmgpb/dtmgimp_grpc.pb.go similarity index 97% rename from dtmgrpc/dtmgimp/dtmgimp_grpc.pb.go rename to dtmgrpc/dtmgpb/dtmgimp_grpc.pb.go index 8d35989..8381443 100644 --- a/dtmgrpc/dtmgimp/dtmgimp_grpc.pb.go +++ b/dtmgrpc/dtmgpb/dtmgimp_grpc.pb.go @@ -1,12 +1,6 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -package dtmgimp +package dtmgpb import ( context "context" @@ -248,5 +242,5 @@ var Dtm_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "dtmgrpc/dtmgimp/dtmgimp.proto", + Metadata: "dtmgrpc/dtmgpb/dtmgimp.proto", } diff --git a/dtmgrpc/tcc.go b/dtmgrpc/tcc.go index ebc1c59..1b8bebd 100644 --- a/dtmgrpc/tcc.go +++ b/dtmgrpc/tcc.go @@ -12,6 +12,7 @@ import ( "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/yedf/dtm/dtmgrpc/dtmgpb" "github.com/yedf/dtmdriver" "google.golang.org/protobuf/proto" ) @@ -31,7 +32,7 @@ type TccGlobalFunc func(tcc *TccGrpc) error func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr error) { tcc := &TccGrpc{TransBase: *dtmimp.NewTransBase(gid, "tcc", dtm, "")} dc := dtmgimp.MustGetDtmClient(tcc.Dtm) - dr := &dtmgimp.DtmRequest{ + dr := &dtmgpb.DtmRequest{ Gid: tcc.Gid, TransType: tcc.TransType, } @@ -72,7 +73,7 @@ func TccFromGrpc(ctx context.Context) (*TccGrpc, error) { func (t *TccGrpc) CallBranch(busiMsg proto.Message, tryURL string, confirmURL string, cancelURL string, reply interface{}) error { branchID := t.NewSubBranchID() bd, err := proto.Marshal(busiMsg) - _, err = dtmgimp.MustGetDtmClient(t.Dtm).RegisterBranch(context.Background(), &dtmgimp.DtmBranchRequest{ + _, err = dtmgimp.MustGetDtmClient(t.Dtm).RegisterBranch(context.Background(), &dtmgpb.DtmBranchRequest{ Gid: t.Gid, TransType: t.TransType, BranchID: branchID, diff --git a/dtmgrpc/xa.go b/dtmgrpc/xa.go index c12a7e6..23ba33c 100644 --- a/dtmgrpc/xa.go +++ b/dtmgrpc/xa.go @@ -14,6 +14,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/yedf/dtm/dtmgrpc/dtmgpb" "github.com/yedf/dtmdriver" grpc "google.golang.org/grpc" "google.golang.org/protobuf/proto" @@ -78,7 +79,7 @@ func (xc *XaGrpcClient) XaLocalTransaction(ctx context.Context, msg proto.Messag if err != nil { return err } - _, err = dtmgimp.MustGetDtmClient(xa.Dtm).RegisterBranch(context.Background(), &dtmgimp.DtmBranchRequest{ + _, err = dtmgimp.MustGetDtmClient(xa.Dtm).RegisterBranch(context.Background(), &dtmgpb.DtmBranchRequest{ Gid: xa.Gid, BranchID: xa.BranchID, TransType: xa.TransType, @@ -93,12 +94,12 @@ func (xc *XaGrpcClient) XaLocalTransaction(ctx context.Context, msg proto.Messag func (xc *XaGrpcClient) XaGlobalTransaction(gid string, xaFunc XaGrpcGlobalFunc) error { xa := XaGrpc{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.Server, "")} dc := dtmgimp.MustGetDtmClient(xa.Dtm) - req := &dtmgimp.DtmRequest{ + req := &dtmgpb.DtmRequest{ Gid: gid, TransType: xa.TransType, } return xc.HandleGlobalTrans(&xa.TransBase, func(action string) error { - f := map[string]func(context.Context, *dtmgimp.DtmRequest, ...grpc.CallOption) (*emptypb.Empty, error){ + f := map[string]func(context.Context, *dtmgpb.DtmRequest, ...grpc.CallOption) (*emptypb.Empty, error){ "prepare": dc.Prepare, "submit": dc.Submit, "abort": dc.Abort, diff --git a/dtmsvr/api_grpc.go b/dtmsvr/api_grpc.go index 07e4d0e..4d4daf8 100644 --- a/dtmsvr/api_grpc.go +++ b/dtmsvr/api_grpc.go @@ -11,7 +11,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmgrpc/dtmgimp" - pb "github.com/yedf/dtm/dtmgrpc/dtmgimp" + pb "github.com/yedf/dtm/dtmgrpc/dtmgpb" "google.golang.org/protobuf/types/known/emptypb" ) @@ -20,8 +20,8 @@ type dtmServer struct { pb.UnimplementedDtmServer } -func (s *dtmServer) NewGid(ctx context.Context, in *emptypb.Empty) (*dtmgimp.DtmGidReply, error) { - return &dtmgimp.DtmGidReply{Gid: GenGid()}, nil +func (s *dtmServer) NewGid(ctx context.Context, in *emptypb.Empty) (*pb.DtmGidReply, error) { + return &pb.DtmGidReply{Gid: GenGid()}, nil } func (s *dtmServer) Submit(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index af92105..ac0dbf2 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -15,6 +15,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/yedf/dtm/dtmgrpc/dtmgpb" "github.com/yedf/dtmdriver" "google.golang.org/grpc" ) @@ -34,7 +35,7 @@ func StartSvr() { grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( grpc.UnaryServerInterceptor(grpcMetrics), grpc.UnaryServerInterceptor(dtmgimp.GrpcServerLog)), )) - dtmgimp.RegisterDtmServer(s, &dtmServer{}) + dtmgpb.RegisterDtmServer(s, &dtmServer{}) dtmimp.Logf("grpc listening at %v", lis.Addr()) go func() { err := s.Serve(lis) diff --git a/dtmsvr/trans_class.go b/dtmsvr/trans_class.go index 4ce6b9e..d8ea01b 100644 --- a/dtmsvr/trans_class.go +++ b/dtmsvr/trans_class.go @@ -12,7 +12,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/yedf/dtm/dtmgrpc/dtmgpb" "github.com/yedf/dtm/dtmsvr/storage" ) @@ -72,8 +72,8 @@ func TransFromContext(c *gin.Context) *TransGlobal { } // TransFromDtmRequest TransFromContext -func TransFromDtmRequest(c *dtmgimp.DtmRequest) *TransGlobal { - o := &dtmgimp.DtmTransOptions{} +func TransFromDtmRequest(c *dtmgpb.DtmRequest) *TransGlobal { + o := &dtmgpb.DtmTransOptions{} if c.TransOptions != nil { o = c.TransOptions } diff --git a/examples/base_grpc.go b/examples/base_grpc.go index d0002b4..3bff6a5 100644 --- a/examples/base_grpc.go +++ b/examples/base_grpc.go @@ -19,6 +19,7 @@ import ( "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/yedf/dtm/dtmgrpc/dtmgpb" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" @@ -29,7 +30,7 @@ import ( var BusiGrpc string = fmt.Sprintf("localhost:%d", BusiGrpcPort) // DtmClient grpc client for dtm -var DtmClient dtmgimp.DtmClient = nil +var DtmClient dtmgpb.DtmClient = nil // XaGrpcClient XA client connection var XaGrpcClient *dtmgrpc.XaGrpcClient = nil @@ -44,7 +45,7 @@ func init() { func GrpcStartup() { conn, err := grpc.Dial(DtmGrpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(dtmgimp.GrpcClientLog)) dtmimp.FatalIfError(err) - DtmClient = dtmgimp.NewDtmClient(conn) + DtmClient = dtmgpb.NewDtmClient(conn) dtmimp.Logf("dtm client inited") lis, err := net.Listen("tcp", fmt.Sprintf(":%d", BusiGrpcPort)) diff --git a/go.sum b/go.sum index 6d8821e..a652bd4 100644 --- a/go.sum +++ b/go.sum @@ -892,3 +892,4 @@ sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZa sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= + diff --git a/helper/test-cover.sh b/helper/test-cover.sh new file mode 100644 index 0000000..0bf9fbe --- /dev/null +++ b/helper/test-cover.sh @@ -0,0 +1,13 @@ +set -x +echo "" > coverage.txt +for store in redis mysql boltdb; do + for d in $(go list ./... | grep -v vendor); do + TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/yedf/dtm/common,github.com/yedf/dtm/dtmcli,github.com/yedf/dtm/dtmcli/dtmimp,github.com/yedf/dtm/dtmgrpc,github.com/yedf/dtm/dtmgrpc/dtmgimp,github.com/yedf/dtm/dtmsvr,github.com/yedf/dtm/dtmsvr/storage,github.com/yedf/dtm/dtmsvr/storage/boltdb,github.com/yedf/dtm/dtmsvr/storage/registry -gcflags=-l $d + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + echo > profile.out + fi + done +done + +curl -s https://codecov.io/bash | bash From 656830980ca468faaa020e81ab81bbc412365a5d Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 14:23:18 +0800 Subject: [PATCH 008/124] use new badge --- README-cn.md | 4 ++-- README-en.md | 4 ++-- README.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README-cn.md b/README-cn.md index 8f866fc..527e771 100644 --- a/README-cn.md +++ b/README-cn.md @@ -1,6 +1,6 @@ ![license](https://img.shields.io/github/license/yedf/dtm) -[![Build Status](https://travis-ci.com/yedf/dtm.svg?branch=main)](https://travis-ci.com/yedf/dtm) -[![Coverage Status](https://coveralls.io/repos/github/yedf/dtm/badge.svg?branch=main)](https://coveralls.io/github/yedf/dtm?branch=main) +![Build Status](https://github.com/yedf/dtm/actions/workflows/tests.yml/badge.svg?branch=main) +[![codecov](https://codecov.io/gh/yedf/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/yedf/dtm) [![Go Report Card](https://goreportcard.com/badge/github.com/yedf/dtm)](https://goreportcard.com/report/github.com/yedf/dtm) [![Go Reference](https://pkg.go.dev/badge/github.com/yedf/dtm.svg)](https://pkg.go.dev/github.com/yedf/dtm) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#database) diff --git a/README-en.md b/README-en.md index 4f547b9..a16b0bf 100644 --- a/README-en.md +++ b/README-en.md @@ -1,6 +1,6 @@ ![license](https://img.shields.io/github/license/yedf/dtm) -[![Build Status](https://travis-ci.com/yedf/dtm.svg?branch=main)](https://travis-ci.com/yedf/dtm) -[![Coverage Status](https://coveralls.io/repos/github/yedf/dtm/badge.svg?branch=main)](https://coveralls.io/github/yedf/dtm?branch=main) +![Build Status](https://github.com/yedf/dtm/actions/workflows/tests.yml/badge.svg?branch=main) +[![codecov](https://codecov.io/gh/yedf/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/yedf/dtm) [![Go Report Card](https://goreportcard.com/badge/github.com/yedf/dtm)](https://goreportcard.com/report/github.com/yedf/dtm) [![Go Reference](https://pkg.go.dev/badge/github.com/yedf/dtm.svg)](https://pkg.go.dev/github.com/yedf/dtm) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#database) diff --git a/README.md b/README.md index 8f866fc..527e771 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ ![license](https://img.shields.io/github/license/yedf/dtm) -[![Build Status](https://travis-ci.com/yedf/dtm.svg?branch=main)](https://travis-ci.com/yedf/dtm) -[![Coverage Status](https://coveralls.io/repos/github/yedf/dtm/badge.svg?branch=main)](https://coveralls.io/github/yedf/dtm?branch=main) +![Build Status](https://github.com/yedf/dtm/actions/workflows/tests.yml/badge.svg?branch=main) +[![codecov](https://codecov.io/gh/yedf/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/yedf/dtm) [![Go Report Card](https://goreportcard.com/badge/github.com/yedf/dtm)](https://goreportcard.com/report/github.com/yedf/dtm) [![Go Reference](https://pkg.go.dev/badge/github.com/yedf/dtm.svg)](https://pkg.go.dev/github.com/yedf/dtm) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#database) From 0b1f2233cfabe9ee1dde5fe34474687e0aa7e251 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 15:52:46 +0800 Subject: [PATCH 009/124] add storage subdirs --- helper/test-cover.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/test-cover.sh b/helper/test-cover.sh index 0bf9fbe..b94a361 100644 --- a/helper/test-cover.sh +++ b/helper/test-cover.sh @@ -2,7 +2,7 @@ set -x echo "" > coverage.txt for store in redis mysql boltdb; do for d in $(go list ./... | grep -v vendor); do - TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/yedf/dtm/common,github.com/yedf/dtm/dtmcli,github.com/yedf/dtm/dtmcli/dtmimp,github.com/yedf/dtm/dtmgrpc,github.com/yedf/dtm/dtmgrpc/dtmgimp,github.com/yedf/dtm/dtmsvr,github.com/yedf/dtm/dtmsvr/storage,github.com/yedf/dtm/dtmsvr/storage/boltdb,github.com/yedf/dtm/dtmsvr/storage/registry -gcflags=-l $d + TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/yedf/dtm/common,github.com/yedf/dtm/dtmcli,github.com/yedf/dtm/dtmcli/dtmimp,github.com/yedf/dtm/dtmgrpc,github.com/yedf/dtm/dtmgrpc/dtmgimp,github.com/yedf/dtm/dtmsvr,github.com/yedf/dtm/dtmsvr/storage,github.com/yedf/dtm/dtmsvr/storage/boltdb,github.com/yedf/dtm/dtmsvr/storage/redis,github.com/yedf/dtm/dtmsvr/storage/registry,github.com/yedf/dtm/dtmsvr/storage/sql,github.com/yedf/dtm/dtmsvr/storage/boltdb,github.com/yedf/dtm/dtmsvr/storage/registry -gcflags=-l $d if [ -f profile.out ]; then cat profile.out >> coverage.txt echo > profile.out From 9cb10db62c7295a7b9550d6bf24cbb2740e2f595 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 16:00:35 +0800 Subject: [PATCH 010/124] empty url is supported --- dtmsvr/trans_status.go | 3 +++ test/saga_grpc_test.go | 11 +++++++++++ test/saga_test.go | 11 +++++++++++ 3 files changed, 25 insertions(+) diff --git a/dtmsvr/trans_status.go b/dtmsvr/trans_status.go index b7fda72..d7097ca 100644 --- a/dtmsvr/trans_status.go +++ b/dtmsvr/trans_status.go @@ -67,6 +67,9 @@ func (t *TransGlobal) needProcess() bool { } func (t *TransGlobal) getURLResult(url string, branchID, op string, branchPayload []byte) (string, error) { + if url == "" { // empty url is success + return dtmcli.ResultSuccess, nil + } if t.Protocol == "grpc" { dtmimp.PanicIf(strings.HasPrefix(url, "http"), fmt.Errorf("bad url for grpc: %s", url)) server, method, err := dtmdriver.GetDriver().ParseServerMethod(url) diff --git a/test/saga_grpc_test.go b/test/saga_grpc_test.go index ca06f07..d611241 100644 --- a/test/saga_grpc_test.go +++ b/test/saga_grpc_test.go @@ -75,6 +75,17 @@ func TestSagaGrpcNormalWait(t *testing.T) { waitTransProcessed(saga.Gid) } +func TestSagaGrpcEmptyUrl(t *testing.T) { + saga := dtmgrpc.NewSagaGrpc(examples.DtmGrpcServer, dtmimp.GetFuncName()) + req := examples.GenBusiReq(30, false, false) + saga.Add(examples.BusiGrpc+"/examples.Busi/TransOut", examples.BusiGrpc+"/examples.Busi/TransOutRevert", req) + saga.Add("", examples.BusiGrpc+"/examples.Busi/TransInRevert", req) + saga.Submit() + waitTransProcessed(saga.Gid) + assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) + assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) +} + func genSagaGrpc(gid string, outFailed bool, inFailed bool) *dtmgrpc.SagaGrpc { saga := dtmgrpc.NewSagaGrpc(examples.DtmGrpcServer, gid) req := examples.GenBusiReq(30, outFailed, inFailed) diff --git a/test/saga_test.go b/test/saga_test.go index 0e42b05..5fbc166 100644 --- a/test/saga_test.go +++ b/test/saga_test.go @@ -58,6 +58,17 @@ func TestSagaAbnormal(t *testing.T) { assert.Error(t, err) // a succeed trans can't accept submit } +func TestSagaEmptyUrl(t *testing.T) { + saga := dtmcli.NewSaga(examples.DtmHttpServer, dtmimp.GetFuncName()) + req := examples.GenTransReq(30, false, false) + saga.Add(examples.Busi+"/TransOut", "", &req) + saga.Add("", "", &req) + saga.Submit() + waitTransProcessed(saga.Gid) + assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) + assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) +} + func genSaga(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { saga := dtmcli.NewSaga(examples.DtmHttpServer, gid) req := examples.GenTransReq(30, outFailed, inFailed) From 9ef08f23f184d382473223f1d8de217521c9fb14 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 17:00:09 +0800 Subject: [PATCH 011/124] Fatal is changed --- app/main.go | 3 +- bench/http.go | 21 ++++---- common/config.go | 7 +-- common/utils.go | 7 +-- dtmcli/dtmimp/utils.go | 82 ++++++++---------------------- dtmcli/dtmimp/utils_test.go | 18 ------- dtmsvr/svr.go | 9 ++-- examples/base_grpc.go | 11 ++-- examples/base_types.go | 11 ++-- examples/data.go | 4 +- examples/grpc_msg.go | 4 +- examples/grpc_saga.go | 6 +-- examples/grpc_saga_barrier.go | 3 +- examples/grpc_tcc.go | 3 +- examples/grpc_xa.go | 4 +- examples/http_gorm_xa.go | 4 +- examples/http_msg.go | 5 +- examples/http_saga.go | 7 +-- examples/http_saga_barrier.go | 3 +- examples/http_saga_gorm_barrier.go | 3 +- examples/http_tcc.go | 7 +-- examples/http_tcc_barrier.go | 3 +- examples/http_xa.go | 6 +-- examples/quick_start.go | 3 +- test/types.go | 3 +- 25 files changed, 98 insertions(+), 139 deletions(-) diff --git a/app/main.go b/app/main.go index aa87722..3382911 100644 --- a/app/main.go +++ b/app/main.go @@ -16,6 +16,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr" "github.com/yedf/dtm/dtmsvr/storage/registry" "github.com/yedf/dtm/examples" @@ -75,7 +76,7 @@ func main() { examples.BaseAppStartup() sample := examples.Samples[os.Args[1]] - dtmimp.LogIfFatalf(sample == nil, "no sample name for %s", os.Args[1]) + logger.FatalfIf(sample == nil, "no sample name for %s", os.Args[1]) sample.Action() } select {} diff --git a/bench/http.go b/bench/http.go index 8a6a470..2e8389c 100644 --- a/bench/http.go +++ b/bench/http.go @@ -17,6 +17,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr" "github.com/yedf/dtm/examples" ) @@ -32,14 +33,14 @@ var benchBusi = fmt.Sprintf("http://localhost:%d%s", benchPort, benchAPI) func sdbGet() *sql.DB { db, err := dtmimp.PooledDB(common.Config.Store.GetDBConf()) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return db } func txGet() *sql.Tx { db := sdbGet() tx, err := db.Begin() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return tx } @@ -50,7 +51,7 @@ func reloadData() { tables := []string{"dtm_busi.user_account", "dtm_busi.user_account_log", "dtm.trans_global", "dtm.trans_branch_op", "dtm_barrier.barrier"} for _, t := range tables { _, err := dtmimp.DBExec(db, fmt.Sprintf("truncate %s", t)) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } s := "insert ignore into dtm_busi.user_account(user_id, balance) values " ss := []string{} @@ -58,7 +59,7 @@ func reloadData() { ss = append(ss, fmt.Sprintf("(%d, 1000000)", i)) } _, err := dtmimp.DBExec(db, s+strings.Join(ss, ",")) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) dtmimp.Logf("%d users inserted. used: %dms", total, time.Since(began).Milliseconds()) } @@ -74,7 +75,7 @@ func StartSvr() { go app.Run(fmt.Sprintf(":%d", benchPort)) db := sdbGet() _, err := dtmimp.DBExec(db, "drop table if exists dtm_busi.user_account_log") - dtmimp.FatalIfError(err) + logger.FatalIfError(err) _, err = dtmimp.DBExec(db, `create table if not exists dtm_busi.user_account_log ( id INT(11) AUTO_INCREMENT PRIMARY KEY, user_id INT(11) NOT NULL, @@ -89,7 +90,7 @@ func StartSvr() { key(create_time) ) `) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { @@ -101,21 +102,21 @@ func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { for i := 0; i < sqls; i++ { _, err := dtmimp.DBExec(tx, "insert into dtm_busi.user_account_log(user_id, delta, gid, branch_id, op, reason) values(?,?,?,?,?,?)", uid, amount, tb.Gid, c.Query("branch_id"), tb.TransType, fmt.Sprintf("inserted by dtm transaction %s %s", tb.Gid, c.Query("branch_id"))) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) _, err = dtmimp.DBExec(tx, "update dtm_busi.user_account set balance = balance + ?, update_time = now() where user_id = ?", amount, uid) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } return nil } if strings.Contains(mode, "barrier") { barrier, err := dtmcli.BarrierFromQuery(c.Request.URL.Query()) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) barrier.Call(txGet(), f) } else { tx := txGet() f(tx) err := tx.Commit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } return dtmcli.MapSuccess, nil diff --git a/common/config.go b/common/config.go index afc5852..6a0838a 100644 --- a/common/config.go +++ b/common/config.go @@ -8,6 +8,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "gopkg.in/yaml.v2" ) @@ -82,13 +83,13 @@ func MustLoadConfig() { } if len(cont) != 0 { err := yaml.UnmarshalStrict(cont, &Config) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } scont, err := json.MarshalIndent(&Config, "", " ") - dtmimp.FatalIfError(err) + logger.FatalIfError(err) dtmimp.Logf("config is: \n%s", scont) err = checkConfig() - dtmimp.LogIfFatalf(err != nil, `config error: '%v'. + logger.FatalfIf(err != nil, `config error: '%v'. check you env, and conf.yml/conf.sample.yml in current and parent path: %s. please visit http://d.dtm.pub to see the config document. loaded config is: diff --git a/common/utils.go b/common/utils.go index 9465a6c..5e690d9 100644 --- a/common/utils.go +++ b/common/utils.go @@ -20,6 +20,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) // GetGinApp init and return gin @@ -105,10 +106,10 @@ func GetNextTime(second int64) *time.Time { // RunSQLScript 1 func RunSQLScript(conf dtmcli.DBConf, script string, skipDrop bool) { con, err := dtmimp.StandaloneDB(conf) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) defer func() { con.Close() }() content, err := ioutil.ReadFile(script) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) sqls := strings.Split(string(content), ";") for _, sql := range sqls { s := strings.TrimSpace(sql) @@ -116,6 +117,6 @@ func RunSQLScript(conf dtmcli.DBConf, script string, skipDrop bool) { continue } _, err = dtmimp.DBExec(con, s) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } } diff --git a/dtmcli/dtmimp/utils.go b/dtmcli/dtmimp/utils.go index 693f08d..eb264bf 100644 --- a/dtmcli/dtmimp/utils.go +++ b/dtmcli/dtmimp/utils.go @@ -11,23 +11,36 @@ import ( "encoding/json" "errors" "fmt" - "log" "os" "runtime" - "runtime/debug" "strconv" "strings" "sync" "time" "github.com/go-resty/resty/v2" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" + "github.com/yedf/dtm/dtmcli/logger" ) +// Logf an alias of Infof +// Deprecated: use logger.Errorf +var Logf = logger.Infof + +// LogRedf an alias of Errorf +// Deprecated: use logger.Errorf +var LogRedf = logger.Errorf + +// FatalIfError fatal if error is not nil +// Deprecated: use logger.FatalIfError +var FatalIfError = logger.FatalIfError + +// LogIfFatalf fatal if cond is true +// Deprecated: use logger.FatalfIf +var LogIfFatalf = logger.FatalfIf + // AsError wrap a panic value as an error func AsError(x interface{}) error { - LogRedf("panic wrapped to error: '%v'", x) + logger.Errorf("panic wrapped to error: '%v'", x) if e, ok := x.(error); ok { return e } @@ -120,59 +133,6 @@ func MustRemarshal(from interface{}, to interface{}) { E2P(err) } -var logger *zap.SugaredLogger = nil - -func init() { - InitLog() -} - -// InitLog is a initialization for a logger -func InitLog() { - config := zap.NewProductionConfig() - config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - if os.Getenv("DTM_DEBUG") != "" { - config.Encoding = "console" - config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder - } - p, err := config.Build(zap.AddCallerSkip(1)) - if err != nil { - log.Fatal("create logger failed: ", err) - } - logger = p.Sugar() -} - -// Logf is log stdout -func Logf(fmt string, args ...interface{}) { - logger.Infof(fmt, args...) -} - -// LogRedf is print error message with red color -func LogRedf(fmt string, args ...interface{}) { - logger.Errorf(fmt, args...) -} - -// FatalExitFunc is a Fatal exit function ,it will be replaced when testing -var FatalExitFunc = func() { os.Exit(1) } - -// LogFatalf is print error message with red color, and execute FatalExitFunc -func LogFatalf(fmt string, args ...interface{}) { - fmt += "\n" + string(debug.Stack()) - LogRedf(fmt, args...) - FatalExitFunc() -} - -// LogIfFatalf is print error message with red color, and execute LogFatalf, when condition is true -func LogIfFatalf(condition bool, fmt string, args ...interface{}) { - if condition { - LogFatalf(fmt, args...) - } -} - -// FatalIfError is print error message with red color, and execute LogIfFatalf. -func FatalIfError(err error) { - LogIfFatalf(err != nil, "Fatal error: %v", err) -} - // GetFuncName get current call func name func GetFuncName() string { pc, _, _, _ := runtime.Caller(1) @@ -223,9 +183,9 @@ func DBExec(db DB, sql string, values ...interface{}) (affected int64, rerr erro used := time.Since(began) / time.Millisecond if rerr == nil { affected, rerr = r.RowsAffected() - Logf("used: %d ms affected: %d for %s %v", used, affected, sql, values) + logger.Debugf("used: %d ms affected: %d for %s %v", used, affected, sql, values) } else { - LogRedf("used: %d ms exec error: %v for %s %v", used, rerr, sql, values) + logger.Errorf("used: %d ms exec error: %v for %s %v", used, rerr, sql, values) } return } @@ -258,7 +218,7 @@ func CheckResponse(resp *resty.Response, err error) error { return err } -// CheckResult is check result. Return err directly if err is not nil. And return corresponding error by calling CheckResponse if resp is the type of *resty.Response. +// CheckResult is check result. Return err directly if err is not nil. And return corresponding error by calling CheckResponse if resp is the type of *resty.Response. // Otherwise, return error by value of str, the string after marshal. func CheckResult(res interface{}, err error) error { if err != nil { diff --git a/dtmcli/dtmimp/utils_test.go b/dtmcli/dtmimp/utils_test.go index 1625ced..167560c 100644 --- a/dtmcli/dtmimp/utils_test.go +++ b/dtmcli/dtmimp/utils_test.go @@ -8,7 +8,6 @@ package dtmimp import ( "errors" - "fmt" "os" "strings" "testing" @@ -80,20 +79,3 @@ func TestSome(t *testing.T) { s2 := MayReplaceLocalhost("http://localhost") assert.Equal(t, "http://localhost", s2) } - -func TestFatal(t *testing.T) { - old := FatalExitFunc - defer func() { - FatalExitFunc = old - }() - FatalExitFunc = func() { panic(fmt.Errorf("fatal")) } - err := CatchP(func() { - LogIfFatalf(true, "") - }) - assert.Error(t, err, fmt.Errorf("fatal")) -} - -func TestInitLog(t *testing.T) { - os.Setenv("DTM_DEBUG", "1") - InitLog() -} diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index ac0dbf2..de67eeb 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -14,6 +14,7 @@ import ( grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc/dtmgimp" "github.com/yedf/dtm/dtmgrpc/dtmgpb" "github.com/yedf/dtmdriver" @@ -30,7 +31,7 @@ func StartSvr() { go app.Run(fmt.Sprintf(":%d", config.HttpPort)) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", config.GrpcPort)) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) s := grpc.NewServer( grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( grpc.UnaryServerInterceptor(grpcMetrics), grpc.UnaryServerInterceptor(dtmgimp.GrpcServerLog)), @@ -39,15 +40,15 @@ func StartSvr() { dtmimp.Logf("grpc listening at %v", lis.Addr()) go func() { err := s.Serve(lis) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) }() go updateBranchAsync() time.Sleep(100 * time.Millisecond) err = dtmdriver.Use(config.MicroService.Driver) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) err = dtmdriver.GetDriver().RegisterGrpcService(config.MicroService.Target, config.MicroService.EndPoint) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } // PopulateDB setup mysql data diff --git a/examples/base_grpc.go b/examples/base_grpc.go index 3bff6a5..6be8aef 100644 --- a/examples/base_grpc.go +++ b/examples/base_grpc.go @@ -16,6 +16,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/dtmgrpc/dtmgimp" @@ -44,18 +45,18 @@ func init() { // GrpcStartup for grpc func GrpcStartup() { conn, err := grpc.Dial(DtmGrpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(dtmgimp.GrpcClientLog)) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) DtmClient = dtmgpb.NewDtmClient(conn) dtmimp.Logf("dtm client inited") lis, err := net.Listen("tcp", fmt.Sprintf(":%d", BusiGrpcPort)) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) s := grpc.NewServer(grpc.UnaryInterceptor(dtmgimp.GrpcServerLog)) RegisterBusiServer(s, &busiServer{}) go func() { dtmimp.Logf("busi grpc listening at %v", lis.Addr()) err := s.Serve(lis) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) }() time.Sleep(100 * time.Millisecond) } @@ -137,9 +138,9 @@ func (s *busiServer) TransOutXa(ctx context.Context, in *BusiReq) (*emptypb.Empt func (s *busiServer) TransInTccNested(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { tcc, err := dtmgrpc.TccFromGrpc(ctx) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) r := &emptypb.Empty{} err = tcc.CallBranch(in, BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInConfirm", BusiGrpc+"/examples.Busi/TransInRevert", r) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return r, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), in.TransInResult, dtmimp.GetFuncName()) } diff --git a/examples/base_types.go b/examples/base_types.go index a40f491..f906b4a 100644 --- a/examples/base_types.go +++ b/examples/base_types.go @@ -15,6 +15,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc" ) @@ -58,7 +59,7 @@ func reqFrom(c *gin.Context) *TransReq { if !ok { req := TransReq{} err := c.BindJSON(&req) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) c.Set("trans_req", &req) v = &req } @@ -81,27 +82,27 @@ func dbGet() *common.DB { func sdbGet() *sql.DB { db, err := dtmimp.PooledDB(config.ExamplesDB) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return db } func txGet() *sql.Tx { db := sdbGet() tx, err := db.Begin() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return tx } // MustBarrierFromGin 1 func MustBarrierFromGin(c *gin.Context) *dtmcli.BranchBarrier { ti, err := dtmcli.BarrierFromQuery(c.Request.URL.Query()) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return ti } // MustBarrierFromGrpc 1 func MustBarrierFromGrpc(ctx context.Context) *dtmcli.BranchBarrier { ti, err := dtmgrpc.BarrierFromGrpc(ctx) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return ti } diff --git a/examples/data.go b/examples/data.go index b0459c4..0a4f52c 100644 --- a/examples/data.go +++ b/examples/data.go @@ -10,7 +10,7 @@ import ( "fmt" "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) var config = &common.Config @@ -50,6 +50,6 @@ type sampleInfo struct { var Samples = map[string]*sampleInfo{} func addSample(name string, fn func() string) { - dtmimp.LogIfFatalf(Samples[name] != nil, "%s already exists", name) + logger.FatalfIf(Samples[name] != nil, "%s already exists", name) Samples[name] = &sampleInfo{Arg: name, Action: fn} } diff --git a/examples/grpc_msg.go b/examples/grpc_msg.go index 670e8e6..2bbe650 100644 --- a/examples/grpc_msg.go +++ b/examples/grpc_msg.go @@ -7,7 +7,7 @@ package examples import ( - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" dtmgrpc "github.com/yedf/dtm/dtmgrpc" ) @@ -19,7 +19,7 @@ func init() { Add(BusiGrpc+"/examples.Busi/TransOut", req). Add(BusiGrpc+"/examples.Busi/TransIn", req) err := msg.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return msg.Gid }) } diff --git a/examples/grpc_saga.go b/examples/grpc_saga.go index fad3d8f..3a29de4 100644 --- a/examples/grpc_saga.go +++ b/examples/grpc_saga.go @@ -7,7 +7,7 @@ package examples import ( - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" dtmgrpc "github.com/yedf/dtm/dtmgrpc" ) @@ -19,7 +19,7 @@ func init() { Add(BusiGrpc+"/examples.Busi/TransOut", BusiGrpc+"/examples.Busi/TransOutRevert", req). Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransOutRevert", req) err := saga.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid }) addSample("grpc_saga_wait", func() string { @@ -30,7 +30,7 @@ func init() { Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransOutRevert", req) saga.WaitResult = true err := saga.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid }) } diff --git a/examples/grpc_saga_barrier.go b/examples/grpc_saga_barrier.go index 777b236..892e140 100644 --- a/examples/grpc_saga_barrier.go +++ b/examples/grpc_saga_barrier.go @@ -12,6 +12,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -26,7 +27,7 @@ func init() { Add(BusiGrpc+"/examples.Busi/TransOutBSaga", BusiGrpc+"/examples.Busi/TransOutRevertBSaga", req). Add(BusiGrpc+"/examples.Busi/TransInBSaga", BusiGrpc+"/examples.Busi/TransInRevertBSaga", req) err := saga.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid }) } diff --git a/examples/grpc_tcc.go b/examples/grpc_tcc.go index a806983..6bf8cf1 100644 --- a/examples/grpc_tcc.go +++ b/examples/grpc_tcc.go @@ -8,6 +8,7 @@ package examples import ( "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" dtmgrpc "github.com/yedf/dtm/dtmgrpc" emptypb "google.golang.org/protobuf/types/known/emptypb" ) @@ -26,7 +27,7 @@ func init() { err = tcc.CallBranch(data, BusiGrpc+"/examples.Busi/TransInTcc", BusiGrpc+"/examples.Busi/TransInConfirm", BusiGrpc+"/examples.Busi/TransInRevert", r) return err }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return gid }) } diff --git a/examples/grpc_xa.go b/examples/grpc_xa.go index 41aba41..c4f9d3c 100644 --- a/examples/grpc_xa.go +++ b/examples/grpc_xa.go @@ -9,7 +9,7 @@ package examples import ( context "context" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc" "google.golang.org/protobuf/types/known/emptypb" ) @@ -27,7 +27,7 @@ func init() { err = xa.CallBranch(req, BusiGrpc+"/examples.Busi/TransInXa", r) return err }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return gid }) } diff --git a/examples/http_gorm_xa.go b/examples/http_gorm_xa.go index 6034469..caacb79 100644 --- a/examples/http_gorm_xa.go +++ b/examples/http_gorm_xa.go @@ -9,7 +9,7 @@ package examples import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) func init() { @@ -22,7 +22,7 @@ func init() { } return xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInXa") }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return gid }) diff --git a/examples/http_msg.go b/examples/http_msg.go index be0e9ac..59760df 100644 --- a/examples/http_msg.go +++ b/examples/http_msg.go @@ -9,6 +9,7 @@ package examples import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) func init() { @@ -19,10 +20,10 @@ func init() { Add(Busi+"/TransOut", req). Add(Busi+"/TransIn", req) err := msg.Prepare(Busi + "/query") - dtmimp.FatalIfError(err) + logger.FatalIfError(err) dtmimp.Logf("busi trans submit") err = msg.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return msg.Gid }) } diff --git a/examples/http_saga.go b/examples/http_saga.go index 54e2885..208d06d 100644 --- a/examples/http_saga.go +++ b/examples/http_saga.go @@ -9,6 +9,7 @@ package examples import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) func init() { @@ -21,7 +22,7 @@ func init() { dtmimp.Logf("saga busi trans submit") err := saga.Submit() dtmimp.Logf("result gid is: %s", saga.Gid) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid }) addSample("saga_wait", func() string { @@ -33,7 +34,7 @@ func init() { saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) err := saga.Submit() dtmimp.Logf("result gid is: %s", saga.Gid) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid }) addSample("concurrent_saga", func() string { @@ -50,7 +51,7 @@ func init() { dtmimp.Logf("concurrent saga busi trans submit") err := csaga.Submit() dtmimp.Logf("result gid is: %s", csaga.Gid) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return csaga.Gid }) } diff --git a/examples/http_saga_barrier.go b/examples/http_saga_barrier.go index c68aeb8..1b53bbe 100644 --- a/examples/http_saga_barrier.go +++ b/examples/http_saga_barrier.go @@ -13,6 +13,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) func init() { @@ -30,7 +31,7 @@ func init() { Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) dtmimp.Logf("busi trans submit") err := saga.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid }) } diff --git a/examples/http_saga_gorm_barrier.go b/examples/http_saga_gorm_barrier.go index 1f81c44..7b1e65f 100644 --- a/examples/http_saga_gorm_barrier.go +++ b/examples/http_saga_gorm_barrier.go @@ -13,6 +13,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) func init() { @@ -27,7 +28,7 @@ func init() { Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) dtmimp.Logf("busi trans submit") err := saga.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid }) diff --git a/examples/http_tcc.go b/examples/http_tcc.go index 49c949f..1692d3c 100644 --- a/examples/http_tcc.go +++ b/examples/http_tcc.go @@ -12,13 +12,14 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) func init() { setupFuncs["TccSetupSetup"] = func(app *gin.Engine) { app.POST(BusiAPI+"/TransInTccParent", common.WrapHandler(func(c *gin.Context) (interface{}, error) { tcc, err := dtmcli.TccFromQuery(c.Request.URL.Query()) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) dtmimp.Logf("TransInTccParent ") return tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") })) @@ -32,7 +33,7 @@ func init() { } return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInTccParent", Busi+"/TransInConfirm", Busi+"/TransInRevert") }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return gid }) addSample("tcc", func() string { @@ -45,7 +46,7 @@ func init() { } return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return gid }) } diff --git a/examples/http_tcc_barrier.go b/examples/http_tcc_barrier.go index 85e65da..ef52111 100644 --- a/examples/http_tcc_barrier.go +++ b/examples/http_tcc_barrier.go @@ -15,6 +15,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) func init() { @@ -37,7 +38,7 @@ func init() { } return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel") }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return gid }) } diff --git a/examples/http_xa.go b/examples/http_xa.go index 5ed0159..a288b45 100644 --- a/examples/http_xa.go +++ b/examples/http_xa.go @@ -11,7 +11,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) // XaClient XA client connection @@ -25,7 +25,7 @@ func init() { return xa.HandleCallback(c.Query("gid"), c.Query("branch_id"), c.Query("op")) })) }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) } addSample("xa", func() string { gid := dtmcli.MustGenGid(DtmHttpServer) @@ -36,7 +36,7 @@ func init() { } return xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInXa") }) - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return gid }) } diff --git a/examples/quick_start.go b/examples/quick_start.go index e71d816..147d1dd 100644 --- a/examples/quick_start.go +++ b/examples/quick_start.go @@ -14,6 +14,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) // 启动命令:go run app/main.go qs @@ -44,7 +45,7 @@ func QsFireRequest() string { Add(qsBusi+"/TransIn", qsBusi+"/TransInCompensate", req) // 提交saga事务,dtm会完成所有的子事务/回滚所有的子事务 err := saga.Submit() - dtmimp.FatalIfError(err) + logger.FatalIfError(err) return saga.Gid } diff --git a/test/types.go b/test/types.go index 7c54b86..ef1fd40 100644 --- a/test/types.go +++ b/test/types.go @@ -12,6 +12,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr" ) @@ -32,7 +33,7 @@ func waitTransProcessed(gid string) { } dtmimp.Logf("finish for gid %s", gid) case <-time.After(time.Duration(time.Second * 3)): - dtmimp.LogFatalf("Wait Trans timeout") + logger.FatalfIf(true, "Wait Trans timeout") } } From 7283f40f7eb8f5946dfd8a089e26f99a21ec1e26 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 17:00:18 +0800 Subject: [PATCH 012/124] Fatal is changed --- dtmcli/logger/log.go | 63 ++++++++++++++++++++++++++++++++++++ dtmcli/logger/logger_test.go | 17 ++++++++++ 2 files changed, 80 insertions(+) create mode 100644 dtmcli/logger/log.go create mode 100644 dtmcli/logger/logger_test.go diff --git a/dtmcli/logger/log.go b/dtmcli/logger/log.go new file mode 100644 index 0000000..a1ff613 --- /dev/null +++ b/dtmcli/logger/log.go @@ -0,0 +1,63 @@ +package logger + +import ( + "log" + "os" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +var logger *zap.SugaredLogger = nil + +func init() { + InitLog() +} + +// InitLog is a initialization for a logger +func InitLog() { + config := zap.NewProductionConfig() + config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + if os.Getenv("DTM_DEBUG") != "" { + config.Encoding = "console" + config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + } + p, err := config.Build(zap.AddCallerSkip(1)) + if err != nil { + log.Fatal("create logger failed: ", err) + } + logger = p.Sugar() +} + +// Debugf log to level debug +func Debugf(fmt string, args ...interface{}) { + logger.Debugf(fmt, args...) +} + +// Infof log to level info +func Infof(fmt string, args ...interface{}) { + logger.Infof(fmt, args...) +} + +// Warnf log to level warn +func Warnf(fmt string, args ...interface{}) { + logger.Warnf(fmt, args...) +} + +// Errorf log to level error +func Errorf(fmt string, args ...interface{}) { + logger.Errorf(fmt, args...) +} + +// FatalfIf log to level error +func FatalfIf(cond bool, fmt string, args ...interface{}) { + if !cond { + return + } + logger.Fatalf(fmt, args...) +} + +// FatalIfError if err is not nil, then log to level fatal and call os.Exit +func FatalIfError(err error) { + FatalfIf(err != nil, "fatal error: %v", err) +} diff --git a/dtmcli/logger/logger_test.go b/dtmcli/logger/logger_test.go new file mode 100644 index 0000000..159e381 --- /dev/null +++ b/dtmcli/logger/logger_test.go @@ -0,0 +1,17 @@ +package logger + +import ( + "os" + "testing" +) + +func TestInitLog(t *testing.T) { + os.Setenv("DTM_DEBUG", "1") + InitLog() + Debugf("a debug msg") + Infof("a info msg") + Warnf("a warn msg") + Errorf("a error msg") + FatalfIf(false, "nothing") + FatalIfError(nil) +} From 6fed8dae6b506a7654be39271110cf5fb6a874e9 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 17:05:04 +0800 Subject: [PATCH 013/124] Logf changed to Debugf --- app/main.go | 3 +-- bench/http.go | 6 +++--- bench/main.go | 4 ++-- common/config.go | 3 +-- common/config_utils.go | 2 +- common/db.go | 7 ++++--- common/types.go | 4 ++-- common/utils.go | 8 ++++---- dtmcli/barrier.go | 3 ++- dtmgrpc/dtmgimp/grpc_clients.go | 5 +++-- dtmgrpc/dtmgimp/types.go | 15 ++++++++------- dtmgrpc/dtmgimp/utils.go | 3 ++- dtmsvr/cron.go | 5 +++-- dtmsvr/storage/boltdb/boltdb.go | 13 +++++++------ dtmsvr/storage/redis/redis.go | 5 +++-- dtmsvr/svr.go | 11 +++++------ dtmsvr/trans_class.go | 3 ++- dtmsvr/trans_process.go | 9 +++++---- dtmsvr/trans_type_msg.go | 4 ++-- dtmsvr/trans_type_saga.go | 11 ++++++----- dtmsvr/trans_type_tcc.go | 3 ++- examples/base_grpc.go | 6 +++--- examples/base_http.go | 11 ++++++----- examples/grpc_tcc.go | 3 +-- examples/http_msg.go | 5 ++--- examples/http_saga.go | 17 ++++++++--------- examples/http_saga_barrier.go | 4 ++-- examples/http_saga_gorm_barrier.go | 5 ++--- examples/http_tcc.go | 5 ++--- examples/http_tcc_barrier.go | 2 +- examples/quick_start.go | 2 +- test/base_test.go | 5 +++-- test/tcc_barrier_test.go | 9 +++++---- test/tcc_grpc_test.go | 3 ++- test/types.go | 6 +++--- 35 files changed, 109 insertions(+), 101 deletions(-) diff --git a/app/main.go b/app/main.go index 3382911..68a8d57 100644 --- a/app/main.go +++ b/app/main.go @@ -15,7 +15,6 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr" "github.com/yedf/dtm/dtmsvr/storage/registry" @@ -51,7 +50,7 @@ func main() { fmt.Printf("version: %s commit: %s built at: %s\n", Version, Commit, Date) return } - dtmimp.Logf("starting dtm....") + logger.Debugf("starting dtm....") common.MustLoadConfig() if common.Config.ExamplesDB.Driver != "" { dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) diff --git a/bench/http.go b/bench/http.go index 2e8389c..403abd3 100644 --- a/bench/http.go +++ b/bench/http.go @@ -60,7 +60,7 @@ func reloadData() { } _, err := dtmimp.DBExec(db, s+strings.Join(ss, ",")) logger.FatalIfError(err) - dtmimp.Logf("%d users inserted. used: %dms", total, time.Since(began).Milliseconds()) + logger.Debugf("%d users inserted. used: %dms", total, time.Since(began).Milliseconds()) } var uidCounter int32 = 0 @@ -71,7 +71,7 @@ var sqls int = 1 func StartSvr() { app := common.GetGinApp() benchAddRoute(app) - dtmimp.Logf("bench listening at %d", benchPort) + logger.Debugf("bench listening at %d", benchPort) go app.Run(fmt.Sprintf(":%d", benchPort)) db := sdbGet() _, err := dtmimp.DBExec(db, "drop table if exists dtm_busi.user_account_log") @@ -151,7 +151,7 @@ func benchAddRoute(app *gin.Engine) { req := gin.H{} params := fmt.Sprintf("?uid=%s", suid) params2 := fmt.Sprintf("?uid=%s", suid2) - dtmimp.Logf("mode: %s contains dtm: %t", mode, strings.Contains(mode, "dtm")) + logger.Debugf("mode: %s contains dtm: %t", mode, strings.Contains(mode, "dtm")) if strings.Contains(mode, "dtm") { saga := dtmcli.NewSaga(examples.DtmHttpServer, fmt.Sprintf("bench-%d", uid)). Add(benchBusi+"/TransOut"+params, benchBusi+"/TransOutCompensate"+params, req). diff --git a/bench/main.go b/bench/main.go index f757c8c..ebd604d 100644 --- a/bench/main.go +++ b/bench/main.go @@ -6,7 +6,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr" "github.com/yedf/dtm/dtmsvr/storage/registry" "github.com/yedf/dtm/examples" @@ -23,7 +23,7 @@ func main() { fmt.Printf(hint) return } - dtmimp.Logf("starting dtm....") + logger.Debugf("starting dtm....") if os.Args[1] == "http" { fmt.Println("start bench server") common.MustLoadConfig() diff --git a/common/config.go b/common/config.go index 6a0838a..940dd1a 100644 --- a/common/config.go +++ b/common/config.go @@ -7,7 +7,6 @@ import ( "path/filepath" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" "gopkg.in/yaml.v2" ) @@ -87,7 +86,7 @@ func MustLoadConfig() { } scont, err := json.MarshalIndent(&Config, "", " ") logger.FatalIfError(err) - dtmimp.Logf("config is: \n%s", scont) + logger.Debugf("config is: \n%s", scont) err = checkConfig() logger.FatalfIf(err != nil, `config error: '%v'. check you env, and conf.yml/conf.sample.yml in current and parent path: %s. diff --git a/common/config_utils.go b/common/config_utils.go index 44c93f6..e54a834 100644 --- a/common/config_utils.go +++ b/common/config_utils.go @@ -50,6 +50,6 @@ func toUnderscoreUpper(key string) string { key = strings.Trim(key, "_") matchFirstCap := regexp.MustCompile("([a-z])([A-Z]+)") s2 := matchFirstCap.ReplaceAllString(key, "${1}_${2}") - // dtmimp.Logf("loading from env: %s", strings.ToUpper(s2)) + // logger.Debugf("loading from env: %s", strings.ToUpper(s2)) return strings.ToUpper(s2) } diff --git a/common/db.go b/common/db.go index a9c315d..f2d1c66 100644 --- a/common/db.go +++ b/common/db.go @@ -11,6 +11,7 @@ import ( _ "github.com/lib/pq" // register postgres driver "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" @@ -65,7 +66,7 @@ func (op *tracePlugin) Initialize(db *gorm.DB) (err error) { after := func(db *gorm.DB) { _ts, _ := db.InstanceGet("ivy.startTime") sql := db.Dialector.Explain(db.Statement.SQL.String(), db.Statement.Vars...) - dtmimp.Logf("used: %d ms affected: %d sql is: %s", time.Since(_ts.(time.Time)).Milliseconds(), db.RowsAffected, sql) + logger.Debugf("used: %d ms affected: %d sql is: %s", time.Since(_ts.(time.Time)).Milliseconds(), db.RowsAffected, sql) if v, ok := db.InstanceGet("ivy.must"); ok && v.(bool) { if db.Error != nil && db.Error != gorm.ErrRecordNotFound { panic(db.Error) @@ -76,7 +77,7 @@ func (op *tracePlugin) Initialize(db *gorm.DB) (err error) { beforeName := "cb_before" afterName := "cb_after" - dtmimp.Logf("installing db plugin: %s", op.Name()) + logger.Debugf("installing db plugin: %s", op.Name()) // 开始前 _ = db.Callback().Create().Before("gorm:before_create").Register(beforeName, before) _ = db.Callback().Query().Before("gorm:query").Register(beforeName, before) @@ -108,7 +109,7 @@ func DbGet(conf dtmcli.DBConf) *DB { dsn := dtmimp.GetDsn(conf) db, ok := dbs.Load(dsn) if !ok { - dtmimp.Logf("connecting %s", strings.Replace(dsn, conf.Passwrod, "****", 1)) + logger.Debugf("connecting %s", strings.Replace(dsn, conf.Passwrod, "****", 1)) db1, err := gorm.Open(getGormDialetor(conf.Driver, dsn), &gorm.Config{ SkipDefaultTransaction: true, }) diff --git a/common/types.go b/common/types.go index 358dd80..19bd8ea 100644 --- a/common/types.go +++ b/common/types.go @@ -11,7 +11,7 @@ import ( "sync" "github.com/go-redis/redis/v8" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) var rdb *redis.Client @@ -19,7 +19,7 @@ var once sync.Once func RedisGet() *redis.Client { once.Do(func() { - dtmimp.Logf("connecting to redis: %v", Config.Store) + logger.Debugf("connecting to redis: %v", Config.Store) rdb = redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", Config.Store.Host, Config.Store.Port), Username: Config.Store.User, diff --git a/common/utils.go b/common/utils.go index 5e690d9..f9db2b1 100644 --- a/common/utils.go +++ b/common/utils.go @@ -38,9 +38,9 @@ func GetGinApp() *gin.Engine { } } began := time.Now() - dtmimp.Logf("begin %s %s query: %s body: %s", c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) + logger.Debugf("begin %s %s query: %s body: %s", c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) c.Next() - dtmimp.Logf("used %d ms %s %s query: %s body: %s", time.Since(began).Milliseconds(), c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) + logger.Debugf("used %d ms %s %s query: %s body: %s", time.Since(began).Milliseconds(), c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) }) app.Any("/api/ping", func(c *gin.Context) { c.JSON(200, map[string]interface{}{"msg": "pong"}) }) @@ -61,10 +61,10 @@ func WrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc { b, err = json.Marshal(r) } if err != nil { - dtmimp.Logf("status: 500, code: 500 message: %s", err.Error()) + logger.Debugf("status: 500, code: 500 message: %s", err.Error()) c.JSON(500, map[string]interface{}{"code": 500, "message": err.Error()}) } else { - dtmimp.Logf("status: 200, content: %s", string(b)) + logger.Debugf("status: 200, content: %s", string(b)) c.Status(200) c.Writer.Header().Add("Content-Type", "application/json") _, err = c.Writer.Write(b) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index 480ae17..ede7080 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -12,6 +12,7 @@ import ( "net/url" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) // BarrierBusiFunc type for busi func @@ -82,7 +83,7 @@ func (bb *BranchBarrier) Call(tx *sql.Tx, busiCall BarrierBusiFunc) (rerr error) originAffected, _ := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, originType, bid, ti.Op) currentAffected, rerr := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, ti.Op, bid, ti.Op) - dtmimp.Logf("originAffected: %d currentAffected: %d", originAffected, currentAffected) + logger.Debugf("originAffected: %d currentAffected: %d", originAffected, currentAffected) if (ti.Op == BranchCancel || ti.Op == BranchCompensate) && originAffected > 0 || // 这个是空补偿 currentAffected == 0 { // 这个是重复请求或者悬挂 return diff --git a/dtmgrpc/dtmgimp/grpc_clients.go b/dtmgrpc/dtmgimp/grpc_clients.go index 17c7b54..e437054 100644 --- a/dtmgrpc/dtmgimp/grpc_clients.go +++ b/dtmgrpc/dtmgimp/grpc_clients.go @@ -11,6 +11,7 @@ import ( "sync" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc/dtmgpb" grpc "google.golang.org/grpc" ) @@ -57,12 +58,12 @@ func GetGrpcConn(grpcServer string, isRaw bool) (conn *grpc.ClientConn, rerr err if isRaw { opts = grpc.WithDefaultCallOptions(grpc.ForceCodec(rawCodec{})) } - dtmimp.Logf("grpc client connecting %s", grpcServer) + logger.Debugf("grpc client connecting %s", grpcServer) conn, rerr := grpc.Dial(grpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(GrpcClientLog), opts) if rerr == nil { clients.Store(grpcServer, conn) v = conn - dtmimp.Logf("grpc client inited for %s", grpcServer) + logger.Debugf("grpc client inited for %s", grpcServer) } } return v.(*grpc.ClientConn), rerr diff --git a/dtmgrpc/dtmgimp/types.go b/dtmgrpc/dtmgimp/types.go index a188f23..31f0bf9 100644 --- a/dtmgrpc/dtmgimp/types.go +++ b/dtmgrpc/dtmgimp/types.go @@ -12,6 +12,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -19,28 +20,28 @@ import ( // GrpcServerLog 打印grpc服务端的日志 func GrpcServerLog(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - dtmimp.Logf("grpc server handling: %s %v", info.FullMethod, req) + logger.Debugf("grpc server handling: %s %v", info.FullMethod, req) LogDtmCtx(ctx) m, err := handler(ctx, req) res := fmt.Sprintf("grpc server handled: %s %v result: %v err: %v", info.FullMethod, req, m, err) if err != nil { - dtmimp.LogRedf("%s", res) + logger.Errorf("%s", res) } else { - dtmimp.Logf("%s", res) + logger.Debugf("%s", res) } return m, err } // GrpcClientLog 打印grpc服务端的日志 func GrpcClientLog(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - dtmimp.Logf("grpc client calling: %s%s %v", cc.Target(), method, req) + logger.Debugf("grpc client calling: %s%s %v", cc.Target(), method, req) LogDtmCtx(ctx) err := invoker(ctx, method, req, reply, cc, opts...) res := fmt.Sprintf("grpc client called: %s%s %v result: %v err: %v", cc.Target(), method, req, reply, err) if err != nil { - dtmimp.LogRedf("%s", res) + logger.Errorf("%s", res) } else { - dtmimp.Logf("%s", res) + logger.Debugf("%s", res) } return err } @@ -49,7 +50,7 @@ func GrpcClientLog(ctx context.Context, method string, req, reply interface{}, c func Result2Error(res interface{}, err error) error { e := dtmimp.CheckResult(res, err) if e == dtmimp.ErrFailure { - dtmimp.LogRedf("failure: res: %v, err: %v", res, e) + logger.Errorf("failure: res: %v, err: %v", res, e) return status.New(codes.Aborted, dtmcli.ResultFailure).Err() } else if e == dtmimp.ErrOngoing { return status.New(codes.Aborted, dtmcli.ResultOngoing).Err() diff --git a/dtmgrpc/dtmgimp/utils.go b/dtmgrpc/dtmgimp/utils.go index 357d0c7..e600166 100644 --- a/dtmgrpc/dtmgimp/utils.go +++ b/dtmgrpc/dtmgimp/utils.go @@ -10,6 +10,7 @@ import ( context "context" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc/dtmgpb" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" @@ -59,7 +60,7 @@ func TransInfo2Ctx(gid, transType, branchID, op, dtm string) context.Context { func LogDtmCtx(ctx context.Context) { tb := TransBaseFromGrpc(ctx) if tb.Gid != "" { - dtmimp.Logf("gid: %s trans_type: %s branch_id: %s op: %s dtm: %s", tb.Gid, tb.TransType, tb.BranchID, tb.Op, tb.Dtm) + logger.Debugf("gid: %s trans_type: %s branch_id: %s op: %s dtm: %s", tb.Gid, tb.TransType, tb.BranchID, tb.Op, tb.Dtm) } } diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index c4ef282..bd31d29 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -13,6 +13,7 @@ import ( "time" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) // NowForwardDuration will be set in test, trans may be timeout @@ -54,7 +55,7 @@ func lockOneTrans(expireIn time.Duration) *TransGlobal { func handlePanic(perr *error) { if err := recover(); err != nil { - dtmimp.LogRedf("----recovered panic %v\n%s", err, string(debug.Stack())) + logger.Errorf("----recovered panic %v\n%s", err, string(debug.Stack())) if perr != nil { *perr = fmt.Errorf("dtm panic: %v", err) } @@ -64,6 +65,6 @@ func handlePanic(perr *error) { func sleepCronTime() { normal := time.Duration((float64(config.TransCronInterval) - rand.Float64()) * float64(time.Second)) interval := dtmimp.If(CronForwardDuration > 0, 1*time.Millisecond, normal).(time.Duration) - dtmimp.Logf("sleeping for %v milli", interval/time.Microsecond) + logger.Debugf("sleeping for %v milli", interval/time.Microsecond) time.Sleep(interval) } diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index f5b9670..31a0804 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -11,6 +11,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr/storage" ) @@ -100,9 +101,9 @@ func cleanupGlobalWithGids(t *bolt.Tx, gids map[string]struct{}) { return } - dtmimp.Logf("Start to cleanup %d gids", len(gids)) + logger.Debugf("Start to cleanup %d gids", len(gids)) for gid := range gids { - dtmimp.Logf("Start to delete gid: %s", gid) + logger.Debugf("Start to delete gid: %s", gid) bucket.Delete([]byte(gid)) } } @@ -129,9 +130,9 @@ func cleanupBranchWithGids(t *bolt.Tx, gids map[string]struct{}) { } } - dtmimp.Logf("Start to cleanup %d branches", len(branchKeys)) + logger.Debugf("Start to cleanup %d branches", len(branchKeys)) for _, key := range branchKeys { - dtmimp.Logf("Start to delete branch: %s", key) + logger.Debugf("Start to delete branch: %s", key) bucket.Delete([]byte(key)) } } @@ -155,9 +156,9 @@ func cleanupIndexWithGids(t *bolt.Tx, gids map[string]struct{}) { } } - dtmimp.Logf("Start to cleanup %d indexes", len(indexKeys)) + logger.Debugf("Start to cleanup %d indexes", len(indexKeys)) for _, key := range indexKeys { - dtmimp.Logf("Start to delete index: %s", key) + logger.Debugf("Start to delete index: %s", key) bucket.Delete([]byte(key)) } } diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 348e572..00cecd4 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -10,6 +10,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr/storage" ) @@ -114,7 +115,7 @@ func (a *argList) AppendBranches(branches []storage.TransBranchStore) *argList { } func handleRedisResult(ret interface{}, err error) (string, error) { - dtmimp.Logf("result is: '%v', err: '%v'", ret, err) + logger.Debugf("result is: '%v', err: '%v'", ret, err) if err != nil && err != redis.Nil { return "", err } @@ -127,7 +128,7 @@ func handleRedisResult(ret interface{}, err error) (string, error) { } func callLua(a *argList, lua string) (string, error) { - dtmimp.Logf("calling lua. args: %v\nlua:%s", a, lua) + logger.Debugf("calling lua. args: %v\nlua:%s", a, lua) ret, err := redisGet().Eval(ctx, lua, a.Keys, a.List...).Result() return handleRedisResult(ret, err) } diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index de67eeb..4f6c866 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -13,7 +13,6 @@ import ( grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc/dtmgimp" "github.com/yedf/dtm/dtmgrpc/dtmgpb" @@ -23,11 +22,11 @@ import ( // StartSvr StartSvr func StartSvr() { - dtmimp.Logf("start dtmsvr") + logger.Debugf("start dtmsvr") app := common.GetGinApp() app = httpMetrics(app) addRoute(app) - dtmimp.Logf("dtmsvr listen at: %d", config.HttpPort) + logger.Debugf("dtmsvr listen at: %d", config.HttpPort) go app.Run(fmt.Sprintf(":%d", config.HttpPort)) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", config.GrpcPort)) @@ -37,7 +36,7 @@ func StartSvr() { grpc.UnaryServerInterceptor(grpcMetrics), grpc.UnaryServerInterceptor(dtmgimp.GrpcServerLog)), )) dtmgpb.RegisterDtmServer(s, &dtmServer{}) - dtmimp.Logf("grpc listening at %v", lis.Addr()) + logger.Debugf("grpc listening at %v", lis.Addr()) go func() { err := s.Serve(lis) logger.FatalIfError(err) @@ -80,9 +79,9 @@ func updateBranchAsync() { for len(updates) > 0 { dbr := GetStore().UpdateBranchesSql(updates, []string{"status", "finish_time", "update_time"}) - dtmimp.Logf("flushed %d branch status to db. affected: %d", len(updates), dbr.RowsAffected) + logger.Debugf("flushed %d branch status to db. affected: %d", len(updates), dbr.RowsAffected) if dbr.Error != nil { - dtmimp.LogRedf("async update branch status error: %v", dbr.Error) + logger.Errorf("async update branch status error: %v", dbr.Error) time.Sleep(1 * time.Second) } else { updates = []TransBranch{} diff --git a/dtmsvr/trans_class.go b/dtmsvr/trans_class.go index d8ea01b..faf3125 100644 --- a/dtmsvr/trans_class.go +++ b/dtmsvr/trans_class.go @@ -12,6 +12,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc/dtmgpb" "github.com/yedf/dtm/dtmsvr/storage" ) @@ -57,7 +58,7 @@ func TransFromContext(c *gin.Context) *TransGlobal { e2p(err) m := TransGlobal{} dtmimp.MustUnmarshal(b, &m) - dtmimp.Logf("creating trans in prepare") + logger.Debugf("creating trans in prepare") // Payloads will be store in BinPayloads, Payloads is only used to Unmarshal for _, p := range m.Payloads { m.BinPayloads = append(m.BinPayloads, []byte(p)) diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index 38a68b9..a9ef2f9 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -12,6 +12,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) // Process process global transaction once @@ -45,15 +46,15 @@ func (t *TransGlobal) processInner() (rerr error) { defer handlePanic(&rerr) defer func() { if rerr != nil { - dtmimp.LogRedf("processInner got error: %s", rerr.Error()) + logger.Errorf("processInner got error: %s", rerr.Error()) } if TransProcessedTestChan != nil { - dtmimp.Logf("processed: %s", t.Gid) + logger.Debugf("processed: %s", t.Gid) TransProcessedTestChan <- t.Gid - dtmimp.Logf("notified: %s", t.Gid) + logger.Debugf("notified: %s", t.Gid) } }() - dtmimp.Logf("processing: %s status: %s", t.Gid, t.Status) + logger.Debugf("processing: %s status: %s", t.Gid, t.Status) branches := GetStore().FindBranches(t.Gid) t.lastTouched = time.Now() rerr = t.getProcessor().ProcessOnce(branches) diff --git a/dtmsvr/trans_type_msg.go b/dtmsvr/trans_type_msg.go index f6bc9b1..63a62b6 100644 --- a/dtmsvr/trans_type_msg.go +++ b/dtmsvr/trans_type_msg.go @@ -11,7 +11,7 @@ import ( "strings" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) type transMsgProcessor struct { @@ -50,7 +50,7 @@ func (t *TransGlobal) mayQueryPrepared() { } else if strings.Contains(body, dtmcli.ResultOngoing) { t.touchCronTime(cronReset) } else { - dtmimp.LogRedf("getting result failed for %s. error: %s", t.QueryPrepared, err.Error()) + logger.Errorf("getting result failed for %s. error: %s", t.QueryPrepared, err.Error()) t.touchCronTime(cronBackoff) } } diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index dad3d6f..bdeea9b 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -12,6 +12,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) type transSagaProcessor struct { @@ -54,7 +55,7 @@ type branchResult struct { func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { // when saga tasks is fetched, it always need to process - dtmimp.Logf("status: %s timeout: %t", t.Status, t.isTimeout()) + logger.Debugf("status: %s timeout: %t", t.Status, t.isTimeout()) if t.Status == dtmcli.StatusSubmitted && t.isTimeout() { t.changeStatus(dtmcli.StatusAborting) } @@ -104,7 +105,7 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } resultChan <- branchResult{index: i, status: branches[i].Status, op: branches[i].Op} if err != nil { - dtmimp.LogRedf("exec branch error: %v", err) + logger.Errorf("exec branch error: %v", err) } }() err = t.execBranch(&branches[i], i) @@ -117,7 +118,7 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { toRun = append(toRun, current) } } - dtmimp.Logf("toRun picked for action is: %v", toRun) + logger.Debugf("toRun picked for action is: %v", toRun) return toRun } runBranches := func(toRun []int) { @@ -159,9 +160,9 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { rsCSucceed++ } } - dtmimp.Logf("branch done: %v", r) + logger.Debugf("branch done: %v", r) case <-time.After(time.Duration(time.Second * 3)): - dtmimp.Logf("wait once for done") + logger.Debugf("wait once for done") } } diff --git a/dtmsvr/trans_type_tcc.go b/dtmsvr/trans_type_tcc.go index 88145d1..2c32ab6 100644 --- a/dtmsvr/trans_type_tcc.go +++ b/dtmsvr/trans_type_tcc.go @@ -9,6 +9,7 @@ package dtmsvr import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" ) type transTccProcessor struct { @@ -33,7 +34,7 @@ func (t *transTccProcessor) ProcessOnce(branches []TransBranch) error { op := dtmimp.If(t.Status == dtmcli.StatusSubmitted, dtmcli.BranchConfirm, dtmcli.BranchCancel).(string) for current := len(branches) - 1; current >= 0; current-- { if branches[current].Op == op && branches[current].Status == dtmcli.StatusPrepared { - dtmimp.Logf("branch info: current: %d ID: %d", current, branches[current].ID) + logger.Debugf("branch info: current: %d ID: %d", current, branches[current].ID) err := t.execBranch(&branches[current], current) if err != nil { return err diff --git a/examples/base_grpc.go b/examples/base_grpc.go index 6be8aef..07eb749 100644 --- a/examples/base_grpc.go +++ b/examples/base_grpc.go @@ -47,14 +47,14 @@ func GrpcStartup() { conn, err := grpc.Dial(DtmGrpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(dtmgimp.GrpcClientLog)) logger.FatalIfError(err) DtmClient = dtmgpb.NewDtmClient(conn) - dtmimp.Logf("dtm client inited") + logger.Debugf("dtm client inited") lis, err := net.Listen("tcp", fmt.Sprintf(":%d", BusiGrpcPort)) logger.FatalIfError(err) s := grpc.NewServer(grpc.UnaryInterceptor(dtmgimp.GrpcServerLog)) RegisterBusiServer(s, &busiServer{}) go func() { - dtmimp.Logf("busi grpc listening at %v", lis.Addr()) + logger.Debugf("busi grpc listening at %v", lis.Addr()) err := s.Serve(lis) logger.FatalIfError(err) }() @@ -63,7 +63,7 @@ func GrpcStartup() { func handleGrpcBusiness(in *BusiReq, result1 string, result2 string, busi string) error { res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) - dtmimp.Logf("grpc busi %s %v %s %s result: %s", busi, in, result1, result2, res) + logger.Debugf("grpc busi %s %v %s %s result: %s", busi, in, result1, result2, res) if res == dtmcli.ResultSuccess { return nil } else if res == dtmcli.ResultFailure { diff --git a/examples/base_http.go b/examples/base_http.go index 8aa7f37..401d1f3 100644 --- a/examples/base_http.go +++ b/examples/base_http.go @@ -17,6 +17,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" @@ -40,7 +41,7 @@ var Busi string = fmt.Sprintf("http://localhost:%d%s", BusiPort, BusiAPI) // BaseAppStartup base app startup func BaseAppStartup() *gin.Engine { - dtmimp.Logf("examples starting") + logger.Debugf("examples starting") app := common.GetGinApp() app.Use(func(c *gin.Context) { v := MainSwitch.NextResult.Fetch() @@ -54,10 +55,10 @@ func BaseAppStartup() *gin.Engine { BaseAddRoute(app) for k, v := range setupFuncs { - dtmimp.Logf("initing %s", k) + logger.Debugf("initing %s", k) v(app) } - dtmimp.Logf("Starting busi at: %d", BusiPort) + logger.Debugf("Starting busi at: %d", BusiPort) go app.Run(fmt.Sprintf(":%d", BusiPort)) time.Sleep(100 * time.Millisecond) @@ -98,7 +99,7 @@ var MainSwitch mainSwitchType func handleGeneralBusiness(c *gin.Context, result1 string, result2 string, busi string) (interface{}, error) { info := infoFromContext(c) res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) - dtmimp.Logf("%s %s result: %s", busi, info.String(), res) + logger.Debugf("%s %s result: %s", busi, info.String(), res) if res == "ERROR" { return nil, errors.New("ERROR from user") } @@ -136,7 +137,7 @@ func BaseAddRoute(app *gin.Engine) { return handleGeneralBusiness(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) app.GET(BusiAPI+"/CanSubmit", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - dtmimp.Logf("%s CanSubmit", c.Query("gid")) + logger.Debugf("%s CanSubmit", c.Query("gid")) return dtmimp.OrString(MainSwitch.CanSubmitResult.Fetch(), dtmcli.ResultSuccess), nil })) app.POST(BusiAPI+"/TransInXa", common.WrapHandler(func(c *gin.Context) (interface{}, error) { diff --git a/examples/grpc_tcc.go b/examples/grpc_tcc.go index 6bf8cf1..5a6c4fd 100644 --- a/examples/grpc_tcc.go +++ b/examples/grpc_tcc.go @@ -7,7 +7,6 @@ package examples import ( - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" dtmgrpc "github.com/yedf/dtm/dtmgrpc" emptypb "google.golang.org/protobuf/types/known/emptypb" @@ -15,7 +14,7 @@ import ( func init() { addSample("grpc_tcc", func() string { - dtmimp.Logf("tcc simple transaction begin") + logger.Debugf("tcc simple transaction begin") gid := dtmgrpc.MustGenGid(DtmGrpcServer) err := dtmgrpc.TccGlobalTransaction(DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { data := &BusiReq{Amount: 30} diff --git a/examples/http_msg.go b/examples/http_msg.go index 59760df..3f40805 100644 --- a/examples/http_msg.go +++ b/examples/http_msg.go @@ -8,20 +8,19 @@ package examples import ( "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" ) func init() { addSample("msg", func() string { - dtmimp.Logf("a busi transaction begin") + logger.Debugf("a busi transaction begin") req := &TransReq{Amount: 30} msg := dtmcli.NewMsg(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). Add(Busi+"/TransOut", req). Add(Busi+"/TransIn", req) err := msg.Prepare(Busi + "/query") logger.FatalIfError(err) - dtmimp.Logf("busi trans submit") + logger.Debugf("busi trans submit") err = msg.Submit() logger.FatalIfError(err) return msg.Gid diff --git a/examples/http_saga.go b/examples/http_saga.go index 208d06d..d7dd59b 100644 --- a/examples/http_saga.go +++ b/examples/http_saga.go @@ -8,37 +8,36 @@ package examples import ( "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" ) func init() { addSample("saga", func() string { - dtmimp.Logf("a saga busi transaction begin") + logger.Debugf("a saga busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). Add(Busi+"/TransIn", Busi+"/TransInRevert", req) - dtmimp.Logf("saga busi trans submit") + logger.Debugf("saga busi trans submit") err := saga.Submit() - dtmimp.Logf("result gid is: %s", saga.Gid) + logger.Debugf("result gid is: %s", saga.Gid) logger.FatalIfError(err) return saga.Gid }) addSample("saga_wait", func() string { - dtmimp.Logf("a saga busi transaction begin") + logger.Debugf("a saga busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). Add(Busi+"/TransIn", Busi+"/TransInRevert", req) saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) err := saga.Submit() - dtmimp.Logf("result gid is: %s", saga.Gid) + logger.Debugf("result gid is: %s", saga.Gid) logger.FatalIfError(err) return saga.Gid }) addSample("concurrent_saga", func() string { - dtmimp.Logf("a concurrent saga busi transaction begin") + logger.Debugf("a concurrent saga busi transaction begin") req := &TransReq{Amount: 30} csaga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). @@ -48,9 +47,9 @@ func init() { EnableConcurrent(). AddBranchOrder(2, []int{0, 1}). AddBranchOrder(3, []int{0, 1}) - dtmimp.Logf("concurrent saga busi trans submit") + logger.Debugf("concurrent saga busi trans submit") err := csaga.Submit() - dtmimp.Logf("result gid is: %s", csaga.Gid) + logger.Debugf("result gid is: %s", csaga.Gid) logger.FatalIfError(err) return csaga.Gid }) diff --git a/examples/http_saga_barrier.go b/examples/http_saga_barrier.go index 1b53bbe..c633c58 100644 --- a/examples/http_saga_barrier.go +++ b/examples/http_saga_barrier.go @@ -24,12 +24,12 @@ func init() { app.POST(BusiAPI+"/SagaBTransOutCompensate", common.WrapHandler(sagaBarrierTransOutCompensate)) } addSample("saga_barrier", func() string { - dtmimp.Logf("a busi transaction begin") + logger.Debugf("a busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). Add(Busi+"/SagaBTransOut", Busi+"/SagaBTransOutCompensate", req). Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) - dtmimp.Logf("busi trans submit") + logger.Debugf("busi trans submit") err := saga.Submit() logger.FatalIfError(err) return saga.Gid diff --git a/examples/http_saga_gorm_barrier.go b/examples/http_saga_gorm_barrier.go index 7b1e65f..9499506 100644 --- a/examples/http_saga_gorm_barrier.go +++ b/examples/http_saga_gorm_barrier.go @@ -12,7 +12,6 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" ) @@ -21,12 +20,12 @@ func init() { app.POST(BusiAPI+"/SagaBTransOutGorm", common.WrapHandler(sagaGormBarrierTransOut)) } addSample("saga_gorm_barrier", func() string { - dtmimp.Logf("a busi transaction begin") + logger.Debugf("a busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). Add(Busi+"/SagaBTransOutGorm", Busi+"/SagaBTransOutCompensate", req). Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) - dtmimp.Logf("busi trans submit") + logger.Debugf("busi trans submit") err := saga.Submit() logger.FatalIfError(err) return saga.Gid diff --git a/examples/http_tcc.go b/examples/http_tcc.go index 1692d3c..76dff2f 100644 --- a/examples/http_tcc.go +++ b/examples/http_tcc.go @@ -11,7 +11,6 @@ import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmcli/logger" ) @@ -20,7 +19,7 @@ func init() { app.POST(BusiAPI+"/TransInTccParent", common.WrapHandler(func(c *gin.Context) (interface{}, error) { tcc, err := dtmcli.TccFromQuery(c.Request.URL.Query()) logger.FatalIfError(err) - dtmimp.Logf("TransInTccParent ") + logger.Debugf("TransInTccParent ") return tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") })) } @@ -37,7 +36,7 @@ func init() { return gid }) addSample("tcc", func() string { - dtmimp.Logf("tcc simple transaction begin") + logger.Debugf("tcc simple transaction begin") gid := dtmcli.MustGenGid(DtmHttpServer) err := dtmcli.TccGlobalTransaction(DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") diff --git a/examples/http_tcc_barrier.go b/examples/http_tcc_barrier.go index ef52111..56a0467 100644 --- a/examples/http_tcc_barrier.go +++ b/examples/http_tcc_barrier.go @@ -28,7 +28,7 @@ func init() { app.POST(BusiAPI+"/TccBTransOutCancel", common.WrapHandler(TccBarrierTransOutCancel)) } addSample("tcc_barrier", func() string { - dtmimp.Logf("tcc transaction begin") + logger.Debugf("tcc transaction begin") gid := dtmcli.MustGenGid(DtmHttpServer) err := dtmcli.TccGlobalTransaction(DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransOutTry", diff --git a/examples/quick_start.go b/examples/quick_start.go index 147d1dd..47329ed 100644 --- a/examples/quick_start.go +++ b/examples/quick_start.go @@ -29,7 +29,7 @@ var qsBusi = fmt.Sprintf("http://localhost:%d%s", qsBusiPort, qsBusiAPI) func QsStartSvr() { app := common.GetGinApp() qsAddRoute(app) - dtmimp.Logf("quick qs examples listening at %d", qsBusiPort) + logger.Debugf("quick qs examples listening at %d", qsBusiPort) go app.Run(fmt.Sprintf(":%d", qsBusiPort)) time.Sleep(100 * time.Millisecond) } diff --git a/test/base_test.go b/test/base_test.go index 7dbc192..deffa8d 100644 --- a/test/base_test.go +++ b/test/base_test.go @@ -15,6 +15,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/examples" ) @@ -40,7 +41,7 @@ func TestBaseSqlDB(t *testing.T) { tx, err := db.ToSQLDB().Begin() asserts.Nil(err) err = barrier.Call(tx, func(tx *sql.Tx) error { - dtmimp.Logf("rollback gid2") + logger.Debugf("rollback gid2") return fmt.Errorf("gid2 error") }) asserts.Error(err, fmt.Errorf("gid2 error")) @@ -50,7 +51,7 @@ func TestBaseSqlDB(t *testing.T) { asserts.Equal(dbr.RowsAffected, int64(0)) barrier.BarrierID = 0 err = barrier.CallWithDB(db.ToSQLDB(), func(tx *sql.Tx) error { - dtmimp.Logf("submit gid2") + logger.Debugf("submit gid2") return nil }) asserts.Nil(err) diff --git a/test/tcc_barrier_test.go b/test/tcc_barrier_test.go index a1b3c88..238a70d 100644 --- a/test/tcc_barrier_test.go +++ b/test/tcc_barrier_test.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/examples" ) @@ -68,7 +69,7 @@ func TestTccBarrierDisorder(t *testing.T) { res, err := examples.TccBarrierTransOutCancel(c) if !sleeped { sleeped = true - dtmimp.Logf("sleep before cancel return") + logger.Debugf("sleep before cancel return") <-timeoutChan finishedChan <- "1" } @@ -89,7 +90,7 @@ func TestTccBarrierDisorder(t *testing.T) { assert.Contains(t, resp.String(), dtmcli.ResultSuccess) go func() { - dtmimp.Logf("sleeping to wait for tcc try timeout") + logger.Debugf("sleeping to wait for tcc try timeout") <-timeoutChan r, _ := dtmimp.RestyClient.R(). SetBody(body). @@ -104,10 +105,10 @@ func TestTccBarrierDisorder(t *testing.T) { assert.True(t, strings.Contains(r.String(), dtmcli.ResultSuccess)) // 这个是悬挂操作,为了简单起见,依旧让他返回成功 finishedChan <- "1" }() - dtmimp.Logf("cron to timeout and then call cancel") + logger.Debugf("cron to timeout and then call cancel") go cronTransOnceForwardNow(300) time.Sleep(100 * time.Millisecond) - dtmimp.Logf("cron to timeout and then call cancelled twice") + logger.Debugf("cron to timeout and then call cancelled twice") cronTransOnceForwardNow(300) timeoutChan <- "wake" timeoutChan <- "wake" diff --git a/test/tcc_grpc_test.go b/test/tcc_grpc_test.go index ff4b2df..16ba193 100644 --- a/test/tcc_grpc_test.go +++ b/test/tcc_grpc_test.go @@ -13,6 +13,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/examples" "google.golang.org/protobuf/types/known/emptypb" @@ -70,7 +71,7 @@ func TestTccGrpcNested(t *testing.T) { func TestTccGrpcType(t *testing.T) { _, err := dtmgrpc.TccFromGrpc(context.Background()) assert.Error(t, err) - dtmimp.Logf("expecting dtmgrpcserver error") + logger.Debugf("expecting dtmgrpcserver error") err = dtmgrpc.TccGlobalTransaction("-", "", func(tcc *dtmgrpc.TccGrpc) error { return nil }) assert.Error(t, err) } diff --git a/test/types.go b/test/types.go index ef1fd40..bef96cc 100644 --- a/test/types.go +++ b/test/types.go @@ -24,14 +24,14 @@ func dbGet() *common.DB { // waitTransProcessed only for test usage. wait for transaction processed once func waitTransProcessed(gid string) { - dtmimp.Logf("waiting for gid %s", gid) + logger.Debugf("waiting for gid %s", gid) select { case id := <-dtmsvr.TransProcessedTestChan: for id != gid { - dtmimp.LogRedf("-------id %s not match gid %s", id, gid) + logger.Errorf("-------id %s not match gid %s", id, gid) id = <-dtmsvr.TransProcessedTestChan } - dtmimp.Logf("finish for gid %s", gid) + logger.Debugf("finish for gid %s", gid) case <-time.After(time.Duration(time.Second * 3)): logger.FatalfIf(true, "Wait Trans timeout") } From f61665342290d8eb823ebaae7aab2ef073dfab4c Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 19:09:25 +0800 Subject: [PATCH 014/124] storage change add Infof --- common/utils.go | 1 + dtmcli/dtmimp/vars.go | 5 +++-- dtmsvr/api.go | 4 ++++ dtmsvr/cron.go | 1 + dtmsvr/storage/boltdb/boltdb.go | 1 + dtmsvr/storage/redis/redis.go | 7 +++++-- dtmsvr/storage/trans.go | 13 +++++++++++-- dtmsvr/svr.go | 2 +- dtmsvr/trans_process.go | 7 +++++-- dtmsvr/trans_status.go | 5 +++++ dtmsvr/trans_type_saga.go | 2 +- 11 files changed, 38 insertions(+), 10 deletions(-) diff --git a/common/utils.go b/common/utils.go index f9db2b1..c121733 100644 --- a/common/utils.go +++ b/common/utils.go @@ -118,5 +118,6 @@ func RunSQLScript(conf dtmcli.DBConf, script string, skipDrop bool) { } _, err = dtmimp.DBExec(con, s) logger.FatalIfError(err) + logger.Infof("sql scripts finished: %s", s) } } diff --git a/dtmcli/dtmimp/vars.go b/dtmcli/dtmimp/vars.go index ee9bad6..c7af1ff 100644 --- a/dtmcli/dtmimp/vars.go +++ b/dtmcli/dtmimp/vars.go @@ -10,6 +10,7 @@ import ( "errors" "github.com/go-resty/resty/v2" + "github.com/yedf/dtm/dtmcli/logger" ) // ErrFailure error of FAILURE @@ -36,12 +37,12 @@ func init() { // RestyClient.SetRetryWaitTime(1 * time.Second) RestyClient.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error { r.URL = MayReplaceLocalhost(r.URL) - Logf("requesting: %s %s %v %v", r.Method, r.URL, r.Body, r.QueryParam) + logger.Debugf("requesting: %s %s %v %v", r.Method, r.URL, r.Body, r.QueryParam) return nil }) RestyClient.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { r := resp.Request - Logf("requested: %s %s %s", r.Method, r.URL, resp.String()) + logger.Debugf("requested: %s %s %s", r.Method, r.URL, resp.String()) return nil }) } diff --git a/dtmsvr/api.go b/dtmsvr/api.go index eb26ffb..5ca0e9e 100644 --- a/dtmsvr/api.go +++ b/dtmsvr/api.go @@ -11,6 +11,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmsvr/storage" ) @@ -71,7 +72,10 @@ func svcRegisterBranch(transType string, branch *TransBranch, data map[string]st }) if err == storage.ErrNotFound { msg := fmt.Sprintf("no trans with gid: %s status: %s found", branch.Gid, dtmcli.StatusPrepared) + logger.Errorf(msg) return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": msg}, nil } + logger.Infof("LockGlobalSaveBranches result: %v: gid: %s old status: %s branches: %s", + err, branch.Gid, dtmcli.StatusPrepared, dtmimp.MustMarshalString(branches)) return dtmimp.If(err != nil, nil, dtmcli.MapSuccess), err } diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index bd31d29..120b74c 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -50,6 +50,7 @@ func lockOneTrans(expireIn time.Duration) *TransGlobal { if global == nil { return nil } + logger.Infof("cron job return a trans: %s", global.String()) return &TransGlobal{TransGlobalStore: *global} } diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index 31a0804..d02ba5c 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -242,6 +242,7 @@ func (s *BoltdbStore) PopulateData(skipDrop bool) { return nil }) dtmimp.E2P(err) + logger.Infof("Reset all data for boltdb") } } diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 00cecd4..084ce63 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -27,8 +27,11 @@ func (s *RedisStore) Ping() error { } func (s *RedisStore) PopulateData(skipDrop bool) { - _, err := redisGet().FlushAll(ctx).Result() - dtmimp.PanicIf(err != nil, err) + if !skipDrop { + _, err := redisGet().FlushAll(ctx).Result() + logger.Infof("call redis flushall. result: %v", err) + dtmimp.PanicIf(err != nil, err) + } } func (s *RedisStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { diff --git a/dtmsvr/storage/trans.go b/dtmsvr/storage/trans.go index dbabc01..24abd58 100644 --- a/dtmsvr/storage/trans.go +++ b/dtmsvr/storage/trans.go @@ -5,6 +5,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) type TransGlobalStore struct { @@ -29,10 +30,14 @@ type TransGlobalStore struct { } // TableName TableName -func (*TransGlobalStore) TableName() string { +func (g *TransGlobalStore) TableName() string { return "dtm.trans_global" } +func (g *TransGlobalStore) String() string { + return dtmimp.MustMarshalString(g) +} + // TransBranchStore branch transaction type TransBranchStore struct { common.ModelBase @@ -47,6 +52,10 @@ type TransBranchStore struct { } // TableName TableName -func (*TransBranchStore) TableName() string { +func (b *TransBranchStore) TableName() string { return "dtm.trans_branch_op" } + +func (b *TransBranchStore) String() string { + return dtmimp.MustMarshalString(*b) +} diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 4f6c866..283c442 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -79,11 +79,11 @@ func updateBranchAsync() { for len(updates) > 0 { dbr := GetStore().UpdateBranchesSql(updates, []string{"status", "finish_time", "update_time"}) - logger.Debugf("flushed %d branch status to db. affected: %d", len(updates), dbr.RowsAffected) if dbr.Error != nil { logger.Errorf("async update branch status error: %v", dbr.Error) time.Sleep(1 * time.Second) } else { + logger.Infof("flushed %d branch status to db. affected: %d", len(updates), dbr.RowsAffected) updates = []TransBranch{} } } diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index a9ef2f9..721919e 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -45,7 +45,7 @@ func (t *TransGlobal) process() map[string]interface{} { func (t *TransGlobal) processInner() (rerr error) { defer handlePanic(&rerr) defer func() { - if rerr != nil { + if rerr != nil && rerr != dtmcli.ErrOngoing { logger.Errorf("processInner got error: %s", rerr.Error()) } if TransProcessedTestChan != nil { @@ -72,5 +72,8 @@ func (t *TransGlobal) saveNew() error { now := time.Now() t.CreateTime = &now t.UpdateTime = &now - return GetStore().MaySaveNewTrans(&t.TransGlobalStore, branches) + err := GetStore().MaySaveNewTrans(&t.TransGlobalStore, branches) + logger.Infof("MaySaveNewTrans result: %v, global: %v branches: %v", + err, t.TransGlobalStore.String(), dtmimp.MustMarshalString(branches)) + return err } diff --git a/dtmsvr/trans_status.go b/dtmsvr/trans_status.go index d7097ca..371bef8 100644 --- a/dtmsvr/trans_status.go +++ b/dtmsvr/trans_status.go @@ -13,6 +13,7 @@ import ( "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmcli/logger" "github.com/yedf/dtm/dtmgrpc/dtmgimp" "github.com/yedf/dtmdriver" "google.golang.org/grpc/codes" @@ -22,6 +23,7 @@ import ( func (t *TransGlobal) touchCronTime(ctype cronType) { t.lastTouched = time.Now() GetStore().TouchCronTime(&t.TransGlobalStore, t.getNextCronInterval(ctype)) + logger.Infof("TouchCronTime for: %s", t.TransGlobalStore.String()) } func (t *TransGlobal) changeStatus(status string) { @@ -36,6 +38,7 @@ func (t *TransGlobal) changeStatus(status string) { } t.UpdateTime = &now GetStore().ChangeGlobalStatus(&t.TransGlobalStore, status, updates, status == dtmcli.StatusSucceed || status == dtmcli.StatusFailed) + logger.Infof("ChangeGlobalStatus to %s ok for %s", status, t.TransGlobalStore.String()) t.Status = status } @@ -46,6 +49,8 @@ func (t *TransGlobal) changeBranchStatus(b *TransBranch, status string, branchPo b.UpdateTime = &now if config.Store.Driver != dtmimp.DBTypeMysql && config.Store.Driver != dtmimp.DBTypePostgres || config.UpdateBranchSync > 0 || t.updateBranchSync { GetStore().LockGlobalSaveBranches(t.Gid, t.Status, []TransBranch{*b}, branchPos) + logger.Infof("LockGlobalSaveBranches ok: gid: %s old status: %s branches: %s", + b.Gid, dtmcli.StatusPrepared, b.String()) } else { // 为了性能优化,把branch的status更新异步化 updateBranchAsyncChan <- branchStatus{id: b.ID, status: status, finishTime: &now} } diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index bdeea9b..e710d46 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -104,7 +104,7 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { err = dtmimp.AsError(x) } resultChan <- branchResult{index: i, status: branches[i].Status, op: branches[i].Op} - if err != nil { + if err != nil && err != dtmcli.ErrOngoing { logger.Errorf("exec branch error: %v", err) } }() From 048abd90e2bb9fa893cb53adf6b296d48a8505c0 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 20:11:02 +0800 Subject: [PATCH 015/124] remove gin log --- app/main.go | 2 +- common/config.go | 1 + common/utils.go | 12 ++++++------ conf.sample.yml | 2 ++ dtmcli/logger/log.go | 13 +++++++------ dtmcli/logger/logger_test.go | 2 +- dtmsvr/svr.go | 6 +++--- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/app/main.go b/app/main.go index 68a8d57..edd4b9a 100644 --- a/app/main.go +++ b/app/main.go @@ -50,7 +50,7 @@ func main() { fmt.Printf("version: %s commit: %s built at: %s\n", Version, Commit, Date) return } - logger.Debugf("starting dtm....") + logger.Infof("starting dtm....") common.MustLoadConfig() if common.Config.ExamplesDB.Driver != "" { dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) diff --git a/common/config.go b/common/config.go index 940dd1a..6044305 100644 --- a/common/config.go +++ b/common/config.go @@ -61,6 +61,7 @@ type configType struct { GrpcPort int64 `yaml:"GrpcPort" default:"36790"` MicroService MicroService `yaml:"MicroService"` UpdateBranchSync int64 `yaml:"UpdateBranchSync"` + LogLevel string `yaml:"LogLevel" default:"info"` ExamplesDB dtmcli.DBConf `yaml:"ExamplesDB"` } diff --git a/common/utils.go b/common/utils.go index c121733..a712f6d 100644 --- a/common/utils.go +++ b/common/utils.go @@ -26,7 +26,8 @@ import ( // GetGinApp init and return gin func GetGinApp() *gin.Engine { gin.SetMode(gin.ReleaseMode) - app := gin.Default() + app := gin.New() + app.Use(gin.Recovery()) app.Use(func(c *gin.Context) { body := "" if c.Request.Body != nil { @@ -37,11 +38,8 @@ func GetGinApp() *gin.Engine { c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(rb)) } } - began := time.Now() logger.Debugf("begin %s %s query: %s body: %s", c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) c.Next() - logger.Debugf("used %d ms %s %s query: %s body: %s", time.Since(began).Milliseconds(), c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) - }) app.Any("/api/ping", func(c *gin.Context) { c.JSON(200, map[string]interface{}{"msg": "pong"}) }) return app @@ -50,6 +48,7 @@ func GetGinApp() *gin.Engine { // WrapHandler name is clear func WrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc { return func(c *gin.Context) { + began := time.Now() r, err := func() (r interface{}, rerr error) { defer dtmimp.P2E(&rerr) return fn(c) @@ -60,11 +59,12 @@ func WrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc { } else if err == nil { b, err = json.Marshal(r) } + if err != nil { - logger.Debugf("status: 500, code: 500 message: %s", err.Error()) + logger.Errorf("%2dms 500 %s %s %s %s", time.Since(began).Milliseconds(), err.Error(), c.Request.Method, c.Request.RequestURI, string(b)) c.JSON(500, map[string]interface{}{"code": 500, "message": err.Error()}) } else { - logger.Debugf("status: 200, content: %s", string(b)) + logger.Infof("%2dms 200 %s %s %s", time.Since(began).Milliseconds(), c.Request.Method, c.Request.RequestURI, string(b)) c.Status(200) c.Writer.Header().Add("Content-Type", "application/json") _, err = c.Writer.Write(b) diff --git a/conf.sample.yml b/conf.sample.yml index 3d698c0..cc7f447 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -39,6 +39,8 @@ Store: # specify which engine to store trans status # TimeoutToFail: 35 # timeout for XA, TCC to fail. saga's timeout default to infinite, which can be overwritten in saga options # RetryInterval: 10 # the subtrans branch will be retried after this interval +# LogLevel: 'info' # default: info. can be debug|info|warn|error + ### dtm can run examples, and examples will use following config to connect db ExamplesDB: Driver: 'mysql' diff --git a/dtmcli/logger/log.go b/dtmcli/logger/log.go index a1ff613..7d3650a 100644 --- a/dtmcli/logger/log.go +++ b/dtmcli/logger/log.go @@ -11,21 +11,22 @@ import ( var logger *zap.SugaredLogger = nil func init() { - InitLog() + InitLog("info") } // InitLog is a initialization for a logger -func InitLog() { +// level can be: debug info warn error +func InitLog(level string) { config := zap.NewProductionConfig() + err := config.Level.UnmarshalText([]byte(level)) + FatalIfError(err) config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder if os.Getenv("DTM_DEBUG") != "" { config.Encoding = "console" config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder } p, err := config.Build(zap.AddCallerSkip(1)) - if err != nil { - log.Fatal("create logger failed: ", err) - } + FatalIfError(err) logger = p.Sugar() } @@ -54,7 +55,7 @@ func FatalfIf(cond bool, fmt string, args ...interface{}) { if !cond { return } - logger.Fatalf(fmt, args...) + log.Fatalf(fmt, args...) } // FatalIfError if err is not nil, then log to level fatal and call os.Exit diff --git a/dtmcli/logger/logger_test.go b/dtmcli/logger/logger_test.go index 159e381..669a39f 100644 --- a/dtmcli/logger/logger_test.go +++ b/dtmcli/logger/logger_test.go @@ -7,7 +7,7 @@ import ( func TestInitLog(t *testing.T) { os.Setenv("DTM_DEBUG", "1") - InitLog() + InitLog("debug") Debugf("a debug msg") Infof("a info msg") Warnf("a warn msg") diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 283c442..2aa8950 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -22,11 +22,11 @@ import ( // StartSvr StartSvr func StartSvr() { - logger.Debugf("start dtmsvr") + logger.Infof("start dtmsvr") app := common.GetGinApp() app = httpMetrics(app) addRoute(app) - logger.Debugf("dtmsvr listen at: %d", config.HttpPort) + logger.Infof("dtmsvr listen at: %d", config.HttpPort) go app.Run(fmt.Sprintf(":%d", config.HttpPort)) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", config.GrpcPort)) @@ -36,7 +36,7 @@ func StartSvr() { grpc.UnaryServerInterceptor(grpcMetrics), grpc.UnaryServerInterceptor(dtmgimp.GrpcServerLog)), )) dtmgpb.RegisterDtmServer(s, &dtmServer{}) - logger.Debugf("grpc listening at %v", lis.Addr()) + logger.Infof("grpc listening at %v", lis.Addr()) go func() { err := s.Serve(lis) logger.FatalIfError(err) From 4b5d366e107a463979f7ddc92702a12e0109d05b Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 20:20:12 +0800 Subject: [PATCH 016/124] grpc request log ok --- dtmgrpc/dtmgimp/types.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dtmgrpc/dtmgimp/types.go b/dtmgrpc/dtmgimp/types.go index 31f0bf9..594c6c9 100644 --- a/dtmgrpc/dtmgimp/types.go +++ b/dtmgrpc/dtmgimp/types.go @@ -9,6 +9,7 @@ package dtmgimp import ( "context" "fmt" + "time" "github.com/yedf/dtm/dtmcli" "github.com/yedf/dtm/dtmcli/dtmimp" @@ -20,14 +21,16 @@ import ( // GrpcServerLog 打印grpc服务端的日志 func GrpcServerLog(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - logger.Debugf("grpc server handling: %s %v", info.FullMethod, req) + began := time.Now() + logger.Debugf("grpc server handling: %s %s", info.FullMethod, dtmimp.MustMarshalString(req)) LogDtmCtx(ctx) m, err := handler(ctx, req) - res := fmt.Sprintf("grpc server handled: %s %v result: %v err: %v", info.FullMethod, req, m, err) + res := fmt.Sprintf("%2dms %v %s %s %s", + time.Since(began).Milliseconds(), err, info.FullMethod, dtmimp.MustMarshalString(m), dtmimp.MustMarshalString(req)) if err != nil { logger.Errorf("%s", res) } else { - logger.Debugf("%s", res) + logger.Infof("%s", res) } return m, err } From ac5126cde08ab92003d7686feac9aaa5cd4100c7 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 20:21:37 +0800 Subject: [PATCH 017/124] remove lua print --- dtmsvr/storage/redis/redis.go | 1 - 1 file changed, 1 deletion(-) diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 084ce63..001b849 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -205,7 +205,6 @@ if os.status ~= ARGV[4] then return 'NOT_FOUND' end redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) -redis.log(redis.LOG_WARNING, 'finished: ', ARGV[5]) if ARGV[5] == '1' then redis.call('ZREM', KEYS[3], gs.gid) end From a47646c21e61f6832a4c1c9e6c411d29027f901b Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 22:34:07 +0800 Subject: [PATCH 018/124] trigger a build --- go.sum | 1 + 1 file changed, 1 insertion(+) diff --git a/go.sum b/go.sum index a652bd4..de06073 100644 --- a/go.sum +++ b/go.sum @@ -893,3 +893,4 @@ sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= + From 7160c3d8ee65135523e385ca434d9ae2839a2554 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 24 Dec 2021 23:22:14 +0800 Subject: [PATCH 019/124] rename to dtm-labs --- README-cn.md | 16 ++++++++-------- README-en.md | 14 +++++++------- README.md | 16 ++++++++-------- app/main.go | 12 ++++++------ bench/http.go | 12 ++++++------ bench/main.go | 12 ++++++------ common/config.go | 4 ++-- common/config_utils.go | 2 +- common/db.go | 6 +++--- common/types.go | 2 +- common/types_test.go | 2 +- common/utils.go | 6 +++--- dtmcli/barrier.go | 4 ++-- dtmcli/consts.go | 2 +- dtmcli/dtmimp/utils.go | 2 +- dtmcli/dtmimp/vars.go | 2 +- dtmcli/msg.go | 2 +- dtmcli/saga.go | 2 +- dtmcli/tcc.go | 2 +- dtmcli/types.go | 2 +- dtmcli/types_test.go | 2 +- dtmcli/xa.go | 2 +- dtmgrpc/barrier.go | 4 ++-- dtmgrpc/dtmgimp/grpc_clients.go | 6 +++--- dtmgrpc/dtmgimp/types.go | 6 +++--- dtmgrpc/dtmgimp/utils.go | 6 +++--- dtmgrpc/msg.go | 6 +++--- dtmgrpc/saga.go | 4 ++-- dtmgrpc/tcc.go | 8 ++++---- dtmgrpc/type.go | 8 ++++---- dtmgrpc/type_test.go | 2 +- dtmgrpc/xa.go | 10 +++++----- dtmsvr/api.go | 8 ++++---- dtmsvr/api_grpc.go | 6 +++--- dtmsvr/api_http.go | 6 +++--- dtmsvr/cron.go | 4 ++-- dtmsvr/storage/boltdb/boltdb.go | 8 ++++---- dtmsvr/storage/boltdb/boltdb_test.go | 4 ++-- dtmsvr/storage/redis/redis.go | 8 ++++---- dtmsvr/storage/registry/registry.go | 10 +++++----- dtmsvr/storage/sql/sql.go | 6 +++--- dtmsvr/storage/trans.go | 6 +++--- dtmsvr/svr.go | 10 +++++----- dtmsvr/svr_imports.go | 6 +++--- dtmsvr/trans_class.go | 10 +++++----- dtmsvr/trans_process.go | 8 ++++---- dtmsvr/trans_status.go | 10 +++++----- dtmsvr/trans_type_msg.go | 4 ++-- dtmsvr/trans_type_saga.go | 6 +++--- dtmsvr/trans_type_tcc.go | 6 +++--- dtmsvr/trans_type_xa.go | 4 ++-- dtmsvr/utils.go | 8 ++++---- examples/base_grpc.go | 12 ++++++------ examples/base_http.go | 8 ++++---- examples/base_types.go | 10 +++++----- examples/data.go | 4 ++-- examples/grpc_msg.go | 4 ++-- examples/grpc_saga.go | 4 ++-- examples/grpc_saga_barrier.go | 8 ++++---- examples/grpc_tcc.go | 4 ++-- examples/grpc_xa.go | 4 ++-- examples/http_gorm_xa.go | 4 ++-- examples/http_msg.go | 4 ++-- examples/http_saga.go | 4 ++-- examples/http_saga_barrier.go | 8 ++++---- examples/http_saga_gorm_barrier.go | 6 +++--- examples/http_tcc.go | 6 +++--- examples/http_tcc_barrier.go | 8 ++++---- examples/http_xa.go | 6 +++--- examples/quick_start.go | 8 ++++---- go.mod | 10 +++++----- go.sum | 24 ++++++++++++++++-------- helper/sync-dtmcli.sh | 8 ++++---- helper/test-cover.sh | 2 +- test/api_test.go | 4 ++-- test/base_test.go | 10 +++++----- test/dtmsvr_test.go | 10 +++++----- test/examples_test.go | 2 +- test/main_test.go | 8 ++++---- test/msg_grpc_test.go | 8 ++++---- test/msg_options_test.go | 6 +++--- test/msg_test.go | 6 +++--- test/saga_barrier_test.go | 6 +++--- test/saga_compatible_test.go | 4 ++-- test/saga_concurrent_test.go | 6 +++--- test/saga_grpc_barrier_test.go | 6 +++--- test/saga_grpc_test.go | 8 ++++---- test/saga_options_test.go | 6 +++--- test/saga_test.go | 6 +++--- test/store_test.go | 6 +++--- test/tcc_barrier_test.go | 8 ++++---- test/tcc_cover_test.go | 6 +++--- test/tcc_grpc_cover_test.go | 6 +++--- test/tcc_grpc_test.go | 10 +++++----- test/tcc_test.go | 6 +++--- test/types.go | 10 +++++----- test/xa_cover_test.go | 6 +++--- test/xa_grpc_test.go | 6 +++--- test/xa_test.go | 6 +++--- 99 files changed, 327 insertions(+), 319 deletions(-) diff --git a/README-cn.md b/README-cn.md index 527e771..85eb559 100644 --- a/README-cn.md +++ b/README-cn.md @@ -1,8 +1,8 @@ -![license](https://img.shields.io/github/license/yedf/dtm) -![Build Status](https://github.com/yedf/dtm/actions/workflows/tests.yml/badge.svg?branch=main) -[![codecov](https://codecov.io/gh/yedf/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/yedf/dtm) -[![Go Report Card](https://goreportcard.com/badge/github.com/yedf/dtm)](https://goreportcard.com/report/github.com/yedf/dtm) -[![Go Reference](https://pkg.go.dev/badge/github.com/yedf/dtm.svg)](https://pkg.go.dev/github.com/yedf/dtm) +![license](https://img.shields.io/github/license/dtm-labs/dtm) +![Build Status](https://github.com/dtm-labs/dtm/actions/workflows/tests.yml/badge.svg?branch=main) +[![codecov](https://codecov.io/gh/dtm-labs/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/dtm-labs/dtm) +[![Go Report Card](https://goreportcard.com/badge/github.com/dtm-labs/dtm)](https://goreportcard.com/report/github.com/dtm-labs/dtm) +[![Go Reference](https://pkg.go.dev/badge/github.com/dtm-labs/dtm.svg)](https://pkg.go.dev/github.com/dtm-labs/dtm) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#database) # [English Docs](https://en.dtm.pub) @@ -55,7 +55,7 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 |事务消息|||dtm提供类似rocketmq的事务消息| |单服务多数据源|||| |通信协议|HTTP、gRPC、go-zero|dubbo等协议|dtm对云原生更加友好| -|star数量|github stars|github stars|dtm从20210604发布0.1,发展快| +|star数量|github stars|github stars|dtm从20210604发布0.1,发展快| 从上面对比的特性来看,如果您的语言栈包含了Java之外的语言,那么dtm是您的首选。如果您的语言栈是Java,您也可以选择接入dtm,使用子事务屏障技术,简化您的业务编写。 @@ -75,7 +75,7 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ### 获取代码 -`git clone https://github.com/yedf/dtm && cd dtm` +`git clone https://github.com/dtm-labs/dtm && cd dtm` ### dtm依赖于mysql @@ -126,7 +126,7 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) -欢迎使用[dtm](https://github.com/yedf/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 +欢迎使用[dtm](https://github.com/dtm-labs/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 ## 谁在使用
diff --git a/README-en.md b/README-en.md index a16b0bf..a83160f 100644 --- a/README-en.md +++ b/README-en.md @@ -1,8 +1,8 @@ -![license](https://img.shields.io/github/license/yedf/dtm) -![Build Status](https://github.com/yedf/dtm/actions/workflows/tests.yml/badge.svg?branch=main) -[![codecov](https://codecov.io/gh/yedf/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/yedf/dtm) -[![Go Report Card](https://goreportcard.com/badge/github.com/yedf/dtm)](https://goreportcard.com/report/github.com/yedf/dtm) -[![Go Reference](https://pkg.go.dev/badge/github.com/yedf/dtm.svg)](https://pkg.go.dev/github.com/yedf/dtm) +![license](https://img.shields.io/github/license/dtm-labs/dtm) +![Build Status](https://github.com/dtm-labs/dtm/actions/workflows/tests.yml/badge.svg?branch=main) +[![codecov](https://codecov.io/gh/dtm-labs/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/dtm-labs/dtm) +[![Go Report Card](https://goreportcard.com/badge/github.com/dtm-labs/dtm)](https://goreportcard.com/report/github.com/dtm-labs/dtm) +[![Go Reference](https://pkg.go.dev/badge/github.com/dtm-labs/dtm.svg)](https://pkg.go.dev/github.com/dtm-labs/dtm) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#database) # [中文文档](http://dtm.pub) @@ -62,7 +62,7 @@ The following is a comparison of the main features of dtm and Seata. | Transactional Messaging | | | dtm provides Transactional Messaging similar to RocketMQ | | Multiple DBs in a service |||| | Communication protocols | HTTP, gRPC | Dubbo, no HTTP | | -| Star count | github stars | github stars | dtm 0.1 is released from 20210604 and under fast development | +| Star count | github stars | github stars | dtm 0.1 is released from 20210604 and under fast development | From the features' comparison above, if your language stack includes languages other than Java, then dtm is the one for you. If your language stack is Java, you can also choose to access dtm and use sub-transaction barrier technology to simplify your business development. @@ -73,7 +73,7 @@ If your language stack is Java, you can also choose to access dtm and use sub-tr ### Install -`git clone https://github.com/yedf/dtm` +`git clone https://github.com/dtm-labs/dtm` ### Configure Mysql diff --git a/README.md b/README.md index 527e771..85eb559 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -![license](https://img.shields.io/github/license/yedf/dtm) -![Build Status](https://github.com/yedf/dtm/actions/workflows/tests.yml/badge.svg?branch=main) -[![codecov](https://codecov.io/gh/yedf/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/yedf/dtm) -[![Go Report Card](https://goreportcard.com/badge/github.com/yedf/dtm)](https://goreportcard.com/report/github.com/yedf/dtm) -[![Go Reference](https://pkg.go.dev/badge/github.com/yedf/dtm.svg)](https://pkg.go.dev/github.com/yedf/dtm) +![license](https://img.shields.io/github/license/dtm-labs/dtm) +![Build Status](https://github.com/dtm-labs/dtm/actions/workflows/tests.yml/badge.svg?branch=main) +[![codecov](https://codecov.io/gh/dtm-labs/dtm/branch/main/graph/badge.svg?token=UKKEYQLP3F)](https://codecov.io/gh/dtm-labs/dtm) +[![Go Report Card](https://goreportcard.com/badge/github.com/dtm-labs/dtm)](https://goreportcard.com/report/github.com/dtm-labs/dtm) +[![Go Reference](https://pkg.go.dev/badge/github.com/dtm-labs/dtm.svg)](https://pkg.go.dev/github.com/dtm-labs/dtm) [![Mentioned in Awesome Go](https://awesome.re/mentioned-badge-flat.svg)](https://github.com/avelino/awesome-go#database) # [English Docs](https://en.dtm.pub) @@ -55,7 +55,7 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 |事务消息|||dtm提供类似rocketmq的事务消息| |单服务多数据源|||| |通信协议|HTTP、gRPC、go-zero|dubbo等协议|dtm对云原生更加友好| -|star数量|github stars|github stars|dtm从20210604发布0.1,发展快| +|star数量|github stars|github stars|dtm从20210604发布0.1,发展快| 从上面对比的特性来看,如果您的语言栈包含了Java之外的语言,那么dtm是您的首选。如果您的语言栈是Java,您也可以选择接入dtm,使用子事务屏障技术,简化您的业务编写。 @@ -75,7 +75,7 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ### 获取代码 -`git clone https://github.com/yedf/dtm && cd dtm` +`git clone https://github.com/dtm-labs/dtm && cd dtm` ### dtm依赖于mysql @@ -126,7 +126,7 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) -欢迎使用[dtm](https://github.com/yedf/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 +欢迎使用[dtm](https://github.com/dtm-labs/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 ## 谁在使用
diff --git a/app/main.go b/app/main.go index edd4b9a..c0e5c5d 100644 --- a/app/main.go +++ b/app/main.go @@ -13,12 +13,12 @@ import ( _ "go.uber.org/automaxprocs" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmsvr" - "github.com/yedf/dtm/dtmsvr/storage/registry" - "github.com/yedf/dtm/examples" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/dtmsvr/storage/registry" + "github.com/dtm-labs/dtm/examples" ) var Version, Commit, Date string diff --git a/bench/http.go b/bench/http.go index 403abd3..4682271 100644 --- a/bench/http.go +++ b/bench/http.go @@ -13,13 +13,13 @@ import ( "sync/atomic" "time" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/examples" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmsvr" - "github.com/yedf/dtm/examples" ) // launch command:go run app/main.go qs diff --git a/bench/main.go b/bench/main.go index ebd604d..9bff1b0 100644 --- a/bench/main.go +++ b/bench/main.go @@ -4,12 +4,12 @@ import ( "fmt" "os" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmsvr" - "github.com/yedf/dtm/dtmsvr/storage/registry" - "github.com/yedf/dtm/examples" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/dtmsvr/storage/registry" + "github.com/dtm-labs/dtm/examples" ) var hint = `To start the bench server, you need to specify the parameters: diff --git a/common/config.go b/common/config.go index 6044305..68bf312 100644 --- a/common/config.go +++ b/common/config.go @@ -6,8 +6,8 @@ import ( "io/ioutil" "path/filepath" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" "gopkg.in/yaml.v2" ) diff --git a/common/config_utils.go b/common/config_utils.go index e54a834..60069b8 100644 --- a/common/config_utils.go +++ b/common/config_utils.go @@ -7,7 +7,7 @@ import ( "regexp" "strings" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" ) func loadFromEnv(prefix string, conf interface{}) { diff --git a/common/db.go b/common/db.go index f2d1c66..009725e 100644 --- a/common/db.go +++ b/common/db.go @@ -7,11 +7,11 @@ import ( "sync" "time" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" _ "github.com/go-sql-driver/mysql" // register mysql driver _ "github.com/lib/pq" // register postgres driver - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" diff --git a/common/types.go b/common/types.go index 19bd8ea..8949021 100644 --- a/common/types.go +++ b/common/types.go @@ -10,8 +10,8 @@ import ( "fmt" "sync" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/go-redis/redis/v8" - "github.com/yedf/dtm/dtmcli/logger" ) var rdb *redis.Client diff --git a/common/types_test.go b/common/types_test.go index 8aea076..7bb5500 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -9,8 +9,8 @@ package common import ( "testing" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" ) func TestGeneralDB(t *testing.T) { diff --git a/common/utils.go b/common/utils.go index a712f6d..4af5c1b 100644 --- a/common/utils.go +++ b/common/utils.go @@ -18,9 +18,9 @@ import ( "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" ) // GetGinApp init and return gin diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index ede7080..ff14336 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -11,8 +11,8 @@ import ( "fmt" "net/url" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" ) // BarrierBusiFunc type for busi func diff --git a/dtmcli/consts.go b/dtmcli/consts.go index 5b538a7..b27b90a 100644 --- a/dtmcli/consts.go +++ b/dtmcli/consts.go @@ -7,7 +7,7 @@ package dtmcli import ( - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" ) const ( diff --git a/dtmcli/dtmimp/utils.go b/dtmcli/dtmimp/utils.go index eb264bf..242089d 100644 --- a/dtmcli/dtmimp/utils.go +++ b/dtmcli/dtmimp/utils.go @@ -18,8 +18,8 @@ import ( "sync" "time" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/dtmcli/logger" ) // Logf an alias of Infof diff --git a/dtmcli/dtmimp/vars.go b/dtmcli/dtmimp/vars.go index c7af1ff..eea02ad 100644 --- a/dtmcli/dtmimp/vars.go +++ b/dtmcli/dtmimp/vars.go @@ -9,8 +9,8 @@ package dtmimp import ( "errors" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/dtmcli/logger" ) // ErrFailure error of FAILURE diff --git a/dtmcli/msg.go b/dtmcli/msg.go index e7dc97c..a461ea2 100644 --- a/dtmcli/msg.go +++ b/dtmcli/msg.go @@ -6,7 +6,7 @@ package dtmcli -import "github.com/yedf/dtm/dtmcli/dtmimp" +import "github.com/dtm-labs/dtm/dtmcli/dtmimp" // Msg reliable msg type type Msg struct { diff --git a/dtmcli/saga.go b/dtmcli/saga.go index 05ad6f9..2ac9c1c 100644 --- a/dtmcli/saga.go +++ b/dtmcli/saga.go @@ -7,7 +7,7 @@ package dtmcli import ( - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" ) // Saga struct of saga diff --git a/dtmcli/tcc.go b/dtmcli/tcc.go index d1f85b0..9df1bd4 100644 --- a/dtmcli/tcc.go +++ b/dtmcli/tcc.go @@ -10,8 +10,8 @@ import ( "fmt" "net/url" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/dtmcli/dtmimp" ) // Tcc struct of tcc diff --git a/dtmcli/types.go b/dtmcli/types.go index 3726e56..e0e54e2 100644 --- a/dtmcli/types.go +++ b/dtmcli/types.go @@ -9,7 +9,7 @@ package dtmcli import ( "fmt" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" ) // MustGenGid generate a new gid diff --git a/dtmcli/types_test.go b/dtmcli/types_test.go index 8128e7d..b37ba9a 100644 --- a/dtmcli/types_test.go +++ b/dtmcli/types_test.go @@ -10,8 +10,8 @@ import ( "net/url" "testing" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" ) func TestTypes(t *testing.T) { diff --git a/dtmcli/xa.go b/dtmcli/xa.go index cd9ca48..d28bed7 100644 --- a/dtmcli/xa.go +++ b/dtmcli/xa.go @@ -11,8 +11,8 @@ import ( "fmt" "net/url" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/dtmcli/dtmimp" ) // XaGlobalFunc type of xa global function diff --git a/dtmgrpc/barrier.go b/dtmgrpc/barrier.go index 05cf5ee..973c14a 100644 --- a/dtmgrpc/barrier.go +++ b/dtmgrpc/barrier.go @@ -9,8 +9,8 @@ package dtmgrpc import ( "context" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" ) // BarrierFromGrpc generate a Barrier from grpc context diff --git a/dtmgrpc/dtmgimp/grpc_clients.go b/dtmgrpc/dtmgimp/grpc_clients.go index e437054..d2c63a0 100644 --- a/dtmgrpc/dtmgimp/grpc_clients.go +++ b/dtmgrpc/dtmgimp/grpc_clients.go @@ -10,9 +10,9 @@ import ( "fmt" "sync" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" grpc "google.golang.org/grpc" ) diff --git a/dtmgrpc/dtmgimp/types.go b/dtmgrpc/dtmgimp/types.go index 594c6c9..3b8048d 100644 --- a/dtmgrpc/dtmgimp/types.go +++ b/dtmgrpc/dtmgimp/types.go @@ -11,9 +11,9 @@ import ( "fmt" "time" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" diff --git a/dtmgrpc/dtmgimp/utils.go b/dtmgrpc/dtmgimp/utils.go index e600166..bb49f39 100644 --- a/dtmgrpc/dtmgimp/utils.go +++ b/dtmgrpc/dtmgimp/utils.go @@ -9,9 +9,9 @@ package dtmgimp import ( context "context" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" emptypb "google.golang.org/protobuf/types/known/emptypb" diff --git a/dtmgrpc/msg.go b/dtmgrpc/msg.go index 31448a9..e112713 100644 --- a/dtmgrpc/msg.go +++ b/dtmgrpc/msg.go @@ -7,9 +7,9 @@ package dtmgrpc import ( - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "google.golang.org/protobuf/proto" ) diff --git a/dtmgrpc/saga.go b/dtmgrpc/saga.go index feb0879..af09038 100644 --- a/dtmgrpc/saga.go +++ b/dtmgrpc/saga.go @@ -7,8 +7,8 @@ package dtmgrpc import ( - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "google.golang.org/protobuf/proto" ) diff --git a/dtmgrpc/tcc.go b/dtmgrpc/tcc.go index 1b8bebd..d4c0592 100644 --- a/dtmgrpc/tcc.go +++ b/dtmgrpc/tcc.go @@ -10,10 +10,10 @@ import ( context "context" "fmt" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" - "github.com/yedf/dtm/dtmgrpc/dtmgpb" - "github.com/yedf/dtmdriver" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtmdriver" "google.golang.org/protobuf/proto" ) diff --git a/dtmgrpc/type.go b/dtmgrpc/type.go index 3990261..c2b7fa7 100644 --- a/dtmgrpc/type.go +++ b/dtmgrpc/type.go @@ -9,10 +9,10 @@ package dtmgrpc import ( context "context" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" - "github.com/yedf/dtmdriver" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtmdriver" emptypb "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/dtmgrpc/type_test.go b/dtmgrpc/type_test.go index 9440905..7c44e4a 100644 --- a/dtmgrpc/type_test.go +++ b/dtmgrpc/type_test.go @@ -10,8 +10,8 @@ import ( "context" "testing" + "github.com/dtm-labs/dtm/dtmcli" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" ) func TestType(t *testing.T) { diff --git a/dtmgrpc/xa.go b/dtmgrpc/xa.go index 23ba33c..95a97a1 100644 --- a/dtmgrpc/xa.go +++ b/dtmgrpc/xa.go @@ -11,11 +11,11 @@ import ( "database/sql" "fmt" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" - "github.com/yedf/dtm/dtmgrpc/dtmgpb" - "github.com/yedf/dtmdriver" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtmdriver" grpc "google.golang.org/grpc" "google.golang.org/protobuf/proto" emptypb "google.golang.org/protobuf/types/known/emptypb" diff --git a/dtmsvr/api.go b/dtmsvr/api.go index 5ca0e9e..5c61a8d 100644 --- a/dtmsvr/api.go +++ b/dtmsvr/api.go @@ -9,10 +9,10 @@ package dtmsvr import ( "fmt" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr/storage" ) func svcSubmit(t *TransGlobal) (interface{}, error) { diff --git a/dtmsvr/api_grpc.go b/dtmsvr/api_grpc.go index 4d4daf8..461b251 100644 --- a/dtmsvr/api_grpc.go +++ b/dtmsvr/api_grpc.go @@ -9,9 +9,9 @@ package dtmsvr import ( "context" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" - pb "github.com/yedf/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + pb "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/dtmsvr/api_http.go b/dtmsvr/api_http.go index 5102506..bbd09de 100644 --- a/dtmsvr/api_http.go +++ b/dtmsvr/api_http.go @@ -9,11 +9,11 @@ package dtmsvr import ( "errors" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" ) func addRoute(engine *gin.Engine) { diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index 120b74c..c718840 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -12,8 +12,8 @@ import ( "runtime/debug" "time" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" ) // NowForwardDuration will be set in test, trans may be timeout diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index d02ba5c..e1af190 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -9,10 +9,10 @@ import ( bolt "go.etcd.io/bbolt" "gorm.io/gorm" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr/storage" ) var config = &common.Config diff --git a/dtmsvr/storage/boltdb/boltdb_test.go b/dtmsvr/storage/boltdb/boltdb_test.go index 7388222..2e96a7c 100644 --- a/dtmsvr/storage/boltdb/boltdb_test.go +++ b/dtmsvr/storage/boltdb/boltdb_test.go @@ -8,8 +8,8 @@ import ( . "github.com/onsi/gomega" bolt "go.etcd.io/bbolt" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/storage" ) func TestInitializeBuckets(t *testing.T) { diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 001b849..8dca435 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -8,10 +8,10 @@ import ( "github.com/go-redis/redis/v8" "gorm.io/gorm" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr/storage" ) var config = &common.Config diff --git a/dtmsvr/storage/registry/registry.go b/dtmsvr/storage/registry/registry.go index e0fbe93..2fc349c 100644 --- a/dtmsvr/storage/registry/registry.go +++ b/dtmsvr/storage/registry/registry.go @@ -3,11 +3,11 @@ package registry import ( "time" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmsvr/storage" - "github.com/yedf/dtm/dtmsvr/storage/boltdb" - "github.com/yedf/dtm/dtmsvr/storage/redis" - "github.com/yedf/dtm/dtmsvr/storage/sql" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmsvr/storage/boltdb" + "github.com/dtm-labs/dtm/dtmsvr/storage/redis" + "github.com/dtm-labs/dtm/dtmsvr/storage/sql" ) var config = &common.Config diff --git a/dtmsvr/storage/sql/sql.go b/dtmsvr/storage/sql/sql.go index db4ad26..3b246ba 100644 --- a/dtmsvr/storage/sql/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -9,9 +9,9 @@ import ( "gorm.io/gorm" "gorm.io/gorm/clause" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/storage" ) var config = &common.Config diff --git a/dtmsvr/storage/trans.go b/dtmsvr/storage/trans.go index 24abd58..cb85ee1 100644 --- a/dtmsvr/storage/trans.go +++ b/dtmsvr/storage/trans.go @@ -3,9 +3,9 @@ package storage import ( "time" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" ) type TransGlobalStore struct { diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 2aa8950..e2c739d 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -11,12 +11,12 @@ import ( "net" "time" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtmdriver" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" - "github.com/yedf/dtm/dtmgrpc/dtmgpb" - "github.com/yedf/dtmdriver" "google.golang.org/grpc" ) diff --git a/dtmsvr/svr_imports.go b/dtmsvr/svr_imports.go index f708b1f..7cc1bea 100644 --- a/dtmsvr/svr_imports.go +++ b/dtmsvr/svr_imports.go @@ -1,7 +1,7 @@ package dtmsvr import ( - _ "github.com/ychensha/dtmdriver-polaris" - _ "github.com/yedf/dtmdriver-gozero" - _ "github.com/yedf/dtmdriver-protocol1" + _ "github.com/dtm-labs/dtmdriver-gozero" + _ "github.com/dtm-labs/dtmdriver-polaris" + _ "github.com/dtm-labs/dtmdriver-protocol1" ) diff --git a/dtmsvr/trans_class.go b/dtmsvr/trans_class.go index faf3125..977f44b 100644 --- a/dtmsvr/trans_class.go +++ b/dtmsvr/trans_class.go @@ -9,12 +9,12 @@ package dtmsvr import ( "time" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtm/dtmsvr/storage" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc/dtmgpb" - "github.com/yedf/dtm/dtmsvr/storage" ) // TransGlobal global transaction diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index 721919e..8165e50 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -9,10 +9,10 @@ package dtmsvr import ( "time" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" ) // Process process global transaction once diff --git a/dtmsvr/trans_status.go b/dtmsvr/trans_status.go index 371bef8..bf14e43 100644 --- a/dtmsvr/trans_status.go +++ b/dtmsvr/trans_status.go @@ -11,11 +11,11 @@ import ( "strings" "time" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" - "github.com/yedf/dtmdriver" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtmdriver" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) diff --git a/dtmsvr/trans_type_msg.go b/dtmsvr/trans_type_msg.go index 63a62b6..3f62f74 100644 --- a/dtmsvr/trans_type_msg.go +++ b/dtmsvr/trans_type_msg.go @@ -10,8 +10,8 @@ import ( "fmt" "strings" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" ) type transMsgProcessor struct { diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index e710d46..b74dce4 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -10,9 +10,9 @@ import ( "fmt" "time" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" ) type transSagaProcessor struct { diff --git a/dtmsvr/trans_type_tcc.go b/dtmsvr/trans_type_tcc.go index 2c32ab6..31ae557 100644 --- a/dtmsvr/trans_type_tcc.go +++ b/dtmsvr/trans_type_tcc.go @@ -7,9 +7,9 @@ package dtmsvr import ( - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" ) type transTccProcessor struct { diff --git a/dtmsvr/trans_type_xa.go b/dtmsvr/trans_type_xa.go index ad44dd0..4f45205 100644 --- a/dtmsvr/trans_type_xa.go +++ b/dtmsvr/trans_type_xa.go @@ -7,8 +7,8 @@ package dtmsvr import ( - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" ) type transXaProcessor struct { diff --git a/dtmsvr/utils.go b/dtmsvr/utils.go index 07e017a..b711d40 100644 --- a/dtmsvr/utils.go +++ b/dtmsvr/utils.go @@ -12,10 +12,10 @@ import ( "github.com/google/uuid" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmsvr/storage" - "github.com/yedf/dtm/dtmsvr/storage/registry" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmsvr/storage/registry" ) type branchStatus struct { diff --git a/examples/base_grpc.go b/examples/base_grpc.go index 07eb749..38cda95 100644 --- a/examples/base_grpc.go +++ b/examples/base_grpc.go @@ -13,14 +13,14 @@ import ( "net" "time" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc" - "github.com/yedf/dtm/dtmgrpc/dtmgimp" - "github.com/yedf/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" grpc "google.golang.org/grpc" codes "google.golang.org/grpc/codes" status "google.golang.org/grpc/status" diff --git a/examples/base_http.go b/examples/base_http.go index 401d1f3..cad5834 100644 --- a/examples/base_http.go +++ b/examples/base_http.go @@ -13,11 +13,11 @@ import ( "strings" "time" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" diff --git a/examples/base_types.go b/examples/base_types.go index f906b4a..f7a4392 100644 --- a/examples/base_types.go +++ b/examples/base_types.go @@ -11,12 +11,12 @@ import ( "database/sql" "fmt" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc" ) // DtmHttpServer dtm service address diff --git a/examples/data.go b/examples/data.go index 0a4f52c..c865ba7 100644 --- a/examples/data.go +++ b/examples/data.go @@ -9,8 +9,8 @@ package examples import ( "fmt" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli/logger" ) var config = &common.Config diff --git a/examples/grpc_msg.go b/examples/grpc_msg.go index 2bbe650..5e89058 100644 --- a/examples/grpc_msg.go +++ b/examples/grpc_msg.go @@ -7,8 +7,8 @@ package examples import ( - "github.com/yedf/dtm/dtmcli/logger" - dtmgrpc "github.com/yedf/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmcli/logger" + dtmgrpc "github.com/dtm-labs/dtm/dtmgrpc" ) func init() { diff --git a/examples/grpc_saga.go b/examples/grpc_saga.go index 3a29de4..395976b 100644 --- a/examples/grpc_saga.go +++ b/examples/grpc_saga.go @@ -7,8 +7,8 @@ package examples import ( - "github.com/yedf/dtm/dtmcli/logger" - dtmgrpc "github.com/yedf/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmcli/logger" + dtmgrpc "github.com/dtm-labs/dtm/dtmgrpc" ) func init() { diff --git a/examples/grpc_saga_barrier.go b/examples/grpc_saga_barrier.go index 892e140..d838181 100644 --- a/examples/grpc_saga_barrier.go +++ b/examples/grpc_saga_barrier.go @@ -10,10 +10,10 @@ import ( "context" "database/sql" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" emptypb "google.golang.org/protobuf/types/known/emptypb" diff --git a/examples/grpc_tcc.go b/examples/grpc_tcc.go index 5a6c4fd..411a3e8 100644 --- a/examples/grpc_tcc.go +++ b/examples/grpc_tcc.go @@ -7,8 +7,8 @@ package examples import ( - "github.com/yedf/dtm/dtmcli/logger" - dtmgrpc "github.com/yedf/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmcli/logger" + dtmgrpc "github.com/dtm-labs/dtm/dtmgrpc" emptypb "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/examples/grpc_xa.go b/examples/grpc_xa.go index c4f9d3c..c55e953 100644 --- a/examples/grpc_xa.go +++ b/examples/grpc_xa.go @@ -9,8 +9,8 @@ package examples import ( context "context" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/examples/http_gorm_xa.go b/examples/http_gorm_xa.go index caacb79..b77e7dd 100644 --- a/examples/http_gorm_xa.go +++ b/examples/http_gorm_xa.go @@ -7,9 +7,9 @@ package examples import ( + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" ) func init() { diff --git a/examples/http_msg.go b/examples/http_msg.go index 3f40805..34bbc82 100644 --- a/examples/http_msg.go +++ b/examples/http_msg.go @@ -7,8 +7,8 @@ package examples import ( - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" ) func init() { diff --git a/examples/http_saga.go b/examples/http_saga.go index d7dd59b..398f045 100644 --- a/examples/http_saga.go +++ b/examples/http_saga.go @@ -7,8 +7,8 @@ package examples import ( - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" ) func init() { diff --git a/examples/http_saga_barrier.go b/examples/http_saga_barrier.go index c633c58..53af51d 100644 --- a/examples/http_saga_barrier.go +++ b/examples/http_saga_barrier.go @@ -9,11 +9,11 @@ package examples import ( "database/sql" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" ) func init() { diff --git a/examples/http_saga_gorm_barrier.go b/examples/http_saga_gorm_barrier.go index 9499506..0eda05e 100644 --- a/examples/http_saga_gorm_barrier.go +++ b/examples/http_saga_gorm_barrier.go @@ -9,10 +9,10 @@ package examples import ( "database/sql" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" ) func init() { diff --git a/examples/http_tcc.go b/examples/http_tcc.go index 76dff2f..3055d44 100644 --- a/examples/http_tcc.go +++ b/examples/http_tcc.go @@ -7,11 +7,11 @@ package examples import ( + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" ) func init() { diff --git a/examples/http_tcc_barrier.go b/examples/http_tcc_barrier.go index 56a0467..70b018a 100644 --- a/examples/http_tcc_barrier.go +++ b/examples/http_tcc_barrier.go @@ -10,12 +10,12 @@ import ( "database/sql" "fmt" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" ) func init() { diff --git a/examples/http_xa.go b/examples/http_xa.go index a288b45..6ba6f2d 100644 --- a/examples/http_xa.go +++ b/examples/http_xa.go @@ -7,11 +7,11 @@ package examples import ( + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/logger" ) // XaClient XA client connection diff --git a/examples/quick_start.go b/examples/quick_start.go index 47329ed..8115c89 100644 --- a/examples/quick_start.go +++ b/examples/quick_start.go @@ -10,11 +10,11 @@ import ( "fmt" "time" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" ) // 启动命令:go run app/main.go qs diff --git a/go.mod b/go.mod index 5982ea1..fdd8107 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,12 @@ -module github.com/yedf/dtm +module github.com/dtm-labs/dtm go 1.15 require ( + github.com/dtm-labs/dtmdriver v0.0.1 + github.com/dtm-labs/dtmdriver-gozero v0.0.1 + github.com/dtm-labs/dtmdriver-polaris v0.0.2 + github.com/dtm-labs/dtmdriver-protocol1 v0.0.1 github.com/gin-gonic/gin v1.6.3 github.com/go-playground/assert/v2 v2.0.1 github.com/go-redis/redis/v8 v8.11.4 @@ -15,10 +19,6 @@ require ( github.com/polarismesh/grpc-go-polaris v0.0.0-20211128162137-1a59cd7b5733 // indirect github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 - github.com/ychensha/dtmdriver-polaris v0.0.1 - github.com/yedf/dtmdriver v0.0.0-20211203060147-29426c663b6e - github.com/yedf/dtmdriver-gozero v0.0.0-20211204083751-a14485949435 - github.com/yedf/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.9.0 // indirect go.uber.org/automaxprocs v1.4.1-0.20210525221652-0180b04c18a7 diff --git a/go.sum b/go.sum index de06073..1aa3c42 100644 --- a/go.sum +++ b/go.sum @@ -31,6 +31,8 @@ github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= +github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ClickHouse/clickhouse-go v1.5.1/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= @@ -92,6 +94,20 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dtm-labs/dtmdriver v0.0.0-20211203060147-29426c663b6e h1:xXyb4mr46T5KqR5SXd37ivXNJ33k/MSAAwsGP6btmh8= +github.com/dtm-labs/dtmdriver v0.0.0-20211203060147-29426c663b6e/go.mod h1:aeo6ZWiVI0x8P8O18r6uB1cG2uw9BCQyYZaH15MlRDI= +github.com/dtm-labs/dtmdriver v0.0.1 h1:dHUZQ6g2ZN6eRUqds9kKq/3K7u9bcUGatUlbthD92fA= +github.com/dtm-labs/dtmdriver v0.0.1/go.mod h1:fLiEeD2BPwM9Yq96TfcP9KpbTwFsn5nTxa/PP0jmFuk= +github.com/dtm-labs/dtmdriver-gozero v0.0.0-20211204083751-a14485949435 h1:qLBNU16bK1ZeaZ6tmfarf49qx9O9sUJAe7/IzoXpuEg= +github.com/dtm-labs/dtmdriver-gozero v0.0.0-20211204083751-a14485949435/go.mod h1:RYtA6oZny6LzlIRb1tPGt5bHfgqws/JaU6ogFly8ByQ= +github.com/dtm-labs/dtmdriver-gozero v0.0.1 h1:ExDhMsn3MJCd+psSmIJVDgGUqbFrQGP0IpKL8x900AE= +github.com/dtm-labs/dtmdriver-gozero v0.0.1/go.mod h1:uIiAMkG/Vp4jvINk5XfVMT0mSCzRqIYyXgpmqAQfqbA= +github.com/dtm-labs/dtmdriver-polaris v0.0.2 h1:bh8u7bLWhairwpiA688dZMAX/OWcRoQk7a5bVcGzsjo= +github.com/dtm-labs/dtmdriver-polaris v0.0.2/go.mod h1:vyXDTRj3CpROiRnI0dqM/lHFfZaKY9JAS1MSey2azIQ= +github.com/dtm-labs/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e h1:hNSfnVdE46i45HS6aneN+6umk+12EqI3AErbbzeLsoo= +github.com/dtm-labs/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e/go.mod h1:kB3NPnDKSGioVjgdfj6qgbqYJinOml45GnlHqR46Ycc= +github.com/dtm-labs/dtmdriver-protocol1 v0.0.1 h1:nwGpGWi7XlUAcDhEw1qZ3TheBskqCvfE96n1uVjmDf4= +github.com/dtm-labs/dtmdriver-protocol1 v0.0.1/go.mod h1:x3bRe8x7pAfHIIQBTK+LibVq96gBSzMzsgRYe85zxAc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -495,12 +511,6 @@ github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+ github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= github.com/ychensha/dtmdriver-polaris v0.0.1 h1:+gYWFma5pflxNyV1HkcXmhzVHpijMSW9G4qTDcs63xc= github.com/ychensha/dtmdriver-polaris v0.0.1/go.mod h1:0BdQvxXlGOlF6YVlsDoVvu8jyxdTlJZ9Kyh5t9lRA94= -github.com/yedf/dtmdriver v0.0.0-20211203060147-29426c663b6e h1:xXyb4mr46T5KqR5SXd37ivXNJ33k/MSAAwsGP6btmh8= -github.com/yedf/dtmdriver v0.0.0-20211203060147-29426c663b6e/go.mod h1:aeo6ZWiVI0x8P8O18r6uB1cG2uw9BCQyYZaH15MlRDI= -github.com/yedf/dtmdriver-gozero v0.0.0-20211204083751-a14485949435 h1:qLBNU16bK1ZeaZ6tmfarf49qx9O9sUJAe7/IzoXpuEg= -github.com/yedf/dtmdriver-gozero v0.0.0-20211204083751-a14485949435/go.mod h1:RYtA6oZny6LzlIRb1tPGt5bHfgqws/JaU6ogFly8ByQ= -github.com/yedf/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e h1:hNSfnVdE46i45HS6aneN+6umk+12EqI3AErbbzeLsoo= -github.com/yedf/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e/go.mod h1:kB3NPnDKSGioVjgdfj6qgbqYJinOml45GnlHqR46Ycc= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -892,5 +902,3 @@ sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZa sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= - - diff --git a/helper/sync-dtmcli.sh b/helper/sync-dtmcli.sh index 7f809d0..25a0d51 100755 --- a/helper/sync-dtmcli.sh +++ b/helper/sync-dtmcli.sh @@ -24,7 +24,7 @@ git tag $ver git push --tags cd ../dtmcli-go-sample -go get -u github.com/yedf/dtmcli@$ver +go get -u github.com/dtm-labs/dtmcli@$ver go mod tidy go build || exit 1 git add . @@ -37,7 +37,7 @@ git push --tags cd ../dtmgrpc rm -rf *.go dtmgimp cp -r ../dtm/dtmgrpc/* ./ -go get github.com/yedf/dtmcli@$ver +go get github.com/dtm-labs/dtmcli@$ver sed -i '' -e 's/yedf\/dtm\//yedf\//g' *.go sed -i '' -e 's/yedf\/dtm\//yedf\//g' dtmgimp/*.go dtmgimp/*.proto rm -rf *_test.go @@ -50,8 +50,8 @@ git tag $ver git push --tags cd ../dtmgrpc-go-sample -go get github.com/yedf/dtmcli@$ver -go get github.com/yedf/dtmgrpc@$ver +go get github.com/dtm-labs/dtmcli@$ver +go get github.com/dtm-labs/dtmgrpc@$ver protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative busi/*.proto || exit 1 go build || exit 1 git add . diff --git a/helper/test-cover.sh b/helper/test-cover.sh index b94a361..c462626 100644 --- a/helper/test-cover.sh +++ b/helper/test-cover.sh @@ -2,7 +2,7 @@ set -x echo "" > coverage.txt for store in redis mysql boltdb; do for d in $(go list ./... | grep -v vendor); do - TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/yedf/dtm/common,github.com/yedf/dtm/dtmcli,github.com/yedf/dtm/dtmcli/dtmimp,github.com/yedf/dtm/dtmgrpc,github.com/yedf/dtm/dtmgrpc/dtmgimp,github.com/yedf/dtm/dtmsvr,github.com/yedf/dtm/dtmsvr/storage,github.com/yedf/dtm/dtmsvr/storage/boltdb,github.com/yedf/dtm/dtmsvr/storage/redis,github.com/yedf/dtm/dtmsvr/storage/registry,github.com/yedf/dtm/dtmsvr/storage/sql,github.com/yedf/dtm/dtmsvr/storage/boltdb,github.com/yedf/dtm/dtmsvr/storage/registry -gcflags=-l $d + TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/dtm-labs/dtm/common,github.com/dtm-labs/dtm/dtmcli,github.com/dtm-labs/dtm/dtmcli/dtmimp,github.com/dtm-labs/dtm/dtmgrpc,github.com/dtm-labs/dtm/dtmgrpc/dtmgimp,github.com/dtm-labs/dtm/dtmsvr,github.com/dtm-labs/dtm/dtmsvr/storage,github.com/dtm-labs/dtm/dtmsvr/storage/boltdb,github.com/dtm-labs/dtm/dtmsvr/storage/redis,github.com/dtm-labs/dtm/dtmsvr/storage/registry,github.com/dtm-labs/dtm/dtmsvr/storage/sql,github.com/dtm-labs/dtm/dtmsvr/storage/boltdb,github.com/dtm-labs/dtm/dtmsvr/storage/registry -gcflags=-l $d if [ -f profile.out ]; then cat profile.out >> coverage.txt echo > profile.out diff --git a/test/api_test.go b/test/api_test.go index e44ed14..bb37e40 100644 --- a/test/api_test.go +++ b/test/api_test.go @@ -10,9 +10,9 @@ import ( "fmt" "testing" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestAPIQuery(t *testing.T) { diff --git a/test/base_test.go b/test/base_test.go index deffa8d..3748802 100644 --- a/test/base_test.go +++ b/test/base_test.go @@ -11,12 +11,12 @@ import ( "fmt" "testing" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/examples" ) // BarrierModel barrier model for gorm diff --git a/test/dtmsvr_test.go b/test/dtmsvr_test.go index 52ac6ae..b855e79 100644 --- a/test/dtmsvr_test.go +++ b/test/dtmsvr_test.go @@ -10,13 +10,13 @@ import ( "testing" "time" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/examples" "github.com/gin-gonic/gin" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmsvr" - "github.com/yedf/dtm/examples" ) var DtmServer = examples.DtmHttpServer diff --git a/test/examples_test.go b/test/examples_test.go index e7c70cf..0ed0ca2 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -9,7 +9,7 @@ package test import ( "testing" - "github.com/yedf/dtm/examples" + "github.com/dtm-labs/dtm/examples" ) func TestExamples(t *testing.T) { diff --git a/test/main_test.go b/test/main_test.go index 306a10c..5aa62d5 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -11,11 +11,11 @@ import ( "testing" "time" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/examples" "github.com/gin-gonic/gin" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmsvr" - "github.com/yedf/dtm/examples" ) func exitIf(code int) { diff --git a/test/msg_grpc_test.go b/test/msg_grpc_test.go index 3ae048d..1869be9 100644 --- a/test/msg_grpc_test.go +++ b/test/msg_grpc_test.go @@ -10,11 +10,11 @@ import ( "fmt" "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc" - "github.com/yedf/dtm/examples" ) func TestMsgGrpcNormal(t *testing.T) { diff --git a/test/msg_options_test.go b/test/msg_options_test.go index 85e57ff..49e6265 100644 --- a/test/msg_options_test.go +++ b/test/msg_options_test.go @@ -9,10 +9,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestMsgOptionsTimeout(t *testing.T) { diff --git a/test/msg_test.go b/test/msg_test.go index 1fd9c4f..40d5dc2 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -9,10 +9,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestMsgNormal(t *testing.T) { diff --git a/test/saga_barrier_test.go b/test/saga_barrier_test.go index 6d8842c..59a84dd 100644 --- a/test/saga_barrier_test.go +++ b/test/saga_barrier_test.go @@ -9,10 +9,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestSagaBarrierNormal(t *testing.T) { diff --git a/test/saga_compatible_test.go b/test/saga_compatible_test.go index c7e29f9..20ea21f 100644 --- a/test/saga_compatible_test.go +++ b/test/saga_compatible_test.go @@ -10,9 +10,9 @@ import ( "fmt" "testing" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestSagaCompatibleNormal(t *testing.T) { // compatible with old http, which put payload in steps.data diff --git a/test/saga_concurrent_test.go b/test/saga_concurrent_test.go index dda6aaf..a629510 100644 --- a/test/saga_concurrent_test.go +++ b/test/saga_concurrent_test.go @@ -9,10 +9,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func genSagaCon(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { diff --git a/test/saga_grpc_barrier_test.go b/test/saga_grpc_barrier_test.go index 589eb32..1078368 100644 --- a/test/saga_grpc_barrier_test.go +++ b/test/saga_grpc_barrier_test.go @@ -9,10 +9,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc" - "github.com/yedf/dtm/examples" ) func TestSagaGrpcBarrierNormal(t *testing.T) { diff --git a/test/saga_grpc_test.go b/test/saga_grpc_test.go index d611241..61a114c 100644 --- a/test/saga_grpc_test.go +++ b/test/saga_grpc_test.go @@ -9,11 +9,11 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc" - "github.com/yedf/dtm/examples" ) func TestSagaGrpcNormal(t *testing.T) { diff --git a/test/saga_options_test.go b/test/saga_options_test.go index 7a11fcf..c82bd56 100644 --- a/test/saga_options_test.go +++ b/test/saga_options_test.go @@ -9,10 +9,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestSagaOptionsRetryOngoing(t *testing.T) { diff --git a/test/saga_test.go b/test/saga_test.go index 5fbc166..5093ec5 100644 --- a/test/saga_test.go +++ b/test/saga_test.go @@ -9,10 +9,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestSagaNormal(t *testing.T) { diff --git a/test/store_test.go b/test/store_test.go index 49549c0..08c9966 100644 --- a/test/store_test.go +++ b/test/store_test.go @@ -6,9 +6,9 @@ import ( "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmsvr/storage" - "github.com/yedf/dtm/dtmsvr/storage/registry" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmsvr/storage/registry" ) func initTransGlobal(gid string) (*storage.TransGlobalStore, storage.Store) { diff --git a/test/tcc_barrier_test.go b/test/tcc_barrier_test.go index 238a70d..6194b64 100644 --- a/test/tcc_barrier_test.go +++ b/test/tcc_barrier_test.go @@ -14,13 +14,13 @@ import ( "testing" "time" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/examples" "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/examples" ) func TestTccBarrierNormal(t *testing.T) { diff --git a/test/tcc_cover_test.go b/test/tcc_cover_test.go index 12e5a32..d865395 100644 --- a/test/tcc_cover_test.go +++ b/test/tcc_cover_test.go @@ -3,11 +3,11 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestTccCoverNotConnected(t *testing.T) { diff --git a/test/tcc_grpc_cover_test.go b/test/tcc_grpc_cover_test.go index f4c3fef..c23c160 100644 --- a/test/tcc_grpc_cover_test.go +++ b/test/tcc_grpc_cover_test.go @@ -3,10 +3,10 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc" - "github.com/yedf/dtm/examples" "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/test/tcc_grpc_test.go b/test/tcc_grpc_test.go index 16ba193..c2c919d 100644 --- a/test/tcc_grpc_test.go +++ b/test/tcc_grpc_test.go @@ -10,12 +10,12 @@ import ( "context" "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmgrpc" - "github.com/yedf/dtm/examples" "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/test/tcc_test.go b/test/tcc_test.go index 0697f4e..b2cf9c3 100644 --- a/test/tcc_test.go +++ b/test/tcc_test.go @@ -9,11 +9,11 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestTccNormal(t *testing.T) { diff --git a/test/types.go b/test/types.go index bef96cc..923cc35 100644 --- a/test/types.go +++ b/test/types.go @@ -9,11 +9,11 @@ package test import ( "time" - "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmcli/logger" - "github.com/yedf/dtm/dtmsvr" + "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr" ) var config = &common.Config diff --git a/test/xa_cover_test.go b/test/xa_cover_test.go index bd6d8be..6c61700 100644 --- a/test/xa_cover_test.go +++ b/test/xa_cover_test.go @@ -3,11 +3,11 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func TestXaCoverDBError(t *testing.T) { diff --git a/test/xa_grpc_test.go b/test/xa_grpc_test.go index 76e1111..283df1b 100644 --- a/test/xa_grpc_test.go +++ b/test/xa_grpc_test.go @@ -11,10 +11,10 @@ import ( "fmt" "testing" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/examples" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/dtmgrpc" - "github.com/yedf/dtm/examples" "google.golang.org/protobuf/types/known/emptypb" ) diff --git a/test/xa_test.go b/test/xa_test.go index 7122910..929d80d 100644 --- a/test/xa_test.go +++ b/test/xa_test.go @@ -10,11 +10,11 @@ import ( "fmt" "testing" + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/examples" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmcli/dtmimp" - "github.com/yedf/dtm/examples" ) func getXc() *dtmcli.XaClient { From 95eafb667bab7bdc970066b6bdd8424994eae274 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 08:08:00 +0800 Subject: [PATCH 020/124] update sync script --- helper/sync-dtmcli.sh | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/helper/sync-dtmcli.sh b/helper/sync-dtmcli.sh index 25a0d51..3ac42b0 100755 --- a/helper/sync-dtmcli.sh +++ b/helper/sync-dtmcli.sh @@ -14,7 +14,7 @@ fi cd ../dtmcli cp -rf ../dtm/dtmcli/* ./ rm -f *_test.go -sed -i '' -e 's/yedf\/dtm\//yedf\//g' *.go +sed -i '' -e 's/dtm-labs\/dtm\//dtm-labs\//g' *.go */**.go go mod tidy go build || exit 1 git add . @@ -38,8 +38,7 @@ cd ../dtmgrpc rm -rf *.go dtmgimp cp -r ../dtm/dtmgrpc/* ./ go get github.com/dtm-labs/dtmcli@$ver -sed -i '' -e 's/yedf\/dtm\//yedf\//g' *.go -sed -i '' -e 's/yedf\/dtm\//yedf\//g' dtmgimp/*.go dtmgimp/*.proto +sed -i '' -e 's/dtm-labs\/dtm\//dtm-labs\//g' *.go */**.go rm -rf *_test.go go mod tidy go build || exit 1 From 8075bfcab41759966618f1cb0789b2a6aaf0f122 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 09:45:26 +0800 Subject: [PATCH 021/124] update compare --- README-cn.md | 21 +++++++++++---------- README.md | 21 +++++++++++---------- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/README-cn.md b/README-cn.md index 85eb559..9dc13a8 100644 --- a/README-cn.md +++ b/README-cn.md @@ -46,19 +46,20 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 | 特性| DTM | SEATA |备注| |:-----:|:----:|:----:|:----:| -| 支持语言 |Go、Java、python、php、c#...|Java|dtm可轻松接入一门新语言| -|异常处理| [子事务屏障自动处理](https://zhuanlan.zhihu.com/p/388444465) |手动处理 |dtm解决了幂等、悬挂、空补偿| -| TCC事务| ||| -| XA事务|||| -|AT事务|建议使用XA||AT与XA类似,性能更好,但有脏回滚| -| SAGA事务 |支持并发 |状态机模式 || -|事务消息|||dtm提供类似rocketmq的事务消息| -|单服务多数据源|||| -|通信协议|HTTP、gRPC、go-zero|dubbo等协议|dtm对云原生更加友好| -|star数量|github stars|github stars|dtm从20210604发布0.1,发展快| +| [支持语言](https://dtm.pub/other/opensource.html#lang) |Go、Java、python、php、c#...|Java|dtm可轻松接入一门新语言| +|[异常处理](https://dtm.pub/other/opensource.html#exception)| 子事务屏障自动处理 |手动处理 |dtm解决了幂等、悬挂、空补偿| +| [TCC事务](https://dtm.pub/other/opensource.html#tcc)| ||| +| [XA事务](https://dtm.pub/other/opensource.html#xa)|||| +|[AT事务](https://dtm.pub/other/opensource.html#at)|建议使用XA||AT与XA类似,性能更好,但有脏回滚| +| [SAGA事务](https://dtm.pub/other/opensource.html#saga) |支持并发 |状态机模式 || +|[二阶段消息](https://dtm.pub/other/opensource.html#msg)|||dtm提供类似rocketmq的事务消息| +|[单服务多数据源](https://dtm.pub/other/opensource.html#multidb)|||| +|[通信协议](https://dtm.pub/other/opensource.html#protocol)|HTTP、gRPC、go-zero|dubbo等协议|dtm对云原生更加友好| +|[star数量](https://dtm.pub/other/opensource.html#star)|github stars|github stars|dtm从20210604发布0.1,发展快| 从上面对比的特性来看,如果您的语言栈包含了Java之外的语言,那么dtm是您的首选。如果您的语言栈是Java,您也可以选择接入dtm,使用子事务屏障技术,简化您的业务编写。 +详细的对比可以点击特性中的链接,跳到相关文档 ## [性能测试报告](https://dtm.pub/other/performance.html) ## [教程与文档](https://dtm.pub) diff --git a/README.md b/README.md index 85eb559..9dc13a8 100644 --- a/README.md +++ b/README.md @@ -46,19 +46,20 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 | 特性| DTM | SEATA |备注| |:-----:|:----:|:----:|:----:| -| 支持语言 |Go、Java、python、php、c#...|Java|dtm可轻松接入一门新语言| -|异常处理| [子事务屏障自动处理](https://zhuanlan.zhihu.com/p/388444465) |手动处理 |dtm解决了幂等、悬挂、空补偿| -| TCC事务| ||| -| XA事务|||| -|AT事务|建议使用XA||AT与XA类似,性能更好,但有脏回滚| -| SAGA事务 |支持并发 |状态机模式 || -|事务消息|||dtm提供类似rocketmq的事务消息| -|单服务多数据源|||| -|通信协议|HTTP、gRPC、go-zero|dubbo等协议|dtm对云原生更加友好| -|star数量|github stars|github stars|dtm从20210604发布0.1,发展快| +| [支持语言](https://dtm.pub/other/opensource.html#lang) |Go、Java、python、php、c#...|Java|dtm可轻松接入一门新语言| +|[异常处理](https://dtm.pub/other/opensource.html#exception)| 子事务屏障自动处理 |手动处理 |dtm解决了幂等、悬挂、空补偿| +| [TCC事务](https://dtm.pub/other/opensource.html#tcc)| ||| +| [XA事务](https://dtm.pub/other/opensource.html#xa)|||| +|[AT事务](https://dtm.pub/other/opensource.html#at)|建议使用XA||AT与XA类似,性能更好,但有脏回滚| +| [SAGA事务](https://dtm.pub/other/opensource.html#saga) |支持并发 |状态机模式 || +|[二阶段消息](https://dtm.pub/other/opensource.html#msg)|||dtm提供类似rocketmq的事务消息| +|[单服务多数据源](https://dtm.pub/other/opensource.html#multidb)|||| +|[通信协议](https://dtm.pub/other/opensource.html#protocol)|HTTP、gRPC、go-zero|dubbo等协议|dtm对云原生更加友好| +|[star数量](https://dtm.pub/other/opensource.html#star)|github stars|github stars|dtm从20210604发布0.1,发展快| 从上面对比的特性来看,如果您的语言栈包含了Java之外的语言,那么dtm是您的首选。如果您的语言栈是Java,您也可以选择接入dtm,使用子事务屏障技术,简化您的业务编写。 +详细的对比可以点击特性中的链接,跳到相关文档 ## [性能测试报告](https://dtm.pub/other/performance.html) ## [教程与文档](https://dtm.pub) From ead74554ef1c7d015570d12a28c66746cb7b25f6 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 12:15:32 +0800 Subject: [PATCH 022/124] update using --- README-cn.md | 10 +++++----- README.md | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/README-cn.md b/README-cn.md index 9dc13a8..27be69d 100644 --- a/README-cn.md +++ b/README-cn.md @@ -15,15 +15,15 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 作者受邀参加中国数据库大会分享[多语言环境下分布式事务实践](http://dtcc.it168.com/yicheng.html#b9) ## 谁在使用dtm -[Tencent 腾讯](https://www.tencent.com/) +[Tencent 腾讯](https://dtm.pub/other/using.html#tencent) -[Ivydad 常青藤爸爸](https://ivydad.com) +[Ivydad 常青藤爸爸](https://dtm.pub/other/using.html#ivydad) -[Eglass 视咖镜小二](https://epeijing.cn) +[Eglass 视咖镜小二](https://dtm.pub/other/using.html) -[极欧科技](http://jiou.me) +[极欧科技](https://dtm.pub/other/using.html) -[金数智联]() +[金数智联](https://dtm.pub/other/using.html) ## 亮点 diff --git a/README.md b/README.md index 9dc13a8..27be69d 100644 --- a/README.md +++ b/README.md @@ -15,15 +15,15 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 作者受邀参加中国数据库大会分享[多语言环境下分布式事务实践](http://dtcc.it168.com/yicheng.html#b9) ## 谁在使用dtm -[Tencent 腾讯](https://www.tencent.com/) +[Tencent 腾讯](https://dtm.pub/other/using.html#tencent) -[Ivydad 常青藤爸爸](https://ivydad.com) +[Ivydad 常青藤爸爸](https://dtm.pub/other/using.html#ivydad) -[Eglass 视咖镜小二](https://epeijing.cn) +[Eglass 视咖镜小二](https://dtm.pub/other/using.html) -[极欧科技](http://jiou.me) +[极欧科技](https://dtm.pub/other/using.html) -[金数智联]() +[金数智联](https://dtm.pub/other/using.html) ## 亮点 From 9aef7dda4b949823294d273adf9b082c0a9292f4 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 13:43:27 +0800 Subject: [PATCH 023/124] before redis test --- bench/main.go | 10 ++++++---- bench/run-dtm.sh | 2 ++ bench/{ => svr}/http.go | 14 ++++++++++++-- dtmsvr/storage/sql/sql.go | 4 ++-- dtmsvr/utils.go | 5 ++--- go.mod | 2 ++ go.sum | 7 +++++++ 7 files changed, 33 insertions(+), 11 deletions(-) rename bench/{ => svr}/http.go (93%) diff --git a/bench/main.go b/bench/main.go index 9bff1b0..56542c8 100644 --- a/bench/main.go +++ b/bench/main.go @@ -4,6 +4,7 @@ import ( "fmt" "os" + "github.com/dtm-labs/dtm/bench/svr" "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/logger" @@ -23,17 +24,18 @@ func main() { fmt.Printf(hint) return } - logger.Debugf("starting dtm....") + logger.Infof("starting dtm....") if os.Args[1] == "http" { fmt.Println("start bench server") common.MustLoadConfig() + logger.InitLog(common.Config.LogLevel) dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) registry.WaitStoreUp() - dtmsvr.PopulateDB(true) - examples.PopulateDB(true) + dtmsvr.PopulateDB(false) + examples.PopulateDB(false) dtmsvr.StartSvr() // 启动dtmsvr的api服务 go dtmsvr.CronExpiredTrans(-1) // 启动dtmsvr的定时过期查询 - StartSvr() + svr.StartSvr() select {} } else { fmt.Printf(hint) diff --git a/bench/run-dtm.sh b/bench/run-dtm.sh index 5bc8e39..0566f25 100755 --- a/bench/run-dtm.sh +++ b/bench/run-dtm.sh @@ -17,3 +17,5 @@ curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_empty" && ab -t $TIM # curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_tx" && curl "http://127.0.0.1:8083/api/busi_bench/bench" # curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_tx" && curl "http://127.0.0.1:8083/api/busi_bench/bench" # curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_barrier" && curl "http://127.0.0.1:8083/api/busi_bench/bench" + +ab -t $TIME -c $CONCURRENT "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" \ No newline at end of file diff --git a/bench/http.go b/bench/svr/http.go similarity index 93% rename from bench/http.go rename to bench/svr/http.go index 4682271..de03f07 100644 --- a/bench/http.go +++ b/bench/svr/http.go @@ -4,7 +4,7 @@ * license that can be found in the LICENSE file. */ -package main +package svr import ( "database/sql" @@ -20,6 +20,7 @@ import ( "github.com/dtm-labs/dtm/dtmsvr" "github.com/dtm-labs/dtm/examples" "github.com/gin-gonic/gin" + "github.com/lithammer/shortuuid" ) // launch command:go run app/main.go qs @@ -32,7 +33,7 @@ const total = 200000 var benchBusi = fmt.Sprintf("http://localhost:%d%s", benchPort, benchAPI) func sdbGet() *sql.DB { - db, err := dtmimp.PooledDB(common.Config.Store.GetDBConf()) + db, err := dtmimp.PooledDB(common.Config.ExamplesDB) logger.FatalIfError(err) return db } @@ -167,4 +168,13 @@ func benchAddRoute(app *gin.Engine) { } return nil, nil })) + app.Any(benchAPI+"/benchEmptyUrl", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + gid := shortuuid.New() + req := gin.H{} + saga := dtmcli.NewSaga(examples.DtmHttpServer, gid). + Add("", "", req). + Add("", "", req) + err := saga.Submit() + return nil, err + })) } diff --git a/dtmsvr/storage/sql/sql.go b/dtmsvr/storage/sql/sql.go index 3b246ba..fd3fe56 100644 --- a/dtmsvr/storage/sql/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -5,7 +5,7 @@ import ( "math" "time" - "github.com/google/uuid" + "github.com/lithammer/shortuuid/v3" "gorm.io/gorm" "gorm.io/gorm/clause" @@ -126,7 +126,7 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlob } expire := int(expireIn / time.Second) whereTime := fmt.Sprintf("next_cron_time < %s", getTime(expire)) - owner := uuid.NewString() + owner := shortuuid.New() global := &storage.TransGlobalStore{} dbr := db.Must().Model(global). Where(whereTime + "and status in ('prepared', 'aborting', 'submitted')"). diff --git a/dtmsvr/utils.go b/dtmsvr/utils.go index b711d40..3b296cc 100644 --- a/dtmsvr/utils.go +++ b/dtmsvr/utils.go @@ -10,12 +10,11 @@ import ( "fmt" "time" - "github.com/google/uuid" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmsvr/storage" "github.com/dtm-labs/dtm/dtmsvr/storage/registry" + "github.com/lithammer/shortuuid/v3" ) type branchStatus struct { @@ -38,7 +37,7 @@ var TransProcessedTestChan chan string = nil // GenGid generate gid, use uuid func GenGid() string { - return uuid.NewString() + return shortuuid.New() } // GetTransGlobal construct trans from db diff --git a/go.mod b/go.mod index fdd8107..a8dfe82 100644 --- a/go.mod +++ b/go.mod @@ -15,6 +15,8 @@ require ( github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/lib/pq v1.10.3 + github.com/lithammer/shortuuid v2.0.3+incompatible + github.com/lithammer/shortuuid/v3 v3.0.7 github.com/onsi/gomega v1.16.0 github.com/polarismesh/grpc-go-polaris v0.0.0-20211128162137-1a59cd7b5733 // indirect github.com/prometheus/client_golang v1.11.0 diff --git a/go.sum b/go.sum index 1aa3c42..3ec84e4 100644 --- a/go.sum +++ b/go.sum @@ -241,6 +241,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -369,6 +370,11 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lithammer/shortuuid v1.0.0 h1:kdcbvjGVEgqeVeDIRtnANOi/F6ftbKrtbxY+cjQmK1Q= +github.com/lithammer/shortuuid v2.0.3+incompatible h1:ao1r3cQ9AUX+c6dZXwbCM/ELGf10EoO4SyqqxBXTyHc= +github.com/lithammer/shortuuid v2.0.3+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w= +github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= +github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts= github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -467,6 +473,7 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= From 6c77f660e2305edbde8674d4009cadf1522b703a Mon Sep 17 00:00:00 2001 From: songliwei Date: Sat, 25 Dec 2021 16:12:29 +0800 Subject: [PATCH 024/124] Fix grpc_saga typo --- examples/grpc_saga.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/grpc_saga.go b/examples/grpc_saga.go index 395976b..eb2c6b0 100644 --- a/examples/grpc_saga.go +++ b/examples/grpc_saga.go @@ -17,7 +17,7 @@ func init() { gid := dtmgrpc.MustGenGid(DtmGrpcServer) saga := dtmgrpc.NewSagaGrpc(DtmGrpcServer, gid). Add(BusiGrpc+"/examples.Busi/TransOut", BusiGrpc+"/examples.Busi/TransOutRevert", req). - Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransOutRevert", req) + Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInRevert", req) err := saga.Submit() logger.FatalIfError(err) return saga.Gid @@ -27,7 +27,7 @@ func init() { gid := dtmgrpc.MustGenGid(DtmGrpcServer) saga := dtmgrpc.NewSagaGrpc(DtmGrpcServer, gid). Add(BusiGrpc+"/examples.Busi/TransOut", BusiGrpc+"/examples.Busi/TransOutRevert", req). - Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransOutRevert", req) + Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInRevert", req) saga.WaitResult = true err := saga.Submit() logger.FatalIfError(err) From f66d099c68149e103891f224ea63162e9928fb95 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 17:57:08 +0800 Subject: [PATCH 025/124] before opt redis --- bench/run-dtm.sh | 2 +- bench/setup.sh | 2 +- dtmsvr/storage/redis/redis.go | 2 +- test/main_test.go | 2 ++ 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/bench/run-dtm.sh b/bench/run-dtm.sh index 0566f25..0c6376b 100755 --- a/bench/run-dtm.sh +++ b/bench/run-dtm.sh @@ -18,4 +18,4 @@ curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_empty" && ab -t $TIM # curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_tx" && curl "http://127.0.0.1:8083/api/busi_bench/bench" # curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_barrier" && curl "http://127.0.0.1:8083/api/busi_bench/bench" -ab -t $TIME -c $CONCURRENT "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" \ No newline at end of file +ab -t 10 -c 30 "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" diff --git a/bench/setup.sh b/bench/setup.sh index fe47bd0..b10125e 100755 --- a/bench/setup.sh +++ b/bench/setup.sh @@ -12,4 +12,4 @@ chmod +x /usr/local/bin/docker-compose # install go wget https://golang.org/dl/go1.17.1.linux-amd64.tar.gz -rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz && cp -f /usr/local/bin/go /usr/local/go/bin/go +rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz && cp -f /usr/local/go/bin/go /usr/local/bin/go diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 8dca435..919963f 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -167,7 +167,7 @@ func (s *RedisStore) LockGlobalSaveBranches(gid string, status string, branches AppendObject(&storage.TransGlobalStore{Gid: gid, Status: status}). AppendRaw(branchStart). AppendBranches(branches) - _, err := callLua(args, ` + _, err := callLua(args, `-- LockGlobalSaveBranches local gs = cjson.decode(ARGV[3]) local g = redis.call('GET', KEYS[1]) if (g == false) then diff --git a/test/main_test.go b/test/main_test.go index 5aa62d5..95c5836 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -13,6 +13,7 @@ import ( "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmsvr" "github.com/dtm-labs/dtm/examples" "github.com/gin-gonic/gin" @@ -26,6 +27,7 @@ func exitIf(code int) { func TestMain(m *testing.M) { common.MustLoadConfig() + logger.InitLog(config.LogLevel) dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) dtmsvr.TransProcessedTestChan = make(chan string, 1) dtmsvr.NowForwardDuration = 0 * time.Second From 202a24453e909fbb3c2a0e246a1a10dfcd206aa1 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 18:01:34 +0800 Subject: [PATCH 026/124] LockGlobalSaveBranches ok --- dtmsvr/storage/redis/redis.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 919963f..b62dd2e 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -164,17 +164,16 @@ redis.call('EXPIRE', KEYS[2], ARGV[2]) func (s *RedisStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { args := newArgList(). AppendGid(gid). - AppendObject(&storage.TransGlobalStore{Gid: gid, Status: status}). + AppendRaw(status). AppendRaw(branchStart). AppendBranches(branches) _, err := callLua(args, `-- LockGlobalSaveBranches -local gs = cjson.decode(ARGV[3]) local g = redis.call('GET', KEYS[1]) if (g == false) then return 'NOT_FOUND' end local js = cjson.decode(g) -if js.status ~= gs.status then +if js.status ~= ARGV[3] then return 'NOT_FOUND' end local start = ARGV[4] From f63f8d6c5d4cf61dba001e272b13c271805a1ff5 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 18:05:04 +0800 Subject: [PATCH 027/124] remove additional decode in ChangeGlobalStatus --- dtmsvr/storage/redis/redis.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index b62dd2e..e87cb67 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -192,9 +192,8 @@ redis.call('EXPIRE', KEYS[2], ARGV[2]) func (s *RedisStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus - args := newArgList().AppendGid(global.Gid).AppendObject(global).AppendRaw(old).AppendRaw(finished) + args := newArgList().AppendGid(global.Gid).AppendObject(global).AppendRaw(old).AppendRaw(finished).AppendRaw(global.Gid) _, err := callLua(args, `-- ChangeGlobalStatus -local gs = cjson.decode(ARGV[3]) local old = redis.call('GET', KEYS[1]) if old == false then return 'NOT_FOUND' @@ -205,7 +204,7 @@ if os.status ~= ARGV[4] then end redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) if ARGV[5] == '1' then - redis.call('ZREM', KEYS[3], gs.gid) + redis.call('ZREM', KEYS[3], ARGV[6]) end `) dtmimp.E2P(err) From da690eb9c025acc45f7a0249c01faee27a136204 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 18:11:38 +0800 Subject: [PATCH 028/124] MaySaveNewTrans decode removed --- dtmsvr/storage/redis/redis.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index e87cb67..4539829 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -141,19 +141,19 @@ func (s *RedisStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches AppendGid(global.Gid). AppendObject(global). AppendRaw(global.NextCronTime.Unix()). + AppendRaw(global.Gid). AppendBranches(branches) global.Steps = nil global.Payloads = nil _, err := callLua(a, `-- MaySaveNewTrans -local gs = cjson.decode(ARGV[3]) local g = redis.call('GET', KEYS[1]) if g ~= false then return 'UNIQUE_CONFLICT' end redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) -redis.call('ZADD', KEYS[3], ARGV[4], gs.gid) -for k = 5, table.getn(ARGV) do +redis.call('ZADD', KEYS[3], ARGV[4], ARGV[5]) +for k = 6, table.getn(ARGV) do redis.call('RPUSH', KEYS[2], ARGV[k]) end redis.call('EXPIRE', KEYS[2], ARGV[2]) From 89034536d14f2f447a72cce5e003f405efa97e85 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 18:50:58 +0800 Subject: [PATCH 029/124] all cjson.decode removed --- dtmsvr/storage/redis/redis.go | 48 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 4539829..b525f7f 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -98,6 +98,7 @@ func (a *argList) AppendGid(gid string) *argList { a.Keys = append(a.Keys, config.Store.RedisPrefix+"_g_"+gid) a.Keys = append(a.Keys, config.Store.RedisPrefix+"_b_"+gid) a.Keys = append(a.Keys, config.Store.RedisPrefix+"_u") + a.Keys = append(a.Keys, config.Store.RedisPrefix+"_s_"+gid) return a } @@ -142,6 +143,7 @@ func (s *RedisStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches AppendObject(global). AppendRaw(global.NextCronTime.Unix()). AppendRaw(global.Gid). + AppendRaw(global.Status). AppendBranches(branches) global.Steps = nil global.Payloads = nil @@ -152,8 +154,9 @@ if g ~= false then end redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) +redis.call('SET', KEYS[4], ARGV[6], 'EX', ARGV[2]) redis.call('ZADD', KEYS[3], ARGV[4], ARGV[5]) -for k = 6, table.getn(ARGV) do +for k = 7, table.getn(ARGV) do redis.call('RPUSH', KEYS[2], ARGV[k]) end redis.call('EXPIRE', KEYS[2], ARGV[2]) @@ -168,12 +171,8 @@ func (s *RedisStore) LockGlobalSaveBranches(gid string, status string, branches AppendRaw(branchStart). AppendBranches(branches) _, err := callLua(args, `-- LockGlobalSaveBranches -local g = redis.call('GET', KEYS[1]) -if (g == false) then - return 'NOT_FOUND' -end -local js = cjson.decode(g) -if js.status ~= ARGV[3] then +local old = redis.call('GET', KEYS[4]) +if old ~= ARGV[3] then return 'NOT_FOUND' end local start = ARGV[4] @@ -192,17 +191,20 @@ redis.call('EXPIRE', KEYS[2], ARGV[2]) func (s *RedisStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus - args := newArgList().AppendGid(global.Gid).AppendObject(global).AppendRaw(old).AppendRaw(finished).AppendRaw(global.Gid) + args := newArgList(). + AppendGid(global.Gid). + AppendObject(global). + AppendRaw(old). + AppendRaw(finished). + AppendRaw(global.Gid). + AppendRaw(newStatus) _, err := callLua(args, `-- ChangeGlobalStatus -local old = redis.call('GET', KEYS[1]) -if old == false then - return 'NOT_FOUND' -end -local os = cjson.decode(old) -if os.status ~= ARGV[4] then +local old = redis.call('GET', KEYS[4]) +if old ~= ARGV[4] then return 'NOT_FOUND' end redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) +redis.call('SET', KEYS[4], ARGV[7], 'EX', ARGV[2]) if ARGV[5] == '1' then redis.call('ZREM', KEYS[3], ARGV[6]) end @@ -244,18 +246,18 @@ func (s *RedisStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInt global.NextCronTime = common.GetNextTime(nextCronInterval) global.UpdateTime = common.GetNextTime(0) global.NextCronInterval = nextCronInterval - args := newArgList().AppendGid(global.Gid).AppendObject(global).AppendRaw(global.NextCronTime.Unix()) + args := newArgList(). + AppendGid(global.Gid). + AppendObject(global). + AppendRaw(global.NextCronTime.Unix()). + AppendRaw(global.Status). + AppendRaw(global.Gid) _, err := callLua(args, `-- TouchCronTime -local g = cjson.decode(ARGV[3]) -local old = redis.call('GET', KEYS[1]) -if old == false then +local old = redis.call('GET', KEYS[4]) +if old ~= ARGV[5] then return 'NOT_FOUND' end -local os = cjson.decode(old) -if os.status ~= g.status then - return 'NOT_FOUND' -end -redis.call('ZADD', KEYS[3], ARGV[4], g.gid) +redis.call('ZADD', KEYS[3], ARGV[4], ARGV[6]) redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) `) dtmimp.E2P(err) From 9a4ab06f839deebdf6d5bbcca6d47fa35f72aef8 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 25 Dec 2021 19:36:41 +0800 Subject: [PATCH 030/124] redis bench finished --- bench/run-dtm.sh | 2 +- bench/setup.sh | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/bench/run-dtm.sh b/bench/run-dtm.sh index 0c6376b..0f8cd2f 100755 --- a/bench/run-dtm.sh +++ b/bench/run-dtm.sh @@ -18,4 +18,4 @@ curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_empty" && ab -t $TIM # curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_tx" && curl "http://127.0.0.1:8083/api/busi_bench/bench" # curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_barrier" && curl "http://127.0.0.1:8083/api/busi_bench/bench" -ab -t 10 -c 30 "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" +ab -n 1000000 -c 10 "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" diff --git a/bench/setup.sh b/bench/setup.sh index b10125e..bd90f1a 100755 --- a/bench/setup.sh +++ b/bench/setup.sh @@ -13,3 +13,5 @@ chmod +x /usr/local/bin/docker-compose # install go wget https://golang.org/dl/go1.17.1.linux-amd64.tar.gz rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz && cp -f /usr/local/go/bin/go /usr/local/bin/go + +apt install -y redis \ No newline at end of file From 8a898f697eeedc6b40715019aeb55c520532f428 Mon Sep 17 00:00:00 2001 From: parkma99 Date: Sun, 26 Dec 2021 15:33:28 +0800 Subject: [PATCH 031/124] translate trans_xa_base.go --- dtmcli/dtmimp/trans_xa_base.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dtmcli/dtmimp/trans_xa_base.go b/dtmcli/dtmimp/trans_xa_base.go index 737f2a4..bdcdf60 100644 --- a/dtmcli/dtmimp/trans_xa_base.go +++ b/dtmcli/dtmimp/trans_xa_base.go @@ -18,7 +18,7 @@ type XaClientBase struct { NotifyURL string } -// HandleCallback 处理commit/rollback的回调 +// HandleCallback type of commit/rollback callback handler func (xc *XaClientBase) HandleCallback(gid string, branchID string, action string) error { db, err := StandaloneDB(xc.Conf) if err != nil { @@ -28,7 +28,7 @@ func (xc *XaClientBase) HandleCallback(gid string, branchID string, action strin xaID := gid + "-" + branchID _, err = DBExec(db, GetDBSpecial().GetXaSQL(action, xaID)) if err != nil && - (strings.Contains(err.Error(), "XAER_NOTA") || strings.Contains(err.Error(), "does not exist")) { // 重复commit/rollback同一个id,报这个错误,忽略 + (strings.Contains(err.Error(), "XAER_NOTA") || strings.Contains(err.Error(), "does not exist")) { // Repeat commit/rollback with the same id, report this error, ignore err = nil } return err From 98388d2916d80abf197bd9c94e35e8034fefb42a Mon Sep 17 00:00:00 2001 From: jiahui-97 Date: Sun, 26 Dec 2021 20:33:10 +0800 Subject: [PATCH 032/124] translate trans_xa_base.go for first issue --- dtmcli/dtmimp/trans_xa_base.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmcli/dtmimp/trans_xa_base.go b/dtmcli/dtmimp/trans_xa_base.go index bdcdf60..95a8811 100644 --- a/dtmcli/dtmimp/trans_xa_base.go +++ b/dtmcli/dtmimp/trans_xa_base.go @@ -34,7 +34,7 @@ func (xc *XaClientBase) HandleCallback(gid string, branchID string, action strin return err } -// HandleLocalTrans http/grpc 处理LocalTransaction的公共方法 +// HandleLocalTrans public handler of LocalTransaction via http/grpc func (xc *XaClientBase) HandleLocalTrans(xa *TransBase, cb func(*sql.DB) error) (rerr error) { xaBranch := xa.Gid + "-" + xa.BranchID db, rerr := StandaloneDB(xc.Conf) From 0f338f2ef9d21eed5ad36def36be76157a0ee098 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sun, 26 Dec 2021 22:22:22 +0800 Subject: [PATCH 033/124] redis bench ok --- bench/Makefile | 28 +++++++++++++++++ bench/main.go | 49 ++++++++++++++++++----------- bench/prepare.sh | 10 ++++++ bench/run-mysql.sh | 8 ----- bench/run-services.sh | 5 --- bench/setup-redis6.sh | 6 ++++ bench/setup.sh | 5 ++- bench/svr/http.go | 27 +++++++++------- bench/test-boltdb.sh | 5 +++ bench/{run-dtm.sh => test-mysql.sh} | 15 ++++----- bench/test-redis.sh | 27 ++++++++++++++++ dtmsvr/api.go | 10 +++--- dtmsvr/cron.go | 3 +- dtmsvr/storage/redis/redis.go | 3 ++ dtmsvr/trans_process.go | 23 ++++++++------ 15 files changed, 156 insertions(+), 68 deletions(-) create mode 100644 bench/Makefile create mode 100755 bench/prepare.sh delete mode 100755 bench/run-mysql.sh delete mode 100644 bench/run-services.sh create mode 100755 bench/setup-redis6.sh create mode 100755 bench/test-boltdb.sh rename bench/{run-dtm.sh => test-mysql.sh} (67%) create mode 100755 bench/test-redis.sh diff --git a/bench/Makefile b/bench/Makefile new file mode 100644 index 0000000..e819a4b --- /dev/null +++ b/bench/Makefile @@ -0,0 +1,28 @@ +# All targets. +default: bench + +bench: /usr/local/bin/go /etc/redis/redis.conf /usr/local/bin/docker-compose main.go + rm -f ../conf.sample.yml + go build -o bench + +go: /usr/local/bin/go + +redis: /etc/redis/redis.conf + +mysql: /usr/local/bin/docker-compose + +/usr/local/bin/go: + wget https://golang.org/dl/go1.17.1.linux-amd64.tar.gz + rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz && cp -f /usr/local/go/bin/go /usr/local/bin/go && rm go1.* + +/etc/redis/redis.conf: + apt update + apt install -y redis redis-tools + +/usr/local/bin/docker-compose: + apt update + apt install -y sysbench apache2-utils mysql-client-core-8.0 + curl -fsSL https://get.docker.com | sh + curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose + chmod +x /usr/local/bin/docker-compose + cd .. && docker-compose -f helper/compose.mysql.yml up -d && cd bench diff --git a/bench/main.go b/bench/main.go index 56542c8..ec2a78e 100644 --- a/bench/main.go +++ b/bench/main.go @@ -13,31 +13,42 @@ import ( "github.com/dtm-labs/dtm/examples" ) -var hint = `To start the bench server, you need to specify the parameters: - -Available commands: - http start bench server +var usage = `bench is a bench test server for dtmf +usage: + redis prepare for redis bench test + db prepare for mysql|postgres bench test + boltdb prepare for boltdb bench test ` +func hintAndExit() { + fmt.Printf(usage) + os.Exit(0) +} + +var conf = &common.Config + func main() { if len(os.Args) <= 1 { - fmt.Printf(hint) - return + hintAndExit() + } + logger.Infof("starting bench server") + common.MustLoadConfig() + logger.InitLog(conf.LogLevel) + if conf.ExamplesDB.Driver != "" { + dtmcli.SetCurrentDBType(conf.ExamplesDB.Driver) + svr.PrepareBenchDB() } - logger.Infof("starting dtm....") - if os.Args[1] == "http" { - fmt.Println("start bench server") - common.MustLoadConfig() - logger.InitLog(common.Config.LogLevel) - dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) - registry.WaitStoreUp() - dtmsvr.PopulateDB(false) + registry.WaitStoreUp() + dtmsvr.PopulateDB(false) + if os.Args[1] == "db" { examples.PopulateDB(false) - dtmsvr.StartSvr() // 启动dtmsvr的api服务 - go dtmsvr.CronExpiredTrans(-1) // 启动dtmsvr的定时过期查询 - svr.StartSvr() - select {} + } else if os.Args[1] == "redis" || os.Args[1] == "boltdb" { + } else { - fmt.Printf(hint) + hintAndExit() } + dtmsvr.StartSvr() // 启动dtmsvr的api服务 + go dtmsvr.CronExpiredTrans(-1) // 启动dtmsvr的定时过期查询 + svr.StartSvr() // 启动bench服务 + select {} } diff --git a/bench/prepare.sh b/bench/prepare.sh new file mode 100755 index 0000000..2ec3ad1 --- /dev/null +++ b/bench/prepare.sh @@ -0,0 +1,10 @@ +# !/bin/bash +apt update +apt install -y git +git clone https://github.com/dtm-labs/dtm.git && cd dtm && git checkout alpha && cd bench && make + + +echo 'all prepared. you shoud run following commands to test in different terminal' +echo +echo 'cd dtm && go run bench/main.go redis|boltdb|db' +echo 'cd dtm && bench/run-redis|boltdb|mysql.sh' diff --git a/bench/run-mysql.sh b/bench/run-mysql.sh deleted file mode 100755 index 8db27b4..0000000 --- a/bench/run-mysql.sh +++ /dev/null @@ -1,8 +0,0 @@ -# !/bin/bash - -cd /usr/share/sysbench/ -echo 'create database sbtest;' > mysql -h 127.0.0.1 -uroot - -sysbench oltp_write_only.lua --time=60 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password= --mysql-db=sbtest --table-size=1000000 --tables=10 --threads=10 --events=999999999 --report-interval=10 prepare - -sysbench oltp_write_only.lua --time=60 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password= --mysql-db=sbtest --table-size=1000000 --tables=10 --threads=10 --events=999999999 --report-interval=10 run diff --git a/bench/run-services.sh b/bench/run-services.sh deleted file mode 100644 index a95f9a3..0000000 --- a/bench/run-services.sh +++ /dev/null @@ -1,5 +0,0 @@ -# !/bin/bash - -# start all services -docker-compose -f helper/compose.mysql.yml up -d -go run app/main.go bench > /dev/nul \ No newline at end of file diff --git a/bench/setup-redis6.sh b/bench/setup-redis6.sh new file mode 100755 index 0000000..ed180f4 --- /dev/null +++ b/bench/setup-redis6.sh @@ -0,0 +1,6 @@ +# !/bin/bash +apt update +apt install -y software-properties-common +add-apt-repository -y ppa:redislabs/redis +apt install -y redis redis-tools + diff --git a/bench/setup.sh b/bench/setup.sh index bd90f1a..985aaa3 100755 --- a/bench/setup.sh +++ b/bench/setup.sh @@ -1,8 +1,9 @@ # !/bin/bash # install all commands needed + apt update -apt install -y git sysbench apache2-utils mysql-client-core-8.0 +apt install -y sysbench apache2-utils mysql-client-core-8.0 redis redis-tools # install docker and docker-compose curl -fsSL https://get.docker.com -o get-docker.sh @@ -13,5 +14,3 @@ chmod +x /usr/local/bin/docker-compose # install go wget https://golang.org/dl/go1.17.1.linux-amd64.tar.gz rm -rf /usr/local/go && tar -C /usr/local -xzf go1.17.1.linux-amd64.tar.gz && cp -f /usr/local/go/bin/go /usr/local/bin/go - -apt install -y redis \ No newline at end of file diff --git a/bench/svr/http.go b/bench/svr/http.go index de03f07..0ff80a8 100644 --- a/bench/svr/http.go +++ b/bench/svr/http.go @@ -9,6 +9,7 @@ package svr import ( "database/sql" "fmt" + "os" "strings" "sync/atomic" "time" @@ -18,7 +19,6 @@ import ( "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmsvr" - "github.com/dtm-labs/dtm/examples" "github.com/gin-gonic/gin" "github.com/lithammer/shortuuid" ) @@ -27,10 +27,10 @@ import ( // service address of the transcation const benchAPI = "/api/busi_bench" -const benchPort = 8083 const total = 200000 -var benchBusi = fmt.Sprintf("http://localhost:%d%s", benchPort, benchAPI) +var benchPort = dtmimp.If(os.Getenv("BENCH_PORT") == "", "8083", os.Getenv("BENCH_PORT")).(string) +var benchBusi = fmt.Sprintf("http://localhost:%s%s", benchPort, benchAPI) func sdbGet() *sql.DB { db, err := dtmimp.PooledDB(common.Config.ExamplesDB) @@ -68,12 +68,7 @@ var uidCounter int32 = 0 var mode string = "" var sqls int = 1 -// StartSvr 1 -func StartSvr() { - app := common.GetGinApp() - benchAddRoute(app) - logger.Debugf("bench listening at %d", benchPort) - go app.Run(fmt.Sprintf(":%d", benchPort)) +func PrepareBenchDB() { db := sdbGet() _, err := dtmimp.DBExec(db, "drop table if exists dtm_busi.user_account_log") logger.FatalIfError(err) @@ -94,6 +89,14 @@ func StartSvr() { logger.FatalIfError(err) } +// StartSvr 1 +func StartSvr() { + app := common.GetGinApp() + benchAddRoute(app) + logger.Debugf("bench listening at %d", benchPort) + go app.Run(fmt.Sprintf(":%s", benchPort)) +} + func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { if strings.Contains(mode, "empty") || sqls == 0 { return dtmcli.MapSuccess, nil @@ -124,6 +127,7 @@ func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { } func benchAddRoute(app *gin.Engine) { + dtmHttpServer := fmt.Sprintf("http://localhost:%d/api/dtmsvr", common.Config.HttpPort) app.POST(benchAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), 1, c) })) @@ -154,7 +158,7 @@ func benchAddRoute(app *gin.Engine) { params2 := fmt.Sprintf("?uid=%s", suid2) logger.Debugf("mode: %s contains dtm: %t", mode, strings.Contains(mode, "dtm")) if strings.Contains(mode, "dtm") { - saga := dtmcli.NewSaga(examples.DtmHttpServer, fmt.Sprintf("bench-%d", uid)). + saga := dtmcli.NewSaga(dtmHttpServer, fmt.Sprintf("bench-%d", uid)). Add(benchBusi+"/TransOut"+params, benchBusi+"/TransOutCompensate"+params, req). Add(benchBusi+"/TransIn"+params2, benchBusi+"/TransInCompensate"+params2, req) saga.WaitResult = true @@ -171,9 +175,10 @@ func benchAddRoute(app *gin.Engine) { app.Any(benchAPI+"/benchEmptyUrl", common.WrapHandler(func(c *gin.Context) (interface{}, error) { gid := shortuuid.New() req := gin.H{} - saga := dtmcli.NewSaga(examples.DtmHttpServer, gid). + saga := dtmcli.NewSaga(dtmHttpServer, gid). Add("", "", req). Add("", "", req) + saga.WaitResult = true err := saga.Submit() return nil, err })) diff --git a/bench/test-boltdb.sh b/bench/test-boltdb.sh new file mode 100755 index 0000000..ddd2807 --- /dev/null +++ b/bench/test-boltdb.sh @@ -0,0 +1,5 @@ +# !/bin/bash + +set -x + +ab -n 50000 -c 10 "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" diff --git a/bench/run-dtm.sh b/bench/test-mysql.sh similarity index 67% rename from bench/run-dtm.sh rename to bench/test-mysql.sh index 0f8cd2f..9a7f259 100755 --- a/bench/run-dtm.sh +++ b/bench/test-mysql.sh @@ -1,7 +1,14 @@ # !/bin/bash -# go run ../app/main.go set -x + +cd /usr/share/sysbench/ +echo 'create database sbtest;' > mysql -h 127.0.0.1 -uroot + +sysbench oltp_write_only.lua --time=60 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password= --mysql-db=sbtest --table-size=1000000 --tables=10 --threads=10 --events=999999999 --report-interval=10 prepare + +sysbench oltp_write_only.lua --time=60 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password= --mysql-db=sbtest --table-size=1000000 --tables=10 --threads=10 --events=999999999 --report-interval=10 run + export TIME=10 export CONCURRENT=20 curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_tx&sqls=0" && ab -t $TIME -c $CONCURRENT "http://127.0.0.1:8083/api/busi_bench/bench" @@ -13,9 +20,3 @@ curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_barrier&sqls=1" && a curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_tx&sqls=1" && ab -t $TIME -c $CONCURRENT "http://127.0.0.1:8083/api/busi_bench/bench" curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_empty" && ab -t $TIME -c $CONCURRENT "http://127.0.0.1:8083/api/busi_bench/bench" -# curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_empty" && curl "http://127.0.0.1:8083/api/busi_bench/bench" -# curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=raw_tx" && curl "http://127.0.0.1:8083/api/busi_bench/bench" -# curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_tx" && curl "http://127.0.0.1:8083/api/busi_bench/bench" -# curl "http://127.0.0.1:8083/api/busi_bench/reloadData?m=dtm_barrier" && curl "http://127.0.0.1:8083/api/busi_bench/bench" - -ab -n 1000000 -c 10 "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" diff --git a/bench/test-redis.sh b/bench/test-redis.sh new file mode 100755 index 0000000..403c1c5 --- /dev/null +++ b/bench/test-redis.sh @@ -0,0 +1,27 @@ +# !/bin/bash + +set -x + +export LOG_LEVEL=warn +export STORE_DRIVER=redis +export STORE_HOST=localhost +export STORE_PORT=6379 +cd .. && bench/bench redis & +echo 'sleeping 3s for dtm bench to run up.' && sleep 3 +ab -n 1000000 -c 10 "http://127.0.0.1:8083/api/busi_bench/benchEmptyUrl" +pkill bench + +redis-benchmark -n 300000 SET 'abcdefg' 'ddddddd' + +redis-benchmark -n 300000 EVAL "redis.call('SET', 'abcdedf', 'ddddddd')" 0 + +redis-benchmark -n 300000 EVAL "redis.call('SET', KEYS[1], ARGV[1])" 1 'aaaaaaaaa' 'bbbbbbbbbb' + +redis-benchmark -n 3000000 -P 50 SET 'abcdefg' 'ddddddd' + +redis-benchmark -n 300000 EVAL "for k=1, 10 do; redis.call('SET', KEYS[1], ARGV[1]);end" 1 'aaaaaaaaa' 'bbbbbbbbbb' + +redis-benchmark -n 300000 -P 50 EVAL "redis.call('SET', KEYS[1], ARGV[1])" 1 'aaaaaaaaa' 'bbbbbbbbbb' + +redis-benchmark -n 300000 EVAL "for k=1,10 do;local c = cjson.decode(ARGV[1]);end" 1 'aaaaaaaaa' '{"aaaaa":"bbbbb","b":1,"t":"2012-01-01 14:00:00"}' + diff --git a/dtmsvr/api.go b/dtmsvr/api.go index 5c61a8d..7fb5673 100644 --- a/dtmsvr/api.go +++ b/dtmsvr/api.go @@ -17,22 +17,23 @@ import ( func svcSubmit(t *TransGlobal) (interface{}, error) { t.Status = dtmcli.StatusSubmitted - err := t.saveNew() + branches, err := t.saveNew() if err == storage.ErrUniqueConflict { dbt := GetTransGlobal(t.Gid) if dbt.Status == dtmcli.StatusPrepared { dbt.changeStatus(t.Status) + branches = GetStore().FindBranches(t.Gid) } else if dbt.Status != dtmcli.StatusSubmitted { return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status '%s', cannot sumbmit", dbt.Status)}, nil } } - return t.Process(), nil + return t.Process(branches), nil } func svcPrepare(t *TransGlobal) (interface{}, error) { t.Status = dtmcli.StatusPrepared - err := t.saveNew() + _, err := t.saveNew() if err == storage.ErrUniqueConflict { dbt := GetTransGlobal(t.Gid) if dbt.Status != dtmcli.StatusPrepared { @@ -48,7 +49,8 @@ func svcAbort(t *TransGlobal) (interface{}, error) { return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("trans type: '%s' current status '%s', cannot abort", dbt.TransType, dbt.Status)}, nil } dbt.changeStatus(dtmcli.StatusAborting) - return dbt.Process(), nil + branches := GetStore().FindBranches(t.Gid) + return dbt.Process(branches), nil } func svcRegisterBranch(transType string, branch *TransBranch, data map[string]string) (ret interface{}, rerr error) { diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index c718840..5eec83c 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -31,7 +31,8 @@ func CronTransOnce() (gid string) { } gid = trans.Gid trans.WaitResult = true - trans.Process() + branches := GetStore().FindBranches(gid) + trans.Process(branches) return } diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index b525f7f..60ec8fd 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -35,6 +35,7 @@ func (s *RedisStore) PopulateData(skipDrop bool) { } func (s *RedisStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { + logger.Debugf("calling FindTransGlobalStore: %s", gid) r, err := redisGet().Get(ctx, config.Store.RedisPrefix+"_g_"+gid).Result() if err == redis.Nil { return nil @@ -46,6 +47,7 @@ func (s *RedisStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore } func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { + logger.Debugf("calling ScanTransGlobalStores: %s %d", *position, limit) lid := uint64(0) if *position != "" { lid = uint64(dtmimp.MustAtoi(*position)) @@ -71,6 +73,7 @@ func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []stor } func (s *RedisStore) FindBranches(gid string) []storage.TransBranchStore { + logger.Debugf("calling FindBranches: %s", gid) sa, err := redisGet().LRange(ctx, config.Store.RedisPrefix+"_b_"+gid, 0, -1).Result() dtmimp.E2P(err) branches := make([]storage.TransBranchStore, len(sa)) diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index 8165e50..cb5a288 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -16,23 +16,23 @@ import ( ) // Process process global transaction once -func (t *TransGlobal) Process() map[string]interface{} { - r := t.process() +func (t *TransGlobal) Process(branches []TransBranch) map[string]interface{} { + r := t.process(branches) transactionMetrics(t, r["dtm_result"] == dtmcli.ResultSuccess) return r } -func (t *TransGlobal) process() map[string]interface{} { +func (t *TransGlobal) process(branches []TransBranch) map[string]interface{} { if t.Options != "" { dtmimp.MustUnmarshalString(t.Options, &t.TransOptions) } if !t.WaitResult { - go t.processInner() + go t.processInner(branches) return dtmcli.MapSuccess } submitting := t.Status == dtmcli.StatusSubmitted - err := t.processInner() + err := t.processInner(branches) if err != nil { return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": err.Error()} } @@ -42,7 +42,7 @@ func (t *TransGlobal) process() map[string]interface{} { return dtmcli.MapSuccess } -func (t *TransGlobal) processInner() (rerr error) { +func (t *TransGlobal) processInner(branches []TransBranch) (rerr error) { defer handlePanic(&rerr) defer func() { if rerr != nil && rerr != dtmcli.ErrOngoing { @@ -55,14 +55,12 @@ func (t *TransGlobal) processInner() (rerr error) { } }() logger.Debugf("processing: %s status: %s", t.Gid, t.Status) - branches := GetStore().FindBranches(t.Gid) t.lastTouched = time.Now() rerr = t.getProcessor().ProcessOnce(branches) return } -func (t *TransGlobal) saveNew() error { - branches := t.getProcessor().GenBranches() +func (t *TransGlobal) saveNew() ([]TransBranch, error) { t.NextCronInterval = t.getNextCronInterval(cronReset) t.NextCronTime = common.GetNextTime(t.NextCronInterval) t.Options = dtmimp.MustMarshalString(t.TransOptions) @@ -72,8 +70,13 @@ func (t *TransGlobal) saveNew() error { now := time.Now() t.CreateTime = &now t.UpdateTime = &now + branches := t.getProcessor().GenBranches() + for i, _ := range branches { + branches[i].CreateTime = &now + branches[i].UpdateTime = &now + } err := GetStore().MaySaveNewTrans(&t.TransGlobalStore, branches) logger.Infof("MaySaveNewTrans result: %v, global: %v branches: %v", err, t.TransGlobalStore.String(), dtmimp.MustMarshalString(branches)) - return err + return branches, err } From 5907f997fc40594a6f12938d7110b7a70fa80155 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sun, 26 Dec 2021 22:33:52 +0800 Subject: [PATCH 034/124] a minor change --- dtmsvr/trans_process.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index cb5a288..22c2fab 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -71,7 +71,7 @@ func (t *TransGlobal) saveNew() ([]TransBranch, error) { t.CreateTime = &now t.UpdateTime = &now branches := t.getProcessor().GenBranches() - for i, _ := range branches { + for i := range branches { branches[i].CreateTime = &now branches[i].UpdateTime = &now } From 0d71c267bd4be6b6d1b578f3baeda3e0fc1ecc58 Mon Sep 17 00:00:00 2001 From: freedom Date: Mon, 27 Dec 2021 09:41:20 +0800 Subject: [PATCH 035/124] add license --- dtmsvr/storage/boltdb/boltdb.go | 6 ++++++ dtmsvr/storage/boltdb/boltdb_test.go | 6 ++++++ 2 files changed, 12 insertions(+) diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index e1af190..439cfd0 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + package boltdb import ( diff --git a/dtmsvr/storage/boltdb/boltdb_test.go b/dtmsvr/storage/boltdb/boltdb_test.go index 2e96a7c..70048ea 100644 --- a/dtmsvr/storage/boltdb/boltdb_test.go +++ b/dtmsvr/storage/boltdb/boltdb_test.go @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + package boltdb import ( From d4d4ab66bb25b3914911609637bff13e26d422ac Mon Sep 17 00:00:00 2001 From: freedom Date: Mon, 27 Dec 2021 10:07:42 +0800 Subject: [PATCH 036/124] fix:Passwrod => Password --- common/config.go | 2 +- common/db.go | 2 +- dtmcli/dtmimp/types.go | 2 +- dtmcli/dtmimp/utils.go | 6 +++--- go.mod | 1 - go.sum | 9 --------- 6 files changed, 6 insertions(+), 16 deletions(-) diff --git a/common/config.go b/common/config.go index 68bf312..1c5af74 100644 --- a/common/config.go +++ b/common/config.go @@ -48,7 +48,7 @@ func (s *Store) GetDBConf() dtmcli.DBConf { Host: s.Host, Port: s.Port, User: s.User, - Passwrod: s.Password, + Password: s.Password, } } diff --git a/common/db.go b/common/db.go index 009725e..d479078 100644 --- a/common/db.go +++ b/common/db.go @@ -109,7 +109,7 @@ func DbGet(conf dtmcli.DBConf) *DB { dsn := dtmimp.GetDsn(conf) db, ok := dbs.Load(dsn) if !ok { - logger.Debugf("connecting %s", strings.Replace(dsn, conf.Passwrod, "****", 1)) + logger.Debugf("connecting %s", strings.Replace(dsn, conf.Password, "****", 1)) db1, err := gorm.Open(getGormDialetor(conf.Driver, dsn), &gorm.Config{ SkipDefaultTransaction: true, }) diff --git a/dtmcli/dtmimp/types.go b/dtmcli/dtmimp/types.go index a092295..ef7133a 100644 --- a/dtmcli/dtmimp/types.go +++ b/dtmcli/dtmimp/types.go @@ -19,5 +19,5 @@ type DBConf struct { Host string `yaml:"Host"` Port int64 `yaml:"Port"` User string `yaml:"User"` - Passwrod string `yaml:"Password"` + Password string `yaml:"Password"` } diff --git a/dtmcli/dtmimp/utils.go b/dtmcli/dtmimp/utils.go index 242089d..75b3fbd 100644 --- a/dtmcli/dtmimp/utils.go +++ b/dtmcli/dtmimp/utils.go @@ -168,7 +168,7 @@ func PooledDB(conf DBConf) (*sql.DB, error) { // StandaloneDB get a standalone db instance func StandaloneDB(conf DBConf) (*sql.DB, error) { dsn := GetDsn(conf) - Logf("opening standalone %s: %s", conf.Driver, strings.Replace(dsn, conf.Passwrod, "****", 1)) + logger.Errorf("opening standalone %s: %s", conf.Driver, strings.Replace(dsn, conf.Password, "****", 1)) return sql.Open(conf.Driver, dsn) } @@ -196,9 +196,9 @@ func GetDsn(conf DBConf) string { driver := conf.Driver dsn := map[string]string{ "mysql": fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&loc=Local", - conf.User, conf.Passwrod, host, conf.Port, ""), + conf.User, conf.Password, host, conf.Port, ""), "postgres": fmt.Sprintf("host=%s user=%s password=%s dbname='%s' port=%d sslmode=disable", - host, conf.User, conf.Passwrod, "", conf.Port), + host, conf.User, conf.Password, "", conf.Port), }[driver] PanicIf(dsn == "", fmt.Errorf("unknow driver: %s", driver)) return dsn diff --git a/go.mod b/go.mod index fdd8107..1457278 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,6 @@ require ( github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/lib/pq v1.10.3 github.com/onsi/gomega v1.16.0 - github.com/polarismesh/grpc-go-polaris v0.0.0-20211128162137-1a59cd7b5733 // indirect github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 go.etcd.io/bbolt v1.3.6 diff --git a/go.sum b/go.sum index 1aa3c42..560cc4b 100644 --- a/go.sum +++ b/go.sum @@ -29,7 +29,6 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v0.4.1 h1:GaI7EiDXDRfa8VshkTj7Fym7ha+y8/XxIgD2okUIjLw= github.com/BurntSushi/toml v0.4.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -94,18 +93,12 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/r github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dtm-labs/dtmdriver v0.0.0-20211203060147-29426c663b6e h1:xXyb4mr46T5KqR5SXd37ivXNJ33k/MSAAwsGP6btmh8= -github.com/dtm-labs/dtmdriver v0.0.0-20211203060147-29426c663b6e/go.mod h1:aeo6ZWiVI0x8P8O18r6uB1cG2uw9BCQyYZaH15MlRDI= github.com/dtm-labs/dtmdriver v0.0.1 h1:dHUZQ6g2ZN6eRUqds9kKq/3K7u9bcUGatUlbthD92fA= github.com/dtm-labs/dtmdriver v0.0.1/go.mod h1:fLiEeD2BPwM9Yq96TfcP9KpbTwFsn5nTxa/PP0jmFuk= -github.com/dtm-labs/dtmdriver-gozero v0.0.0-20211204083751-a14485949435 h1:qLBNU16bK1ZeaZ6tmfarf49qx9O9sUJAe7/IzoXpuEg= -github.com/dtm-labs/dtmdriver-gozero v0.0.0-20211204083751-a14485949435/go.mod h1:RYtA6oZny6LzlIRb1tPGt5bHfgqws/JaU6ogFly8ByQ= github.com/dtm-labs/dtmdriver-gozero v0.0.1 h1:ExDhMsn3MJCd+psSmIJVDgGUqbFrQGP0IpKL8x900AE= github.com/dtm-labs/dtmdriver-gozero v0.0.1/go.mod h1:uIiAMkG/Vp4jvINk5XfVMT0mSCzRqIYyXgpmqAQfqbA= github.com/dtm-labs/dtmdriver-polaris v0.0.2 h1:bh8u7bLWhairwpiA688dZMAX/OWcRoQk7a5bVcGzsjo= github.com/dtm-labs/dtmdriver-polaris v0.0.2/go.mod h1:vyXDTRj3CpROiRnI0dqM/lHFfZaKY9JAS1MSey2azIQ= -github.com/dtm-labs/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e h1:hNSfnVdE46i45HS6aneN+6umk+12EqI3AErbbzeLsoo= -github.com/dtm-labs/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e/go.mod h1:kB3NPnDKSGioVjgdfj6qgbqYJinOml45GnlHqR46Ycc= github.com/dtm-labs/dtmdriver-protocol1 v0.0.1 h1:nwGpGWi7XlUAcDhEw1qZ3TheBskqCvfE96n1uVjmDf4= github.com/dtm-labs/dtmdriver-protocol1 v0.0.1/go.mod h1:x3bRe8x7pAfHIIQBTK+LibVq96gBSzMzsgRYe85zxAc= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -509,8 +502,6 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/ychensha/dtmdriver-polaris v0.0.1 h1:+gYWFma5pflxNyV1HkcXmhzVHpijMSW9G4qTDcs63xc= -github.com/ychensha/dtmdriver-polaris v0.0.1/go.mod h1:0BdQvxXlGOlF6YVlsDoVvu8jyxdTlJZ9Kyh5t9lRA94= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= From 14813ac2e307b6492944b65df3c85378853338dd Mon Sep 17 00:00:00 2001 From: lsytj0413 <511121939@qq.com> Date: Mon, 27 Dec 2021 17:08:28 +0800 Subject: [PATCH 037/124] refactor(*): mv common.RedisGet to storage/redis --- common/types.go | 30 ------------------------------ common/types_test.go | 1 + dtmsvr/storage/redis/redis.go | 21 +++++++++++++++++++-- 3 files changed, 20 insertions(+), 32 deletions(-) delete mode 100644 common/types.go diff --git a/common/types.go b/common/types.go deleted file mode 100644 index 8949021..0000000 --- a/common/types.go +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package common - -import ( - "fmt" - "sync" - - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/go-redis/redis/v8" -) - -var rdb *redis.Client -var once sync.Once - -func RedisGet() *redis.Client { - once.Do(func() { - logger.Debugf("connecting to redis: %v", Config.Store) - rdb = redis.NewClient(&redis.Options{ - Addr: fmt.Sprintf("%s:%d", Config.Store.Host, Config.Store.Port), - Username: Config.Store.User, - Password: Config.Store.Password, - }) - }) - return rdb -} diff --git a/common/types_test.go b/common/types_test.go index 7bb5500..72203d0 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -20,6 +20,7 @@ func TestGeneralDB(t *testing.T) { testDbAlone(t) } } + func testSql(t *testing.T) { db := DbGet(Config.Store.GetDBConf()) err := func() (rerr error) { diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 60ec8fd..b32872b 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -3,6 +3,7 @@ package redis import ( "context" "fmt" + "sync" "time" "github.com/go-redis/redis/v8" @@ -14,10 +15,13 @@ import ( "github.com/dtm-labs/dtm/dtmsvr/storage" ) +// TODO: optimize this, it's very strange to use pointer to common.Config var config = &common.Config -var ctx context.Context = context.Background() +// TODO: optimize this, all function should have context as first parameter +var ctx = context.Background() +// RedisStore is the storage with redis, all transaction information will bachend with redis type RedisStore struct { } @@ -266,6 +270,19 @@ redis.call('SET', KEYS[1], ARGV[3], 'EX', ARGV[2]) dtmimp.E2P(err) } +var ( + rdb *redis.Client + once sync.Once +) + func redisGet() *redis.Client { - return common.RedisGet() + once.Do(func() { + logger.Debugf("connecting to redis: %v", config.Store) + rdb = redis.NewClient(&redis.Options{ + Addr: fmt.Sprintf("%s:%d", config.Store.Host, config.Store.Port), + Username: config.Store.User, + Password: config.Store.Password, + }) + }) + return rdb } From 70554cb4c456f4f733dd8809745f9cb358473ba6 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 27 Dec 2021 12:06:14 +0800 Subject: [PATCH 038/124] add comment --- app/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main.go b/app/main.go index c0e5c5d..f6c2d26 100644 --- a/app/main.go +++ b/app/main.go @@ -68,7 +68,7 @@ func main() { // quick_start 比较独立,单独作为一个例子运行,方便新人上手 examples.QsStartSvr() examples.QsFireRequest() - case "dev", "dtmsvr": + case "dev", "dtmsvr": // do nothing, not fallthrough default: // 下面是各类的例子 examples.GrpcStartup() From 9a5aa3390c71042ba6f1c5717be062a86bdb3df5 Mon Sep 17 00:00:00 2001 From: lsytj0413 <511121939@qq.com> Date: Tue, 28 Dec 2021 11:34:18 +0800 Subject: [PATCH 039/124] refactor(*): rename UpdateBranchesSql -> UpdateBranches --- dtmsvr/storage/boltdb/boltdb.go | 5 ++--- dtmsvr/storage/redis/redis.go | 5 ++--- dtmsvr/storage/sql/sql.go | 5 +++-- dtmsvr/storage/store.go | 7 ++++--- dtmsvr/svr.go | 8 ++++---- test/store_test.go | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index 439cfd0..3441f90 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -13,7 +13,6 @@ import ( "time" bolt "go.etcd.io/bbolt" - "gorm.io/gorm" "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/dtmimp" @@ -297,8 +296,8 @@ func (s *BoltdbStore) FindBranches(gid string) []storage.TransBranchStore { return branches } -func (s *BoltdbStore) UpdateBranchesSql(branches []storage.TransBranchStore, updates []string) *gorm.DB { - return nil // not implemented +func (s *BoltdbStore) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { + return 0, nil // not implemented } func (s *BoltdbStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index b32872b..7893f59 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -7,7 +7,6 @@ import ( "time" "github.com/go-redis/redis/v8" - "gorm.io/gorm" "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/dtmimp" @@ -87,8 +86,8 @@ func (s *RedisStore) FindBranches(gid string) []storage.TransBranchStore { return branches } -func (s *RedisStore) UpdateBranchesSql(branches []storage.TransBranchStore, updates []string) *gorm.DB { - return nil // not implemented +func (s *RedisStore) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { + return 0, nil // not implemented } type argList struct { diff --git a/dtmsvr/storage/sql/sql.go b/dtmsvr/storage/sql/sql.go index fd3fe56..9e86b82 100644 --- a/dtmsvr/storage/sql/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -62,11 +62,12 @@ func (s *SqlStore) FindBranches(gid string) []storage.TransBranchStore { return branches } -func (s *SqlStore) UpdateBranchesSql(branches []storage.TransBranchStore, updates []string) *gorm.DB { - return dbGet().Clauses(clause.OnConflict{ +func (s *SqlStore) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { + db := dbGet().Clauses(clause.OnConflict{ OnConstraint: "trans_branch_op_pkey", DoUpdates: clause.AssignmentColumns(updates), }).Create(branches) + return int(db.RowsAffected), db.Error } func (s *SqlStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { diff --git a/dtmsvr/storage/store.go b/dtmsvr/storage/store.go index 54a40f9..1a9da9c 100644 --- a/dtmsvr/storage/store.go +++ b/dtmsvr/storage/store.go @@ -3,11 +3,12 @@ package storage import ( "errors" "time" - - "gorm.io/gorm" ) +// ErrNotFound defines the query item is not found in storage implement. var ErrNotFound = errors.New("storage: NotFound") + +// ErrUniqueConflict defines the item is conflict with unique key in storage implement. var ErrUniqueConflict = errors.New("storage: UniqueKeyConflict") type Store interface { @@ -16,7 +17,7 @@ type Store interface { FindTransGlobalStore(gid string) *TransGlobalStore ScanTransGlobalStores(position *string, limit int64) []TransGlobalStore FindBranches(gid string) []TransBranchStore - UpdateBranchesSql(branches []TransBranchStore, updates []string) *gorm.DB + UpdateBranches(branches []TransBranchStore, updates []string) (int, error) LockGlobalSaveBranches(gid string, status string, branches []TransBranchStore, branchStart int) MaySaveNewTrans(global *TransGlobalStore, branches []TransBranchStore) error ChangeGlobalStatus(global *TransGlobalStore, newStatus string, updates []string, finished bool) diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index e2c739d..b782d05 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -77,13 +77,13 @@ func updateBranchAsync() { } } for len(updates) > 0 { - dbr := GetStore().UpdateBranchesSql(updates, []string{"status", "finish_time", "update_time"}) + rowAffected, err := GetStore().UpdateBranches(updates, []string{"status", "finish_time", "update_time"}) - if dbr.Error != nil { - logger.Errorf("async update branch status error: %v", dbr.Error) + if err != nil { + logger.Errorf("async update branch status error: %v", err) time.Sleep(1 * time.Second) } else { - logger.Infof("flushed %d branch status to db. affected: %d", len(updates), dbr.RowsAffected) + logger.Infof("flushed %d branch status to db. affected: %d", len(updates), rowAffected) updates = []TransBranch{} } } diff --git a/test/store_test.go b/test/store_test.go index 08c9966..28aafae 100644 --- a/test/store_test.go +++ b/test/store_test.go @@ -94,7 +94,7 @@ func TestStoreWait(t *testing.T) { func TestUpdateBranchSql(t *testing.T) { if !config.Store.IsDB() { - r := registry.GetStore().UpdateBranchesSql(nil, nil) - assert.Nil(t, r) + _, err := registry.GetStore().UpdateBranches(nil, nil) + assert.Nil(t, err) } } From dd4c4e0a672720debc8f4e5f41f7d4a7da5dd68f Mon Sep 17 00:00:00 2001 From: zxxshaycormac <39913068+zxxshaycormac@users.noreply.github.com> Date: Tue, 28 Dec 2021 20:54:40 +0800 Subject: [PATCH 040/124] translate dtmcli/tcc.go MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 翻译TccGlobalTransaction方法的注释 --- dtmcli/tcc.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmcli/tcc.go b/dtmcli/tcc.go index 9df1bd4..73d1172 100644 --- a/dtmcli/tcc.go +++ b/dtmcli/tcc.go @@ -24,7 +24,7 @@ type TccGlobalFunc func(tcc *Tcc) (*resty.Response, error) // TccGlobalTransaction begin a tcc global transaction // dtm dtm server address -// gid 全局事务id +// gid global transaction ID // tccFunc tcc事务函数,里面会定义全局事务的分支 func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr error) { tcc := &Tcc{TransBase: *dtmimp.NewTransBase(gid, "tcc", dtm, "")} From 1e835778d6a5d68431852f58b02ac3443220fb55 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 15:40:14 +0800 Subject: [PATCH 041/124] default no config needed --- .gitignore | 6 +- .golangci.yml | 6 +- .vscode/launch.json.sample | 33 -- .vscode/settings.json.sample | 3 - README-cn.md | 37 +- app/main.go | 82 ----- bench/main.go | 14 +- bench/svr/http.go | 26 +- common/config.go | 128 ------- common/types_test.go | 67 ---- conf.sample.yml | 7 - dtmcli/dtmimp/utils.go | 2 +- dtmgrpc/dtmgimp/types.go | 7 +- dtmsvr/api_http.go | 20 +- dtmsvr/config/config.go | 83 +++++ {common => dtmsvr/config}/config_test.go | 27 +- {common => dtmsvr/config}/config_utils.go | 34 +- dtmsvr/cron.go | 2 +- dtmsvr/storage/boltdb/boltdb.go | 13 +- dtmsvr/storage/redis/redis.go | 39 ++- dtmsvr/storage/registry/registry.go | 6 +- dtmsvr/storage/sql/sql.go | 32 +- dtmsvr/storage/trans.go | 6 +- dtmsvr/svr.go | 18 +- dtmsvr/svr_imports.go | 7 - dtmsvr/trans_process.go | 4 +- dtmsvr/trans_status.go | 8 +- dtmsvr/utils.go | 4 +- dtmsvr/utils_test.go | 4 +- dtmutil/consts.go | 14 + {common => dtmutil}/db.go | 16 +- {common => dtmutil}/utils.go | 2 +- {common => dtmutil}/utils_test.go | 4 +- examples/base.go | 14 - examples/busi.pb.go | 330 ------------------ examples/data.go | 55 --- examples/grpc_msg.go | 25 -- examples/grpc_saga.go | 36 -- examples/grpc_saga_barrier.go | 70 ---- examples/grpc_tcc.go | 32 -- examples/grpc_xa.go | 37 -- examples/http_gorm_xa.go | 29 -- examples/http_msg.go | 28 -- examples/http_saga.go | 56 --- examples/http_saga_barrier.go | 79 ----- examples/http_saga_gorm_barrier.go | 43 --- examples/http_tcc.go | 51 --- examples/http_tcc_barrier.go | 111 ------ examples/http_xa.go | 42 --- go.mod | 1 + go.sum | 1 + helper/test-cover.sh | 2 +- main.go | 72 ++++ qs/main.go | 19 + sqls/{examples.mysql.sql => busi.mysql.sql} | 0 ...xamples.postgres.sql => busi.postgres.sql} | 0 test/api_test.go | 14 +- test/base_test.go | 12 +- test/busi/barrier.go | 124 +++++++ {examples => test/busi}/base_grpc.go | 45 +-- {examples => test/busi}/base_http.go | 124 +++---- {examples => test/busi}/base_types.go | 84 +++-- test/busi/busi.go | 85 +++++ test/busi/busi.pb.go | 325 +++++++++++++++++ {examples => test/busi}/busi.proto | 4 +- {examples => test/busi}/busi_grpc.pb.go | 74 ++-- {examples => test/busi}/quick_start.go | 38 +- test/busi/startup.go | 23 ++ test/busi/utils.go | 61 ++++ test/common_test.go | 38 ++ test/dtmsvr_test.go | 16 +- test/examples_test.go | 20 -- test/main_test.go | 47 ++- test/msg_grpc_test.go | 21 +- test/msg_options_test.go | 4 +- test/msg_test.go | 21 +- test/saga_barrier_test.go | 4 +- test/saga_compatible_test.go | 7 +- test/saga_concurrent_test.go | 6 +- test/saga_grpc_barrier_test.go | 11 +- test/saga_grpc_test.go | 23 +- test/saga_options_test.go | 10 +- test/saga_test.go | 27 +- test/store_test.go | 14 +- test/tcc_barrier_test.go | 93 ++--- test/tcc_cover_test.go | 4 +- test/tcc_grpc_cover_test.go | 13 +- test/tcc_grpc_test.go | 31 +- test/tcc_test.go | 21 +- test/types.go | 12 +- test/xa_cover_test.go | 12 +- test/xa_grpc_test.go | 22 +- test/xa_test.go | 32 +- 93 files changed, 1446 insertions(+), 1970 deletions(-) delete mode 100644 .vscode/launch.json.sample delete mode 100644 .vscode/settings.json.sample delete mode 100644 app/main.go delete mode 100644 common/config.go delete mode 100644 common/types_test.go create mode 100644 dtmsvr/config/config.go rename {common => dtmsvr/config}/config_test.go (68%) rename {common => dtmsvr/config}/config_utils.go (64%) delete mode 100644 dtmsvr/svr_imports.go create mode 100644 dtmutil/consts.go rename {common => dtmutil}/db.go (90%) rename {common => dtmutil}/utils.go (99%) rename {common => dtmutil}/utils_test.go (96%) delete mode 100644 examples/base.go delete mode 100644 examples/busi.pb.go delete mode 100644 examples/data.go delete mode 100644 examples/grpc_msg.go delete mode 100644 examples/grpc_saga.go delete mode 100644 examples/grpc_saga_barrier.go delete mode 100644 examples/grpc_tcc.go delete mode 100644 examples/grpc_xa.go delete mode 100644 examples/http_gorm_xa.go delete mode 100644 examples/http_msg.go delete mode 100644 examples/http_saga.go delete mode 100644 examples/http_saga_barrier.go delete mode 100644 examples/http_saga_gorm_barrier.go delete mode 100644 examples/http_tcc.go delete mode 100644 examples/http_tcc_barrier.go delete mode 100644 examples/http_xa.go create mode 100644 main.go create mode 100644 qs/main.go rename sqls/{examples.mysql.sql => busi.mysql.sql} (100%) rename sqls/{examples.postgres.sql => busi.postgres.sql} (100%) create mode 100644 test/busi/barrier.go rename {examples => test/busi}/base_grpc.go (71%) rename {examples => test/busi}/base_http.go (53%) rename {examples => test/busi}/base_types.go (52%) create mode 100644 test/busi/busi.go create mode 100644 test/busi/busi.pb.go rename {examples => test/busi}/busi.proto (96%) rename {examples => test/busi}/busi_grpc.pb.go (91%) rename {examples => test/busi}/quick_start.go (58%) create mode 100644 test/busi/startup.go create mode 100644 test/busi/utils.go create mode 100644 test/common_test.go delete mode 100644 test/examples_test.go diff --git a/.gitignore b/.gitignore index 771c69c..e89d163 100644 --- a/.gitignore +++ b/.gitignore @@ -5,11 +5,13 @@ conf.yml main dist .idea/** -.vscode/*.json +.vscode default.etcd */**/*.bolt # Output file of unit test coverage coverage.* profile.* -test.sh \ No newline at end of file +test.sh +dtm +dtm.* \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 78a6813..5d5bf7b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,8 +1,8 @@ run: deadline: 5m - skip-dirs: - - test - - examples + # skip-dirs: + # - test + # - examples linter-settings: goconst: diff --git a/.vscode/launch.json.sample b/.vscode/launch.json.sample deleted file mode 100644 index 7cf371c..0000000 --- a/.vscode/launch.json.sample +++ /dev/null @@ -1,33 +0,0 @@ -{ - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "Launch", - "type": "go", - "request": "launch", - "mode": "debug", - "program": "${workspaceFolder}/app/main.go", - "cwd": "${workspaceFolder}", - "env": { - // "GIN_MODE": "release" - }, - "args": ["grpc_saga"] - }, - { - "name": "Test", - "type": "go", - "request": "launch", - "mode": "test", - "port": 2345, - "host": "127.0.0.1", - "program": "${file}", - "env": { - // "GIN_MODE": "release" - }, - "args": [] - } - ] -} \ No newline at end of file diff --git a/.vscode/settings.json.sample b/.vscode/settings.json.sample deleted file mode 100644 index 079a897..0000000 --- a/.vscode/settings.json.sample +++ /dev/null @@ -1,3 +0,0 @@ -{ - "go.formatTool": "gofmt" -} \ No newline at end of file diff --git a/README-cn.md b/README-cn.md index 27be69d..122e7df 100644 --- a/README-cn.md +++ b/README-cn.md @@ -74,26 +74,21 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 具体微服务接入使用,参见[微服务支持](https://dtm.pub/protocol/intro.html) ## 快速开始 -### 获取代码 +如果您不是Go语言,可以跳转[各语言客户端及示例](https://dtm.pub/summary/code.html#go),里面有相关的快速开始示例 -`git clone https://github.com/dtm-labs/dtm && cd dtm` +### 运行dtm -### dtm依赖于mysql - -安装[docker 20.04+](https://docs.docker.com/get-docker/)之后 - -`docker-compose -f helper/compose.mysql.yml up` - -> 您也可以配置使用现有的mysql,需要高级权限,允许dtm创建数据库 -> -> `cp conf.sample.yml conf.yml # 修改conf.yml` +``` bash +git clone https://github.com/dtm-labs/dtm && cd dtm +go run main.go +``` -### 启动并运行saga示例 -`go run app/main.go qs` +### 启动并运行一个saga示例 +`go run qs/main.go` -## 开始使用 +## 接入详解 -### 使用 +### 接入代码 ``` GO // 具体业务微服务地址 const qsBusi = "http://localhost:8081/api/busi_saga" @@ -117,8 +112,8 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 -### 完整示例 -参考[examples/quick_start.go](./examples/quick_start.go) +### 更多示例 +参考[dtm-labs/dtm-examples](https://github.com/dtm-labs/dtm-examples) ## 公众号 您可以关注公众号:分布式事务,及时跟踪dtm的最新内容 @@ -129,11 +124,3 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 欢迎使用[dtm](https://github.com/dtm-labs/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 -## 谁在使用 -
- 腾讯 - 常青藤爸爸 - 镜小二 - 极欧科技 - 金数智联 -
diff --git a/app/main.go b/app/main.go deleted file mode 100644 index f6c2d26..0000000 --- a/app/main.go +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package main - -import ( - "fmt" - "os" - "strings" - - _ "go.uber.org/automaxprocs" - - "github.com/dtm-labs/dtm/common" - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/dtm-labs/dtm/dtmsvr" - "github.com/dtm-labs/dtm/dtmsvr/storage/registry" - "github.com/dtm-labs/dtm/examples" -) - -var Version, Commit, Date string - -var usage = `dtm is a lightweight distributed transaction manager. - -usage: - dtm [command] - -Available commands: - version print dtm version - dtmsvr run dtm as a server - dev create all needed table and run dtm as a server - bench start bench server - - quick_start run quick start example (dtm will create needed table) - qs same as quick_start -` - -func main() { - if len(os.Args) == 1 { - fmt.Println(usage) - for name := range examples.Samples { - fmt.Printf("%4s%-18srun a sample includes %s\n", "", name, strings.ReplaceAll(name, "_", " ")) - } - return - } - if os.Args[1] == "version" { - fmt.Printf("version: %s commit: %s built at: %s\n", Version, Commit, Date) - return - } - logger.Infof("starting dtm....") - common.MustLoadConfig() - if common.Config.ExamplesDB.Driver != "" { - dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) - } - if os.Args[1] != "dtmsvr" { // 实际线上运行,只启动dtmsvr,不准备table相关的数据 - registry.WaitStoreUp() - dtmsvr.PopulateDB(true) - examples.PopulateDB(true) - } - dtmsvr.StartSvr() // 启动dtmsvr的api服务 - go dtmsvr.CronExpiredTrans(-1) // 启动dtmsvr的定时过期查询 - - switch os.Args[1] { - case "quick_start", "qs": - // quick_start 比较独立,单独作为一个例子运行,方便新人上手 - examples.QsStartSvr() - examples.QsFireRequest() - case "dev", "dtmsvr": // do nothing, not fallthrough - default: - // 下面是各类的例子 - examples.GrpcStartup() - examples.BaseAppStartup() - - sample := examples.Samples[os.Args[1]] - logger.FatalfIf(sample == nil, "no sample name for %s", os.Args[1]) - sample.Action() - } - select {} -} diff --git a/bench/main.go b/bench/main.go index ec2a78e..310af87 100644 --- a/bench/main.go +++ b/bench/main.go @@ -5,12 +5,12 @@ import ( "os" "github.com/dtm-labs/dtm/bench/svr" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage/registry" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" ) var usage = `bench is a bench test server for dtmf @@ -25,23 +25,23 @@ func hintAndExit() { os.Exit(0) } -var conf = &common.Config +var conf = &config.Config func main() { if len(os.Args) <= 1 { hintAndExit() } logger.Infof("starting bench server") - common.MustLoadConfig() + config.MustLoadConfig("") logger.InitLog(conf.LogLevel) - if conf.ExamplesDB.Driver != "" { - dtmcli.SetCurrentDBType(conf.ExamplesDB.Driver) + if busi.BusiConf.Driver != "" { + dtmcli.SetCurrentDBType(busi.BusiConf.Driver) svr.PrepareBenchDB() } registry.WaitStoreUp() dtmsvr.PopulateDB(false) if os.Args[1] == "db" { - examples.PopulateDB(false) + busi.PopulateDB(false) } else if os.Args[1] == "redis" || os.Args[1] == "boltdb" { } else { diff --git a/bench/svr/http.go b/bench/svr/http.go index 0ff80a8..d1c8978 100644 --- a/bench/svr/http.go +++ b/bench/svr/http.go @@ -14,11 +14,12 @@ import ( "sync/atomic" "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/gin-gonic/gin" "github.com/lithammer/shortuuid" ) @@ -33,7 +34,7 @@ var benchPort = dtmimp.If(os.Getenv("BENCH_PORT") == "", "8083", os.Getenv("BENC var benchBusi = fmt.Sprintf("http://localhost:%s%s", benchPort, benchAPI) func sdbGet() *sql.DB { - db, err := dtmimp.PooledDB(common.Config.ExamplesDB) + db, err := dtmimp.PooledDB(busi.BusiConf) logger.FatalIfError(err) return db } @@ -91,7 +92,7 @@ func PrepareBenchDB() { // StartSvr 1 func StartSvr() { - app := common.GetGinApp() + app := dtmutil.GetGinApp() benchAddRoute(app) logger.Debugf("bench listening at %d", benchPort) go app.Run(fmt.Sprintf(":%s", benchPort)) @@ -127,20 +128,19 @@ func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { } func benchAddRoute(app *gin.Engine) { - dtmHttpServer := fmt.Sprintf("http://localhost:%d/api/dtmsvr", common.Config.HttpPort) - app.POST(benchAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), 1, c) })) - app.POST(benchAPI+"/TransInCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransInCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), -1, c) })) - app.POST(benchAPI+"/TransOut", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), -1, c) })) - app.POST(benchAPI+"/TransOutCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransOutCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), 30, c) })) - app.Any(benchAPI+"/reloadData", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.Any(benchAPI+"/reloadData", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { reloadData() mode = c.Query("m") s := c.Query("sqls") @@ -149,7 +149,7 @@ func benchAddRoute(app *gin.Engine) { } return nil, nil })) - app.Any(benchAPI+"/bench", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.Any(benchAPI+"/bench", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { uid := (atomic.AddInt32(&uidCounter, 1)-1)%total + 1 suid := fmt.Sprintf("%d", uid) suid2 := fmt.Sprintf("%d", total+1-uid) @@ -158,7 +158,7 @@ func benchAddRoute(app *gin.Engine) { params2 := fmt.Sprintf("?uid=%s", suid2) logger.Debugf("mode: %s contains dtm: %t", mode, strings.Contains(mode, "dtm")) if strings.Contains(mode, "dtm") { - saga := dtmcli.NewSaga(dtmHttpServer, fmt.Sprintf("bench-%d", uid)). + saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, fmt.Sprintf("bench-%d", uid)). Add(benchBusi+"/TransOut"+params, benchBusi+"/TransOutCompensate"+params, req). Add(benchBusi+"/TransIn"+params2, benchBusi+"/TransInCompensate"+params2, req) saga.WaitResult = true @@ -172,10 +172,10 @@ func benchAddRoute(app *gin.Engine) { } return nil, nil })) - app.Any(benchAPI+"/benchEmptyUrl", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.Any(benchAPI+"/benchEmptyUrl", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { gid := shortuuid.New() req := gin.H{} - saga := dtmcli.NewSaga(dtmHttpServer, gid). + saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gid). Add("", "", req). Add("", "", req) saga.WaitResult = true diff --git a/common/config.go b/common/config.go deleted file mode 100644 index 1c5af74..0000000 --- a/common/config.go +++ /dev/null @@ -1,128 +0,0 @@ -package common - -import ( - "encoding/json" - "errors" - "io/ioutil" - "path/filepath" - - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" - "gopkg.in/yaml.v2" -) - -const ( - DtmMetricsPort = 8889 - Mysql = "mysql" - Redis = "redis" - BoltDb = "boltdb" -) - -// MicroService config type for micro service -type MicroService struct { - Driver string `yaml:"Driver" default:"default"` - Target string `yaml:"Target"` - EndPoint string `yaml:"EndPoint"` -} - -type Store struct { - Driver string `yaml:"Driver" default:"boltdb"` - Host string `yaml:"Host"` - Port int64 `yaml:"Port"` - User string `yaml:"User"` - Password string `yaml:"Password"` - MaxOpenConns int64 `yaml:"MaxOpenConns" default:"500"` - MaxIdleConns int64 `yaml:"MaxIdleConns" default:"500"` - ConnMaxLifeTime int64 `yaml:"ConnMaxLifeTime" default:"5"` - DataExpire int64 `yaml:"DataExpire" default:"604800"` // Trans data will expire in 7 days. only for redis/boltdb. - RedisPrefix string `yaml:"RedisPrefix" default:"{a}"` // Redis storage prefix. store data to only one slot in cluster -} - -func (s *Store) IsDB() bool { - return s.Driver == dtmcli.DBTypeMysql || s.Driver == dtmcli.DBTypePostgres -} - -func (s *Store) GetDBConf() dtmcli.DBConf { - return dtmcli.DBConf{ - Driver: s.Driver, - Host: s.Host, - Port: s.Port, - User: s.User, - Password: s.Password, - } -} - -type configType struct { - Store Store `yaml:"Store"` - TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` - TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` - RetryInterval int64 `yaml:"RetryInterval" default:"10"` - HttpPort int64 `yaml:"HttpPort" default:"36789"` - GrpcPort int64 `yaml:"GrpcPort" default:"36790"` - MicroService MicroService `yaml:"MicroService"` - UpdateBranchSync int64 `yaml:"UpdateBranchSync"` - LogLevel string `yaml:"LogLevel" default:"info"` - ExamplesDB dtmcli.DBConf `yaml:"ExamplesDB"` -} - -// Config 配置 -var Config = configType{} - -func MustLoadConfig() { - loadFromEnv("", &Config) - cont := []byte{} - for d := MustGetwd(); d != "" && d != "/"; d = filepath.Dir(d) { - cont1, err := ioutil.ReadFile(d + "/conf.yml") - if err != nil { - cont1, err = ioutil.ReadFile(d + "/conf.sample.yml") - } - if cont1 != nil { - cont = cont1 - break - } - } - if len(cont) != 0 { - err := yaml.UnmarshalStrict(cont, &Config) - logger.FatalIfError(err) - } - scont, err := json.MarshalIndent(&Config, "", " ") - logger.FatalIfError(err) - logger.Debugf("config is: \n%s", scont) - err = checkConfig() - logger.FatalfIf(err != nil, `config error: '%v'. - check you env, and conf.yml/conf.sample.yml in current and parent path: %s. - please visit http://d.dtm.pub to see the config document. - loaded config is: - %v`, err, MustGetwd(), Config) -} - -func checkConfig() error { - if Config.RetryInterval < 10 { - return errors.New("RetryInterval should not be less than 10") - } - if Config.TimeoutToFail < Config.RetryInterval { - return errors.New("TimeoutToFail should not be less than RetryInterval") - } - switch Config.Store.Driver { - case BoltDb: - return nil - case Mysql: - if Config.Store.Host == "" { - return errors.New("Db host not valid ") - } - if Config.Store.Port == 0 { - return errors.New("Db port not valid ") - } - if Config.Store.User == "" { - return errors.New("Db user not valid ") - } - case Redis: - if Config.Store.Host == "" { - return errors.New("Redis host not valid ") - } - if Config.Store.Port == 0 { - return errors.New("Redis port not valid ") - } - } - return nil -} diff --git a/common/types_test.go b/common/types_test.go deleted file mode 100644 index 72203d0..0000000 --- a/common/types_test.go +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package common - -import ( - "testing" - - "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/stretchr/testify/assert" -) - -func TestGeneralDB(t *testing.T) { - MustLoadConfig() - if Config.Store.IsDB() { - testSql(t) - testDbAlone(t) - } -} - -func testSql(t *testing.T) { - db := DbGet(Config.Store.GetDBConf()) - err := func() (rerr error) { - defer dtmimp.P2E(&rerr) - db.Must().Exec("select a") - return nil - }() - assert.NotEqual(t, nil, err) -} - -func testDbAlone(t *testing.T) { - db, err := dtmimp.StandaloneDB(Config.Store.GetDBConf()) - assert.Nil(t, err) - _, err = dtmimp.DBExec(db, "select 1") - assert.Equal(t, nil, err) - _, err = dtmimp.DBExec(db, "") - assert.Equal(t, nil, err) - db.Close() - _, err = dtmimp.DBExec(db, "select 1") - assert.NotEqual(t, nil, err) -} - -func TestConfig(t *testing.T) { - testConfigStringField(&Config.Store.Driver, "", t) - testConfigStringField(&Config.Store.User, "", t) - testConfigIntField(&Config.RetryInterval, 9, t) - testConfigIntField(&Config.TimeoutToFail, 9, t) -} - -func testConfigStringField(fd *string, val string, t *testing.T) { - old := *fd - *fd = val - str := checkConfig() - assert.NotEqual(t, "", str) - *fd = old -} - -func testConfigIntField(fd *int64, val int64, t *testing.T) { - old := *fd - *fd = val - str := checkConfig() - assert.NotEqual(t, "", str) - *fd = old -} diff --git a/conf.sample.yml b/conf.sample.yml index cc7f447..e4f6348 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -41,10 +41,3 @@ Store: # specify which engine to store trans status # LogLevel: 'info' # default: info. can be debug|info|warn|error -### dtm can run examples, and examples will use following config to connect db -ExamplesDB: - Driver: 'mysql' - Host: 'localhost' - User: 'root' - Password: '' - Port: 3306 diff --git a/dtmcli/dtmimp/utils.go b/dtmcli/dtmimp/utils.go index 75b3fbd..e2576e2 100644 --- a/dtmcli/dtmimp/utils.go +++ b/dtmcli/dtmimp/utils.go @@ -168,7 +168,7 @@ func PooledDB(conf DBConf) (*sql.DB, error) { // StandaloneDB get a standalone db instance func StandaloneDB(conf DBConf) (*sql.DB, error) { dsn := GetDsn(conf) - logger.Errorf("opening standalone %s: %s", conf.Driver, strings.Replace(dsn, conf.Password, "****", 1)) + logger.Infof("opening standalone %s: %s", conf.Driver, strings.Replace(dsn, conf.Password, "****", 1)) return sql.Open(conf.Driver, dsn) } diff --git a/dtmgrpc/dtmgimp/types.go b/dtmgrpc/dtmgimp/types.go index 3b8048d..a11fe71 100644 --- a/dtmgrpc/dtmgimp/types.go +++ b/dtmgrpc/dtmgimp/types.go @@ -35,12 +35,13 @@ func GrpcServerLog(ctx context.Context, req interface{}, info *grpc.UnaryServerI return m, err } -// GrpcClientLog 打印grpc服务端的日志 +// GrpcClientLog 打印grpc调用的日志 func GrpcClientLog(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - logger.Debugf("grpc client calling: %s%s %v", cc.Target(), method, req) + logger.Debugf("grpc client calling: %s%s %v", cc.Target(), method, dtmimp.MustMarshalString(req)) LogDtmCtx(ctx) err := invoker(ctx, method, req, reply, cc, opts...) - res := fmt.Sprintf("grpc client called: %s%s %v result: %v err: %v", cc.Target(), method, req, reply, err) + res := fmt.Sprintf("grpc client called: %s%s %s result: %s err: %v", + cc.Target(), method, dtmimp.MustMarshalString(req), dtmimp.MustMarshalString(reply), err) if err != nil { logger.Errorf("%s", res) } else { diff --git a/dtmsvr/api_http.go b/dtmsvr/api_http.go index bbd09de..fa98498 100644 --- a/dtmsvr/api_http.go +++ b/dtmsvr/api_http.go @@ -9,23 +9,23 @@ package dtmsvr import ( "errors" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmutil" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus/promhttp" ) func addRoute(engine *gin.Engine) { - engine.GET("/api/dtmsvr/newGid", common.WrapHandler(newGid)) - engine.POST("/api/dtmsvr/prepare", common.WrapHandler(prepare)) - engine.POST("/api/dtmsvr/submit", common.WrapHandler(submit)) - engine.POST("/api/dtmsvr/abort", common.WrapHandler(abort)) - engine.POST("/api/dtmsvr/registerBranch", common.WrapHandler(registerBranch)) - engine.POST("/api/dtmsvr/registerXaBranch", common.WrapHandler(registerBranch)) // compatible for old sdk - engine.POST("/api/dtmsvr/registerTccBranch", common.WrapHandler(registerBranch)) // compatible for old sdk - engine.GET("/api/dtmsvr/query", common.WrapHandler(query)) - engine.GET("/api/dtmsvr/all", common.WrapHandler(all)) + engine.GET("/api/dtmsvr/newGid", dtmutil.WrapHandler(newGid)) + engine.POST("/api/dtmsvr/prepare", dtmutil.WrapHandler(prepare)) + engine.POST("/api/dtmsvr/submit", dtmutil.WrapHandler(submit)) + engine.POST("/api/dtmsvr/abort", dtmutil.WrapHandler(abort)) + engine.POST("/api/dtmsvr/registerBranch", dtmutil.WrapHandler(registerBranch)) + engine.POST("/api/dtmsvr/registerXaBranch", dtmutil.WrapHandler(registerBranch)) // compatible for old sdk + engine.POST("/api/dtmsvr/registerTccBranch", dtmutil.WrapHandler(registerBranch)) // compatible for old sdk + engine.GET("/api/dtmsvr/query", dtmutil.WrapHandler(query)) + engine.GET("/api/dtmsvr/all", dtmutil.WrapHandler(all)) // add prometheus exporter h := promhttp.Handler() diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go new file mode 100644 index 0000000..9acc8f5 --- /dev/null +++ b/dtmsvr/config/config.go @@ -0,0 +1,83 @@ +package config + +import ( + "encoding/json" + "io/ioutil" + + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" + "gopkg.in/yaml.v2" +) + +const ( + DtmMetricsPort = 8889 + Mysql = "mysql" + Redis = "redis" + BoltDb = "boltdb" +) + +// MicroService config type for micro service +type MicroService struct { + Driver string `yaml:"Driver" default:"default"` + Target string `yaml:"Target"` + EndPoint string `yaml:"EndPoint"` +} + +type Store struct { + Driver string `yaml:"Driver" default:"boltdb"` + Host string `yaml:"Host"` + Port int64 `yaml:"Port"` + User string `yaml:"User"` + Password string `yaml:"Password"` + MaxOpenConns int64 `yaml:"MaxOpenConns" default:"500"` + MaxIdleConns int64 `yaml:"MaxIdleConns" default:"500"` + ConnMaxLifeTime int64 `yaml:"ConnMaxLifeTime" default:"5"` + DataExpire int64 `yaml:"DataExpire" default:"604800"` // Trans data will expire in 7 days. only for redis/boltdb. + RedisPrefix string `yaml:"RedisPrefix" default:"{a}"` // Redis storage prefix. store data to only one slot in cluster +} + +func (s *Store) IsDB() bool { + return s.Driver == dtmcli.DBTypeMysql || s.Driver == dtmcli.DBTypePostgres +} + +func (s *Store) GetDBConf() dtmcli.DBConf { + return dtmcli.DBConf{ + Driver: s.Driver, + Host: s.Host, + Port: s.Port, + User: s.User, + Password: s.Password, + } +} + +type configType struct { + Store Store `yaml:"Store"` + TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` + TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` + RetryInterval int64 `yaml:"RetryInterval" default:"10"` + HttpPort int64 `yaml:"HttpPort" default:"36789"` + GrpcPort int64 `yaml:"GrpcPort" default:"36790"` + MicroService MicroService `yaml:"MicroService"` + UpdateBranchSync int64 `yaml:"UpdateBranchSync"` + LogLevel string `yaml:"LogLevel" default:"info"` +} + +// Config 配置 +var Config = configType{} + +// MustLoadConfig load config from env and file +func MustLoadConfig(confFile string) { + loadFromEnv("", &Config) + if confFile != "" { + cont, err := ioutil.ReadFile(confFile) + logger.FatalIfError(err) + err = yaml.UnmarshalStrict(cont, &Config) + logger.FatalIfError(err) + } + scont, err := json.MarshalIndent(&Config, "", " ") + logger.FatalIfError(err) + logger.Infof("config file: %s loaded config is: \n%s", confFile, scont) + err = checkConfig() + logger.FatalfIf(err != nil, `config error: '%v'. + please visit http://d.dtm.pub to see the config document.`, err) +} diff --git a/common/config_test.go b/dtmsvr/config/config_test.go similarity index 68% rename from common/config_test.go rename to dtmsvr/config/config_test.go index b3ea8dc..db62add 100644 --- a/common/config_test.go +++ b/dtmsvr/config/config_test.go @@ -1,11 +1,11 @@ -package common +package config import ( "errors" "os" "testing" - "github.com/go-playground/assert/v2" + "github.com/stretchr/testify/assert" ) func TestLoadFromEnv(t *testing.T) { @@ -47,3 +47,26 @@ func TestCheckConfig(t *testing.T) { userExpect := errors.New("Db user not valid ") assert.Equal(t, userErr, userExpect) } + +func TestConfig(t *testing.T) { + testConfigStringField(&Config.Store.Driver, "", t) + testConfigStringField(&Config.Store.User, "", t) + testConfigIntField(&Config.RetryInterval, 9, t) + testConfigIntField(&Config.TimeoutToFail, 9, t) +} + +func testConfigStringField(fd *string, val string, t *testing.T) { + old := *fd + *fd = val + str := checkConfig() + assert.NotEqual(t, "", str) + *fd = old +} + +func testConfigIntField(fd *int64, val int64, t *testing.T) { + old := *fd + *fd = val + str := checkConfig() + assert.NotEqual(t, "", str) + *fd = old +} diff --git a/common/config_utils.go b/dtmsvr/config/config_utils.go similarity index 64% rename from common/config_utils.go rename to dtmsvr/config/config_utils.go index 60069b8..1dc991f 100644 --- a/common/config_utils.go +++ b/dtmsvr/config/config_utils.go @@ -1,6 +1,7 @@ -package common +package config import ( + "errors" "fmt" "os" "reflect" @@ -53,3 +54,34 @@ func toUnderscoreUpper(key string) string { // logger.Debugf("loading from env: %s", strings.ToUpper(s2)) return strings.ToUpper(s2) } + +func checkConfig() error { + if Config.RetryInterval < 10 { + return errors.New("RetryInterval should not be less than 10") + } + if Config.TimeoutToFail < Config.RetryInterval { + return errors.New("TimeoutToFail should not be less than RetryInterval") + } + switch Config.Store.Driver { + case BoltDb: + return nil + case Mysql: + if Config.Store.Host == "" { + return errors.New("Db host not valid ") + } + if Config.Store.Port == 0 { + return errors.New("Db port not valid ") + } + if Config.Store.User == "" { + return errors.New("Db user not valid ") + } + case Redis: + if Config.Store.Host == "" { + return errors.New("Redis host not valid ") + } + if Config.Store.Port == 0 { + return errors.New("Redis port not valid ") + } + } + return nil +} diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index 5eec83c..8b1520a 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -65,7 +65,7 @@ func handlePanic(perr *error) { } func sleepCronTime() { - normal := time.Duration((float64(config.TransCronInterval) - rand.Float64()) * float64(time.Second)) + normal := time.Duration((float64(conf.TransCronInterval) - rand.Float64()) * float64(time.Second)) interval := dtmimp.If(CronForwardDuration > 0, 1*time.Millisecond, normal).(time.Duration) logger.Debugf("sleeping for %v milli", interval/time.Microsecond) time.Sleep(interval) diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index 439cfd0..d0cd912 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -15,13 +15,14 @@ import ( bolt "go.etcd.io/bbolt" "gorm.io/gorm" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmutil" ) -var config = &common.Config +var conf = &config.Config type BoltdbStore struct { } @@ -42,7 +43,7 @@ func boltGet() *bolt.DB { // 1. refactor this code // 2. make cleanup run period, to avoid the file growup when server long-running err = cleanupExpiredData( - time.Duration(common.Config.Store.DataExpire)*time.Second, + time.Duration(conf.Store.DataExpire)*time.Second, db, ) dtmimp.E2P(err) @@ -348,8 +349,8 @@ func (s *BoltdbStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newSt func (s *BoltdbStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { oldUnix := global.NextCronTime.Unix() - global.NextCronTime = common.GetNextTime(nextCronInterval) - global.UpdateTime = common.GetNextTime(0) + global.NextCronTime = dtmutil.GetNextTime(nextCronInterval) + global.UpdateTime = dtmutil.GetNextTime(0) global.NextCronInterval = nextCronInterval err := boltGet().Update(func(t *bolt.Tx) error { g := tGetGlobal(t, global.Gid) @@ -367,7 +368,7 @@ func (s *BoltdbStore) TouchCronTime(global *storage.TransGlobalStore, nextCronIn func (s *BoltdbStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { var trans *storage.TransGlobalStore = nil min := fmt.Sprintf("%d", time.Now().Add(expireIn).Unix()) - next := time.Now().Add(time.Duration(config.RetryInterval) * time.Second) + next := time.Now().Add(time.Duration(conf.RetryInterval) * time.Second) err := boltGet().Update(func(t *bolt.Tx) error { cursor := t.Bucket(bucketIndex).Cursor() for trans == nil { diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index b32872b..f8cef4b 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -9,14 +9,15 @@ import ( "github.com/go-redis/redis/v8" "gorm.io/gorm" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmutil" ) -// TODO: optimize this, it's very strange to use pointer to common.Config -var config = &common.Config +// TODO: optimize this, it's very strange to use pointer to dtmutil.Config +var conf = &config.Config // TODO: optimize this, all function should have context as first parameter var ctx = context.Background() @@ -40,7 +41,7 @@ func (s *RedisStore) PopulateData(skipDrop bool) { func (s *RedisStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { logger.Debugf("calling FindTransGlobalStore: %s", gid) - r, err := redisGet().Get(ctx, config.Store.RedisPrefix+"_g_"+gid).Result() + r, err := redisGet().Get(ctx, conf.Store.RedisPrefix+"_g_"+gid).Result() if err == redis.Nil { return nil } @@ -56,7 +57,7 @@ func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []stor if *position != "" { lid = uint64(dtmimp.MustAtoi(*position)) } - keys, cursor, err := redisGet().Scan(ctx, lid, config.Store.RedisPrefix+"_g_*", limit).Result() + keys, cursor, err := redisGet().Scan(ctx, lid, conf.Store.RedisPrefix+"_g_*", limit).Result() dtmimp.E2P(err) globals := []storage.TransGlobalStore{} if len(keys) > 0 { @@ -78,7 +79,7 @@ func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []stor func (s *RedisStore) FindBranches(gid string) []storage.TransBranchStore { logger.Debugf("calling FindBranches: %s", gid) - sa, err := redisGet().LRange(ctx, config.Store.RedisPrefix+"_b_"+gid, 0, -1).Result() + sa, err := redisGet().LRange(ctx, conf.Store.RedisPrefix+"_b_"+gid, 0, -1).Result() dtmimp.E2P(err) branches := make([]storage.TransBranchStore, len(sa)) for k, v := range sa { @@ -98,14 +99,14 @@ type argList struct { func newArgList() *argList { a := &argList{} - return a.AppendRaw(config.Store.RedisPrefix).AppendObject(config.Store.DataExpire) + return a.AppendRaw(conf.Store.RedisPrefix).AppendObject(conf.Store.DataExpire) } func (a *argList) AppendGid(gid string) *argList { - a.Keys = append(a.Keys, config.Store.RedisPrefix+"_g_"+gid) - a.Keys = append(a.Keys, config.Store.RedisPrefix+"_b_"+gid) - a.Keys = append(a.Keys, config.Store.RedisPrefix+"_u") - a.Keys = append(a.Keys, config.Store.RedisPrefix+"_s_"+gid) + a.Keys = append(a.Keys, conf.Store.RedisPrefix+"_g_"+gid) + a.Keys = append(a.Keys, conf.Store.RedisPrefix+"_b_"+gid) + a.Keys = append(a.Keys, conf.Store.RedisPrefix+"_u") + a.Keys = append(a.Keys, conf.Store.RedisPrefix+"_s_"+gid) return a } @@ -221,9 +222,9 @@ end func (s *RedisStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { expired := time.Now().Add(expireIn).Unix() - next := time.Now().Add(time.Duration(config.RetryInterval) * time.Second).Unix() + next := time.Now().Add(time.Duration(conf.RetryInterval) * time.Second).Unix() args := newArgList().AppendGid("").AppendRaw(expired).AppendRaw(next) - lua := `-- LocakOneGlobalTrans + lua := `-- LockOneGlobalTrans local r = redis.call('ZRANGE', KEYS[3], 0, 0, 'WITHSCORES') local gid = r[1] if gid == nil then @@ -250,8 +251,8 @@ return gid } func (s *RedisStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { - global.NextCronTime = common.GetNextTime(nextCronInterval) - global.UpdateTime = common.GetNextTime(0) + global.NextCronTime = dtmutil.GetNextTime(nextCronInterval) + global.UpdateTime = dtmutil.GetNextTime(0) global.NextCronInterval = nextCronInterval args := newArgList(). AppendGid(global.Gid). @@ -277,11 +278,11 @@ var ( func redisGet() *redis.Client { once.Do(func() { - logger.Debugf("connecting to redis: %v", config.Store) + logger.Debugf("connecting to redis: %v", conf.Store) rdb = redis.NewClient(&redis.Options{ - Addr: fmt.Sprintf("%s:%d", config.Store.Host, config.Store.Port), - Username: config.Store.User, - Password: config.Store.Password, + Addr: fmt.Sprintf("%s:%d", conf.Store.Host, conf.Store.Port), + Username: conf.Store.User, + Password: conf.Store.Password, }) }) return rdb diff --git a/dtmsvr/storage/registry/registry.go b/dtmsvr/storage/registry/registry.go index 2fc349c..d65f2e1 100644 --- a/dtmsvr/storage/registry/registry.go +++ b/dtmsvr/storage/registry/registry.go @@ -3,14 +3,14 @@ package registry import ( "time" - "github.com/dtm-labs/dtm/common" + "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage" "github.com/dtm-labs/dtm/dtmsvr/storage/boltdb" "github.com/dtm-labs/dtm/dtmsvr/storage/redis" "github.com/dtm-labs/dtm/dtmsvr/storage/sql" ) -var config = &common.Config +var conf = &config.Config var stores map[string]storage.Store = map[string]storage.Store{ "redis": &redis.RedisStore{}, @@ -20,7 +20,7 @@ var stores map[string]storage.Store = map[string]storage.Store{ } func GetStore() storage.Store { - return stores[config.Store.Driver] + return stores[conf.Store.Driver] } // WaitStoreUp wait for db to go up diff --git a/dtmsvr/storage/sql/sql.go b/dtmsvr/storage/sql/sql.go index fd3fe56..45d03b3 100644 --- a/dtmsvr/storage/sql/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -9,26 +9,27 @@ import ( "gorm.io/gorm" "gorm.io/gorm/clause" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage" + "github.com/dtm-labs/dtm/dtmutil" ) -var config = &common.Config +var conf = &config.Config type SqlStore struct { } func (s *SqlStore) Ping() error { - db, err := dtmimp.StandaloneDB(config.Store.GetDBConf()) + db, err := dtmimp.StandaloneDB(conf.Store.GetDBConf()) dtmimp.E2P(err) _, err = db.Exec("select 1") return err } func (s *SqlStore) PopulateData(skipDrop bool) { - file := fmt.Sprintf("%s/dtmsvr.storage.%s.sql", common.GetSqlDir(), config.Store.Driver) - common.RunSQLScript(config.Store.GetDBConf(), file, skipDrop) + file := fmt.Sprintf("%s/dtmsvr.storage.%s.sql", dtmutil.GetSqlDir(), conf.Store.Driver) + dtmutil.RunSQLScript(conf.Store.GetDBConf(), file, skipDrop) } func (s *SqlStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { @@ -83,7 +84,7 @@ func (s *SqlStore) LockGlobalSaveBranches(gid string, status string, branches [] func (s *SqlStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { return dbGet().Transaction(func(db1 *gorm.DB) error { - db := &common.DB{DB: db1} + db := &dtmutil.DB{DB: db1} dbr := db.Must().Clauses(clause.OnConflict{ DoNothing: true, }).Create(global) @@ -109,8 +110,8 @@ func (s *SqlStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatu } func (s *SqlStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { - global.NextCronTime = common.GetNextTime(nextCronInterval) - global.UpdateTime = common.GetNextTime(0) + global.NextCronTime = dtmutil.GetNextTime(nextCronInterval) + global.UpdateTime = dtmutil.GetNextTime(0) global.NextCronInterval = nextCronInterval dbGet().Must().Model(global).Where("status=? and gid=?", global.Status, global.Gid). Select([]string{"next_cron_time", "update_time", "next_cron_interval"}).Updates(global) @@ -122,7 +123,7 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlob return map[string]string{ "mysql": fmt.Sprintf("date_add(now(), interval %d second)", second), "postgres": fmt.Sprintf("current_timestamp + interval '%d second'", second), - }[config.Store.Driver] + }[conf.Store.Driver] } expire := int(expireIn / time.Second) whereTime := fmt.Sprintf("next_cron_time < %s", getTime(expire)) @@ -134,7 +135,7 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlob Select([]string{"owner", "next_cron_time"}). Updates(&storage.TransGlobalStore{ Owner: owner, - NextCronTime: common.GetNextTime(common.Config.RetryInterval), + NextCronTime: dtmutil.GetNextTime(conf.RetryInterval), }) if dbr.RowsAffected == 0 { return nil @@ -143,8 +144,15 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlob return global } -func dbGet() *common.DB { - return common.DbGet(config.Store.GetDBConf()) +func setDBConn(db *gorm.DB) { + sqldb, _ := db.DB() + sqldb.SetMaxOpenConns(int(conf.Store.MaxOpenConns)) + sqldb.SetMaxIdleConns(int(conf.Store.MaxIdleConns)) + sqldb.SetConnMaxLifetime(time.Duration(conf.Store.ConnMaxLifeTime) * time.Minute) +} + +func dbGet() *dtmutil.DB { + return dtmutil.DbGet(conf.Store.GetDBConf(), setDBConn) } func wrapError(err error) error { diff --git a/dtmsvr/storage/trans.go b/dtmsvr/storage/trans.go index cb85ee1..e1f3fa3 100644 --- a/dtmsvr/storage/trans.go +++ b/dtmsvr/storage/trans.go @@ -3,13 +3,13 @@ package storage import ( "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmutil" ) type TransGlobalStore struct { - common.ModelBase + dtmutil.ModelBase Gid string `json:"gid,omitempty"` TransType string `json:"trans_type,omitempty"` Steps []map[string]string `json:"steps,omitempty" gorm:"-"` @@ -40,7 +40,7 @@ func (g *TransGlobalStore) String() string { // TransBranchStore branch transaction type TransBranchStore struct { - common.ModelBase + dtmutil.ModelBase Gid string `json:"gid,omitempty"` URL string `json:"url,omitempty"` BinData []byte diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index e2c739d..f241e18 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -11,10 +11,10 @@ import ( "net" "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" + "github.com/dtm-labs/dtm/dtmutil" "github.com/dtm-labs/dtmdriver" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "google.golang.org/grpc" @@ -23,13 +23,13 @@ import ( // StartSvr StartSvr func StartSvr() { logger.Infof("start dtmsvr") - app := common.GetGinApp() + app := dtmutil.GetGinApp() app = httpMetrics(app) addRoute(app) - logger.Infof("dtmsvr listen at: %d", config.HttpPort) - go app.Run(fmt.Sprintf(":%d", config.HttpPort)) + logger.Infof("dtmsvr listen at: %d", conf.HttpPort) + go app.Run(fmt.Sprintf(":%d", conf.HttpPort)) - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", config.GrpcPort)) + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.GrpcPort)) logger.FatalIfError(err) s := grpc.NewServer( grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( @@ -44,9 +44,9 @@ func StartSvr() { go updateBranchAsync() time.Sleep(100 * time.Millisecond) - err = dtmdriver.Use(config.MicroService.Driver) + err = dtmdriver.Use(conf.MicroService.Driver) logger.FatalIfError(err) - err = dtmdriver.GetDriver().RegisterGrpcService(config.MicroService.Target, config.MicroService.EndPoint) + err = dtmdriver.GetDriver().RegisterGrpcService(conf.MicroService.Target, conf.MicroService.EndPoint) logger.FatalIfError(err) } @@ -61,7 +61,7 @@ var updateBranchAsyncChan chan branchStatus = make(chan branchStatus, 1000) func updateBranchAsync() { for { // flush branches every second - defer common.RecoverPanic(nil) + defer dtmutil.RecoverPanic(nil) updates := []TransBranch{} started := time.Now() checkInterval := 20 * time.Millisecond @@ -69,7 +69,7 @@ func updateBranchAsync() { select { case updateBranch := <-updateBranchAsyncChan: updates = append(updates, TransBranch{ - ModelBase: common.ModelBase{ID: updateBranch.id}, + ModelBase: dtmutil.ModelBase{ID: updateBranch.id}, Status: updateBranch.status, FinishTime: updateBranch.finishTime, }) diff --git a/dtmsvr/svr_imports.go b/dtmsvr/svr_imports.go deleted file mode 100644 index 7cc1bea..0000000 --- a/dtmsvr/svr_imports.go +++ /dev/null @@ -1,7 +0,0 @@ -package dtmsvr - -import ( - _ "github.com/dtm-labs/dtmdriver-gozero" - _ "github.com/dtm-labs/dtmdriver-polaris" - _ "github.com/dtm-labs/dtmdriver-protocol1" -) diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index 22c2fab..cac4c96 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -9,10 +9,10 @@ package dtmsvr import ( "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmutil" ) // Process process global transaction once @@ -62,7 +62,7 @@ func (t *TransGlobal) processInner(branches []TransBranch) (rerr error) { func (t *TransGlobal) saveNew() ([]TransBranch, error) { t.NextCronInterval = t.getNextCronInterval(cronReset) - t.NextCronTime = common.GetNextTime(t.NextCronInterval) + t.NextCronTime = dtmutil.GetNextTime(t.NextCronInterval) t.Options = dtmimp.MustMarshalString(t.TransOptions) if t.Options == "{}" { t.Options = "" diff --git a/dtmsvr/trans_status.go b/dtmsvr/trans_status.go index bf14e43..6f1dea0 100644 --- a/dtmsvr/trans_status.go +++ b/dtmsvr/trans_status.go @@ -47,7 +47,7 @@ func (t *TransGlobal) changeBranchStatus(b *TransBranch, status string, branchPo b.Status = status b.FinishTime = &now b.UpdateTime = &now - if config.Store.Driver != dtmimp.DBTypeMysql && config.Store.Driver != dtmimp.DBTypePostgres || config.UpdateBranchSync > 0 || t.updateBranchSync { + if conf.Store.Driver != dtmimp.DBTypeMysql && conf.Store.Driver != dtmimp.DBTypePostgres || conf.UpdateBranchSync > 0 || t.updateBranchSync { GetStore().LockGlobalSaveBranches(t.Gid, t.Status, []TransBranch{*b}, branchPos) logger.Infof("LockGlobalSaveBranches ok: gid: %s old status: %s branches: %s", b.Gid, dtmcli.StatusPrepared, b.String()) @@ -59,7 +59,7 @@ func (t *TransGlobal) changeBranchStatus(b *TransBranch, status string, branchPo func (t *TransGlobal) isTimeout() bool { timeout := t.TimeoutToFail if t.TimeoutToFail == 0 && t.TransType != "saga" { - timeout = config.TimeoutToFail + timeout = conf.TimeoutToFail } if timeout == 0 { return false @@ -136,7 +136,7 @@ func (t *TransGlobal) execBranch(branch *TransBranch, branchPos int) error { branchMetrics(t, branch, status == dtmcli.StatusSucceed) // if time pass 1500ms and NextCronInterval is not default, then reset NextCronInterval if err == nil && time.Since(t.lastTouched)+NowForwardDuration >= 1500*time.Millisecond || - t.NextCronInterval > config.RetryInterval && t.NextCronInterval > t.RetryInterval { + t.NextCronInterval > conf.RetryInterval && t.NextCronInterval > t.RetryInterval { t.touchCronTime(cronReset) } else if err == dtmimp.ErrOngoing { t.touchCronTime(cronKeep) @@ -154,6 +154,6 @@ func (t *TransGlobal) getNextCronInterval(ctype cronType) int64 { } else if t.RetryInterval != 0 { return t.RetryInterval } else { - return config.RetryInterval + return conf.RetryInterval } } diff --git a/dtmsvr/utils.go b/dtmsvr/utils.go index 3b296cc..37d938c 100644 --- a/dtmsvr/utils.go +++ b/dtmsvr/utils.go @@ -10,8 +10,8 @@ import ( "fmt" "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage" "github.com/dtm-labs/dtm/dtmsvr/storage/registry" "github.com/lithammer/shortuuid/v3" @@ -26,7 +26,7 @@ type branchStatus struct { var p2e = dtmimp.P2E var e2p = dtmimp.E2P -var config = &common.Config +var conf = &config.Config func GetStore() storage.Store { return registry.GetStore() diff --git a/dtmsvr/utils_test.go b/dtmsvr/utils_test.go index 6c6f371..2c24571 100644 --- a/dtmsvr/utils_test.go +++ b/dtmsvr/utils_test.go @@ -22,6 +22,6 @@ func TestSetNextCron(t *testing.T) { tg.RetryInterval = 15 assert.Equal(t, int64(15), tg.getNextCronInterval(cronReset)) tg.RetryInterval = 0 - assert.Equal(t, config.RetryInterval, tg.getNextCronInterval(cronReset)) - assert.Equal(t, config.RetryInterval*2, tg.getNextCronInterval(cronBackoff)) + assert.Equal(t, conf.RetryInterval, tg.getNextCronInterval(cronReset)) + assert.Equal(t, conf.RetryInterval*2, tg.getNextCronInterval(cronBackoff)) } diff --git a/dtmutil/consts.go b/dtmutil/consts.go new file mode 100644 index 0000000..5dfd9a6 --- /dev/null +++ b/dtmutil/consts.go @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +package dtmutil + +const ( + // DefaultHttpServer default url for http server. used by test and examples + DefaultHttpServer = "http://localhost:36789/api/dtmsvr" + // DefaultGrpcServer default url for grpc server. used by test and examples + DefaultGrpcServer = "localhost:36790" +) diff --git a/common/db.go b/dtmutil/db.go similarity index 90% rename from common/db.go rename to dtmutil/db.go index d479078..da41468 100644 --- a/common/db.go +++ b/dtmutil/db.go @@ -1,4 +1,4 @@ -package common +package dtmutil import ( "database/sql" @@ -96,16 +96,8 @@ func (op *tracePlugin) Initialize(db *gorm.DB) (err error) { return } -// SetDBConn set db connection conf -func SetDBConn(db *DB) { - sqldb, _ := db.DB.DB() - sqldb.SetMaxOpenConns(int(Config.Store.MaxOpenConns)) - sqldb.SetMaxIdleConns(int(Config.Store.MaxIdleConns)) - sqldb.SetConnMaxLifetime(time.Duration(Config.Store.ConnMaxLifeTime) * time.Minute) -} - // DbGet get db connection for specified conf -func DbGet(conf dtmcli.DBConf) *DB { +func DbGet(conf dtmcli.DBConf, ops ...func(*gorm.DB)) *DB { dsn := dtmimp.GetDsn(conf) db, ok := dbs.Load(dsn) if !ok { @@ -116,7 +108,9 @@ func DbGet(conf dtmcli.DBConf) *DB { dtmimp.E2P(err) db1.Use(&tracePlugin{}) db = &DB{DB: db1} - SetDBConn(db.(*DB)) + for _, op := range ops { + op(db1) + } dbs.Store(dsn, db) } return db.(*DB) diff --git a/common/utils.go b/dtmutil/utils.go similarity index 99% rename from common/utils.go rename to dtmutil/utils.go index 4af5c1b..4fbbc7d 100644 --- a/common/utils.go +++ b/dtmutil/utils.go @@ -4,7 +4,7 @@ * license that can be found in the LICENSE file. */ -package common +package dtmutil import ( "bytes" diff --git a/common/utils_test.go b/dtmutil/utils_test.go similarity index 96% rename from common/utils_test.go rename to dtmutil/utils_test.go index 303a8ab..6900796 100644 --- a/common/utils_test.go +++ b/dtmutil/utils_test.go @@ -4,7 +4,7 @@ * license that can be found in the LICENSE file. */ -package common +package dtmutil import ( "errors" @@ -16,7 +16,7 @@ import ( "testing" "github.com/gin-gonic/gin" - "github.com/go-playground/assert/v2" + "github.com/stretchr/testify/assert" ) func TestGin(t *testing.T) { diff --git a/examples/base.go b/examples/base.go deleted file mode 100644 index d9b8fcf..0000000 --- a/examples/base.go +++ /dev/null @@ -1,14 +0,0 @@ -package examples - -import "fmt" - -func Startup() { - InitConfig() - GrpcStartup() - BaseAppStartup() -} - -func InitConfig() { - DtmHttpServer = fmt.Sprintf("http://localhost:%d/api/dtmsvr", config.HttpPort) - DtmGrpcServer = fmt.Sprintf("localhost:%d", config.GrpcPort) -} diff --git a/examples/busi.pb.go b/examples/busi.pb.go deleted file mode 100644 index 7746311..0000000 --- a/examples/busi.pb.go +++ /dev/null @@ -1,330 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.27.1 -// protoc v3.17.3 -// source: examples/busi.proto - -package examples - -import ( - protoreflect "google.golang.org/protobuf/reflect/protoreflect" - protoimpl "google.golang.org/protobuf/runtime/protoimpl" - emptypb "google.golang.org/protobuf/types/known/emptypb" - reflect "reflect" - sync "sync" -) - -const ( - // Verify that this generated code is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) - // Verify that runtime/protoimpl is sufficiently up-to-date. - _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) -) - -// DtmRequest request sent to dtm server -type BusiReq struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Amount int64 `protobuf:"varint,1,opt,name=Amount,proto3" json:"Amount,omitempty"` - TransOutResult string `protobuf:"bytes,2,opt,name=TransOutResult,proto3" json:"TransOutResult,omitempty"` - TransInResult string `protobuf:"bytes,3,opt,name=TransInResult,proto3" json:"TransInResult,omitempty"` -} - -func (x *BusiReq) Reset() { - *x = BusiReq{} - if protoimpl.UnsafeEnabled { - mi := &file_examples_busi_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BusiReq) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BusiReq) ProtoMessage() {} - -func (x *BusiReq) ProtoReflect() protoreflect.Message { - mi := &file_examples_busi_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BusiReq.ProtoReflect.Descriptor instead. -func (*BusiReq) Descriptor() ([]byte, []int) { - return file_examples_busi_proto_rawDescGZIP(), []int{0} -} - -func (x *BusiReq) GetAmount() int64 { - if x != nil { - return x.Amount - } - return 0 -} - -func (x *BusiReq) GetTransOutResult() string { - if x != nil { - return x.TransOutResult - } - return "" -} - -func (x *BusiReq) GetTransInResult() string { - if x != nil { - return x.TransInResult - } - return "" -} - -type BusiReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` -} - -func (x *BusiReply) Reset() { - *x = BusiReply{} - if protoimpl.UnsafeEnabled { - mi := &file_examples_busi_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BusiReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BusiReply) ProtoMessage() {} - -func (x *BusiReply) ProtoReflect() protoreflect.Message { - mi := &file_examples_busi_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - if ms.LoadMessageInfo() == nil { - ms.StoreMessageInfo(mi) - } - return ms - } - return mi.MessageOf(x) -} - -// Deprecated: Use BusiReply.ProtoReflect.Descriptor instead. -func (*BusiReply) Descriptor() ([]byte, []int) { - return file_examples_busi_proto_rawDescGZIP(), []int{1} -} - -func (x *BusiReply) GetMessage() string { - if x != nil { - return x.Message - } - return "" -} - -var File_examples_busi_proto protoreflect.FileDescriptor - -var file_examples_busi_proto_rawDesc = []byte{ - 0x0a, 0x13, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x62, 0x75, 0x73, 0x69, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x08, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x1a, - 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6f, 0x0a, 0x07, - 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, - 0x26, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, - 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x49, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x25, 0x0a, - 0x09, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, - 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x32, 0x97, 0x08, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x35, 0x0a, - 0x09, 0x43, 0x61, 0x6e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x13, 0x2e, - 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x12, - 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, - 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x08, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, - 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, - 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, - 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, - 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, - 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x72, 0x6d, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, - 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x3e, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x72, 0x6d, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, - 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x3c, 0x0a, 0x08, 0x58, 0x61, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, - 0x38, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x58, 0x61, 0x12, 0x11, 0x2e, 0x65, - 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0a, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x58, 0x61, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, - 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x54, - 0x63, 0x63, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, - 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, - 0x3a, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x54, 0x63, 0x63, 0x12, 0x11, - 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, - 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3f, 0x0a, 0x10, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, - 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, - 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x0c, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x11, 0x2e, 0x65, - 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x0d, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, - 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x49, 0x6e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x11, 0x2e, - 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, - 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x42, 0x0a, 0x13, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, - 0x61, 0x12, 0x11, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x42, 0x75, 0x73, - 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x0c, - 0x5a, 0x0a, 0x2e, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_examples_busi_proto_rawDescOnce sync.Once - file_examples_busi_proto_rawDescData = file_examples_busi_proto_rawDesc -) - -func file_examples_busi_proto_rawDescGZIP() []byte { - file_examples_busi_proto_rawDescOnce.Do(func() { - file_examples_busi_proto_rawDescData = protoimpl.X.CompressGZIP(file_examples_busi_proto_rawDescData) - }) - return file_examples_busi_proto_rawDescData -} - -var file_examples_busi_proto_msgTypes = make([]protoimpl.MessageInfo, 2) -var file_examples_busi_proto_goTypes = []interface{}{ - (*BusiReq)(nil), // 0: examples.BusiReq - (*BusiReply)(nil), // 1: examples.BusiReply - (*emptypb.Empty)(nil), // 2: google.protobuf.Empty -} -var file_examples_busi_proto_depIdxs = []int32{ - 0, // 0: examples.Busi.CanSubmit:input_type -> examples.BusiReq - 0, // 1: examples.Busi.TransIn:input_type -> examples.BusiReq - 0, // 2: examples.Busi.TransOut:input_type -> examples.BusiReq - 0, // 3: examples.Busi.TransInRevert:input_type -> examples.BusiReq - 0, // 4: examples.Busi.TransOutRevert:input_type -> examples.BusiReq - 0, // 5: examples.Busi.TransInConfirm:input_type -> examples.BusiReq - 0, // 6: examples.Busi.TransOutConfirm:input_type -> examples.BusiReq - 2, // 7: examples.Busi.XaNotify:input_type -> google.protobuf.Empty - 0, // 8: examples.Busi.TransInXa:input_type -> examples.BusiReq - 0, // 9: examples.Busi.TransOutXa:input_type -> examples.BusiReq - 0, // 10: examples.Busi.TransInTcc:input_type -> examples.BusiReq - 0, // 11: examples.Busi.TransOutTcc:input_type -> examples.BusiReq - 0, // 12: examples.Busi.TransInTccNested:input_type -> examples.BusiReq - 0, // 13: examples.Busi.TransInBSaga:input_type -> examples.BusiReq - 0, // 14: examples.Busi.TransOutBSaga:input_type -> examples.BusiReq - 0, // 15: examples.Busi.TransInRevertBSaga:input_type -> examples.BusiReq - 0, // 16: examples.Busi.TransOutRevertBSaga:input_type -> examples.BusiReq - 1, // 17: examples.Busi.CanSubmit:output_type -> examples.BusiReply - 2, // 18: examples.Busi.TransIn:output_type -> google.protobuf.Empty - 2, // 19: examples.Busi.TransOut:output_type -> google.protobuf.Empty - 2, // 20: examples.Busi.TransInRevert:output_type -> google.protobuf.Empty - 2, // 21: examples.Busi.TransOutRevert:output_type -> google.protobuf.Empty - 2, // 22: examples.Busi.TransInConfirm:output_type -> google.protobuf.Empty - 2, // 23: examples.Busi.TransOutConfirm:output_type -> google.protobuf.Empty - 2, // 24: examples.Busi.XaNotify:output_type -> google.protobuf.Empty - 2, // 25: examples.Busi.TransInXa:output_type -> google.protobuf.Empty - 2, // 26: examples.Busi.TransOutXa:output_type -> google.protobuf.Empty - 2, // 27: examples.Busi.TransInTcc:output_type -> google.protobuf.Empty - 2, // 28: examples.Busi.TransOutTcc:output_type -> google.protobuf.Empty - 2, // 29: examples.Busi.TransInTccNested:output_type -> google.protobuf.Empty - 2, // 30: examples.Busi.TransInBSaga:output_type -> google.protobuf.Empty - 2, // 31: examples.Busi.TransOutBSaga:output_type -> google.protobuf.Empty - 2, // 32: examples.Busi.TransInRevertBSaga:output_type -> google.protobuf.Empty - 2, // 33: examples.Busi.TransOutRevertBSaga:output_type -> google.protobuf.Empty - 17, // [17:34] is the sub-list for method output_type - 0, // [0:17] is the sub-list for method input_type - 0, // [0:0] is the sub-list for extension type_name - 0, // [0:0] is the sub-list for extension extendee - 0, // [0:0] is the sub-list for field type_name -} - -func init() { file_examples_busi_proto_init() } -func file_examples_busi_proto_init() { - if File_examples_busi_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_examples_busi_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BusiReq); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_examples_busi_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BusiReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - type x struct{} - out := protoimpl.TypeBuilder{ - File: protoimpl.DescBuilder{ - GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_examples_busi_proto_rawDesc, - NumEnums: 0, - NumMessages: 2, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_examples_busi_proto_goTypes, - DependencyIndexes: file_examples_busi_proto_depIdxs, - MessageInfos: file_examples_busi_proto_msgTypes, - }.Build() - File_examples_busi_proto = out.File - file_examples_busi_proto_rawDesc = nil - file_examples_busi_proto_goTypes = nil - file_examples_busi_proto_depIdxs = nil -} diff --git a/examples/data.go b/examples/data.go deleted file mode 100644 index c865ba7..0000000 --- a/examples/data.go +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "fmt" - - "github.com/dtm-labs/dtm/common" - "github.com/dtm-labs/dtm/dtmcli/logger" -) - -var config = &common.Config - -func resetXaData() { - if config.ExamplesDB.Driver != "mysql" { - return - } - - db := dbGet() - type XaRow struct { - Data string - } - xas := []XaRow{} - db.Must().Raw("xa recover").Scan(&xas) - for _, xa := range xas { - db.Must().Exec(fmt.Sprintf("xa rollback '%s'", xa.Data)) - } -} - -// PopulateDB populate example mysql data -func PopulateDB(skipDrop bool) { - resetXaData() - file := fmt.Sprintf("%s/examples.%s.sql", common.GetSqlDir(), config.ExamplesDB.Driver) - common.RunSQLScript(config.ExamplesDB, file, skipDrop) - file = fmt.Sprintf("%s/dtmcli.barrier.%s.sql", common.GetSqlDir(), config.ExamplesDB.Driver) - common.RunSQLScript(config.ExamplesDB, file, skipDrop) -} - -type sampleInfo struct { - Arg string - Action func() string - Desc string -} - -// Samples 所有的示例都会注册到这里 -var Samples = map[string]*sampleInfo{} - -func addSample(name string, fn func() string) { - logger.FatalfIf(Samples[name] != nil, "%s already exists", name) - Samples[name] = &sampleInfo{Arg: name, Action: fn} -} diff --git a/examples/grpc_msg.go b/examples/grpc_msg.go deleted file mode 100644 index 5e89058..0000000 --- a/examples/grpc_msg.go +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/dtmcli/logger" - dtmgrpc "github.com/dtm-labs/dtm/dtmgrpc" -) - -func init() { - addSample("grpc_msg", func() string { - req := &BusiReq{Amount: 30} - gid := dtmgrpc.MustGenGid(DtmGrpcServer) - msg := dtmgrpc.NewMsgGrpc(DtmGrpcServer, gid). - Add(BusiGrpc+"/examples.Busi/TransOut", req). - Add(BusiGrpc+"/examples.Busi/TransIn", req) - err := msg.Submit() - logger.FatalIfError(err) - return msg.Gid - }) -} diff --git a/examples/grpc_saga.go b/examples/grpc_saga.go deleted file mode 100644 index eb2c6b0..0000000 --- a/examples/grpc_saga.go +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/dtmcli/logger" - dtmgrpc "github.com/dtm-labs/dtm/dtmgrpc" -) - -func init() { - addSample("grpc_saga", func() string { - req := &BusiReq{Amount: 30} - gid := dtmgrpc.MustGenGid(DtmGrpcServer) - saga := dtmgrpc.NewSagaGrpc(DtmGrpcServer, gid). - Add(BusiGrpc+"/examples.Busi/TransOut", BusiGrpc+"/examples.Busi/TransOutRevert", req). - Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInRevert", req) - err := saga.Submit() - logger.FatalIfError(err) - return saga.Gid - }) - addSample("grpc_saga_wait", func() string { - req := &BusiReq{Amount: 30} - gid := dtmgrpc.MustGenGid(DtmGrpcServer) - saga := dtmgrpc.NewSagaGrpc(DtmGrpcServer, gid). - Add(BusiGrpc+"/examples.Busi/TransOut", BusiGrpc+"/examples.Busi/TransOutRevert", req). - Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInRevert", req) - saga.WaitResult = true - err := saga.Submit() - logger.FatalIfError(err) - return saga.Gid - }) -} diff --git a/examples/grpc_saga_barrier.go b/examples/grpc_saga_barrier.go deleted file mode 100644 index d838181..0000000 --- a/examples/grpc_saga_barrier.go +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "context" - "database/sql" - - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/dtm-labs/dtm/dtmgrpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -func init() { - addSample("grpc_saga_barrier", func() string { - req := &BusiReq{Amount: 30} - gid := dtmgrpc.MustGenGid(DtmGrpcServer) - saga := dtmgrpc.NewSagaGrpc(DtmGrpcServer, gid). - Add(BusiGrpc+"/examples.Busi/TransOutBSaga", BusiGrpc+"/examples.Busi/TransOutRevertBSaga", req). - Add(BusiGrpc+"/examples.Busi/TransInBSaga", BusiGrpc+"/examples.Busi/TransInRevertBSaga", req) - err := saga.Submit() - logger.FatalIfError(err) - return saga.Gid - }) -} - -func sagaGrpcBarrierAdjustBalance(db dtmcli.DB, uid int, amount int64, result string) error { - if result == dtmcli.ResultFailure { - return status.New(codes.Aborted, dtmcli.ResultFailure).Err() - } - _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) - return err - -} - -func (s *busiServer) TransInBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { - barrier := MustBarrierFromGrpc(ctx) - return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcBarrierAdjustBalance(tx, 2, in.Amount, in.TransInResult) - }) -} - -func (s *busiServer) TransOutBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { - barrier := MustBarrierFromGrpc(ctx) - return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcBarrierAdjustBalance(tx, 1, -in.Amount, in.TransOutResult) - }) -} - -func (s *busiServer) TransInRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { - barrier := MustBarrierFromGrpc(ctx) - return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcBarrierAdjustBalance(tx, 2, -in.Amount, "") - }) -} - -func (s *busiServer) TransOutRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { - barrier := MustBarrierFromGrpc(ctx) - return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcBarrierAdjustBalance(tx, 1, in.Amount, "") - }) -} diff --git a/examples/grpc_tcc.go b/examples/grpc_tcc.go deleted file mode 100644 index 411a3e8..0000000 --- a/examples/grpc_tcc.go +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/dtmcli/logger" - dtmgrpc "github.com/dtm-labs/dtm/dtmgrpc" - emptypb "google.golang.org/protobuf/types/known/emptypb" -) - -func init() { - addSample("grpc_tcc", func() string { - logger.Debugf("tcc simple transaction begin") - gid := dtmgrpc.MustGenGid(DtmGrpcServer) - err := dtmgrpc.TccGlobalTransaction(DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { - data := &BusiReq{Amount: 30} - r := &emptypb.Empty{} - err := tcc.CallBranch(data, BusiGrpc+"/examples.Busi/TransOutTcc", BusiGrpc+"/examples.Busi/TransOutConfirm", BusiGrpc+"/examples.Busi/TransOutRevert", r) - if err != nil { - return err - } - err = tcc.CallBranch(data, BusiGrpc+"/examples.Busi/TransInTcc", BusiGrpc+"/examples.Busi/TransInConfirm", BusiGrpc+"/examples.Busi/TransInRevert", r) - return err - }) - logger.FatalIfError(err) - return gid - }) -} diff --git a/examples/grpc_xa.go b/examples/grpc_xa.go deleted file mode 100644 index c55e953..0000000 --- a/examples/grpc_xa.go +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - context "context" - - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/dtm-labs/dtm/dtmgrpc" - "google.golang.org/protobuf/types/known/emptypb" -) - -func init() { - addSample("grpc_xa", func() string { - gid := dtmgrpc.MustGenGid(DtmGrpcServer) - req := &BusiReq{Amount: 30} - err := XaGrpcClient.XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { - r := &emptypb.Empty{} - err := xa.CallBranch(req, BusiGrpc+"/examples.Busi/TransOutXa", r) - if err != nil { - return err - } - err = xa.CallBranch(req, BusiGrpc+"/examples.Busi/TransInXa", r) - return err - }) - logger.FatalIfError(err) - return gid - }) -} - -func (s *busiServer) XaNotify(ctx context.Context, in *emptypb.Empty) (*emptypb.Empty, error) { - return XaGrpcClient.HandleCallback(ctx) -} diff --git a/examples/http_gorm_xa.go b/examples/http_gorm_xa.go deleted file mode 100644 index b77e7dd..0000000 --- a/examples/http_gorm_xa.go +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/go-resty/resty/v2" -) - -func init() { - addSample("xa_gorm", func() string { - gid := dtmcli.MustGenGid(DtmHttpServer) - err := XaClient.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { - resp, err := xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOutXaGorm") - if err != nil { - return resp, err - } - return xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInXa") - }) - logger.FatalIfError(err) - return gid - }) - -} diff --git a/examples/http_msg.go b/examples/http_msg.go deleted file mode 100644 index 34bbc82..0000000 --- a/examples/http_msg.go +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" -) - -func init() { - addSample("msg", func() string { - logger.Debugf("a busi transaction begin") - req := &TransReq{Amount: 30} - msg := dtmcli.NewMsg(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). - Add(Busi+"/TransOut", req). - Add(Busi+"/TransIn", req) - err := msg.Prepare(Busi + "/query") - logger.FatalIfError(err) - logger.Debugf("busi trans submit") - err = msg.Submit() - logger.FatalIfError(err) - return msg.Gid - }) -} diff --git a/examples/http_saga.go b/examples/http_saga.go deleted file mode 100644 index 398f045..0000000 --- a/examples/http_saga.go +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" -) - -func init() { - addSample("saga", func() string { - logger.Debugf("a saga busi transaction begin") - req := &TransReq{Amount: 30} - saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). - Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). - Add(Busi+"/TransIn", Busi+"/TransInRevert", req) - logger.Debugf("saga busi trans submit") - err := saga.Submit() - logger.Debugf("result gid is: %s", saga.Gid) - logger.FatalIfError(err) - return saga.Gid - }) - addSample("saga_wait", func() string { - logger.Debugf("a saga busi transaction begin") - req := &TransReq{Amount: 30} - saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). - Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). - Add(Busi+"/TransIn", Busi+"/TransInRevert", req) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) - err := saga.Submit() - logger.Debugf("result gid is: %s", saga.Gid) - logger.FatalIfError(err) - return saga.Gid - }) - addSample("concurrent_saga", func() string { - logger.Debugf("a concurrent saga busi transaction begin") - req := &TransReq{Amount: 30} - csaga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). - Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). - Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). - Add(Busi+"/TransIn", Busi+"/TransInRevert", req). - Add(Busi+"/TransIn", Busi+"/TransInRevert", req). - EnableConcurrent(). - AddBranchOrder(2, []int{0, 1}). - AddBranchOrder(3, []int{0, 1}) - logger.Debugf("concurrent saga busi trans submit") - err := csaga.Submit() - logger.Debugf("result gid is: %s", csaga.Gid) - logger.FatalIfError(err) - return csaga.Gid - }) -} diff --git a/examples/http_saga_barrier.go b/examples/http_saga_barrier.go deleted file mode 100644 index 53af51d..0000000 --- a/examples/http_saga_barrier.go +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "database/sql" - - "github.com/dtm-labs/dtm/common" - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/gin-gonic/gin" -) - -func init() { - setupFuncs["SagaBarrierSetup"] = func(app *gin.Engine) { - app.POST(BusiAPI+"/SagaBTransIn", common.WrapHandler(sagaBarrierTransIn)) - app.POST(BusiAPI+"/SagaBTransInCompensate", common.WrapHandler(sagaBarrierTransInCompensate)) - app.POST(BusiAPI+"/SagaBTransOut", common.WrapHandler(sagaBarrierTransOut)) - app.POST(BusiAPI+"/SagaBTransOutCompensate", common.WrapHandler(sagaBarrierTransOutCompensate)) - } - addSample("saga_barrier", func() string { - logger.Debugf("a busi transaction begin") - req := &TransReq{Amount: 30} - saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). - Add(Busi+"/SagaBTransOut", Busi+"/SagaBTransOutCompensate", req). - Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) - logger.Debugf("busi trans submit") - err := saga.Submit() - logger.FatalIfError(err) - return saga.Gid - }) -} - -func sagaBarrierAdjustBalance(db dtmcli.DB, uid int, amount int) error { - _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) - return err - -} - -func sagaBarrierTransIn(c *gin.Context) (interface{}, error) { - req := reqFrom(c) - if req.TransInResult != "" { - return req.TransInResult, nil - } - barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaBarrierAdjustBalance(tx, 1, req.Amount) - }) -} - -func sagaBarrierTransInCompensate(c *gin.Context) (interface{}, error) { - barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaBarrierAdjustBalance(tx, 1, -reqFrom(c).Amount) - }) -} - -func sagaBarrierTransOut(c *gin.Context) (interface{}, error) { - req := reqFrom(c) - if req.TransOutResult != "" { - return req.TransOutResult, nil - } - barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaBarrierAdjustBalance(tx, 2, -req.Amount) - }) -} - -func sagaBarrierTransOutCompensate(c *gin.Context) (interface{}, error) { - barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaBarrierAdjustBalance(tx, 2, reqFrom(c).Amount) - }) -} diff --git a/examples/http_saga_gorm_barrier.go b/examples/http_saga_gorm_barrier.go deleted file mode 100644 index 0eda05e..0000000 --- a/examples/http_saga_gorm_barrier.go +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "database/sql" - - "github.com/dtm-labs/dtm/common" - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/gin-gonic/gin" -) - -func init() { - setupFuncs["SagaGormBarrierSetup"] = func(app *gin.Engine) { - app.POST(BusiAPI+"/SagaBTransOutGorm", common.WrapHandler(sagaGormBarrierTransOut)) - } - addSample("saga_gorm_barrier", func() string { - logger.Debugf("a busi transaction begin") - req := &TransReq{Amount: 30} - saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). - Add(Busi+"/SagaBTransOutGorm", Busi+"/SagaBTransOutCompensate", req). - Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) - logger.Debugf("busi trans submit") - err := saga.Submit() - logger.FatalIfError(err) - return saga.Gid - }) - -} - -func sagaGormBarrierTransOut(c *gin.Context) (interface{}, error) { - req := reqFrom(c) - barrier := MustBarrierFromGin(c) - tx := dbGet().DB.Begin() - return dtmcli.MapSuccess, barrier.Call(tx.Statement.ConnPool.(*sql.Tx), func(tx1 *sql.Tx) error { - return tx.Exec("update dtm_busi.user_account set balance = balance + ? where user_id = ?", -req.Amount, 2).Error - }) -} diff --git a/examples/http_tcc.go b/examples/http_tcc.go deleted file mode 100644 index 3055d44..0000000 --- a/examples/http_tcc.go +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/common" - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/gin-gonic/gin" - "github.com/go-resty/resty/v2" -) - -func init() { - setupFuncs["TccSetupSetup"] = func(app *gin.Engine) { - app.POST(BusiAPI+"/TransInTccParent", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - tcc, err := dtmcli.TccFromQuery(c.Request.URL.Query()) - logger.FatalIfError(err) - logger.Debugf("TransInTccParent ") - return tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") - })) - } - addSample("tcc_nested", func() string { - gid := dtmcli.MustGenGid(DtmHttpServer) - err := dtmcli.TccGlobalTransaction(DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { - resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") - if err != nil { - return resp, err - } - return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInTccParent", Busi+"/TransInConfirm", Busi+"/TransInRevert") - }) - logger.FatalIfError(err) - return gid - }) - addSample("tcc", func() string { - logger.Debugf("tcc simple transaction begin") - gid := dtmcli.MustGenGid(DtmHttpServer) - err := dtmcli.TccGlobalTransaction(DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { - resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") - if err != nil { - return resp, err - } - return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") - }) - logger.FatalIfError(err) - return gid - }) -} diff --git a/examples/http_tcc_barrier.go b/examples/http_tcc_barrier.go deleted file mode 100644 index 70b018a..0000000 --- a/examples/http_tcc_barrier.go +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "database/sql" - "fmt" - - "github.com/dtm-labs/dtm/common" - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/gin-gonic/gin" - "github.com/go-resty/resty/v2" -) - -func init() { - setupFuncs["TccBarrierSetup"] = func(app *gin.Engine) { - app.POST(BusiAPI+"/TccBTransInTry", common.WrapHandler(tccBarrierTransInTry)) - app.POST(BusiAPI+"/TccBTransInConfirm", common.WrapHandler(tccBarrierTransInConfirm)) - app.POST(BusiAPI+"/TccBTransInCancel", common.WrapHandler(tccBarrierTransInCancel)) - app.POST(BusiAPI+"/TccBTransOutTry", common.WrapHandler(tccBarrierTransOutTry)) - app.POST(BusiAPI+"/TccBTransOutConfirm", common.WrapHandler(tccBarrierTransOutConfirm)) - app.POST(BusiAPI+"/TccBTransOutCancel", common.WrapHandler(TccBarrierTransOutCancel)) - } - addSample("tcc_barrier", func() string { - logger.Debugf("tcc transaction begin") - gid := dtmcli.MustGenGid(DtmHttpServer) - err := dtmcli.TccGlobalTransaction(DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { - resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransOutTry", - Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel") - if err != nil { - return resp, err - } - return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel") - }) - logger.FatalIfError(err) - return gid - }) -} - -const transInUID = 1 -const transOutUID = 2 - -func adjustTrading(db dtmcli.DB, uid int, amount int) error { - affected, err := dtmimp.DBExec(db, `update dtm_busi.user_account set trading_balance=trading_balance+? - where user_id=? and trading_balance + ? + balance >= 0`, amount, uid, amount) - if err == nil && affected == 0 { - return fmt.Errorf("update error, maybe balance not enough") - } - return err -} - -func adjustBalance(db dtmcli.DB, uid int, amount int) error { - affected, err := dtmimp.DBExec(db, `update dtm_busi.user_account set trading_balance=trading_balance-?, - balance=balance+? where user_id=?`, amount, amount, uid) - if err == nil && affected == 0 { - return fmt.Errorf("update user_account 0 rows") - } - return err -} - -// TCC下,转入 -func tccBarrierTransInTry(c *gin.Context) (interface{}, error) { - req := reqFrom(c) // 去重构一下,改成可以重复使用的输入 - if req.TransInResult != "" { - return req.TransInResult, nil - } - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return adjustTrading(tx, transInUID, req.Amount) - }) -} - -func tccBarrierTransInConfirm(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return adjustBalance(tx, transInUID, reqFrom(c).Amount) - }) -} - -func tccBarrierTransInCancel(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return adjustTrading(tx, transInUID, -reqFrom(c).Amount) - }) -} - -func tccBarrierTransOutTry(c *gin.Context) (interface{}, error) { - req := reqFrom(c) - if req.TransOutResult != "" { - return req.TransOutResult, nil - } - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return adjustTrading(tx, transOutUID, -req.Amount) - }) -} - -func tccBarrierTransOutConfirm(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return adjustBalance(tx, transOutUID, -reqFrom(c).Amount) - }) -} - -// TccBarrierTransOutCancel will be use in test -func TccBarrierTransOutCancel(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return adjustTrading(tx, transOutUID, reqFrom(c).Amount) - }) -} diff --git a/examples/http_xa.go b/examples/http_xa.go deleted file mode 100644 index 6ba6f2d..0000000 --- a/examples/http_xa.go +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package examples - -import ( - "github.com/dtm-labs/dtm/common" - "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/gin-gonic/gin" - "github.com/go-resty/resty/v2" -) - -// XaClient XA client connection -var XaClient *dtmcli.XaClient = nil - -func init() { - setupFuncs["XaSetup"] = func(app *gin.Engine) { - var err error - XaClient, err = dtmcli.NewXaClient(DtmHttpServer, config.ExamplesDB, Busi+"/xa", func(path string, xa *dtmcli.XaClient) { - app.POST(path, common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return xa.HandleCallback(c.Query("gid"), c.Query("branch_id"), c.Query("op")) - })) - }) - logger.FatalIfError(err) - } - addSample("xa", func() string { - gid := dtmcli.MustGenGid(DtmHttpServer) - err := XaClient.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { - resp, err := xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOutXa") - if err != nil { - return resp, err - } - return xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInXa") - }) - logger.FatalIfError(err) - return gid - }) -} diff --git a/go.mod b/go.mod index 778bc7a..9c897a0 100644 --- a/go.mod +++ b/go.mod @@ -32,6 +32,7 @@ require ( gorm.io/driver/mysql v1.0.3 gorm.io/driver/postgres v1.2.1 gorm.io/gorm v1.22.2 + honnef.co/go/tools v0.0.1-2020.1.3 // gotest.tools v2.2.0+incompatible ) diff --git a/go.sum b/go.sum index 2c9c5a0..09eb829 100644 --- a/go.sum +++ b/go.sum @@ -877,6 +877,7 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.20.12 h1:LfRpmRkJLwPP8eaYehsVVmIIfg1yCBIIUHaSsdqCgHA= k8s.io/api v0.20.12/go.mod h1:A2brwyEkVLM3wQGNnzoAa5JsQRzHK0uoOQ+bsnv7V68= diff --git a/helper/test-cover.sh b/helper/test-cover.sh index c462626..ca14aa6 100644 --- a/helper/test-cover.sh +++ b/helper/test-cover.sh @@ -2,7 +2,7 @@ set -x echo "" > coverage.txt for store in redis mysql boltdb; do for d in $(go list ./... | grep -v vendor); do - TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/dtm-labs/dtm/common,github.com/dtm-labs/dtm/dtmcli,github.com/dtm-labs/dtm/dtmcli/dtmimp,github.com/dtm-labs/dtm/dtmgrpc,github.com/dtm-labs/dtm/dtmgrpc/dtmgimp,github.com/dtm-labs/dtm/dtmsvr,github.com/dtm-labs/dtm/dtmsvr/storage,github.com/dtm-labs/dtm/dtmsvr/storage/boltdb,github.com/dtm-labs/dtm/dtmsvr/storage/redis,github.com/dtm-labs/dtm/dtmsvr/storage/registry,github.com/dtm-labs/dtm/dtmsvr/storage/sql,github.com/dtm-labs/dtm/dtmsvr/storage/boltdb,github.com/dtm-labs/dtm/dtmsvr/storage/registry -gcflags=-l $d + TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/dtm-labs/dtm/dtmcli,github.com/dtm-labs/dtm/dtmcli/dtmimp,github.com/dtm-labs/dtm/dtmcli/logger,github.com/dtm-labs/dtm/dtmgrpc,github.com/dtm-labs/dtm/dtmgrpc/dtmgimp,github.com/dtm-labs/dtm/dtmsvr,github.com/dtm-labs/dtm/dtmsvr/config,github.com/dtm-labs/dtm/dtmsvr/storage,github.com/dtm-labs/dtm/dtmsvr/storage/boltdb,github.com/dtm-labs/dtm/dtmsvr/storage/redis,github.com/dtm-labs/dtm/dtmsvr/storage/registry,github.com/dtm-labs/dtm/dtmsvr/storage/sql,github.com/dtm-labs/dtm/dtmutil -gcflags=-l $d if [ -f profile.out ]; then cat profile.out >> coverage.txt echo > profile.out diff --git a/main.go b/main.go new file mode 100644 index 0000000..4308f4a --- /dev/null +++ b/main.go @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +package main + +import ( + "flag" + "fmt" + "os" + "path/filepath" + + "go.uber.org/automaxprocs/maxprocs" + + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/dtmsvr/config" + "github.com/dtm-labs/dtm/dtmsvr/storage/registry" + + // load the microserver driver + _ "github.com/dtm-labs/dtmdriver-gozero" + _ "github.com/dtm-labs/dtmdriver-polaris" + _ "github.com/dtm-labs/dtmdriver-protocol1" +) + +var Version, Commit, Date string + +func version() { + if Version == "" { + Version = "0.0.0-dev" + Commit = "NA" + Date = "NA" + } + if len(Commit) > 8 { + Commit = Commit[:8] + } + fmt.Printf("version: %s commit: %s built at: %s\n", Version, Commit, Date) +} + +func usage() { + cmd := filepath.Base(os.Args[0]) + s := "Usage: %s [options]\n\n" + fmt.Fprintf(os.Stderr, s, cmd) + flag.PrintDefaults() +} + +var isVersion = flag.Bool("v", false, "Show the version of dtm.") +var isDebug = flag.Bool("d", false, "Set log level to debug.") +var isHelp = flag.Bool("h", false, "Show the help information about etcd.") +var confFile = flag.String("c", "", "Path to the server configuration file.") + +func main() { + flag.Parse() + if flag.NArg() > 0 || *isHelp { + usage() + return + } else if *isVersion { + version() + return + } + config.MustLoadConfig(*confFile) + if *isDebug { + config.Config.LogLevel = "debug" + } + maxprocs.Set(maxprocs.Logger(logger.Infof)) + registry.WaitStoreUp() + dtmsvr.StartSvr() // 启动dtmsvr的api服务 + go dtmsvr.CronExpiredTrans(-1) // 启动dtmsvr的定时过期查询 + select {} +} diff --git a/qs/main.go b/qs/main.go new file mode 100644 index 0000000..f31d83a --- /dev/null +++ b/qs/main.go @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +package main + +import ( + "time" + + "github.com/dtm-labs/dtm/test/busi" +) + +func main() { + busi.QsStartSvr() + busi.QsFireRequest() + time.Sleep(1 * time.Second) +} diff --git a/sqls/examples.mysql.sql b/sqls/busi.mysql.sql similarity index 100% rename from sqls/examples.mysql.sql rename to sqls/busi.mysql.sql diff --git a/sqls/examples.postgres.sql b/sqls/busi.postgres.sql similarity index 100% rename from sqls/examples.postgres.sql rename to sqls/busi.postgres.sql diff --git a/test/api_test.go b/test/api_test.go index 5997a58..92d3058 100644 --- a/test/api_test.go +++ b/test/api_test.go @@ -11,7 +11,7 @@ import ( "testing" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" "github.com/stretchr/testify/assert" ) @@ -20,7 +20,7 @@ func TestAPIQuery(t *testing.T) { err := genMsg(gid).Submit() assert.Nil(t, err) waitTransProcessed(gid) - resp, err := dtmimp.RestyClient.R().SetQueryParam("gid", gid).Get(examples.DtmHttpServer + "/query") + resp, err := dtmimp.RestyClient.R().SetQueryParam("gid", gid).Get(dtmutil.DefaultHttpServer + "/query") assert.Nil(t, err) m := map[string]interface{}{} assert.Equal(t, resp.StatusCode(), 200) @@ -28,11 +28,11 @@ func TestAPIQuery(t *testing.T) { assert.NotEqual(t, nil, m["transaction"]) assert.Equal(t, 2, len(m["branches"].([]interface{}))) - resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "").Get(examples.DtmHttpServer + "/query") + resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "").Get(dtmutil.DefaultHttpServer + "/query") e2p(err) assert.Equal(t, resp.StatusCode(), 500) - resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "1").Get(examples.DtmHttpServer + "/query") + resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "1").Get(dtmutil.DefaultHttpServer + "/query") e2p(err) assert.Equal(t, resp.StatusCode(), 200) dtmimp.MustUnmarshalString(resp.String(), &m) @@ -47,7 +47,7 @@ func TestAPIAll(t *testing.T) { assert.Nil(t, err) waitTransProcessed(gid) } - resp, err := dtmimp.RestyClient.R().SetQueryParam("limit", "1").Get(examples.DtmHttpServer + "/all") + resp, err := dtmimp.RestyClient.R().SetQueryParam("limit", "1").Get(dtmutil.DefaultHttpServer + "/all") assert.Nil(t, err) m := map[string]interface{}{} dtmimp.MustUnmarshalString(resp.String(), &m) @@ -57,7 +57,7 @@ func TestAPIAll(t *testing.T) { resp, err = dtmimp.RestyClient.R().SetQueryParams(map[string]string{ "limit": "1", "position": nextPos, - }).Get(examples.DtmHttpServer + "/all") + }).Get(dtmutil.DefaultHttpServer + "/all") assert.Nil(t, err) dtmimp.MustUnmarshalString(resp.String(), &m) nextPos2 := m["next_position"].(string) @@ -67,7 +67,7 @@ func TestAPIAll(t *testing.T) { resp, err = dtmimp.RestyClient.R().SetQueryParams(map[string]string{ "limit": "1000", "position": nextPos, - }).Get(examples.DtmHttpServer + "/all") + }).Get(dtmutil.DefaultHttpServer + "/all") assert.Nil(t, err) dtmimp.MustUnmarshalString(resp.String(), &m) nextPos3 := m["next_position"].(string) diff --git a/test/base_test.go b/test/base_test.go index 3748802..b33bfd8 100644 --- a/test/base_test.go +++ b/test/base_test.go @@ -11,17 +11,17 @@ import ( "fmt" "testing" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) // BarrierModel barrier model for gorm type BarrierModel struct { - common.ModelBase + dtmutil.ModelBase dtmcli.BranchBarrier } @@ -30,7 +30,7 @@ func (BarrierModel) TableName() string { return "dtm_barrier.barrier" } func TestBaseSqlDB(t *testing.T) { asserts := assert.New(t) - db := common.DbGet(config.ExamplesDB) + db := dtmutil.DbGet(busi.BusiConf) barrier := &dtmcli.BranchBarrier{ TransType: "saga", Gid: "gid2", @@ -60,10 +60,10 @@ func TestBaseSqlDB(t *testing.T) { } func TestBaseHttp(t *testing.T) { - resp, err := dtmimp.RestyClient.R().SetQueryParam("panic_string", "1").Post(examples.Busi + "/TestPanic") + resp, err := dtmimp.RestyClient.R().SetQueryParam("panic_string", "1").Post(busi.Busi + "/TestPanic") assert.Nil(t, err) assert.Contains(t, resp.String(), "panic_string") - resp, err = dtmimp.RestyClient.R().SetQueryParam("panic_error", "1").Post(examples.Busi + "/TestPanic") + resp, err = dtmimp.RestyClient.R().SetQueryParam("panic_error", "1").Post(busi.Busi + "/TestPanic") assert.Nil(t, err) assert.Contains(t, resp.String(), "panic_error") } diff --git a/test/busi/barrier.go b/test/busi/barrier.go new file mode 100644 index 0000000..df30145 --- /dev/null +++ b/test/busi/barrier.go @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +package busi + +import ( + "context" + "database/sql" + + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/gin-gonic/gin" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +func init() { + setupFuncs["TccBarrierSetup"] = func(app *gin.Engine) { + app.POST(BusiAPI+"/SagaBTransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + barrier := MustBarrierFromGin(c) + return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaAdjustBalance(tx, transInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) + }) + })) + app.POST(BusiAPI+"/SagaBTransInCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + barrier := MustBarrierFromGin(c) + return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaAdjustBalance(tx, transInUID, -reqFrom(c).Amount, "") + }) + })) + app.POST(BusiAPI+"/SagaBTransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + barrier := MustBarrierFromGin(c) + return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaAdjustBalance(tx, transOutUID, -reqFrom(c).Amount, reqFrom(c).TransOutResult) + }) + })) + app.POST(BusiAPI+"/SagaBTransOutCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + barrier := MustBarrierFromGin(c) + return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaAdjustBalance(tx, transOutUID, reqFrom(c).Amount, "") + }) + })) + app.POST(BusiAPI+"/SagaBTransOutGorm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + req := reqFrom(c) + barrier := MustBarrierFromGin(c) + tx := dbGet().DB.Begin() + return dtmcli.MapSuccess, barrier.Call(tx.Statement.ConnPool.(*sql.Tx), func(tx1 *sql.Tx) error { + return tx.Exec("update dtm_busi.user_account set balance = balance + ? where user_id = ?", -req.Amount, transOutUID).Error + }) + })) + + app.POST(BusiAPI+"/TccBTransInTry", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + req := reqFrom(c) // 去重构一下,改成可以重复使用的输入 + if req.TransInResult != "" { + return req.TransInResult, nil + } + return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return tccAdjustTrading(tx, transInUID, req.Amount) + }) + })) + app.POST(BusiAPI+"/TccBTransInConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return tccAdjustBalance(tx, transInUID, reqFrom(c).Amount) + }) + })) + app.POST(BusiAPI+"/TccBTransInCancel", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return tccAdjustTrading(tx, transInUID, -reqFrom(c).Amount) + }) + })) + app.POST(BusiAPI+"/TccBTransOutTry", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + req := reqFrom(c) + if req.TransOutResult != "" { + return req.TransOutResult, nil + } + return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return tccAdjustTrading(tx, transOutUID, -req.Amount) + }) + })) + app.POST(BusiAPI+"/TccBTransOutConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return tccAdjustBalance(tx, transOutUID, -reqFrom(c).Amount) + }) + })) + app.POST(BusiAPI+"/TccBTransOutCancel", dtmutil.WrapHandler(TccBarrierTransOutCancel)) + } +} + +// TccBarrierTransOutCancel will be use in test +func TccBarrierTransOutCancel(c *gin.Context) (interface{}, error) { + return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return tccAdjustTrading(tx, transOutUID, reqFrom(c).Amount) + }) +} + +func (s *busiServer) TransInBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaGrpcAdjustBalance(tx, transInUID, in.Amount, in.TransInResult) + }) +} + +func (s *busiServer) TransOutBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaGrpcAdjustBalance(tx, transOutUID, -in.Amount, in.TransOutResult) + }) +} + +func (s *busiServer) TransInRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaGrpcAdjustBalance(tx, transInUID, -in.Amount, "") + }) +} + +func (s *busiServer) TransOutRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { + return sagaGrpcAdjustBalance(tx, transOutUID, in.Amount, "") + }) +} diff --git a/examples/base_grpc.go b/test/busi/base_grpc.go similarity index 71% rename from examples/base_grpc.go rename to test/busi/base_grpc.go index 38cda95..dcfca4e 100644 --- a/examples/base_grpc.go +++ b/test/busi/base_grpc.go @@ -4,26 +4,23 @@ * license that can be found in the LICENSE file. */ -package examples +package busi import ( "context" "database/sql" "fmt" "net" - "time" - "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmutil" "github.com/gin-gonic/gin" "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - status "google.golang.org/grpc/status" emptypb "google.golang.org/protobuf/types/known/emptypb" ) @@ -38,13 +35,13 @@ var XaGrpcClient *dtmgrpc.XaGrpcClient = nil func init() { setupFuncs["XaGrpcSetup"] = func(app *gin.Engine) { - XaGrpcClient = dtmgrpc.NewXaGrpcClient(DtmGrpcServer, config.ExamplesDB, BusiGrpc+"/examples.Busi/XaNotify") + XaGrpcClient = dtmgrpc.NewXaGrpcClient(dtmutil.DefaultGrpcServer, BusiConf, BusiGrpc+"/busi.Busi/XaNotify") } } // GrpcStartup for grpc func GrpcStartup() { - conn, err := grpc.Dial(DtmGrpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(dtmgimp.GrpcClientLog)) + conn, err := grpc.Dial(dtmutil.DefaultGrpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(dtmgimp.GrpcClientLog)) logger.FatalIfError(err) DtmClient = dtmgpb.NewDtmClient(conn) logger.Debugf("dtm client inited") @@ -58,23 +55,9 @@ func GrpcStartup() { err := s.Serve(lis) logger.FatalIfError(err) }() - time.Sleep(100 * time.Millisecond) -} - -func handleGrpcBusiness(in *BusiReq, result1 string, result2 string, busi string) error { - res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) - logger.Debugf("grpc busi %s %v %s %s result: %s", busi, in, result1, result2, res) - if res == dtmcli.ResultSuccess { - return nil - } else if res == dtmcli.ResultFailure { - return status.New(codes.Aborted, dtmcli.ResultFailure).Err() - } else if res == dtmcli.ResultOngoing { - return status.New(codes.Aborted, dtmcli.ResultOngoing).Err() - } - return status.New(codes.Internal, fmt.Sprintf("unknow result %s", res)).Err() } -// busiServer is used to implement examples.BusiServer. +// busiServer is used to implement busi.BusiServer. type busiServer struct { UnimplementedBusiServer } @@ -118,21 +101,13 @@ func (s *busiServer) TransOutTcc(ctx context.Context, in *BusiReq) (*emptypb.Emp func (s *busiServer) TransInXa(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { return &emptypb.Empty{}, XaGrpcClient.XaLocalTransaction(ctx, in, func(db *sql.DB, xa *dtmgrpc.XaGrpc) error { - if in.TransInResult == dtmcli.ResultFailure { - return status.New(codes.Aborted, dtmcli.ResultFailure).Err() - } - _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance+? where user_id=?", in.Amount, 2) - return err + return sagaGrpcAdjustBalance(db, transInUID, in.Amount, in.TransInResult) }) } func (s *busiServer) TransOutXa(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { return &emptypb.Empty{}, XaGrpcClient.XaLocalTransaction(ctx, in, func(db *sql.DB, xa *dtmgrpc.XaGrpc) error { - if in.TransOutResult == dtmcli.ResultFailure { - return status.New(codes.Aborted, dtmcli.ResultFailure).Err() - } - _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance-? where user_id=?", in.Amount, 1) - return err + return sagaGrpcAdjustBalance(db, transOutUID, in.Amount, in.TransOutResult) }) } @@ -140,7 +115,11 @@ func (s *busiServer) TransInTccNested(ctx context.Context, in *BusiReq) (*emptyp tcc, err := dtmgrpc.TccFromGrpc(ctx) logger.FatalIfError(err) r := &emptypb.Empty{} - err = tcc.CallBranch(in, BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInConfirm", BusiGrpc+"/examples.Busi/TransInRevert", r) + err = tcc.CallBranch(in, BusiGrpc+"/busi.Busi/TransIn", BusiGrpc+"/busi.Busi/TransInConfirm", BusiGrpc+"/busi.Busi/TransInRevert", r) logger.FatalIfError(err) return r, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), in.TransInResult, dtmimp.GetFuncName()) } + +func (s *busiServer) XaNotify(ctx context.Context, in *emptypb.Empty) (*emptypb.Empty, error) { + return XaGrpcClient.HandleCallback(ctx) +} diff --git a/examples/base_http.go b/test/busi/base_http.go similarity index 53% rename from examples/base_http.go rename to test/busi/base_http.go index cad5834..4518d0e 100644 --- a/examples/base_http.go +++ b/test/busi/base_http.go @@ -4,19 +4,17 @@ * license that can be found in the LICENSE file. */ -package examples +package busi import ( "database/sql" "errors" "fmt" - "strings" - "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmutil" "github.com/gin-gonic/gin" "gorm.io/driver/mysql" "gorm.io/driver/postgres" @@ -39,10 +37,20 @@ var setupFuncs = map[string]setupFunc{} // Busi busi service url prefix var Busi string = fmt.Sprintf("http://localhost:%d%s", BusiPort, BusiAPI) +var XaClient *dtmcli.XaClient = nil + +type SleepCancelHandler func(c *gin.Context) (interface{}, error) + +var sleepCancelHandler SleepCancelHandler = nil + +func SetSleepCancelHandler(handler SleepCancelHandler) { + sleepCancelHandler = handler +} + // BaseAppStartup base app startup func BaseAppStartup() *gin.Engine { - logger.Debugf("examples starting") - app := common.GetGinApp() + logger.Infof("examples starting") + app := dtmutil.GetGinApp() app.Use(func(c *gin.Context) { v := MainSwitch.NextResult.Fetch() if v != "" { @@ -52,6 +60,13 @@ func BaseAppStartup() *gin.Engine { } c.Next() }) + var err error + XaClient, err = dtmcli.NewXaClient(dtmutil.DefaultHttpServer, BusiConf, Busi+"/xa", func(path string, xa *dtmcli.XaClient) { + app.POST(path, dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + return xa.HandleCallback(c.Query("gid"), c.Query("branch_id"), c.Query("op")) + })) + }) + logger.FatalIfError(err) BaseAddRoute(app) for k, v := range setupFuncs { @@ -61,107 +76,53 @@ func BaseAppStartup() *gin.Engine { logger.Debugf("Starting busi at: %d", BusiPort) go app.Run(fmt.Sprintf(":%d", BusiPort)) - time.Sleep(100 * time.Millisecond) return app } -// AutoEmptyString auto reset to empty when used once -type AutoEmptyString struct { - value string -} - -// SetOnce set a value once -func (s *AutoEmptyString) SetOnce(v string) { - s.value = v -} - -// Fetch fetch the stored value, then reset the value to empty -func (s *AutoEmptyString) Fetch() string { - v := s.value - s.value = "" - return v -} - -type mainSwitchType struct { - TransInResult AutoEmptyString - TransOutResult AutoEmptyString - TransInConfirmResult AutoEmptyString - TransOutConfirmResult AutoEmptyString - TransInRevertResult AutoEmptyString - TransOutRevertResult AutoEmptyString - CanSubmitResult AutoEmptyString - NextResult AutoEmptyString -} - -// MainSwitch controls busi success or fail -var MainSwitch mainSwitchType - -func handleGeneralBusiness(c *gin.Context, result1 string, result2 string, busi string) (interface{}, error) { - info := infoFromContext(c) - res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) - logger.Debugf("%s %s result: %s", busi, info.String(), res) - if res == "ERROR" { - return nil, errors.New("ERROR from user") - } - return map[string]interface{}{"dtm_result": res}, nil -} - -func error2Resp(err error) (interface{}, error) { - if err != nil { - s := err.Error() - if strings.Contains(s, dtmcli.ResultFailure) || strings.Contains(s, dtmcli.ResultOngoing) { - return gin.H{"dtm_result": s}, nil - } - } - return nil, err -} - // BaseAddRoute add base route handler func BaseAddRoute(app *gin.Engine) { - app.POST(BusiAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusiness(c, MainSwitch.TransInResult.Fetch(), reqFrom(c).TransInResult, "transIn") })) - app.POST(BusiAPI+"/TransOut", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusiness(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") })) - app.POST(BusiAPI+"/TransInConfirm", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusiness(c, MainSwitch.TransInConfirmResult.Fetch(), "", "TransInConfirm") })) - app.POST(BusiAPI+"/TransOutConfirm", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusiness(c, MainSwitch.TransOutConfirmResult.Fetch(), "", "TransOutConfirm") })) - app.POST(BusiAPI+"/TransInRevert", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInRevert", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusiness(c, MainSwitch.TransInRevertResult.Fetch(), "", "TransInRevert") })) - app.POST(BusiAPI+"/TransOutRevert", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutRevert", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusiness(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) - app.GET(BusiAPI+"/CanSubmit", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.GET(BusiAPI+"/CanSubmit", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { logger.Debugf("%s CanSubmit", c.Query("gid")) return dtmimp.OrString(MainSwitch.CanSubmitResult.Fetch(), dtmcli.ResultSuccess), nil })) - app.POST(BusiAPI+"/TransInXa", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInXa", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { - if reqFrom(c).TransInResult == dtmcli.ResultFailure { - return dtmcli.ErrFailure - } - _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance+? where user_id=?", reqFrom(c).Amount, 2) - return err + return sagaAdjustBalance(db, transInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) return error2Resp(err) })) - app.POST(BusiAPI+"/TransOutXa", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutXa", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { - if reqFrom(c).TransOutResult == dtmcli.ResultFailure { - return dtmcli.ErrFailure - } - _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, 1) - return err + return sagaAdjustBalance(db, transOutUID, reqFrom(c).Amount, reqFrom(c).TransOutResult) }) return error2Resp(err) })) - app.POST(BusiAPI+"/TransOutXaGorm", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInTccParent", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + tcc, err := dtmcli.TccFromQuery(c.Request.URL.Query()) + logger.FatalIfError(err) + logger.Debugf("TransInTccParent ") + return tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") + })) + app.POST(BusiAPI+"/TransOutXaGorm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { if reqFrom(c).TransOutResult == dtmcli.ResultFailure { return dtmcli.ErrFailure @@ -176,13 +137,13 @@ func BaseAddRoute(app *gin.Engine) { if err != nil { return err } - dbr := gdb.Exec("update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, 1) + dbr := gdb.Exec("update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, transOutUID) return dbr.Error }) return error2Resp(err) })) - app.POST(BusiAPI+"/TestPanic", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TestPanic", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { if c.Query("panic_error") != "" { panic(errors.New("panic_error")) } else if c.Query("panic_string") != "" { @@ -190,4 +151,7 @@ func BaseAddRoute(app *gin.Engine) { } return "SUCCESS", nil })) + app.POST(BusiAPI+"/TccBSleepCancel", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + return sleepCancelHandler(c) + })) } diff --git a/examples/base_types.go b/test/busi/base_types.go similarity index 52% rename from examples/base_types.go rename to test/busi/base_types.go index f7a4392..471bbe3 100644 --- a/examples/base_types.go +++ b/test/busi/base_types.go @@ -4,32 +4,50 @@ * license that can be found in the LICENSE file. */ -package examples +package busi import ( - "context" - "database/sql" "fmt" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/dtm-labs/dtm/dtmgrpc" "github.com/gin-gonic/gin" ) -// DtmHttpServer dtm service address -var DtmHttpServer = fmt.Sprintf("http://localhost:%d/api/dtmsvr", 36789) +var BusiConf = dtmcli.DBConf{ + Driver: "mysql", + Host: "localhost", + Port: 3306, + User: "root", +} -// DtmGrpcServer dtm grpc service address -var DtmGrpcServer = fmt.Sprintf("localhost:%d", 36790) +type UserAccount struct { + UserId int + Balance string + TradingBalance string +} + +func (*UserAccount) TableName() string { + return "dtm_busi.user_account" +} + +func GetUserAccountByUid(uid int) *UserAccount { + ua := UserAccount{} + dbr := dbGet().Must().Model(&ua).Where("user_id=?", uid).First(&ua) + dtmimp.E2P(dbr.Error) + return &ua +} + +func IsEqual(ua1, ua2 *UserAccount) bool { + return ua1.UserId == ua2.UserId && ua1.Balance == ua2.Balance && ua1.TradingBalance == ua2.TradingBalance +} // TransReq transaction request payload type TransReq struct { Amount int `json:"amount"` - TransInResult string `json:"transInResult"` - TransOutResult string `json:"transOutResult"` + TransInResult string `json:"trans_in_result"` + TransOutResult string `json:"trans_out_Result"` } func (t *TransReq) String() string { @@ -76,33 +94,33 @@ func infoFromContext(c *gin.Context) *dtmcli.BranchBarrier { return &info } -func dbGet() *common.DB { - return common.DbGet(config.ExamplesDB) +// AutoEmptyString auto reset to empty when used once +type AutoEmptyString struct { + value string } -func sdbGet() *sql.DB { - db, err := dtmimp.PooledDB(config.ExamplesDB) - logger.FatalIfError(err) - return db +// SetOnce set a value once +func (s *AutoEmptyString) SetOnce(v string) { + s.value = v } -func txGet() *sql.Tx { - db := sdbGet() - tx, err := db.Begin() - logger.FatalIfError(err) - return tx +// Fetch fetch the stored value, then reset the value to empty +func (s *AutoEmptyString) Fetch() string { + v := s.value + s.value = "" + return v } -// MustBarrierFromGin 1 -func MustBarrierFromGin(c *gin.Context) *dtmcli.BranchBarrier { - ti, err := dtmcli.BarrierFromQuery(c.Request.URL.Query()) - logger.FatalIfError(err) - return ti +type mainSwitchType struct { + TransInResult AutoEmptyString + TransOutResult AutoEmptyString + TransInConfirmResult AutoEmptyString + TransOutConfirmResult AutoEmptyString + TransInRevertResult AutoEmptyString + TransOutRevertResult AutoEmptyString + CanSubmitResult AutoEmptyString + NextResult AutoEmptyString } -// MustBarrierFromGrpc 1 -func MustBarrierFromGrpc(ctx context.Context) *dtmcli.BranchBarrier { - ti, err := dtmgrpc.BarrierFromGrpc(ctx) - logger.FatalIfError(err) - return ti -} +// MainSwitch controls busi success or fail +var MainSwitch mainSwitchType diff --git a/test/busi/busi.go b/test/busi/busi.go new file mode 100644 index 0000000..13eb7e8 --- /dev/null +++ b/test/busi/busi.go @@ -0,0 +1,85 @@ +package busi + +import ( + "errors" + "fmt" + "strings" + + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/gin-gonic/gin" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" +) + +const transOutUID = 1 +const transInUID = 2 + +func handleGrpcBusiness(in *BusiReq, result1 string, result2 string, busi string) error { + res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) + logger.Debugf("grpc busi %s %v %s %s result: %s", busi, in, result1, result2, res) + if res == dtmcli.ResultSuccess { + return nil + } else if res == dtmcli.ResultFailure { + return status.New(codes.Aborted, dtmcli.ResultFailure).Err() + } else if res == dtmcli.ResultOngoing { + return status.New(codes.Aborted, dtmcli.ResultOngoing).Err() + } + return status.New(codes.Internal, fmt.Sprintf("unknow result %s", res)).Err() +} + +func handleGeneralBusiness(c *gin.Context, result1 string, result2 string, busi string) (interface{}, error) { + info := infoFromContext(c) + res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) + logger.Debugf("%s %s result: %s", busi, info.String(), res) + if res == "ERROR" { + return nil, errors.New("ERROR from user") + } + return map[string]interface{}{"dtm_result": res}, nil +} + +func error2Resp(err error) (interface{}, error) { + if err != nil { + s := err.Error() + if strings.Contains(s, dtmcli.ResultFailure) || strings.Contains(s, dtmcli.ResultOngoing) { + return gin.H{"dtm_result": s}, nil + } + return nil, err + } + return gin.H{"dtm_result": dtmcli.ResultSuccess}, nil +} + +func sagaGrpcAdjustBalance(db dtmcli.DB, uid int, amount int64, result string) error { + if result == dtmcli.ResultFailure { + return status.New(codes.Aborted, dtmcli.ResultFailure).Err() + } + _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) + return err + +} + +func sagaAdjustBalance(db dtmcli.DB, uid int, amount int, result string) error { + if strings.Contains(result, dtmcli.ResultFailure) { + return dtmcli.ErrFailure + } + _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) + return err +} +func tccAdjustTrading(db dtmcli.DB, uid int, amount int) error { + affected, err := dtmimp.DBExec(db, `update dtm_busi.user_account set trading_balance=trading_balance+? + where user_id=? and trading_balance + ? + balance >= 0`, amount, uid, amount) + if err == nil && affected == 0 { + return fmt.Errorf("update error, maybe balance not enough") + } + return err +} + +func tccAdjustBalance(db dtmcli.DB, uid int, amount int) error { + affected, err := dtmimp.DBExec(db, `update dtm_busi.user_account set trading_balance=trading_balance-?, + balance=balance+? where user_id=?`, amount, amount, uid) + if err == nil && affected == 0 { + return fmt.Errorf("update user_account 0 rows") + } + return err +} diff --git a/test/busi/busi.pb.go b/test/busi/busi.pb.go new file mode 100644 index 0000000..fa73c00 --- /dev/null +++ b/test/busi/busi.pb.go @@ -0,0 +1,325 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.17.3 +// source: test/busi/busi.proto + +package busi + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// DtmRequest request sent to dtm server +type BusiReq struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Amount int64 `protobuf:"varint,1,opt,name=Amount,proto3" json:"Amount,omitempty"` + TransOutResult string `protobuf:"bytes,2,opt,name=TransOutResult,proto3" json:"TransOutResult,omitempty"` + TransInResult string `protobuf:"bytes,3,opt,name=TransInResult,proto3" json:"TransInResult,omitempty"` +} + +func (x *BusiReq) Reset() { + *x = BusiReq{} + if protoimpl.UnsafeEnabled { + mi := &file_test_busi_busi_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BusiReq) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BusiReq) ProtoMessage() {} + +func (x *BusiReq) ProtoReflect() protoreflect.Message { + mi := &file_test_busi_busi_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BusiReq.ProtoReflect.Descriptor instead. +func (*BusiReq) Descriptor() ([]byte, []int) { + return file_test_busi_busi_proto_rawDescGZIP(), []int{0} +} + +func (x *BusiReq) GetAmount() int64 { + if x != nil { + return x.Amount + } + return 0 +} + +func (x *BusiReq) GetTransOutResult() string { + if x != nil { + return x.TransOutResult + } + return "" +} + +func (x *BusiReq) GetTransInResult() string { + if x != nil { + return x.TransInResult + } + return "" +} + +type BusiReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` +} + +func (x *BusiReply) Reset() { + *x = BusiReply{} + if protoimpl.UnsafeEnabled { + mi := &file_test_busi_busi_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BusiReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BusiReply) ProtoMessage() {} + +func (x *BusiReply) ProtoReflect() protoreflect.Message { + mi := &file_test_busi_busi_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use BusiReply.ProtoReflect.Descriptor instead. +func (*BusiReply) Descriptor() ([]byte, []int) { + return file_test_busi_busi_proto_rawDescGZIP(), []int{1} +} + +func (x *BusiReply) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +var File_test_busi_busi_proto protoreflect.FileDescriptor + +var file_test_busi_busi_proto_rawDesc = []byte{ + 0x0a, 0x14, 0x74, 0x65, 0x73, 0x74, 0x2f, 0x62, 0x75, 0x73, 0x69, 0x2f, 0x62, 0x75, 0x73, 0x69, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x62, 0x75, 0x73, 0x69, 0x1a, 0x1b, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x6f, 0x0a, 0x07, 0x42, 0x75, 0x73, + 0x69, 0x52, 0x65, 0x71, 0x12, 0x16, 0x0a, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x06, 0x41, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x26, 0x0a, 0x0e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x25, 0x0a, 0x09, 0x42, 0x75, + 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x65, 0x32, 0xd3, 0x07, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x2d, 0x0a, 0x09, 0x43, 0x61, + 0x6e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, + 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, + 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x49, 0x6e, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, + 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x33, 0x0a, + 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, + 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x76, + 0x65, 0x72, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, + 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x0d, + 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x49, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, + 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, + 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, + 0x0a, 0x08, 0x58, 0x61, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x58, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, + 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x58, 0x61, + 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, + 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, + 0x12, 0x36, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x54, 0x63, 0x63, 0x12, + 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x0d, 0x2e, 0x62, + 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, + 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, + 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, + 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, + 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, + 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, + 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x62, 0x75, 0x73, + 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_test_busi_busi_proto_rawDescOnce sync.Once + file_test_busi_busi_proto_rawDescData = file_test_busi_busi_proto_rawDesc +) + +func file_test_busi_busi_proto_rawDescGZIP() []byte { + file_test_busi_busi_proto_rawDescOnce.Do(func() { + file_test_busi_busi_proto_rawDescData = protoimpl.X.CompressGZIP(file_test_busi_busi_proto_rawDescData) + }) + return file_test_busi_busi_proto_rawDescData +} + +var file_test_busi_busi_proto_msgTypes = make([]protoimpl.MessageInfo, 2) +var file_test_busi_busi_proto_goTypes = []interface{}{ + (*BusiReq)(nil), // 0: busi.BusiReq + (*BusiReply)(nil), // 1: busi.BusiReply + (*emptypb.Empty)(nil), // 2: google.protobuf.Empty +} +var file_test_busi_busi_proto_depIdxs = []int32{ + 0, // 0: busi.Busi.CanSubmit:input_type -> busi.BusiReq + 0, // 1: busi.Busi.TransIn:input_type -> busi.BusiReq + 0, // 2: busi.Busi.TransOut:input_type -> busi.BusiReq + 0, // 3: busi.Busi.TransInRevert:input_type -> busi.BusiReq + 0, // 4: busi.Busi.TransOutRevert:input_type -> busi.BusiReq + 0, // 5: busi.Busi.TransInConfirm:input_type -> busi.BusiReq + 0, // 6: busi.Busi.TransOutConfirm:input_type -> busi.BusiReq + 2, // 7: busi.Busi.XaNotify:input_type -> google.protobuf.Empty + 0, // 8: busi.Busi.TransInXa:input_type -> busi.BusiReq + 0, // 9: busi.Busi.TransOutXa:input_type -> busi.BusiReq + 0, // 10: busi.Busi.TransInTcc:input_type -> busi.BusiReq + 0, // 11: busi.Busi.TransOutTcc:input_type -> busi.BusiReq + 0, // 12: busi.Busi.TransInTccNested:input_type -> busi.BusiReq + 0, // 13: busi.Busi.TransInBSaga:input_type -> busi.BusiReq + 0, // 14: busi.Busi.TransOutBSaga:input_type -> busi.BusiReq + 0, // 15: busi.Busi.TransInRevertBSaga:input_type -> busi.BusiReq + 0, // 16: busi.Busi.TransOutRevertBSaga:input_type -> busi.BusiReq + 1, // 17: busi.Busi.CanSubmit:output_type -> busi.BusiReply + 2, // 18: busi.Busi.TransIn:output_type -> google.protobuf.Empty + 2, // 19: busi.Busi.TransOut:output_type -> google.protobuf.Empty + 2, // 20: busi.Busi.TransInRevert:output_type -> google.protobuf.Empty + 2, // 21: busi.Busi.TransOutRevert:output_type -> google.protobuf.Empty + 2, // 22: busi.Busi.TransInConfirm:output_type -> google.protobuf.Empty + 2, // 23: busi.Busi.TransOutConfirm:output_type -> google.protobuf.Empty + 2, // 24: busi.Busi.XaNotify:output_type -> google.protobuf.Empty + 2, // 25: busi.Busi.TransInXa:output_type -> google.protobuf.Empty + 2, // 26: busi.Busi.TransOutXa:output_type -> google.protobuf.Empty + 2, // 27: busi.Busi.TransInTcc:output_type -> google.protobuf.Empty + 2, // 28: busi.Busi.TransOutTcc:output_type -> google.protobuf.Empty + 2, // 29: busi.Busi.TransInTccNested:output_type -> google.protobuf.Empty + 2, // 30: busi.Busi.TransInBSaga:output_type -> google.protobuf.Empty + 2, // 31: busi.Busi.TransOutBSaga:output_type -> google.protobuf.Empty + 2, // 32: busi.Busi.TransInRevertBSaga:output_type -> google.protobuf.Empty + 2, // 33: busi.Busi.TransOutRevertBSaga:output_type -> google.protobuf.Empty + 17, // [17:34] is the sub-list for method output_type + 0, // [0:17] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_test_busi_busi_proto_init() } +func file_test_busi_busi_proto_init() { + if File_test_busi_busi_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_test_busi_busi_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BusiReq); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_test_busi_busi_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BusiReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_test_busi_busi_proto_rawDesc, + NumEnums: 0, + NumMessages: 2, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_test_busi_busi_proto_goTypes, + DependencyIndexes: file_test_busi_busi_proto_depIdxs, + MessageInfos: file_test_busi_busi_proto_msgTypes, + }.Build() + File_test_busi_busi_proto = out.File + file_test_busi_busi_proto_rawDesc = nil + file_test_busi_busi_proto_goTypes = nil + file_test_busi_busi_proto_depIdxs = nil +} diff --git a/examples/busi.proto b/test/busi/busi.proto similarity index 96% rename from examples/busi.proto rename to test/busi/busi.proto index 8e34fa8..0e421b0 100644 --- a/examples/busi.proto +++ b/test/busi/busi.proto @@ -1,9 +1,9 @@ syntax = "proto3"; -package examples; +package busi; import "google/protobuf/empty.proto"; -option go_package = "./examples"; +option go_package = "./busi"; // DtmRequest request sent to dtm server message BusiReq { diff --git a/examples/busi_grpc.pb.go b/test/busi/busi_grpc.pb.go similarity index 91% rename from examples/busi_grpc.pb.go rename to test/busi/busi_grpc.pb.go index f9e9427..bc612b1 100644 --- a/examples/busi_grpc.pb.go +++ b/test/busi/busi_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -package examples +package busi import ( context "context" @@ -48,7 +48,7 @@ func NewBusiClient(cc grpc.ClientConnInterface) BusiClient { func (c *busiClient) CanSubmit(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*BusiReply, error) { out := new(BusiReply) - err := c.cc.Invoke(ctx, "/examples.Busi/CanSubmit", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/CanSubmit", in, out, opts...) if err != nil { return nil, err } @@ -57,7 +57,7 @@ func (c *busiClient) CanSubmit(ctx context.Context, in *BusiReq, opts ...grpc.Ca func (c *busiClient) TransIn(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransIn", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransIn", in, out, opts...) if err != nil { return nil, err } @@ -66,7 +66,7 @@ func (c *busiClient) TransIn(ctx context.Context, in *BusiReq, opts ...grpc.Call func (c *busiClient) TransOut(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransOut", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOut", in, out, opts...) if err != nil { return nil, err } @@ -75,7 +75,7 @@ func (c *busiClient) TransOut(ctx context.Context, in *BusiReq, opts ...grpc.Cal func (c *busiClient) TransInRevert(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransInRevert", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransInRevert", in, out, opts...) if err != nil { return nil, err } @@ -84,7 +84,7 @@ func (c *busiClient) TransInRevert(ctx context.Context, in *BusiReq, opts ...grp func (c *busiClient) TransOutRevert(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransOutRevert", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutRevert", in, out, opts...) if err != nil { return nil, err } @@ -93,7 +93,7 @@ func (c *busiClient) TransOutRevert(ctx context.Context, in *BusiReq, opts ...gr func (c *busiClient) TransInConfirm(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransInConfirm", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransInConfirm", in, out, opts...) if err != nil { return nil, err } @@ -102,7 +102,7 @@ func (c *busiClient) TransInConfirm(ctx context.Context, in *BusiReq, opts ...gr func (c *busiClient) TransOutConfirm(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransOutConfirm", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutConfirm", in, out, opts...) if err != nil { return nil, err } @@ -111,7 +111,7 @@ func (c *busiClient) TransOutConfirm(ctx context.Context, in *BusiReq, opts ...g func (c *busiClient) XaNotify(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/XaNotify", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/XaNotify", in, out, opts...) if err != nil { return nil, err } @@ -120,7 +120,7 @@ func (c *busiClient) XaNotify(ctx context.Context, in *emptypb.Empty, opts ...gr func (c *busiClient) TransInXa(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransInXa", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransInXa", in, out, opts...) if err != nil { return nil, err } @@ -129,7 +129,7 @@ func (c *busiClient) TransInXa(ctx context.Context, in *BusiReq, opts ...grpc.Ca func (c *busiClient) TransOutXa(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransOutXa", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutXa", in, out, opts...) if err != nil { return nil, err } @@ -138,7 +138,7 @@ func (c *busiClient) TransOutXa(ctx context.Context, in *BusiReq, opts ...grpc.C func (c *busiClient) TransInTcc(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransInTcc", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransInTcc", in, out, opts...) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func (c *busiClient) TransInTcc(ctx context.Context, in *BusiReq, opts ...grpc.C func (c *busiClient) TransOutTcc(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransOutTcc", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutTcc", in, out, opts...) if err != nil { return nil, err } @@ -156,7 +156,7 @@ func (c *busiClient) TransOutTcc(ctx context.Context, in *BusiReq, opts ...grpc. func (c *busiClient) TransInTccNested(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransInTccNested", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransInTccNested", in, out, opts...) if err != nil { return nil, err } @@ -165,7 +165,7 @@ func (c *busiClient) TransInTccNested(ctx context.Context, in *BusiReq, opts ... func (c *busiClient) TransInBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransInBSaga", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransInBSaga", in, out, opts...) if err != nil { return nil, err } @@ -174,7 +174,7 @@ func (c *busiClient) TransInBSaga(ctx context.Context, in *BusiReq, opts ...grpc func (c *busiClient) TransOutBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransOutBSaga", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutBSaga", in, out, opts...) if err != nil { return nil, err } @@ -183,7 +183,7 @@ func (c *busiClient) TransOutBSaga(ctx context.Context, in *BusiReq, opts ...grp func (c *busiClient) TransInRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransInRevertBSaga", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransInRevertBSaga", in, out, opts...) if err != nil { return nil, err } @@ -192,7 +192,7 @@ func (c *busiClient) TransInRevertBSaga(ctx context.Context, in *BusiReq, opts . func (c *busiClient) TransOutRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/examples.Busi/TransOutRevertBSaga", in, out, opts...) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutRevertBSaga", in, out, opts...) if err != nil { return nil, err } @@ -301,7 +301,7 @@ func _Busi_CanSubmit_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/CanSubmit", + FullMethod: "/busi.Busi/CanSubmit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).CanSubmit(ctx, req.(*BusiReq)) @@ -319,7 +319,7 @@ func _Busi_TransIn_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransIn", + FullMethod: "/busi.Busi/TransIn", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransIn(ctx, req.(*BusiReq)) @@ -337,7 +337,7 @@ func _Busi_TransOut_Handler(srv interface{}, ctx context.Context, dec func(inter } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransOut", + FullMethod: "/busi.Busi/TransOut", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransOut(ctx, req.(*BusiReq)) @@ -355,7 +355,7 @@ func _Busi_TransInRevert_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransInRevert", + FullMethod: "/busi.Busi/TransInRevert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransInRevert(ctx, req.(*BusiReq)) @@ -373,7 +373,7 @@ func _Busi_TransOutRevert_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransOutRevert", + FullMethod: "/busi.Busi/TransOutRevert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransOutRevert(ctx, req.(*BusiReq)) @@ -391,7 +391,7 @@ func _Busi_TransInConfirm_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransInConfirm", + FullMethod: "/busi.Busi/TransInConfirm", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransInConfirm(ctx, req.(*BusiReq)) @@ -409,7 +409,7 @@ func _Busi_TransOutConfirm_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransOutConfirm", + FullMethod: "/busi.Busi/TransOutConfirm", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransOutConfirm(ctx, req.(*BusiReq)) @@ -427,7 +427,7 @@ func _Busi_XaNotify_Handler(srv interface{}, ctx context.Context, dec func(inter } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/XaNotify", + FullMethod: "/busi.Busi/XaNotify", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).XaNotify(ctx, req.(*emptypb.Empty)) @@ -445,7 +445,7 @@ func _Busi_TransInXa_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransInXa", + FullMethod: "/busi.Busi/TransInXa", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransInXa(ctx, req.(*BusiReq)) @@ -463,7 +463,7 @@ func _Busi_TransOutXa_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransOutXa", + FullMethod: "/busi.Busi/TransOutXa", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransOutXa(ctx, req.(*BusiReq)) @@ -481,7 +481,7 @@ func _Busi_TransInTcc_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransInTcc", + FullMethod: "/busi.Busi/TransInTcc", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransInTcc(ctx, req.(*BusiReq)) @@ -499,7 +499,7 @@ func _Busi_TransOutTcc_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransOutTcc", + FullMethod: "/busi.Busi/TransOutTcc", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransOutTcc(ctx, req.(*BusiReq)) @@ -517,7 +517,7 @@ func _Busi_TransInTccNested_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransInTccNested", + FullMethod: "/busi.Busi/TransInTccNested", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransInTccNested(ctx, req.(*BusiReq)) @@ -535,7 +535,7 @@ func _Busi_TransInBSaga_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransInBSaga", + FullMethod: "/busi.Busi/TransInBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransInBSaga(ctx, req.(*BusiReq)) @@ -553,7 +553,7 @@ func _Busi_TransOutBSaga_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransOutBSaga", + FullMethod: "/busi.Busi/TransOutBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransOutBSaga(ctx, req.(*BusiReq)) @@ -571,7 +571,7 @@ func _Busi_TransInRevertBSaga_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransInRevertBSaga", + FullMethod: "/busi.Busi/TransInRevertBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransInRevertBSaga(ctx, req.(*BusiReq)) @@ -589,7 +589,7 @@ func _Busi_TransOutRevertBSaga_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/examples.Busi/TransOutRevertBSaga", + FullMethod: "/busi.Busi/TransOutRevertBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BusiServer).TransOutRevertBSaga(ctx, req.(*BusiReq)) @@ -601,7 +601,7 @@ func _Busi_TransOutRevertBSaga_Handler(srv interface{}, ctx context.Context, dec // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var Busi_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "examples.Busi", + ServiceName: "busi.Busi", HandlerType: (*BusiServer)(nil), Methods: []grpc.MethodDesc{ { @@ -674,5 +674,5 @@ var Busi_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "examples/busi.proto", + Metadata: "test/busi/busi.proto", } diff --git a/examples/quick_start.go b/test/busi/quick_start.go similarity index 58% rename from examples/quick_start.go rename to test/busi/quick_start.go index 8115c89..3fd9616 100644 --- a/examples/quick_start.go +++ b/test/busi/quick_start.go @@ -4,16 +4,15 @@ * license that can be found in the LICENSE file. */ -package examples +package busi import ( "fmt" "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmutil" "github.com/gin-gonic/gin" ) @@ -25,20 +24,18 @@ const qsBusiPort = 8082 var qsBusi = fmt.Sprintf("http://localhost:%d%s", qsBusiPort, qsBusiAPI) -// QsStartSvr 1 func QsStartSvr() { - app := common.GetGinApp() + app := dtmutil.GetGinApp() qsAddRoute(app) - logger.Debugf("quick qs examples listening at %d", qsBusiPort) + logger.Infof("quick start examples listening at %d", qsBusiPort) go app.Run(fmt.Sprintf(":%d", qsBusiPort)) time.Sleep(100 * time.Millisecond) } -// QsFireRequest 1 func QsFireRequest() string { req := &gin.H{"amount": 30} // 微服务的载荷 // DtmServer为DTM服务的地址 - saga := dtmcli.NewSaga(DtmHttpServer, dtmcli.MustGenGid(DtmHttpServer)). + saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, dtmcli.MustGenGid(dtmutil.DefaultHttpServer)). // 添加一个TransOut的子事务,正向操作为url: qsBusi+"/TransOut", 逆向操作为url: qsBusi+"/TransOutCompensate" Add(qsBusi+"/TransOut", qsBusi+"/TransOutCompensate", req). // 添加一个TransIn的子事务,正向操作为url: qsBusi+"/TransOut", 逆向操作为url: qsBusi+"/TransInCompensate" @@ -49,22 +46,21 @@ func QsFireRequest() string { return saga.Gid } -func qsAdjustBalance(uid int, amount int) (interface{}, error) { - _, err := dtmimp.DBExec(sdbGet(), "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) - return dtmcli.MapSuccess, err -} - func qsAddRoute(app *gin.Engine) { - app.POST(qsBusiAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(2, 30) + app.POST(qsBusiAPI+"/TransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + logger.Infof("TransIn") + return dtmcli.MapSuccess, nil })) - app.POST(qsBusiAPI+"/TransInCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(2, -30) + app.POST(qsBusiAPI+"/TransInCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + logger.Infof("TransInCompensate") + return dtmcli.MapSuccess, nil })) - app.POST(qsBusiAPI+"/TransOut", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(1, -30) + app.POST(qsBusiAPI+"/TransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + logger.Infof("TransOut") + return dtmcli.MapSuccess, nil })) - app.POST(qsBusiAPI+"/TransOutCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(1, 30) + app.POST(qsBusiAPI+"/TransOutCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + logger.Infof("TransOutCompensate") + return dtmcli.MapSuccess, nil })) } diff --git a/test/busi/startup.go b/test/busi/startup.go new file mode 100644 index 0000000..7b85772 --- /dev/null +++ b/test/busi/startup.go @@ -0,0 +1,23 @@ +package busi + +import ( + "fmt" + + "github.com/dtm-labs/dtm/dtmutil" + "github.com/gin-gonic/gin" +) + +// Startup startup the busi's grpc and http service +func Startup() *gin.Engine { + GrpcStartup() + return BaseAppStartup() +} + +// PopulateDB populate example mysql data +func PopulateDB(skipDrop bool) { + resetXaData() + file := fmt.Sprintf("%s/busi.%s.sql", dtmutil.GetSqlDir(), BusiConf.Driver) + dtmutil.RunSQLScript(BusiConf, file, skipDrop) + file = fmt.Sprintf("%s/dtmcli.barrier.%s.sql", dtmutil.GetSqlDir(), BusiConf.Driver) + dtmutil.RunSQLScript(BusiConf, file, skipDrop) +} diff --git a/test/busi/utils.go b/test/busi/utils.go new file mode 100644 index 0000000..2b13712 --- /dev/null +++ b/test/busi/utils.go @@ -0,0 +1,61 @@ +package busi + +import ( + "context" + "database/sql" + "fmt" + + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/gin-gonic/gin" +) + +func dbGet() *dtmutil.DB { + return dtmutil.DbGet(BusiConf) +} + +func sdbGet() *sql.DB { + db, err := dtmimp.PooledDB(BusiConf) + logger.FatalIfError(err) + return db +} + +func txGet() *sql.Tx { + db := sdbGet() + tx, err := db.Begin() + logger.FatalIfError(err) + return tx +} + +func resetXaData() { + if BusiConf.Driver != "mysql" { + return + } + + db := dbGet() + type XaRow struct { + Data string + } + xas := []XaRow{} + db.Must().Raw("xa recover").Scan(&xas) + for _, xa := range xas { + db.Must().Exec(fmt.Sprintf("xa rollback '%s'", xa.Data)) + } +} + +// MustBarrierFromGin 1 +func MustBarrierFromGin(c *gin.Context) *dtmcli.BranchBarrier { + ti, err := dtmcli.BarrierFromQuery(c.Request.URL.Query()) + logger.FatalIfError(err) + return ti +} + +// MustBarrierFromGrpc 1 +func MustBarrierFromGrpc(ctx context.Context) *dtmcli.BranchBarrier { + ti, err := dtmgrpc.BarrierFromGrpc(ctx) + logger.FatalIfError(err) + return ti +} diff --git a/test/common_test.go b/test/common_test.go new file mode 100644 index 0000000..3b14e8d --- /dev/null +++ b/test/common_test.go @@ -0,0 +1,38 @@ +package test + +import ( + "testing" + + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/stretchr/testify/assert" +) + +func TestGeneralDB(t *testing.T) { + if conf.Store.IsDB() { + testSql(t) + testDbAlone(t) + } +} + +func testSql(t *testing.T) { + db := dtmutil.DbGet(conf.Store.GetDBConf()) + err := func() (rerr error) { + defer dtmimp.P2E(&rerr) + db.Must().Exec("select a") + return nil + }() + assert.NotEqual(t, nil, err) +} + +func testDbAlone(t *testing.T) { + db, err := dtmimp.StandaloneDB(conf.Store.GetDBConf()) + assert.Nil(t, err) + _, err = dtmimp.DBExec(db, "select 1") + assert.Equal(t, nil, err) + _, err = dtmimp.DBExec(db, "") + assert.Equal(t, nil, err) + db.Close() + _, err = dtmimp.DBExec(db, "select 1") + assert.NotEqual(t, nil, err) +} diff --git a/test/dtmsvr_test.go b/test/dtmsvr_test.go index b855e79..7af9144 100644 --- a/test/dtmsvr_test.go +++ b/test/dtmsvr_test.go @@ -10,18 +10,16 @@ import ( "testing" "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmsvr" - "github.com/dtm-labs/dtm/examples" - "github.com/gin-gonic/gin" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) -var DtmServer = examples.DtmHttpServer -var Busi = examples.Busi -var app *gin.Engine +var DtmServer = dtmutil.DefaultHttpServer +var Busi = busi.Busi func getTransStatus(gid string) string { return dtmsvr.GetTransGlobal(gid).Status @@ -42,10 +40,10 @@ func assertSucceed(t *testing.T, gid string) { } func TestUpdateBranchAsync(t *testing.T) { - if config.Store.Driver != "mysql" { + if conf.Store.Driver != "mysql" { return } - common.Config.UpdateBranchSync = 0 + conf.UpdateBranchSync = 0 saga := genSaga1(dtmimp.GetFuncName(), false, false) saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) err := saga.Submit() @@ -54,5 +52,5 @@ func TestUpdateBranchAsync(t *testing.T) { time.Sleep(dtmsvr.UpdateBranchAsyncInterval) assert.Equal(t, []string{StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) - common.Config.UpdateBranchSync = 1 + conf.UpdateBranchSync = 1 } diff --git a/test/examples_test.go b/test/examples_test.go deleted file mode 100644 index 0ed0ca2..0000000 --- a/test/examples_test.go +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2021 yedf. All rights reserved. - * Use of this source code is governed by a BSD-style - * license that can be found in the LICENSE file. - */ - -package test - -import ( - "testing" - - "github.com/dtm-labs/dtm/examples" -) - -func TestExamples(t *testing.T) { - examples.QsStartSvr() - for _, s := range examples.Samples { - assertSucceed(t, s.Action()) - } -} diff --git a/test/main_test.go b/test/main_test.go index 95c5836..e7d7ca9 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -11,12 +11,11 @@ import ( "testing" "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmsvr" - "github.com/dtm-labs/dtm/examples" - "github.com/gin-gonic/gin" + "github.com/dtm-labs/dtm/dtmsvr/config" + "github.com/dtm-labs/dtm/test/busi" ) func exitIf(code int) { @@ -26,39 +25,35 @@ func exitIf(code int) { } func TestMain(m *testing.M) { - common.MustLoadConfig() - logger.InitLog(config.LogLevel) - dtmcli.SetCurrentDBType(common.Config.ExamplesDB.Driver) + config.MustLoadConfig("") + logger.InitLog("debug") + dtmcli.SetCurrentDBType(busi.BusiConf.Driver) dtmsvr.TransProcessedTestChan = make(chan string, 1) dtmsvr.NowForwardDuration = 0 * time.Second dtmsvr.CronForwardDuration = 180 * time.Second - common.Config.UpdateBranchSync = 1 + conf.UpdateBranchSync = 1 - // 启动组件 - go dtmsvr.StartSvr() - examples.GrpcStartup() - app = examples.BaseAppStartup() - app.POST(examples.BusiAPI+"/TccBSleepCancel", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return disorderHandler(c) - })) tenv := os.Getenv("TEST_STORE") if tenv == "boltdb" { - config.Store.Driver = "boltdb" + conf.Store.Driver = "boltdb" } else if tenv == "mysql" { - config.Store.Driver = "mysql" - config.Store.Host = "localhost" - config.Store.Port = 3306 - config.Store.User = "root" - config.Store.Password = "" + conf.Store.Driver = "mysql" + conf.Store.Host = "localhost" + conf.Store.Port = 3306 + conf.Store.User = "root" + conf.Store.Password = "" } else { - config.Store.Driver = "redis" - config.Store.Host = "localhost" - config.Store.User = "" - config.Store.Password = "" - config.Store.Port = 6379 + conf.Store.Driver = "redis" + conf.Store.Host = "localhost" + conf.Store.User = "" + conf.Store.Password = "" + conf.Store.Port = 6379 } dtmsvr.PopulateDB(false) - examples.PopulateDB(false) + go dtmsvr.StartSvr() + + busi.PopulateDB(false) + _ = busi.Startup() exitIf(m.Run()) } diff --git a/test/msg_grpc_test.go b/test/msg_grpc_test.go index 1869be9..44af2ab 100644 --- a/test/msg_grpc_test.go +++ b/test/msg_grpc_test.go @@ -13,7 +13,8 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -30,10 +31,10 @@ func TestMsgGrpcTimeoutSuccess(t *testing.T) { msg := genGrpcMsg(dtmimp.GetFuncName()) err := msg.Prepare("") assert.Nil(t, err) - examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusSubmitted, getTransStatus(msg.Gid)) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(msg.Gid)) @@ -46,20 +47,20 @@ func TestMsgGrpcTimeoutFailed(t *testing.T) { msg := genGrpcMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) + busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) cronTransOnceForwardNow(180) assert.Equal(t, StatusFailed, getTransStatus(msg.Gid)) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(msg.Gid)) } func genGrpcMsg(gid string) *dtmgrpc.MsgGrpc { - req := &examples.BusiReq{Amount: 30} - msg := dtmgrpc.NewMsgGrpc(examples.DtmGrpcServer, gid). - Add(examples.BusiGrpc+"/examples.Busi/TransOut", req). - Add(examples.BusiGrpc+"/examples.Busi/TransIn", req) - msg.QueryPrepared = fmt.Sprintf("%s/examples.Busi/CanSubmit", examples.BusiGrpc) + req := &busi.BusiReq{Amount: 30} + msg := dtmgrpc.NewMsgGrpc(dtmutil.DefaultGrpcServer, gid). + Add(busi.BusiGrpc+"/busi.Busi/TransOut", req). + Add(busi.BusiGrpc+"/busi.Busi/TransIn", req) + msg.QueryPrepared = fmt.Sprintf("%s/busi.Busi/CanSubmit", busi.BusiGrpc) return msg } diff --git a/test/msg_options_test.go b/test/msg_options_test.go index 49e6265..f69b8c9 100644 --- a/test/msg_options_test.go +++ b/test/msg_options_test.go @@ -11,7 +11,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -44,7 +44,7 @@ func TestMsgOptionsTimeoutFailed(t *testing.T) { assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) cronTransOnceForwardNow(60) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) + busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) cronTransOnceForwardNow(180) assert.Equal(t, StatusFailed, getTransStatus(msg.Gid)) } diff --git a/test/msg_test.go b/test/msg_test.go index 40d5dc2..fa29923 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -11,7 +11,8 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -28,10 +29,10 @@ func TestMsgTimeoutSuccess(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.TransInResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransInResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusSubmitted, getTransStatus(msg.Gid)) cronTransOnce() @@ -43,10 +44,10 @@ func TestMsgTimeoutFailed(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) + busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) cronTransOnceForwardNow(180) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(msg.Gid)) assert.Equal(t, StatusFailed, getTransStatus(msg.Gid)) @@ -65,10 +66,10 @@ func TestMsgAbnormal(t *testing.T) { } func genMsg(gid string) *dtmcli.Msg { - req := examples.GenTransReq(30, false, false) - msg := dtmcli.NewMsg(examples.DtmHttpServer, gid). - Add(examples.Busi+"/TransOut", &req). - Add(examples.Busi+"/TransIn", &req) - msg.QueryPrepared = examples.Busi + "/CanSubmit" + req := busi.GenTransReq(30, false, false) + msg := dtmcli.NewMsg(dtmutil.DefaultHttpServer, gid). + Add(busi.Busi+"/TransOut", &req). + Add(busi.Busi+"/TransIn", &req) + msg.QueryPrepared = busi.Busi + "/CanSubmit" return msg } diff --git a/test/saga_barrier_test.go b/test/saga_barrier_test.go index 59a84dd..ecb2194 100644 --- a/test/saga_barrier_test.go +++ b/test/saga_barrier_test.go @@ -11,7 +11,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -34,7 +34,7 @@ func TestSagaBarrierRollback(t *testing.T) { } func genSagaBarrier(gid string, outFailed, inFailed bool) *dtmcli.Saga { - req := examples.GenTransReq(30, outFailed, inFailed) + req := busi.GenTransReq(30, outFailed, inFailed) return dtmcli.NewSaga(DtmServer, gid). Add(Busi+"/SagaBTransOut", Busi+"/SagaBTransOutCompensate", req). Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) diff --git a/test/saga_compatible_test.go b/test/saga_compatible_test.go index 20ea21f..fbf81cd 100644 --- a/test/saga_compatible_test.go +++ b/test/saga_compatible_test.go @@ -11,15 +11,16 @@ import ( "testing" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) func TestSagaCompatibleNormal(t *testing.T) { // compatible with old http, which put payload in steps.data gid := dtmimp.GetFuncName() body := fmt.Sprintf(`{"gid":"%s","trans_type":"saga","steps":[{"action":"%s/TransOut","compensate":"%s/TransOutRevert","data":"{\"amount\":30,\"transInResult\":\"SUCCESS\",\"transOutResult\":\"SUCCESS\"}"},{"action":"%s/TransIn","compensate":"%s/TransInRevert","data":"{\"amount\":30,\"transInResult\":\"SUCCESS\",\"transOutResult\":\"SUCCESS\"}"}]}`, - gid, examples.Busi, examples.Busi, examples.Busi, examples.Busi) - dtmimp.RestyClient.R().SetBody(body).Post(fmt.Sprintf("%s/submit", examples.DtmHttpServer)) + gid, busi.Busi, busi.Busi, busi.Busi, busi.Busi) + dtmimp.RestyClient.R().SetBody(body).Post(fmt.Sprintf("%s/submit", dtmutil.DefaultHttpServer)) waitTransProcessed(gid) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) assert.Equal(t, StatusSucceed, getTransStatus(gid)) diff --git a/test/saga_concurrent_test.go b/test/saga_concurrent_test.go index a629510..7ae5635 100644 --- a/test/saga_concurrent_test.go +++ b/test/saga_concurrent_test.go @@ -11,7 +11,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -29,7 +29,7 @@ func TestSagaConNormal(t *testing.T) { func TestSagaConRollbackNormal(t *testing.T) { sagaCon := genSagaCon(dtmimp.GetFuncName(), true, false) - examples.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) err := sagaCon.Submit() assert.Nil(t, err) waitTransProcessed(sagaCon.Gid) @@ -52,7 +52,7 @@ func TestSagaConRollbackOrder(t *testing.T) { func TestSagaConCommittedOngoing(t *testing.T) { sagaCon := genSagaCon(dtmimp.GetFuncName(), false, false) - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) sagaCon.Submit() waitTransProcessed(sagaCon.Gid) assert.Equal(t, []string{StatusPrepared, StatusPrepared, StatusPrepared, StatusSucceed}, getBranchesStatus(sagaCon.Gid)) diff --git a/test/saga_grpc_barrier_test.go b/test/saga_grpc_barrier_test.go index 1078368..ebb5e8a 100644 --- a/test/saga_grpc_barrier_test.go +++ b/test/saga_grpc_barrier_test.go @@ -11,7 +11,8 @@ import ( "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -34,9 +35,9 @@ func TestSagaGrpcBarrierRollback(t *testing.T) { } func genSagaGrpcBarrier(gid string, outFailed bool, inFailed bool) *dtmgrpc.SagaGrpc { - saga := dtmgrpc.NewSagaGrpc(examples.DtmGrpcServer, gid) - req := examples.GenBusiReq(30, outFailed, inFailed) - saga.Add(examples.BusiGrpc+"/examples.Busi/TransOutBSaga", examples.BusiGrpc+"/examples.Busi/TransOutRevertBSaga", req) - saga.Add(examples.BusiGrpc+"/examples.Busi/TransInBSaga", examples.BusiGrpc+"/examples.Busi/TransInRevertBSaga", req) + saga := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, gid) + req := busi.GenBusiReq(30, outFailed, inFailed) + saga.Add(busi.BusiGrpc+"/busi.Busi/TransOutBSaga", busi.BusiGrpc+"/busi.Busi/TransOutRevertBSaga", req) + saga.Add(busi.BusiGrpc+"/busi.Busi/TransInBSaga", busi.BusiGrpc+"/busi.Busi/TransInRevertBSaga", req) return saga } diff --git a/test/saga_grpc_test.go b/test/saga_grpc_test.go index 61a114c..831c649 100644 --- a/test/saga_grpc_test.go +++ b/test/saga_grpc_test.go @@ -12,7 +12,8 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -26,7 +27,7 @@ func TestSagaGrpcNormal(t *testing.T) { func TestSagaGrpcRollback(t *testing.T) { saga := genSagaGrpc(dtmimp.GetFuncName(), false, true) - examples.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, StatusAborting, getTransStatus(saga.Gid)) @@ -56,7 +57,7 @@ func TestSagaGrpcCurrentOrder(t *testing.T) { func TestSagaGrpcCommittedOngoing(t *testing.T) { saga := genSagaGrpc(dtmimp.GetFuncName(), false, false) - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, StatusSubmitted, getTransStatus(saga.Gid)) @@ -76,10 +77,10 @@ func TestSagaGrpcNormalWait(t *testing.T) { } func TestSagaGrpcEmptyUrl(t *testing.T) { - saga := dtmgrpc.NewSagaGrpc(examples.DtmGrpcServer, dtmimp.GetFuncName()) - req := examples.GenBusiReq(30, false, false) - saga.Add(examples.BusiGrpc+"/examples.Busi/TransOut", examples.BusiGrpc+"/examples.Busi/TransOutRevert", req) - saga.Add("", examples.BusiGrpc+"/examples.Busi/TransInRevert", req) + saga := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, dtmimp.GetFuncName()) + req := busi.GenBusiReq(30, false, false) + saga.Add(busi.BusiGrpc+"/busi.Busi/TransOut", busi.BusiGrpc+"/busi.Busi/TransOutRevert", req) + saga.Add("", busi.BusiGrpc+"/busi.Busi/TransInRevert", req) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) @@ -87,9 +88,9 @@ func TestSagaGrpcEmptyUrl(t *testing.T) { } func genSagaGrpc(gid string, outFailed bool, inFailed bool) *dtmgrpc.SagaGrpc { - saga := dtmgrpc.NewSagaGrpc(examples.DtmGrpcServer, gid) - req := examples.GenBusiReq(30, outFailed, inFailed) - saga.Add(examples.BusiGrpc+"/examples.Busi/TransOut", examples.BusiGrpc+"/examples.Busi/TransOutRevert", req) - saga.Add(examples.BusiGrpc+"/examples.Busi/TransIn", examples.BusiGrpc+"/examples.Busi/TransInRevert", req) + saga := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, gid) + req := busi.GenBusiReq(30, outFailed, inFailed) + saga.Add(busi.BusiGrpc+"/busi.Busi/TransOut", busi.BusiGrpc+"/busi.Busi/TransOutRevert", req) + saga.Add(busi.BusiGrpc+"/busi.Busi/TransIn", busi.BusiGrpc+"/busi.Busi/TransInRevert", req) return saga } diff --git a/test/saga_options_test.go b/test/saga_options_test.go index c82bd56..bbd1689 100644 --- a/test/saga_options_test.go +++ b/test/saga_options_test.go @@ -11,14 +11,14 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) func TestSagaOptionsRetryOngoing(t *testing.T) { saga := genSaga1(dtmimp.GetFuncName(), false, false) saga.RetryInterval = 150 // CronForwardDuration is larger than RetryInterval - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) err := saga.Submit() assert.Nil(t, err) waitTransProcessed(saga.Gid) @@ -30,7 +30,7 @@ func TestSagaOptionsRetryOngoing(t *testing.T) { func TestSagaOptionsRetryError(t *testing.T) { saga := genSaga1(dtmimp.GetFuncName(), false, false) saga.RetryInterval = 150 // CronForwardDuration is less than 2*RetryInterval - examples.MainSwitch.TransOutResult.SetOnce("ERROR") + busi.MainSwitch.TransOutResult.SetOnce("ERROR") err := saga.Submit() assert.Nil(t, err) waitTransProcessed(saga.Gid) @@ -45,7 +45,7 @@ func TestSagaOptionsRetryError(t *testing.T) { func TestSagaOptionsTimeout(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, false) saga.TimeoutToFail = 1800 - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, StatusSubmitted, getTransStatus(saga.Gid)) @@ -65,7 +65,7 @@ func TestSagaOptionsNormalWait(t *testing.T) { func TestSagaOptionsCommittedOngoingWait(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, false) - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) err := saga.Submit() assert.Error(t, err) diff --git a/test/saga_test.go b/test/saga_test.go index 5093ec5..57d3a85 100644 --- a/test/saga_test.go +++ b/test/saga_test.go @@ -11,7 +11,8 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -25,7 +26,7 @@ func TestSagaNormal(t *testing.T) { func TestSagaOngoingSucceed(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, false) - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, []string{StatusPrepared, StatusPrepared, StatusPrepared, StatusPrepared}, getBranchesStatus(saga.Gid)) @@ -37,7 +38,7 @@ func TestSagaOngoingSucceed(t *testing.T) { func TestSagaFailed(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, true) - examples.MainSwitch.TransOutRevertResult.SetOnce("ERROR") + busi.MainSwitch.TransOutRevertResult.SetOnce("ERROR") err := saga.Submit() assert.Nil(t, err) waitTransProcessed(saga.Gid) @@ -59,9 +60,9 @@ func TestSagaAbnormal(t *testing.T) { } func TestSagaEmptyUrl(t *testing.T) { - saga := dtmcli.NewSaga(examples.DtmHttpServer, dtmimp.GetFuncName()) - req := examples.GenTransReq(30, false, false) - saga.Add(examples.Busi+"/TransOut", "", &req) + saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, dtmimp.GetFuncName()) + req := busi.GenTransReq(30, false, false) + saga.Add(busi.Busi+"/TransOut", "", &req) saga.Add("", "", &req) saga.Submit() waitTransProcessed(saga.Gid) @@ -70,16 +71,16 @@ func TestSagaEmptyUrl(t *testing.T) { } func genSaga(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { - saga := dtmcli.NewSaga(examples.DtmHttpServer, gid) - req := examples.GenTransReq(30, outFailed, inFailed) - saga.Add(examples.Busi+"/TransOut", examples.Busi+"/TransOutRevert", &req) - saga.Add(examples.Busi+"/TransIn", examples.Busi+"/TransInRevert", &req) + saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gid) + req := busi.GenTransReq(30, outFailed, inFailed) + saga.Add(busi.Busi+"/TransOut", busi.Busi+"/TransOutRevert", &req) + saga.Add(busi.Busi+"/TransIn", busi.Busi+"/TransInRevert", &req) return saga } func genSaga1(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { - saga := dtmcli.NewSaga(examples.DtmHttpServer, gid) - req := examples.GenTransReq(30, outFailed, inFailed) - saga.Add(examples.Busi+"/TransOut", examples.Busi+"/TransOutRevert", &req) + saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gid) + req := busi.GenTransReq(30, outFailed, inFailed) + saga.Add(busi.Busi+"/TransOut", busi.Busi+"/TransOutRevert", &req) return saga } diff --git a/test/store_test.go b/test/store_test.go index 08c9966..47cd425 100644 --- a/test/store_test.go +++ b/test/store_test.go @@ -70,21 +70,21 @@ func TestStoreLockTrans(t *testing.T) { gid := dtmimp.GetFuncName() g, s := initTransGlobal(gid) - g2 := s.LockOneGlobalTrans(2 * time.Duration(config.RetryInterval) * time.Second) + g2 := s.LockOneGlobalTrans(2 * time.Duration(conf.RetryInterval) * time.Second) assert.NotNil(t, g2) assert.Equal(t, gid, g2.Gid) - s.TouchCronTime(g, 3*config.RetryInterval) - g2 = s.LockOneGlobalTrans(2 * time.Duration(config.RetryInterval) * time.Second) + s.TouchCronTime(g, 3*conf.RetryInterval) + g2 = s.LockOneGlobalTrans(2 * time.Duration(conf.RetryInterval) * time.Second) assert.Nil(t, g2) - s.TouchCronTime(g, 1*config.RetryInterval) - g2 = s.LockOneGlobalTrans(2 * time.Duration(config.RetryInterval) * time.Second) + s.TouchCronTime(g, 1*conf.RetryInterval) + g2 = s.LockOneGlobalTrans(2 * time.Duration(conf.RetryInterval) * time.Second) assert.NotNil(t, g2) assert.Equal(t, gid, g2.Gid) s.ChangeGlobalStatus(g, "succeed", []string{}, true) - g2 = s.LockOneGlobalTrans(2 * time.Duration(config.RetryInterval) * time.Second) + g2 = s.LockOneGlobalTrans(2 * time.Duration(conf.RetryInterval) * time.Second) assert.Nil(t, g2) } @@ -93,7 +93,7 @@ func TestStoreWait(t *testing.T) { } func TestUpdateBranchSql(t *testing.T) { - if !config.Store.IsDB() { + if !conf.Store.IsDB() { r := registry.GetStore().UpdateBranchesSql(nil, nil) assert.Nil(t, r) } diff --git a/test/tcc_barrier_test.go b/test/tcc_barrier_test.go index 6194b64..87c3aea 100644 --- a/test/tcc_barrier_test.go +++ b/test/tcc_barrier_test.go @@ -12,19 +12,18 @@ import ( "fmt" "strings" "testing" - "time" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/gin-gonic/gin" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" ) func TestTccBarrierNormal(t *testing.T) { - req := examples.GenTransReq(30, false, false) + req := busi.GenTransReq(30, false, false) gid := dtmimp.GetFuncName() err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel") @@ -38,7 +37,7 @@ func TestTccBarrierNormal(t *testing.T) { } func TestTccBarrierRollback(t *testing.T) { - req := examples.GenTransReq(30, false, true) + req := busi.GenTransReq(30, false, true) gid := dtmimp.GetFuncName() err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel") @@ -51,30 +50,29 @@ func TestTccBarrierRollback(t *testing.T) { assert.Equal(t, []string{StatusSucceed, StatusPrepared, StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) } -var disorderHandler func(c *gin.Context) (interface{}, error) = nil - func TestTccBarrierDisorder(t *testing.T) { - timeoutChan := make(chan string, 2) - finishedChan := make(chan string, 2) + ua1 := busi.GetUserAccountByUid(1) + ua2 := busi.GetUserAccountByUid(2) + cancelFinishedChan := make(chan string, 2) + cancelCanReturnChan := make(chan string, 2) gid := dtmimp.GetFuncName() + cronFinished := make(chan string, 2) err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { - body := &examples.TransReq{Amount: 30} + body := &busi.TransReq{Amount: 30} tryURL := Busi + "/TccBTransOutTry" confirmURL := Busi + "/TccBTransOutConfirm" cancelURL := Busi + "/TccBSleepCancel" // 请参见子事务屏障里的时序图,这里为了模拟该时序图,手动拆解了callbranch branchID := tcc.NewSubBranchID() - sleeped := false - disorderHandler = func(c *gin.Context) (interface{}, error) { - res, err := examples.TccBarrierTransOutCancel(c) - if !sleeped { - sleeped = true - logger.Debugf("sleep before cancel return") - <-timeoutChan - finishedChan <- "1" - } + busi.SetSleepCancelHandler(func(c *gin.Context) (interface{}, error) { + res, err := busi.TccBarrierTransOutCancel(c) + logger.Debugf("disorderHandler before cancel finish write") + cancelFinishedChan <- "1" + logger.Debugf("disorderHandler before cancel return read") + <-cancelCanReturnChan + logger.Debugf("disorderHandler after cancel return read") return res, err - } + }) // 注册子事务 resp, err := dtmimp.RestyClient.R(). SetBody(map[string]interface{}{ @@ -89,37 +87,44 @@ func TestTccBarrierDisorder(t *testing.T) { assert.Nil(t, err) assert.Contains(t, resp.String(), dtmcli.ResultSuccess) - go func() { - logger.Debugf("sleeping to wait for tcc try timeout") - <-timeoutChan - r, _ := dtmimp.RestyClient.R(). - SetBody(body). - SetQueryParams(map[string]string{ - "dtm": tcc.Dtm, - "gid": tcc.Gid, - "branch_id": branchID, - "trans_type": "tcc", - "op": dtmcli.BranchTry, - }). - Post(tryURL) - assert.True(t, strings.Contains(r.String(), dtmcli.ResultSuccess)) // 这个是悬挂操作,为了简单起见,依旧让他返回成功 - finishedChan <- "1" - }() - logger.Debugf("cron to timeout and then call cancel") - go cronTransOnceForwardNow(300) - time.Sleep(100 * time.Millisecond) logger.Debugf("cron to timeout and then call cancelled twice") - cronTransOnceForwardNow(300) - timeoutChan <- "wake" - timeoutChan <- "wake" - <-finishedChan - <-finishedChan - time.Sleep(100 * time.Millisecond) + cron := func() { + cronTransOnceForwardNow(300) + logger.Debugf("cronFinished write") + cronFinished <- "1" + logger.Debugf("cronFinished after write") + } + go cron() + <-cancelFinishedChan + go cron() + <-cancelFinishedChan + cancelCanReturnChan <- "1" + cancelCanReturnChan <- "1" + logger.Debugf("after cancelCanRetrun 2 write") + // after cancel then run try + r, _ := dtmimp.RestyClient.R(). + SetBody(body). + SetQueryParams(map[string]string{ + "dtm": tcc.Dtm, + "gid": tcc.Gid, + "branch_id": branchID, + "trans_type": "tcc", + "op": dtmcli.BranchTry, + }). + Post(tryURL) + assert.True(t, strings.Contains(r.String(), dtmcli.ResultSuccess)) // 这个是悬挂操作,为了简单起见,依旧让他返回成功 + logger.Debugf("cronFinished read") + <-cronFinished + <-cronFinished + logger.Debugf("cronFinished after read") + return nil, fmt.Errorf("a cancelled tcc") }) assert.Error(t, err, fmt.Errorf("a cancelled tcc")) assert.Equal(t, []string{StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) assert.Equal(t, StatusFailed, getTransStatus(gid)) + assert.True(t, busi.IsEqual(ua1, busi.GetUserAccountByUid(1))) + assert.True(t, busi.IsEqual(ua2, busi.GetUserAccountByUid(2))) } func TestTccBarrierPanic(t *testing.T) { diff --git a/test/tcc_cover_test.go b/test/tcc_cover_test.go index d865395..9ca4285 100644 --- a/test/tcc_cover_test.go +++ b/test/tcc_cover_test.go @@ -5,7 +5,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" ) @@ -21,7 +21,7 @@ func TestTccCoverNotConnected(t *testing.T) { func TestTccCoverPanic(t *testing.T) { gid := dtmimp.GetFuncName() err := dtmimp.CatchP(func() { - _ = dtmcli.TccGlobalTransaction(examples.DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + _ = dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { panic("user panic") }) assert.FailNow(t, "not executed") diff --git a/test/tcc_grpc_cover_test.go b/test/tcc_grpc_cover_test.go index c23c160..6056b9e 100644 --- a/test/tcc_grpc_cover_test.go +++ b/test/tcc_grpc_cover_test.go @@ -5,7 +5,8 @@ import ( "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/types/known/emptypb" ) @@ -21,7 +22,7 @@ func TestTccGrpcCoverNotConnected(t *testing.T) { func TestTccGrpcCoverPanic(t *testing.T) { gid := dtmimp.GetFuncName() err := dtmimp.CatchP(func() { - _ = dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { + _ = dtmgrpc.TccGlobalTransaction(dtmutil.DefaultGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { panic("user panic") }) assert.FailNow(t, "not executed") @@ -30,16 +31,16 @@ func TestTccGrpcCoverPanic(t *testing.T) { } func TestTccGrpcCoverCallBranch(t *testing.T) { - req := examples.GenBusiReq(30, false, false) + req := busi.GenBusiReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { + err := dtmgrpc.TccGlobalTransaction(dtmutil.DefaultGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { r := &emptypb.Empty{} - err := tcc.CallBranch(req, "not_exists://abc", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) + err := tcc.CallBranch(req, "not_exists://abc", busi.BusiGrpc+"/busi.Busi/TransOutConfirm", busi.BusiGrpc+"/busi.Busi/TransOutRevert", r) assert.Error(t, err) tcc.Dtm = "localhost:01" - err = tcc.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOut", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) + err = tcc.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransOut", busi.BusiGrpc+"/busi.Busi/TransOutConfirm", busi.BusiGrpc+"/busi.Busi/TransOutRevert", r) assert.Error(t, err) return err diff --git a/test/tcc_grpc_test.go b/test/tcc_grpc_test.go index c2c919d..a9fc40b 100644 --- a/test/tcc_grpc_test.go +++ b/test/tcc_grpc_test.go @@ -14,19 +14,20 @@ import ( "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmgrpc" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/types/known/emptypb" ) func TestTccGrpcNormal(t *testing.T) { - req := examples.GenBusiReq(30, false, false) + req := busi.GenBusiReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { + err := dtmgrpc.TccGlobalTransaction(dtmutil.DefaultGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { r := &emptypb.Empty{} - err := tcc.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOut", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) + err := tcc.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransOut", busi.BusiGrpc+"/busi.Busi/TransOutConfirm", busi.BusiGrpc+"/busi.Busi/TransOutRevert", r) assert.Nil(t, err) - return tcc.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransIn", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert", r) + return tcc.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransIn", busi.BusiGrpc+"/busi.Busi/TransInConfirm", busi.BusiGrpc+"/busi.Busi/TransInRevert", r) }) assert.Nil(t, err) waitTransProcessed(gid) @@ -37,13 +38,13 @@ func TestTccGrpcNormal(t *testing.T) { func TestTccGrpcRollback(t *testing.T) { gid := dtmimp.GetFuncName() - req := examples.GenBusiReq(30, false, true) - err := dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { + req := busi.GenBusiReq(30, false, true) + err := dtmgrpc.TccGlobalTransaction(dtmutil.DefaultGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { r := &emptypb.Empty{} - err := tcc.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutTcc", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) + err := tcc.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransOutTcc", busi.BusiGrpc+"/busi.Busi/TransOutConfirm", busi.BusiGrpc+"/busi.Busi/TransOutRevert", r) assert.Nil(t, err) - examples.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) - return tcc.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInTcc", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert", r) + busi.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) + return tcc.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransInTcc", busi.BusiGrpc+"/busi.Busi/TransInConfirm", busi.BusiGrpc+"/busi.Busi/TransInRevert", r) }) assert.Error(t, err) waitTransProcessed(gid) @@ -54,13 +55,13 @@ func TestTccGrpcRollback(t *testing.T) { } func TestTccGrpcNested(t *testing.T) { - req := examples.GenBusiReq(30, false, false) + req := busi.GenBusiReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { + err := dtmgrpc.TccGlobalTransaction(dtmutil.DefaultGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { r := &emptypb.Empty{} - err := tcc.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutTcc", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) + err := tcc.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransOutTcc", busi.BusiGrpc+"/busi.Busi/TransOutConfirm", busi.BusiGrpc+"/busi.Busi/TransOutRevert", r) assert.Nil(t, err) - return tcc.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInTccNested", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert", r) + return tcc.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransInTccNested", busi.BusiGrpc+"/busi.Busi/TransInConfirm", busi.BusiGrpc+"/busi.Busi/TransInRevert", r) }) assert.Nil(t, err) waitTransProcessed(gid) @@ -71,7 +72,7 @@ func TestTccGrpcNested(t *testing.T) { func TestTccGrpcType(t *testing.T) { _, err := dtmgrpc.TccFromGrpc(context.Background()) assert.Error(t, err) - logger.Debugf("expecting dtmgrpcserver error") + logger.Debugf("expecting dtmutil.DefaultGrpcServer error") err = dtmgrpc.TccGlobalTransaction("-", "", func(tcc *dtmgrpc.TccGrpc) error { return nil }) assert.Error(t, err) } diff --git a/test/tcc_test.go b/test/tcc_test.go index b2cf9c3..3766c59 100644 --- a/test/tcc_test.go +++ b/test/tcc_test.go @@ -11,15 +11,16 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" ) func TestTccNormal(t *testing.T) { - req := examples.GenTransReq(30, false, false) + req := busi.GenTransReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmcli.TccGlobalTransaction(examples.DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, err) return tcc.CallBranch(req, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") @@ -32,11 +33,11 @@ func TestTccNormal(t *testing.T) { func TestTccRollback(t *testing.T) { gid := dtmimp.GetFuncName() - req := examples.GenTransReq(30, false, true) - err := dtmcli.TccGlobalTransaction(examples.DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + req := busi.GenTransReq(30, false, true) + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, rerr := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, rerr) - examples.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) return tcc.CallBranch(req, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") }) assert.Error(t, err) @@ -48,11 +49,11 @@ func TestTccRollback(t *testing.T) { } func TestTccTimeout(t *testing.T) { - req := examples.GenTransReq(30, false, false) + req := busi.GenTransReq(30, false, false) gid := dtmimp.GetFuncName() timeoutChan := make(chan int, 1) - err := dtmcli.TccGlobalTransaction(examples.DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, err) go func() { @@ -70,9 +71,9 @@ func TestTccTimeout(t *testing.T) { } func TestTccCompatible(t *testing.T) { - req := examples.GenTransReq(30, false, false) + req := busi.GenTransReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmcli.TccGlobalTransaction(examples.DtmHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, err) return tcc.CallBranch(req, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") diff --git a/test/types.go b/test/types.go index 923cc35..8ed65c8 100644 --- a/test/types.go +++ b/test/types.go @@ -9,17 +9,19 @@ package test import ( "time" - "github.com/dtm-labs/dtm/common" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmsvr" + "github.com/dtm-labs/dtm/dtmsvr/config" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" ) -var config = &common.Config +var conf = &config.Config -func dbGet() *common.DB { - return common.DbGet(config.ExamplesDB) +func dbGet() *dtmutil.DB { + return dtmutil.DbGet(busi.BusiConf) } // waitTransProcessed only for test usage. wait for transaction processed once @@ -28,7 +30,7 @@ func waitTransProcessed(gid string) { select { case id := <-dtmsvr.TransProcessedTestChan: for id != gid { - logger.Errorf("-------id %s not match gid %s", id, gid) + logger.Warnf("------- expecting: %s but %s found", gid, id) id = <-dtmsvr.TransProcessedTestChan } logger.Debugf("finish for gid %s", gid) diff --git a/test/xa_cover_test.go b/test/xa_cover_test.go index 6c61700..fddada6 100644 --- a/test/xa_cover_test.go +++ b/test/xa_cover_test.go @@ -5,7 +5,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" ) @@ -14,11 +14,11 @@ func TestXaCoverDBError(t *testing.T) { oldDriver := getXc().Conf.Driver gid := dtmimp.GetFuncName() err := getXc().XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { - req := examples.GenTransReq(30, false, false) - _, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") + req := busi.GenTransReq(30, false, false) + _, err := xa.CallBranch(req, busi.Busi+"/TransOutXa") assert.Nil(t, err) getXc().Conf.Driver = "no-driver" - _, err = xa.CallBranch(req, examples.Busi+"/TransInXa") + _, err = xa.CallBranch(req, busi.Busi+"/TransInXa") assert.Error(t, err) getXc().Conf.Driver = oldDriver // make abort succeed return nil, err @@ -45,8 +45,8 @@ func TestXaCoverDTMError(t *testing.T) { func TestXaCoverGidError(t *testing.T) { gid := "errgid-' '" err := getXc().XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { - req := examples.GenTransReq(30, false, false) - _, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") + req := busi.GenTransReq(30, false, false) + _, err := xa.CallBranch(req, busi.Busi+"/TransOutXa") assert.Error(t, err) return nil, err }) diff --git a/test/xa_grpc_test.go b/test/xa_grpc_test.go index 283df1b..586e3db 100644 --- a/test/xa_grpc_test.go +++ b/test/xa_grpc_test.go @@ -13,24 +13,24 @@ import ( "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" "google.golang.org/protobuf/types/known/emptypb" ) func getXcg() *dtmgrpc.XaGrpcClient { - return examples.XaGrpcClient + return busi.XaGrpcClient } func TestXaGrpcNormal(t *testing.T) { gid := dtmimp.GetFuncName() err := getXcg().XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { - req := examples.GenBusiReq(30, false, false) + req := busi.GenBusiReq(30, false, false) r := &emptypb.Empty{} - err := xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutXa", r) + err := xa.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransOutXa", r) if err != nil { return err } - return xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInXa", r) + return xa.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransInXa", r) }) assert.Equal(t, nil, err) waitTransProcessed(gid) @@ -41,13 +41,13 @@ func TestXaGrpcNormal(t *testing.T) { func TestXaGrpcRollback(t *testing.T) { gid := dtmimp.GetFuncName() err := getXcg().XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { - req := examples.GenBusiReq(30, false, true) + req := busi.GenBusiReq(30, false, true) r := &emptypb.Empty{} - err := xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutXa", r) + err := xa.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransOutXa", r) if err != nil { return err } - return xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInXa", r) + return xa.CallBranch(req, busi.BusiGrpc+"/busi.Busi/TransInXa", r) }) assert.Error(t, err) waitTransProcessed(gid) @@ -59,17 +59,17 @@ func TestXaGrpcType(t *testing.T) { _, err := dtmgrpc.XaGrpcFromRequest(context.Background()) assert.Error(t, err) - err = examples.XaGrpcClient.XaLocalTransaction(context.Background(), nil, nil) + err = busi.XaGrpcClient.XaLocalTransaction(context.Background(), nil, nil) assert.Error(t, err) err = dtmimp.CatchP(func() { - examples.XaGrpcClient.XaGlobalTransaction("id1", func(xa *dtmgrpc.XaGrpc) error { panic(fmt.Errorf("hello")) }) + busi.XaGrpcClient.XaGlobalTransaction("id1", func(xa *dtmgrpc.XaGrpc) error { panic(fmt.Errorf("hello")) }) }) assert.Error(t, err) } func TestXaGrpcLocalError(t *testing.T) { - xc := examples.XaGrpcClient + xc := busi.XaGrpcClient err := xc.XaGlobalTransaction(dtmimp.GetFuncName(), func(xa *dtmgrpc.XaGrpc) error { return fmt.Errorf("an error") }) diff --git a/test/xa_test.go b/test/xa_test.go index 929d80d..0515c02 100644 --- a/test/xa_test.go +++ b/test/xa_test.go @@ -12,24 +12,24 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" - "github.com/dtm-labs/dtm/examples" + "github.com/dtm-labs/dtm/test/busi" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" ) func getXc() *dtmcli.XaClient { - return examples.XaClient + return busi.XaClient } func TestXaNormal(t *testing.T) { gid := dtmimp.GetFuncName() err := getXc().XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { - req := examples.GenTransReq(30, false, false) - resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") + req := busi.GenTransReq(30, false, false) + resp, err := xa.CallBranch(req, busi.Busi+"/TransOutXa") if err != nil { return resp, err } - return xa.CallBranch(req, examples.Busi+"/TransInXa") + return xa.CallBranch(req, busi.Busi+"/TransInXa") }) assert.Equal(t, nil, err) waitTransProcessed(gid) @@ -40,10 +40,10 @@ func TestXaNormal(t *testing.T) { func TestXaDuplicate(t *testing.T) { gid := dtmimp.GetFuncName() err := getXc().XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { - req := examples.GenTransReq(30, false, false) - _, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") + req := busi.GenTransReq(30, false, false) + _, err := xa.CallBranch(req, busi.Busi+"/TransOutXa") assert.Nil(t, err) - sdb, err := dtmimp.StandaloneDB(config.ExamplesDB) + sdb, err := dtmimp.StandaloneDB(busi.BusiConf) assert.Nil(t, err) if dtmcli.GetCurrentDBType() == dtmcli.DBTypeMysql { _, err = dtmimp.DBExec(sdb, "xa recover") @@ -51,7 +51,7 @@ func TestXaDuplicate(t *testing.T) { } _, err = dtmimp.DBExec(sdb, dtmimp.GetDBSpecial().GetXaSQL("commit", gid+"-01")) // 先把某一个事务提交,模拟重复请求 assert.Nil(t, err) - return xa.CallBranch(req, examples.Busi+"/TransInXa") + return xa.CallBranch(req, busi.Busi+"/TransInXa") }) assert.Nil(t, err) waitTransProcessed(gid) @@ -62,12 +62,12 @@ func TestXaDuplicate(t *testing.T) { func TestXaRollback(t *testing.T) { gid := dtmimp.GetFuncName() err := getXc().XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { - req := examples.GenTransReq(30, false, true) - resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") + req := busi.GenTransReq(30, false, true) + resp, err := xa.CallBranch(req, busi.Busi+"/TransOutXa") if err != nil { return resp, err } - return xa.CallBranch(req, examples.Busi+"/TransInXa") + return xa.CallBranch(req, busi.Busi+"/TransInXa") }) assert.Error(t, err) waitTransProcessed(gid) @@ -92,7 +92,7 @@ func TestXaTimeout(t *testing.T) { cronTransOnceForwardNow(300) timeoutChan <- 0 }() - _ = <-timeoutChan + <-timeoutChan return nil, nil }) assert.Error(t, err) @@ -109,10 +109,10 @@ func TestXaNotTimeout(t *testing.T) { timeoutChan <- 0 }() _ = <-timeoutChan - req := examples.GenTransReq(30, false, false) - _, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") + req := busi.GenTransReq(30, false, false) + _, err := xa.CallBranch(req, busi.Busi+"/TransOutXa") assert.Nil(t, err) - examples.MainSwitch.NextResult.SetOnce(dtmcli.ResultOngoing) // make commit temp error + busi.MainSwitch.NextResult.SetOnce(dtmcli.ResultOngoing) // make commit temp error return nil, nil }) assert.Nil(t, err) From 46b14d5432708e9d2d8766a538f8f5b6e47a6df6 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 16:25:42 +0800 Subject: [PATCH 042/124] cover more --- conf.sample.yml | 12 ++++++------ dtmsvr/config/config_test.go | 3 +++ dtmsvr/storage/sql/sql.go | 4 ++-- test/common_test.go | 3 ++- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/conf.sample.yml b/conf.sample.yml index e4f6348..8dee2ea 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -1,4 +1,4 @@ -Store: # specify which engine to store trans status +# Store: # specify which engine to store trans status # Driver: 'boltdb' # default store engine # Driver: 'redis' @@ -7,11 +7,11 @@ Store: # specify which engine to store trans status # Password: '' # Port: 6379 - Driver: 'mysql' - Host: 'localhost' - User: 'root' - Password: '' - Port: 3306 +# Driver: 'mysql' +# Host: 'localhost' +# User: 'root' +# Password: '' +# Port: 3306 # Driver: 'postgres' # Host: 'localhost' diff --git a/dtmsvr/config/config_test.go b/dtmsvr/config/config_test.go index db62add..8088bef 100644 --- a/dtmsvr/config/config_test.go +++ b/dtmsvr/config/config_test.go @@ -18,12 +18,15 @@ func TestLoadFromEnv(t *testing.T) { } func TestCheckConfig(t *testing.T) { + MustLoadConfig("../../conf.sample.yml") config := &Config + config.RetryInterval = 1 retryIntervalErr := checkConfig() retryIntervalExpect := errors.New("RetryInterval should not be less than 10") assert.Equal(t, retryIntervalErr, retryIntervalExpect) config.RetryInterval = 10 + config.TimeoutToFail = 5 timeoutToFailErr := checkConfig() timeoutToFailExpect := errors.New("TimeoutToFail should not be less than RetryInterval") assert.Equal(t, timeoutToFailErr, timeoutToFailExpect) diff --git a/dtmsvr/storage/sql/sql.go b/dtmsvr/storage/sql/sql.go index 45d03b3..7e4e74d 100644 --- a/dtmsvr/storage/sql/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -144,7 +144,7 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlob return global } -func setDBConn(db *gorm.DB) { +func SetDBConn(db *gorm.DB) { sqldb, _ := db.DB() sqldb.SetMaxOpenConns(int(conf.Store.MaxOpenConns)) sqldb.SetMaxIdleConns(int(conf.Store.MaxIdleConns)) @@ -152,7 +152,7 @@ func setDBConn(db *gorm.DB) { } func dbGet() *dtmutil.DB { - return dtmutil.DbGet(conf.Store.GetDBConf(), setDBConn) + return dtmutil.DbGet(conf.Store.GetDBConf(), SetDBConn) } func wrapError(err error) error { diff --git a/test/common_test.go b/test/common_test.go index 3b14e8d..21337fb 100644 --- a/test/common_test.go +++ b/test/common_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/storage/sql" "github.com/dtm-labs/dtm/dtmutil" "github.com/stretchr/testify/assert" ) @@ -16,7 +17,7 @@ func TestGeneralDB(t *testing.T) { } func testSql(t *testing.T) { - db := dtmutil.DbGet(conf.Store.GetDBConf()) + db := dtmutil.DbGet(conf.Store.GetDBConf(), sql.SetDBConn) err := func() (rerr error) { defer dtmimp.P2E(&rerr) db.Must().Exec("select a") From 2fe248faac4e2908f843080fc9f9d2b041bdedeb Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 16:34:26 +0800 Subject: [PATCH 043/124] TestDBConn --- test/common_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/common_test.go b/test/common_test.go index 21337fb..683577a 100644 --- a/test/common_test.go +++ b/test/common_test.go @@ -17,7 +17,9 @@ func TestGeneralDB(t *testing.T) { } func testSql(t *testing.T) { - db := dtmutil.DbGet(conf.Store.GetDBConf(), sql.SetDBConn) + conf := conf.Store.GetDBConf() + conf.Host = "127.0.0.1" // use a new host to trigger SetDBConn called + db := dtmutil.DbGet(conf, sql.SetDBConn) err := func() (rerr error) { defer dtmimp.P2E(&rerr) db.Must().Exec("select a") From 4d2b17b62ba3b0ca82b7c7c0e62b77c33135270d Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 16:48:51 +0800 Subject: [PATCH 044/124] update coverage --- test/common_test.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/common_test.go b/test/common_test.go index 683577a..b042fb5 100644 --- a/test/common_test.go +++ b/test/common_test.go @@ -3,7 +3,9 @@ package test import ( "testing" + "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc" "github.com/dtm-labs/dtm/dtmsvr/storage/sql" "github.com/dtm-labs/dtm/dtmutil" "github.com/stretchr/testify/assert" @@ -39,3 +41,8 @@ func testDbAlone(t *testing.T) { _, err = dtmimp.DBExec(db, "select 1") assert.NotEqual(t, nil, err) } + +func TestMustGenGid(t *testing.T) { + dtmgrpc.MustGenGid(dtmutil.DefaultGrpcServer) + dtmcli.MustGenGid(dtmutil.DefaultHttpServer) +} From 51b0748969628de459f74d2cae32c520b7bd1aae Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 18:42:21 +0800 Subject: [PATCH 045/124] update readme --- README-cn.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README-cn.md b/README-cn.md index 122e7df..319790f 100644 --- a/README-cn.md +++ b/README-cn.md @@ -12,9 +12,9 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 他优雅的解决了幂等、空补偿、悬挂等分布式事务难题,提供了简单易用、高性能、易水平扩展的解决方案。 -作者受邀参加中国数据库大会分享[多语言环境下分布式事务实践](http://dtcc.it168.com/yicheng.html#b9) +通俗一点说,DTM提供跨服务事务能力,一组服务要么全部成功,要么全部回滚,避免只更新了一部分数据产生的业务问题。 -## 谁在使用dtm +## 谁在使用DTM(仅列出部分) [Tencent 腾讯](https://dtm.pub/other/using.html#tencent) [Ivydad 常青藤爸爸](https://dtm.pub/other/using.html#ivydad) @@ -86,6 +86,8 @@ go run main.go ### 启动并运行一个saga示例 `go run qs/main.go` +这是一个类似跨行转账的示例,包括两个事务分支:资金转出(TransOut)、资金转入(TransIn)。DTM保证TransIn和TransOut要么全部成功,要么全部回滚,保证最终金额的正确性。 + ## 接入详解 ### 接入代码 From 63742982c089fcbdd960b8e218d69493b1777717 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 19:46:38 +0800 Subject: [PATCH 046/124] update workflow scripts --- helper/.goreleaser.yml | 2 +- helper/Dockerfile-release | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/helper/.goreleaser.yml b/helper/.goreleaser.yml index 39ca3ad..daee966 100644 --- a/helper/.goreleaser.yml +++ b/helper/.goreleaser.yml @@ -10,6 +10,6 @@ builds: - amd64 id: 'dtm' dir: . - main: ./app/main.go + main: main.go ldflags: - -s -w -X main.Version={{.Version}} -X main.Commit={{.Commit}} -X main.Date={{.Date}} diff --git a/helper/Dockerfile-release b/helper/Dockerfile-release index b922185..3ef3ff7 100644 --- a/helper/Dockerfile-release +++ b/helper/Dockerfile-release @@ -6,10 +6,10 @@ WORKDIR /app/dtm # RUN go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct EXPOSE 8080 COPY . . -RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags="-s -w" app/main.go +RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags="-s -w" FROM --platform=$TARGETPLATFORM alpine:3.14 -COPY --from=builder /app/dtm/main /app/dtm/ +COPY --from=builder /app/dtm/dtm /app/dtm/ ENV IS_DOCKER=1 WORKDIR /app/dtm -CMD ["/app/dtm/main", "dtmsvr"] +CMD ["/app/dtm/dtm", "dtmsvr"] From 3005be72792fd9385a61374c18477c525476eab9 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 19:48:18 +0800 Subject: [PATCH 047/124] remove args --- helper/Dockerfile-release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/Dockerfile-release b/helper/Dockerfile-release index 3ef3ff7..acf6846 100644 --- a/helper/Dockerfile-release +++ b/helper/Dockerfile-release @@ -12,4 +12,4 @@ FROM --platform=$TARGETPLATFORM alpine:3.14 COPY --from=builder /app/dtm/dtm /app/dtm/ ENV IS_DOCKER=1 WORKDIR /app/dtm -CMD ["/app/dtm/dtm", "dtmsvr"] +CMD ["/app/dtm/dtm"] From 83c483a9607eeea7cc47062cf07de1b1f5bb0e2a Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 22:26:39 +0800 Subject: [PATCH 048/124] try to publish to homebrew --- helper/.goreleaser.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/helper/.goreleaser.yml b/helper/.goreleaser.yml index daee966..4b70ccc 100644 --- a/helper/.goreleaser.yml +++ b/helper/.goreleaser.yml @@ -13,3 +13,13 @@ builds: main: main.go ldflags: - -s -w -X main.Version={{.Version}} -X main.Commit={{.Commit}} -X main.Date={{.Date}} +brews: + - homepage: 'https://d.dtm.pub' + description: 'A cross-language distributed transaction manager.' + folder: Formula + commit_author: + name: yedf2 + email: 120050102@qq.com + tap: + owner: yedf2 + name: dtm From 93abba9cdcfc7dd09f5f79df68a61504944d3e49 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 29 Dec 2021 22:35:52 +0800 Subject: [PATCH 049/124] fix tap name --- helper/.goreleaser.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helper/.goreleaser.yml b/helper/.goreleaser.yml index 4b70ccc..218bced 100644 --- a/helper/.goreleaser.yml +++ b/helper/.goreleaser.yml @@ -18,8 +18,8 @@ brews: description: 'A cross-language distributed transaction manager.' folder: Formula commit_author: - name: yedf2 + name: dtm-labs email: 120050102@qq.com tap: - owner: yedf2 + owner: dtm-labs name: dtm From e932ddf194a1bceb29260c139ba0618c2bedc6b8 Mon Sep 17 00:00:00 2001 From: dtm-labs <120050102@qq.com> Date: Wed, 29 Dec 2021 14:42:09 +0000 Subject: [PATCH 050/124] Brew formula update for dtm version v1.8.1 --- Formula/dtm.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 Formula/dtm.rb diff --git a/Formula/dtm.rb b/Formula/dtm.rb new file mode 100644 index 0000000..19341e9 --- /dev/null +++ b/Formula/dtm.rb @@ -0,0 +1,31 @@ +# typed: false +# frozen_string_literal: true + +# This file was generated by GoReleaser. DO NOT EDIT. +class Dtm < Formula + desc "A cross-language distributed transaction manager." + homepage "https://d.dtm.pub" + version "1.8.1" + + on_macos do + if Hardware::CPU.intel? + url "https://github.com/dtm-labs/dtm/releases/download/v1.8.1/dtm_1.8.1_darwin_amd64.tar.gz" + sha256 "8277820eac478f48fd6770f41eb2ec674dac1eddc66e4ebbd9c73eb41ae39548" + + def install + bin.install "dtm" + end + end + end + + on_linux do + if Hardware::CPU.intel? + url "https://github.com/dtm-labs/dtm/releases/download/v1.8.1/dtm_1.8.1_linux_amd64.tar.gz" + sha256 "ce83774f50b9f121c5f54baf657555053f817af9efccb50d80a9854b7579807a" + + def install + bin.install "dtm" + end + end + end +end From 00af043e6f4ec0cf1711659ee9413e12ae056db3 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 30 Dec 2021 10:20:47 +0800 Subject: [PATCH 051/124] update readme --- README-cn.md | 24 +++++++++------------ README.md | 61 ++++++++++++++++++++-------------------------------- 2 files changed, 33 insertions(+), 52 deletions(-) diff --git a/README-cn.md b/README-cn.md index 319790f..cc2c53f 100644 --- a/README-cn.md +++ b/README-cn.md @@ -23,8 +23,6 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 [极欧科技](https://dtm.pub/other/using.html) -[金数智联](https://dtm.pub/other/using.html) - ## 亮点 * 极易接入 @@ -34,15 +32,13 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 * 跨语言 - 可适合多语言栈的公司使用。方便go、python、php、nodejs、ruby、c# 各类语言使用。 * 易部署、易扩展 - - 仅依赖mysql,部署简单,易集群化,易水平扩展 + - 支持零配置,或依赖mysql|redis,部署简单,易集群化,易水平扩展 * 多种分布式事务协议支持 - - TCC、SAGA、XA、事务消息 + - TCC、SAGA、XA、二阶段消息 ## 与其他框架对比 -目前开源的分布式事务框架,Java的框架较多,有大厂开源的SEATA、ServiceComb-Pack,shardingsphere,以及个人开源的himly,tcc-transaction,ByteTCC等等,其中以Seata的应用最为广泛。 - -非Java语言类的,暂未看到除dtm之外的成熟框架,因此这里仅将DTM和Java中最成熟的Seata对比: +非Java语言类的,暂未看到除dtm之外的成熟框架,因此这里将DTM和Java中最成熟的Seata对比: | 特性| DTM | SEATA |备注| |:-----:|:----:|:----:|:----:| @@ -69,9 +65,8 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ## 微服务框架支持 - [go-zero](https://github.com/zeromicro/go-zero):一开源就非常火爆的微服务框架,首家接入dtm的微服务框架。感谢go-zero作者[kevwan](https://github.com/kevwan)的大力支持 - [polaris](https://github.com/polarismesh/polaris): 腾讯开源的注册发现组件,以及在其上构建的微服务框架。感谢腾讯同学[ychensha](https://github.com/ychensha)的PR -- 其他:看用户需求量,择机接入 +- 其他:看用户需求量,择机接入,参见[微服务支持](https://dtm.pub/protocol/intro.html) -具体微服务接入使用,参见[微服务支持](https://dtm.pub/protocol/intro.html) ## 快速开始 如果您不是Go语言,可以跳转[各语言客户端及示例](https://dtm.pub/summary/code.html#go),里面有相关的快速开始示例 @@ -84,9 +79,9 @@ go run main.go ``` ### 启动并运行一个saga示例 -`go run qs/main.go` +下面运行一个类似跨行转账的示例,包括两个事务分支:资金转出(TransOut)、资金转入(TransIn)。DTM保证TransIn和TransOut要么全部成功,要么全部回滚,保证最终金额的正确性。 -这是一个类似跨行转账的示例,包括两个事务分支:资金转出(TransOut)、资金转入(TransIn)。DTM保证TransIn和TransOut要么全部成功,要么全部回滚,保证最终金额的正确性。 +`go run qs/main.go` ## 接入详解 @@ -117,9 +112,10 @@ go run main.go ### 更多示例 参考[dtm-labs/dtm-examples](https://github.com/dtm-labs/dtm-examples) -## 公众号 -您可以关注公众号:分布式事务,及时跟踪dtm的最新内容 -## 交流群 +## 联系我们 +### 公众号 +dtm官方公众号:分布式事务,大量干货分享,以及dtm的最新消息 +### 交流群 请加 yedf2008 好友或者扫码加好友,验证回复 dtm 按照指引进群 ![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) diff --git a/README.md b/README.md index 27be69d..cc2c53f 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 他优雅的解决了幂等、空补偿、悬挂等分布式事务难题,提供了简单易用、高性能、易水平扩展的解决方案。 -作者受邀参加中国数据库大会分享[多语言环境下分布式事务实践](http://dtcc.it168.com/yicheng.html#b9) +通俗一点说,DTM提供跨服务事务能力,一组服务要么全部成功,要么全部回滚,避免只更新了一部分数据产生的业务问题。 -## 谁在使用dtm +## 谁在使用DTM(仅列出部分) [Tencent 腾讯](https://dtm.pub/other/using.html#tencent) [Ivydad 常青藤爸爸](https://dtm.pub/other/using.html#ivydad) @@ -23,8 +23,6 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 [极欧科技](https://dtm.pub/other/using.html) -[金数智联](https://dtm.pub/other/using.html) - ## 亮点 * 极易接入 @@ -34,15 +32,13 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 * 跨语言 - 可适合多语言栈的公司使用。方便go、python、php、nodejs、ruby、c# 各类语言使用。 * 易部署、易扩展 - - 仅依赖mysql,部署简单,易集群化,易水平扩展 + - 支持零配置,或依赖mysql|redis,部署简单,易集群化,易水平扩展 * 多种分布式事务协议支持 - - TCC、SAGA、XA、事务消息 + - TCC、SAGA、XA、二阶段消息 ## 与其他框架对比 -目前开源的分布式事务框架,Java的框架较多,有大厂开源的SEATA、ServiceComb-Pack,shardingsphere,以及个人开源的himly,tcc-transaction,ByteTCC等等,其中以Seata的应用最为广泛。 - -非Java语言类的,暂未看到除dtm之外的成熟框架,因此这里仅将DTM和Java中最成熟的Seata对比: +非Java语言类的,暂未看到除dtm之外的成熟框架,因此这里将DTM和Java中最成熟的Seata对比: | 特性| DTM | SEATA |备注| |:-----:|:----:|:----:|:----:| @@ -69,31 +65,27 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ## 微服务框架支持 - [go-zero](https://github.com/zeromicro/go-zero):一开源就非常火爆的微服务框架,首家接入dtm的微服务框架。感谢go-zero作者[kevwan](https://github.com/kevwan)的大力支持 - [polaris](https://github.com/polarismesh/polaris): 腾讯开源的注册发现组件,以及在其上构建的微服务框架。感谢腾讯同学[ychensha](https://github.com/ychensha)的PR -- 其他:看用户需求量,择机接入 +- 其他:看用户需求量,择机接入,参见[微服务支持](https://dtm.pub/protocol/intro.html) -具体微服务接入使用,参见[微服务支持](https://dtm.pub/protocol/intro.html) ## 快速开始 -### 获取代码 - -`git clone https://github.com/dtm-labs/dtm && cd dtm` +如果您不是Go语言,可以跳转[各语言客户端及示例](https://dtm.pub/summary/code.html#go),里面有相关的快速开始示例 -### dtm依赖于mysql +### 运行dtm -安装[docker 20.04+](https://docs.docker.com/get-docker/)之后 - -`docker-compose -f helper/compose.mysql.yml up` +``` bash +git clone https://github.com/dtm-labs/dtm && cd dtm +go run main.go +``` -> 您也可以配置使用现有的mysql,需要高级权限,允许dtm创建数据库 -> -> `cp conf.sample.yml conf.yml # 修改conf.yml` +### 启动并运行一个saga示例 +下面运行一个类似跨行转账的示例,包括两个事务分支:资金转出(TransOut)、资金转入(TransIn)。DTM保证TransIn和TransOut要么全部成功,要么全部回滚,保证最终金额的正确性。 -### 启动并运行saga示例 -`go run app/main.go qs` +`go run qs/main.go` -## 开始使用 +## 接入详解 -### 使用 +### 接入代码 ``` GO // 具体业务微服务地址 const qsBusi = "http://localhost:8081/api/busi_saga" @@ -117,23 +109,16 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 -### 完整示例 -参考[examples/quick_start.go](./examples/quick_start.go) +### 更多示例 +参考[dtm-labs/dtm-examples](https://github.com/dtm-labs/dtm-examples) -## 公众号 -您可以关注公众号:分布式事务,及时跟踪dtm的最新内容 -## 交流群 +## 联系我们 +### 公众号 +dtm官方公众号:分布式事务,大量干货分享,以及dtm的最新消息 +### 交流群 请加 yedf2008 好友或者扫码加好友,验证回复 dtm 按照指引进群 ![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) 欢迎使用[dtm](https://github.com/dtm-labs/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 -## 谁在使用 -
- 腾讯 - 常青藤爸爸 - 镜小二 - 极欧科技 - 金数智联 -
From 0878e8f11400d0d1663b850e07b33256954dec8c Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 30 Dec 2021 11:57:48 +0800 Subject: [PATCH 052/124] update readme --- README-cn.md | 25 ++++++++++++++++++++----- README.md | 25 ++++++++++++++++++++----- go.mod | 4 +--- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/README-cn.md b/README-cn.md index cc2c53f..66cd490 100644 --- a/README-cn.md +++ b/README-cn.md @@ -26,15 +26,15 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ## 亮点 * 极易接入 - - 支持HTTP,提供非常简单的接口,极大降低上手分布式事务的难度,新手也能快速接入 -* 使用简单 - - 开发者不再担心悬挂、空补偿、幂等各类问题,框架层代为处理 + - 零配置启动服务,提供非常简单的HTTP接口,极大降低上手分布式事务的难度,新手也能快速接入 * 跨语言 - 可适合多语言栈的公司使用。方便go、python、php、nodejs、ruby、c# 各类语言使用。 +* 使用简单 + - 开发者不再担心悬挂、空补偿、幂等各类问题,首创子事务屏障技术代为处理 * 易部署、易扩展 - - 支持零配置,或依赖mysql|redis,部署简单,易集群化,易水平扩展 + - 依赖mysql|redis,部署简单,易集群化,易水平扩展 * 多种分布式事务协议支持 - - TCC、SAGA、XA、二阶段消息 + - TCC、SAGA、XA、二阶段消息,一站式解决所有分布式事务问题 ## 与其他框架对比 @@ -109,6 +109,21 @@ go run main.go +### 失败情况 +在实际的业务中,子事务可能出现失败,例如转入的子账号被冻结导致转账失败。我们对业务代码进行修改,让TransIn的正向操作失败,然后看看结果 + +``` go + app.POST(qsBusiAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + return M{"dtm_result": "FAILURE"}, nil + })) +``` + +再运行这个例子,整个事务最终失败,时序图如下: + +![saga_rollback](https://pic3.zhimg.com/80/v2-8d8f1476be8a1e2e09ce97a89b4116c2_1440w.jpg) + +在转入操作失败的情况下,TransIn和TransOut的补偿操作被执行,保证了最终的余额和转账前是一样的。 + ### 更多示例 参考[dtm-labs/dtm-examples](https://github.com/dtm-labs/dtm-examples) diff --git a/README.md b/README.md index cc2c53f..66cd490 100644 --- a/README.md +++ b/README.md @@ -26,15 +26,15 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ## 亮点 * 极易接入 - - 支持HTTP,提供非常简单的接口,极大降低上手分布式事务的难度,新手也能快速接入 -* 使用简单 - - 开发者不再担心悬挂、空补偿、幂等各类问题,框架层代为处理 + - 零配置启动服务,提供非常简单的HTTP接口,极大降低上手分布式事务的难度,新手也能快速接入 * 跨语言 - 可适合多语言栈的公司使用。方便go、python、php、nodejs、ruby、c# 各类语言使用。 +* 使用简单 + - 开发者不再担心悬挂、空补偿、幂等各类问题,首创子事务屏障技术代为处理 * 易部署、易扩展 - - 支持零配置,或依赖mysql|redis,部署简单,易集群化,易水平扩展 + - 依赖mysql|redis,部署简单,易集群化,易水平扩展 * 多种分布式事务协议支持 - - TCC、SAGA、XA、二阶段消息 + - TCC、SAGA、XA、二阶段消息,一站式解决所有分布式事务问题 ## 与其他框架对比 @@ -109,6 +109,21 @@ go run main.go +### 失败情况 +在实际的业务中,子事务可能出现失败,例如转入的子账号被冻结导致转账失败。我们对业务代码进行修改,让TransIn的正向操作失败,然后看看结果 + +``` go + app.POST(qsBusiAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { + return M{"dtm_result": "FAILURE"}, nil + })) +``` + +再运行这个例子,整个事务最终失败,时序图如下: + +![saga_rollback](https://pic3.zhimg.com/80/v2-8d8f1476be8a1e2e09ce97a89b4116c2_1440w.jpg) + +在转入操作失败的情况下,TransIn和TransOut的补偿操作被执行,保证了最终的余额和转账前是一样的。 + ### 更多示例 参考[dtm-labs/dtm-examples](https://github.com/dtm-labs/dtm-examples) diff --git a/go.mod b/go.mod index 9c897a0..0d19a2f 100644 --- a/go.mod +++ b/go.mod @@ -8,11 +8,10 @@ require ( github.com/dtm-labs/dtmdriver-polaris v0.0.2 github.com/dtm-labs/dtmdriver-protocol1 v0.0.1 github.com/gin-gonic/gin v1.6.3 - github.com/go-playground/assert/v2 v2.0.1 + github.com/go-redis/redis/v8 v8.11.4 github.com/go-resty/resty/v2 v2.7.0 github.com/go-sql-driver/mysql v1.6.0 - github.com/google/uuid v1.3.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 github.com/lib/pq v1.10.3 github.com/lithammer/shortuuid v2.0.3+incompatible @@ -32,7 +31,6 @@ require ( gorm.io/driver/mysql v1.0.3 gorm.io/driver/postgres v1.2.1 gorm.io/gorm v1.22.2 - honnef.co/go/tools v0.0.1-2020.1.3 // gotest.tools v2.2.0+incompatible ) From 852731ae3aa4bee386412cdde1305793888e66f4 Mon Sep 17 00:00:00 2001 From: yedf2 <43027375+yedf2@users.noreply.github.com> Date: Thu, 30 Dec 2021 12:13:46 +0800 Subject: [PATCH 053/124] adjust image size --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 66cd490..7d93642 100644 --- a/README.md +++ b/README.md @@ -107,7 +107,7 @@ go run main.go 上述saga分布式事务的时序图如下: - + ### 失败情况 在实际的业务中,子事务可能出现失败,例如转入的子账号被冻结导致转账失败。我们对业务代码进行修改,让TransIn的正向操作失败,然后看看结果 @@ -120,7 +120,7 @@ go run main.go 再运行这个例子,整个事务最终失败,时序图如下: -![saga_rollback](https://pic3.zhimg.com/80/v2-8d8f1476be8a1e2e09ce97a89b4116c2_1440w.jpg) + 在转入操作失败的情况下,TransIn和TransOut的补偿操作被执行,保证了最终的余额和转账前是一样的。 From a441b6ebc2d800eeb0fa3b0bee481e018e29d43e Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 30 Dec 2021 14:50:04 +0800 Subject: [PATCH 054/124] try to add brew test --- Formula/dtm.rb | 31 ------------------------------- helper/.goreleaser.yml | 10 ---------- main.go | 4 ++++ qs/main.go | 7 +++---- test/busi/quick_start.go | 2 ++ 5 files changed, 9 insertions(+), 45 deletions(-) delete mode 100644 Formula/dtm.rb diff --git a/Formula/dtm.rb b/Formula/dtm.rb deleted file mode 100644 index 19341e9..0000000 --- a/Formula/dtm.rb +++ /dev/null @@ -1,31 +0,0 @@ -# typed: false -# frozen_string_literal: true - -# This file was generated by GoReleaser. DO NOT EDIT. -class Dtm < Formula - desc "A cross-language distributed transaction manager." - homepage "https://d.dtm.pub" - version "1.8.1" - - on_macos do - if Hardware::CPU.intel? - url "https://github.com/dtm-labs/dtm/releases/download/v1.8.1/dtm_1.8.1_darwin_amd64.tar.gz" - sha256 "8277820eac478f48fd6770f41eb2ec674dac1eddc66e4ebbd9c73eb41ae39548" - - def install - bin.install "dtm" - end - end - end - - on_linux do - if Hardware::CPU.intel? - url "https://github.com/dtm-labs/dtm/releases/download/v1.8.1/dtm_1.8.1_linux_amd64.tar.gz" - sha256 "ce83774f50b9f121c5f54baf657555053f817af9efccb50d80a9854b7579807a" - - def install - bin.install "dtm" - end - end - end -end diff --git a/helper/.goreleaser.yml b/helper/.goreleaser.yml index 218bced..daee966 100644 --- a/helper/.goreleaser.yml +++ b/helper/.goreleaser.yml @@ -13,13 +13,3 @@ builds: main: main.go ldflags: - -s -w -X main.Version={{.Version}} -X main.Commit={{.Commit}} -X main.Date={{.Date}} -brews: - - homepage: 'https://d.dtm.pub' - description: 'A cross-language distributed transaction manager.' - folder: Formula - commit_author: - name: dtm-labs - email: 120050102@qq.com - tap: - owner: dtm-labs - name: dtm diff --git a/main.go b/main.go index 4308f4a..ab781c2 100644 --- a/main.go +++ b/main.go @@ -49,6 +49,7 @@ func usage() { var isVersion = flag.Bool("v", false, "Show the version of dtm.") var isDebug = flag.Bool("d", false, "Set log level to debug.") var isHelp = flag.Bool("h", false, "Show the help information about etcd.") +var isReset = flag.Bool("r", false, "Reset dtm server data.") var confFile = flag.String("c", "", "Path to the server configuration file.") func main() { @@ -64,6 +65,9 @@ func main() { if *isDebug { config.Config.LogLevel = "debug" } + if *isReset { + dtmsvr.PopulateDB(false) + } maxprocs.Set(maxprocs.Logger(logger.Infof)) registry.WaitStoreUp() dtmsvr.StartSvr() // 启动dtmsvr的api服务 diff --git a/qs/main.go b/qs/main.go index f31d83a..4cf0586 100644 --- a/qs/main.go +++ b/qs/main.go @@ -7,13 +7,12 @@ package main import ( - "time" - + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/test/busi" ) func main() { busi.QsStartSvr() - busi.QsFireRequest() - time.Sleep(1 * time.Second) + gid := busi.QsFireRequest() + logger.Infof("transaction: %s succeed", gid) } diff --git a/test/busi/quick_start.go b/test/busi/quick_start.go index 3fd9616..8e12cb9 100644 --- a/test/busi/quick_start.go +++ b/test/busi/quick_start.go @@ -40,6 +40,8 @@ func QsFireRequest() string { Add(qsBusi+"/TransOut", qsBusi+"/TransOutCompensate", req). // 添加一个TransIn的子事务,正向操作为url: qsBusi+"/TransOut", 逆向操作为url: qsBusi+"/TransInCompensate" Add(qsBusi+"/TransIn", qsBusi+"/TransInCompensate", req) + // 等待事务全部完成后再返回,可选 + saga.WaitResult = true // 提交saga事务,dtm会完成所有的子事务/回滚所有的子事务 err := saga.Submit() logger.FatalIfError(err) From 6f8af2b7e1ace840edc55a35d423491ece8019be Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 30 Dec 2021 16:12:09 +0800 Subject: [PATCH 055/124] update version --- .gitignore | 3 ++- helper/.goreleaser.yml | 2 +- main.go | 9 ++------- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/.gitignore b/.gitignore index e89d163..34e44f0 100644 --- a/.gitignore +++ b/.gitignore @@ -14,4 +14,5 @@ coverage.* profile.* test.sh dtm -dtm.* \ No newline at end of file +dtm-* +dtm.* diff --git a/helper/.goreleaser.yml b/helper/.goreleaser.yml index daee966..5c5a639 100644 --- a/helper/.goreleaser.yml +++ b/helper/.goreleaser.yml @@ -12,4 +12,4 @@ builds: dir: . main: main.go ldflags: - - -s -w -X main.Version={{.Version}} -X main.Commit={{.Commit}} -X main.Date={{.Date}} + - -s -w -X main.Version={{.Version}} diff --git a/main.go b/main.go index ab781c2..013441d 100644 --- a/main.go +++ b/main.go @@ -25,18 +25,13 @@ import ( _ "github.com/dtm-labs/dtmdriver-protocol1" ) -var Version, Commit, Date string +var Version string func version() { if Version == "" { Version = "0.0.0-dev" - Commit = "NA" - Date = "NA" } - if len(Commit) > 8 { - Commit = Commit[:8] - } - fmt.Printf("version: %s commit: %s built at: %s\n", Version, Commit, Date) + fmt.Printf("dtm version: %s\n", Version) } func usage() { From 57f42800a5122fb0676df3ac0913c5da6ba5e0b5 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 30 Dec 2021 16:30:10 +0800 Subject: [PATCH 056/124] update readme --- README-cn.md | 2 -- README.md | 6 ++---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/README-cn.md b/README-cn.md index 66cd490..a339308 100644 --- a/README-cn.md +++ b/README-cn.md @@ -12,8 +12,6 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 他优雅的解决了幂等、空补偿、悬挂等分布式事务难题,提供了简单易用、高性能、易水平扩展的解决方案。 -通俗一点说,DTM提供跨服务事务能力,一组服务要么全部成功,要么全部回滚,避免只更新了一部分数据产生的业务问题。 - ## 谁在使用DTM(仅列出部分) [Tencent 腾讯](https://dtm.pub/other/using.html#tencent) diff --git a/README.md b/README.md index 7d93642..a339308 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,6 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 他优雅的解决了幂等、空补偿、悬挂等分布式事务难题,提供了简单易用、高性能、易水平扩展的解决方案。 -通俗一点说,DTM提供跨服务事务能力,一组服务要么全部成功,要么全部回滚,避免只更新了一部分数据产生的业务问题。 - ## 谁在使用DTM(仅列出部分) [Tencent 腾讯](https://dtm.pub/other/using.html#tencent) @@ -107,7 +105,7 @@ go run main.go 上述saga分布式事务的时序图如下: - + ### 失败情况 在实际的业务中,子事务可能出现失败,例如转入的子账号被冻结导致转账失败。我们对业务代码进行修改,让TransIn的正向操作失败,然后看看结果 @@ -120,7 +118,7 @@ go run main.go 再运行这个例子,整个事务最终失败,时序图如下: - +![saga_rollback](https://pic3.zhimg.com/80/v2-8d8f1476be8a1e2e09ce97a89b4116c2_1440w.jpg) 在转入操作失败的情况下,TransIn和TransOut的补偿操作被执行,保证了最终的余额和转账前是一样的。 From af56f3db1efa670f717358524caeb088e1c1ab7d Mon Sep 17 00:00:00 2001 From: jxlwqq Date: Fri, 31 Dec 2021 11:25:36 +0800 Subject: [PATCH 057/124] use ENTRYPOINT instead of CMD --- helper/Dockerfile-release | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper/Dockerfile-release b/helper/Dockerfile-release index acf6846..0dd5bf1 100644 --- a/helper/Dockerfile-release +++ b/helper/Dockerfile-release @@ -12,4 +12,4 @@ FROM --platform=$TARGETPLATFORM alpine:3.14 COPY --from=builder /app/dtm/dtm /app/dtm/ ENV IS_DOCKER=1 WORKDIR /app/dtm -CMD ["/app/dtm/dtm"] +ENTRYPOINT ["/app/dtm/dtm"] From 09ae1cdaa25a9fa1d19f31d72671cc851f64293b Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 1 Jan 2022 11:28:42 +0800 Subject: [PATCH 058/124] support headers --- bench/svr/http.go | 8 +- conf.sample.yml | 11 +- dtmcli/barrier.go | 2 +- dtmcli/dtmimp/trans_base.go | 23 ++-- dtmcli/dtmimp/vars.go | 8 +- dtmcli/tcc.go | 6 + dtmcli/types.go | 23 ++++ dtmcli/types_test.go | 1 + dtmcli/xa.go | 12 +- dtmgrpc/dtmgimp/grpc_clients.go | 7 +- dtmgrpc/dtmgimp/utils.go | 45 +++++-- dtmgrpc/dtmgpb/dtmgimp.pb.go | 197 ++++++++++++++++++------------- dtmgrpc/dtmgpb/dtmgimp.proto | 2 + dtmgrpc/tcc.go | 23 ++-- dtmgrpc/type.go | 17 +-- dtmgrpc/type_test.go | 5 - dtmgrpc/xa.go | 10 +- dtmsvr/api_grpc.go | 6 +- dtmsvr/config/config.go | 24 ++-- dtmsvr/config/config_test.go | 43 ++++--- dtmsvr/config/config_utils.go | 22 ++-- dtmsvr/storage/trans.go | 12 +- dtmsvr/trans_class.go | 31 ++++- dtmsvr/trans_process.go | 7 ++ dtmsvr/trans_status.go | 6 + go.mod | 1 - go.sum | 6 + helper/sync-dtmcli.sh | 2 - sqls/dtmsvr.storage.mysql.sql | 4 +- sqls/dtmsvr.storage.postgres.sql | 4 +- test/busi/base_grpc.go | 17 +++ test/busi/base_http.go | 14 +++ test/busi/busi.pb.go | 56 +++++---- test/busi/busi.proto | 2 + test/busi/busi_grpc.pb.go | 72 +++++++++++ test/busi/utils.go | 28 ++++- test/dtmsvr_test.go | 3 +- test/main_test.go | 4 + test/msg_grpc_test.go | 3 +- test/msg_options_test.go | 9 +- test/msg_test.go | 5 +- test/saga_concurrent_test.go | 6 +- test/saga_cover_test.go | 11 ++ test/saga_grpc_test.go | 74 +++++++++++- test/saga_options_test.go | 85 +++++++++++-- test/saga_test.go | 8 +- test/tcc_cover_test.go | 1 + test/tcc_grpc_cover_test.go | 3 + test/tcc_grpc_test.go | 22 +++- test/tcc_test.go | 19 ++- test/types.go | 18 +-- test/xa_cover_test.go | 3 +- test/xa_grpc_test.go | 8 +- test/xa_test.go | 3 +- 54 files changed, 779 insertions(+), 263 deletions(-) create mode 100644 test/saga_cover_test.go diff --git a/bench/svr/http.go b/bench/svr/http.go index d1c8978..92fd44d 100644 --- a/bench/svr/http.go +++ b/bench/svr/http.go @@ -33,14 +33,14 @@ const total = 200000 var benchPort = dtmimp.If(os.Getenv("BENCH_PORT") == "", "8083", os.Getenv("BENCH_PORT")).(string) var benchBusi = fmt.Sprintf("http://localhost:%s%s", benchPort, benchAPI) -func sdbGet() *sql.DB { +func pdbGet() *sql.DB { db, err := dtmimp.PooledDB(busi.BusiConf) logger.FatalIfError(err) return db } func txGet() *sql.Tx { - db := sdbGet() + db := pdbGet() tx, err := db.Begin() logger.FatalIfError(err) return tx @@ -49,7 +49,7 @@ func txGet() *sql.Tx { func reloadData() { time.Sleep(dtmsvr.UpdateBranchAsyncInterval * 2) began := time.Now() - db := sdbGet() + db := pdbGet() tables := []string{"dtm_busi.user_account", "dtm_busi.user_account_log", "dtm.trans_global", "dtm.trans_branch_op", "dtm_barrier.barrier"} for _, t := range tables { _, err := dtmimp.DBExec(db, fmt.Sprintf("truncate %s", t)) @@ -70,7 +70,7 @@ var mode string = "" var sqls int = 1 func PrepareBenchDB() { - db := sdbGet() + db := pdbGet() _, err := dtmimp.DBExec(db, "drop table if exists dtm_busi.user_account_log") logger.FatalIfError(err) _, err = dtmimp.DBExec(db, `create table if not exists dtm_busi.user_account_log ( diff --git a/conf.sample.yml b/conf.sample.yml index 8dee2ea..807d582 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -1,3 +1,10 @@ +##################################################################### +### dtm can be run without any config. +### all config in this file is optional. the default value is as specified in each line +### all configs can be specified from env. for example: +### Store.MaxOpenConns can also specified from env: STORE_MAX_OPEN_CONNS +##################################################################### + # Store: # specify which engine to store trans status # Driver: 'boltdb' # default store engine @@ -19,10 +26,12 @@ # Password: 'mysecretpassword' # Port: '5432' -### following connection config is for only Driver postgres/mysql +### following config is for only Driver postgres/mysql # MaxOpenConns: 500 # MaxIdleConns: 500 # ConnMaxLifeTime 5 # default value is 5 (minutes) +# TransGlobalTable: 'dtm.trans_global' +# TransBranchOp: 'dtm.trans_branch_op' ### flollowing config is only for some Driver # DataExpire: 604800 # Trans data will expire in 7 days. only for redis/boltdb. diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index ff14336..62f59b2 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -54,7 +54,7 @@ func insertBarrier(tx DB, transType string, gid string, branchID string, op stri if op == "" { return 0, nil } - sql := dtmimp.GetDBSpecial().GetInsertIgnoreTemplate("dtm_barrier.barrier(trans_type, gid, branch_id, op, barrier_id, reason) values(?,?,?,?,?,?)", "uniq_barrier") + sql := dtmimp.GetDBSpecial().GetInsertIgnoreTemplate(dtmimp.BarrierTableName+"(trans_type, gid, branch_id, op, barrier_id, reason) values(?,?,?,?,?,?)", "uniq_barrier") return dtmimp.DBExec(tx, sql, transType, gid, branchID, op, barrierID, reason) } diff --git a/dtmcli/dtmimp/trans_base.go b/dtmcli/dtmimp/trans_base.go index b050064..9c89a9f 100644 --- a/dtmcli/dtmimp/trans_base.go +++ b/dtmcli/dtmimp/trans_base.go @@ -40,9 +40,11 @@ func (g *BranchIDGen) CurrentSubBranchID() string { // TransOptions transaction options type TransOptions struct { - WaitResult bool `json:"wait_result,omitempty" gorm:"-"` - TimeoutToFail int64 `json:"timeout_to_fail,omitempty" gorm:"-"` // for trans type: xa, tcc - RetryInterval int64 `json:"retry_interval,omitempty" gorm:"-"` // for trans type: msg saga xa tcc + WaitResult bool `json:"wait_result,omitempty" gorm:"-"` + TimeoutToFail int64 `json:"timeout_to_fail,omitempty" gorm:"-"` // for trans type: xa, tcc + RetryInterval int64 `json:"retry_interval,omitempty" gorm:"-"` // for trans type: msg saga xa tcc + PassthroughHeaders []string `json:"passthrough_headers,omitempty" gorm:"-"` + BranchHeaders map[string]string `json:"branch_headers,omitempty" gorm:"-"` } // TransBase base for all trans @@ -62,18 +64,14 @@ type TransBase struct { QueryPrepared string `json:"query_prepared,omitempty"` // used in MSG } -// SetOptions set options -func (tb *TransBase) SetOptions(options *TransOptions) { - tb.TransOptions = *options -} - // NewTransBase new a TransBase func NewTransBase(gid string, transType string, dtm string, branchID string) *TransBase { return &TransBase{ - Gid: gid, - TransType: transType, - BranchIDGen: BranchIDGen{BranchID: branchID}, - Dtm: dtm, + Gid: gid, + TransType: transType, + BranchIDGen: BranchIDGen{BranchID: branchID}, + Dtm: dtm, + TransOptions: TransOptions{PassthroughHeaders: PassthroughHeaders}, } } @@ -118,6 +116,7 @@ func TransRequestBranch(t *TransBase, body interface{}, branchID string, op stri "trans_type": t.TransType, "op": op, }). + SetHeaders(t.BranchHeaders). Post(url) return resp, CheckResponse(resp, err) } diff --git a/dtmcli/dtmimp/vars.go b/dtmcli/dtmimp/vars.go index eea02ad..fc51d70 100644 --- a/dtmcli/dtmimp/vars.go +++ b/dtmcli/dtmimp/vars.go @@ -31,13 +31,19 @@ var MapFailure = map[string]interface{}{"dtm_result": ResultFailure} // RestyClient the resty object var RestyClient = resty.New() +// PassthroughHeaders will be passed to every sub-trans call +var PassthroughHeaders = []string{} + +// BarrierTableName the table name of barrier table +var BarrierTableName = "dtm_barrier.barrier" + func init() { // RestyClient.SetTimeout(3 * time.Second) // RestyClient.SetRetryCount(2) // RestyClient.SetRetryWaitTime(1 * time.Second) RestyClient.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error { r.URL = MayReplaceLocalhost(r.URL) - logger.Debugf("requesting: %s %s %v %v", r.Method, r.URL, r.Body, r.QueryParam) + logger.Debugf("requesting: %s %s %s", r.Method, r.URL, MustMarshalString(r.Body)) return nil }) RestyClient.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { diff --git a/dtmcli/tcc.go b/dtmcli/tcc.go index 73d1172..d61a7fe 100644 --- a/dtmcli/tcc.go +++ b/dtmcli/tcc.go @@ -27,7 +27,13 @@ type TccGlobalFunc func(tcc *Tcc) (*resty.Response, error) // gid global transaction ID // tccFunc tcc事务函数,里面会定义全局事务的分支 func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr error) { + return TccGlobalTransaction2(dtm, gid, func(t *Tcc) {}, tccFunc) +} + +// TccGlobalTransaction2 new version of TccGlobalTransaction, add custom param +func TccGlobalTransaction2(dtm string, gid string, custom func(*Tcc), tccFunc TccGlobalFunc) (rerr error) { tcc := &Tcc{TransBase: *dtmimp.NewTransBase(gid, "tcc", dtm, "")} + custom(tcc) rerr = dtmimp.TransCallDtm(&tcc.TransBase, tcc, "prepare") if rerr != nil { return rerr diff --git a/dtmcli/types.go b/dtmcli/types.go index e0e54e2..482651a 100644 --- a/dtmcli/types.go +++ b/dtmcli/types.go @@ -10,6 +10,7 @@ import ( "fmt" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/go-resty/resty/v2" ) // MustGenGid generate a new gid @@ -49,3 +50,25 @@ func SetXaSqlTimeoutMs(ms int) { func GetXaSqlTimeoutMs() int { return dtmimp.XaSqlTimeoutMs } + +func SetBarrierTableName(tablename string) { + dtmimp.BarrierTableName = tablename +} + +// OnBeforeRequest add before request middleware +func OnBeforeRequest(middleware func(c *resty.Client, r *resty.Request) error) { + dtmimp.RestyClient.OnBeforeRequest(middleware) +} + +// OnAfterResponse add after request middleware +func OnAfterResponse(middleware func(c *resty.Client, resp *resty.Response) error) { + dtmimp.RestyClient.OnAfterResponse(middleware) +} + +// SetPassthroughHeaders experimental. +// apply to http header and grpc metadata +// dtm server will save these headers in trans creating request. +// and then passthrough them to sub-trans +func SetPassthroughHeaders(headers []string) { + dtmimp.PassthroughHeaders = headers +} diff --git a/dtmcli/types_test.go b/dtmcli/types_test.go index b37ba9a..269c54b 100644 --- a/dtmcli/types_test.go +++ b/dtmcli/types_test.go @@ -28,4 +28,5 @@ func TestTypes(t *testing.T) { func TestXaSqlTimeout(t *testing.T) { old := GetXaSqlTimeoutMs() SetXaSqlTimeoutMs(old) + SetBarrierTableName(dtmimp.BarrierTableName) // just cover this func } diff --git a/dtmcli/xa.go b/dtmcli/xa.go index d28bed7..c74b4d1 100644 --- a/dtmcli/xa.go +++ b/dtmcli/xa.go @@ -83,11 +83,17 @@ func (xc *XaClient) XaLocalTransaction(qs url.Values, xaFunc XaLocalFunc) error // XaGlobalTransaction start a xa global transaction func (xc *XaClient) XaGlobalTransaction(gid string, xaFunc XaGlobalFunc) (rerr error) { - xa := Xa{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.XaClientBase.Server, "")} + return xc.XaGlobalTransaction2(gid, func(x *Xa) {}, xaFunc) +} + +// XaGlobalTransaction start a xa global transaction +func (xc *XaClient) XaGlobalTransaction2(gid string, custom func(*Xa), xaFunc XaGlobalFunc) (rerr error) { + xa := &Xa{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.XaClientBase.Server, "")} + custom(xa) return xc.HandleGlobalTrans(&xa.TransBase, func(action string) error { - return dtmimp.TransCallDtm(&xa.TransBase, &xa, action) + return dtmimp.TransCallDtm(&xa.TransBase, xa, action) }, func() error { - _, rerr := xaFunc(&xa) + _, rerr := xaFunc(xa) return rerr }) } diff --git a/dtmgrpc/dtmgimp/grpc_clients.go b/dtmgrpc/dtmgimp/grpc_clients.go index d2c63a0..dc21e81 100644 --- a/dtmgrpc/dtmgimp/grpc_clients.go +++ b/dtmgrpc/dtmgimp/grpc_clients.go @@ -13,6 +13,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" + grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" grpc "google.golang.org/grpc" ) @@ -35,6 +36,8 @@ func (cb rawCodec) Name() string { return "dtm_raw" } var normalClients, rawClients sync.Map +var ClientInterceptors = []grpc.UnaryClientInterceptor{} + // MustGetDtmClient 1 func MustGetDtmClient(grpcServer string) dtmgpb.DtmClient { return dtmgpb.NewDtmClient(MustGetGrpcConn(grpcServer, false)) @@ -59,7 +62,9 @@ func GetGrpcConn(grpcServer string, isRaw bool) (conn *grpc.ClientConn, rerr err opts = grpc.WithDefaultCallOptions(grpc.ForceCodec(rawCodec{})) } logger.Debugf("grpc client connecting %s", grpcServer) - conn, rerr := grpc.Dial(grpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(GrpcClientLog), opts) + interceptors := append(ClientInterceptors, GrpcClientLog) + inOpt := grpc.WithUnaryInterceptor(grpc_middleware.ChainUnaryClient(interceptors...)) + conn, rerr := grpc.Dial(grpcServer, inOpt, grpc.WithInsecure(), opts) if rerr == nil { clients.Store(grpcServer, conn) v = conn diff --git a/dtmgrpc/dtmgimp/utils.go b/dtmgrpc/dtmgimp/utils.go index bb49f39..fb3eadf 100644 --- a/dtmgrpc/dtmgimp/utils.go +++ b/dtmgrpc/dtmgimp/utils.go @@ -31,9 +31,11 @@ func DtmGrpcCall(s *dtmimp.TransBase, operation string) error { Gid: s.Gid, TransType: s.TransType, TransOptions: &dtmgpb.DtmTransOptions{ - WaitResult: s.WaitResult, - TimeoutToFail: s.TimeoutToFail, - RetryInterval: s.RetryInterval, + WaitResult: s.WaitResult, + TimeoutToFail: s.TimeoutToFail, + RetryInterval: s.RetryInterval, + PassthroughHeaders: s.PassthroughHeaders, + BranchHeaders: s.BranchHeaders, }, QueryPrepared: s.QueryPrepared, CustomedData: s.CustomData, @@ -42,20 +44,29 @@ func DtmGrpcCall(s *dtmimp.TransBase, operation string) error { }, &reply) } -const mdpre string = "dtm-" +const dtmpre string = "dtm-" // TransInfo2Ctx add trans info to grpc context func TransInfo2Ctx(gid, transType, branchID, op, dtm string) context.Context { md := metadata.Pairs( - mdpre+"gid", gid, - mdpre+"trans_type", transType, - mdpre+"branch_id", branchID, - mdpre+"op", op, - mdpre+"dtm", dtm, + dtmpre+"gid", gid, + dtmpre+"trans_type", transType, + dtmpre+"branch_id", branchID, + dtmpre+"op", op, + dtmpre+"dtm", dtm, ) return metadata.NewOutgoingContext(context.Background(), md) } +// Map2Kvs map to metadata kv +func Map2Kvs(m map[string]string) []string { + kvs := []string{} + for k, v := range m { + kvs = append(kvs, k, v) + } + return kvs +} + // LogDtmCtx logout dtm info in context metadata func LogDtmCtx(ctx context.Context) { tb := TransBaseFromGrpc(ctx) @@ -64,8 +75,12 @@ func LogDtmCtx(ctx context.Context) { } } +func dtmGet(md metadata.MD, key string) string { + return mdGet(md, dtmpre+key) +} + func mdGet(md metadata.MD, key string) string { - v := md.Get(mdpre + key) + v := md.Get(key) if len(v) == 0 { return "" } @@ -75,7 +90,13 @@ func mdGet(md metadata.MD, key string) string { // TransBaseFromGrpc get trans base info from a context metadata func TransBaseFromGrpc(ctx context.Context) *dtmimp.TransBase { md, _ := metadata.FromIncomingContext(ctx) - tb := dtmimp.NewTransBase(mdGet(md, "gid"), mdGet(md, "trans_type"), mdGet(md, "dtm"), mdGet(md, "branch_id")) - tb.Op = mdGet(md, "op") + tb := dtmimp.NewTransBase(dtmGet(md, "gid"), dtmGet(md, "trans_type"), dtmGet(md, "dtm"), dtmGet(md, "branch_id")) + tb.Op = dtmGet(md, "op") return tb } + +// GetMetaFromContext get header from context +func GetMetaFromContext(ctx context.Context, name string) string { + md, _ := metadata.FromIncomingContext(ctx) + return mdGet(md, name) +} diff --git a/dtmgrpc/dtmgpb/dtmgimp.pb.go b/dtmgrpc/dtmgpb/dtmgimp.pb.go index 89a2526..9247260 100644 --- a/dtmgrpc/dtmgpb/dtmgimp.pb.go +++ b/dtmgrpc/dtmgpb/dtmgimp.pb.go @@ -26,9 +26,11 @@ type DtmTransOptions struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - WaitResult bool `protobuf:"varint,1,opt,name=WaitResult,proto3" json:"WaitResult,omitempty"` - TimeoutToFail int64 `protobuf:"varint,2,opt,name=TimeoutToFail,proto3" json:"TimeoutToFail,omitempty"` - RetryInterval int64 `protobuf:"varint,3,opt,name=RetryInterval,proto3" json:"RetryInterval,omitempty"` + WaitResult bool `protobuf:"varint,1,opt,name=WaitResult,proto3" json:"WaitResult,omitempty"` + TimeoutToFail int64 `protobuf:"varint,2,opt,name=TimeoutToFail,proto3" json:"TimeoutToFail,omitempty"` + RetryInterval int64 `protobuf:"varint,3,opt,name=RetryInterval,proto3" json:"RetryInterval,omitempty"` + PassthroughHeaders []string `protobuf:"bytes,4,rep,name=PassthroughHeaders,proto3" json:"PassthroughHeaders,omitempty"` + BranchHeaders map[string]string `protobuf:"bytes,5,rep,name=BranchHeaders,proto3" json:"BranchHeaders,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` } func (x *DtmTransOptions) Reset() { @@ -84,6 +86,20 @@ func (x *DtmTransOptions) GetRetryInterval() int64 { return 0 } +func (x *DtmTransOptions) GetPassthroughHeaders() []string { + if x != nil { + return x.PassthroughHeaders + } + return nil +} + +func (x *DtmTransOptions) GetBranchHeaders() map[string]string { + if x != nil { + return x.BranchHeaders + } + return nil +} + // DtmRequest request sent to dtm server type DtmRequest struct { state protoimpl.MessageState @@ -321,69 +337,82 @@ var file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDesc = []byte{ 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7d, 0x0a, 0x0f, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x57, 0x61, 0x69, 0x74, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x57, 0x61, 0x69, - 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, - 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x12, 0x24, 0x0a, - 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, - 0x76, 0x61, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x0a, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, - 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, - 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, - 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x64, - 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, - 0x61, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x69, 0x6e, 0x50, 0x61, - 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, - 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x51, - 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, - 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, 0x65, - 0x70, 0x73, 0x22, 0x1f, 0x0a, 0x0b, 0x44, 0x74, 0x6d, 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x47, 0x69, 0x64, 0x22, 0x82, 0x02, 0x0a, 0x10, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, + 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc2, 0x02, 0x0a, 0x0f, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x57, 0x61, 0x69, 0x74, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x57, 0x61, + 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x12, 0x24, + 0x0a, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x12, 0x2e, 0x0a, 0x12, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, + 0x75, 0x67, 0x68, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, + 0x52, 0x12, 0x50, 0x61, 0x73, 0x73, 0x74, 0x68, 0x72, 0x6f, 0x75, 0x67, 0x68, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x12, 0x51, 0x0a, 0x0d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x48, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x64, 0x74, + 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, + 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x48, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x1a, 0x40, 0x0a, 0x12, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xfc, 0x01, 0x0a, 0x0a, 0x44, 0x74, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x02, 0x4f, 0x70, 0x12, 0x37, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, - 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, - 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, - 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, - 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, - 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xb1, 0x02, 0x0a, 0x03, 0x44, 0x74, 0x6d, - 0x12, 0x38, 0x0a, 0x06, 0x4e, 0x65, 0x77, 0x47, 0x69, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, - 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x53, 0x75, - 0x62, 0x6d, 0x69, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, + 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, + 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x75, + 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x69, + 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, + 0x0b, 0x42, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, + 0x65, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x53, 0x74, 0x65, 0x70, 0x73, 0x22, 0x1f, 0x0a, 0x0b, 0x44, 0x74, 0x6d, 0x47, + 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x22, 0x82, 0x02, 0x0a, 0x10, 0x44, 0x74, + 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, + 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, + 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, + 0x0a, 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, 0x44, 0x12, 0x0e, 0x0a, 0x02, 0x4f, 0x70, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x4f, 0x70, 0x12, 0x37, 0x0a, 0x04, 0x44, 0x61, + 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, + 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x2e, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x44, + 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, + 0x61, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, + 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x1a, 0x37, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x32, 0xb1, + 0x02, 0x0a, 0x03, 0x44, 0x74, 0x6d, 0x12, 0x38, 0x0a, 0x06, 0x4e, 0x65, 0x77, 0x47, 0x69, 0x64, + 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, + 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, + 0x12, 0x37, 0x0a, 0x06, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, + 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x07, 0x50, 0x72, 0x65, + 0x70, 0x61, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x13, - 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, - 0x05, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, - 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x19, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, - 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, - 0x2e, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x05, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x2e, 0x64, + 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0e, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x19, 0x2e, + 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x42, 0x0a, 0x5a, 0x08, 0x2e, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x70, 0x62, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -398,33 +427,35 @@ func file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescGZIP() []byte { return file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDescData } -var file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes = make([]protoimpl.MessageInfo, 5) +var file_dtmgrpc_dtmgpb_dtmgimp_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_dtmgrpc_dtmgpb_dtmgimp_proto_goTypes = []interface{}{ (*DtmTransOptions)(nil), // 0: dtmgimp.DtmTransOptions (*DtmRequest)(nil), // 1: dtmgimp.DtmRequest (*DtmGidReply)(nil), // 2: dtmgimp.DtmGidReply (*DtmBranchRequest)(nil), // 3: dtmgimp.DtmBranchRequest - nil, // 4: dtmgimp.DtmBranchRequest.DataEntry - (*emptypb.Empty)(nil), // 5: google.protobuf.Empty + nil, // 4: dtmgimp.DtmTransOptions.BranchHeadersEntry + nil, // 5: dtmgimp.DtmBranchRequest.DataEntry + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty } var file_dtmgrpc_dtmgpb_dtmgimp_proto_depIdxs = []int32{ - 0, // 0: dtmgimp.DtmRequest.TransOptions:type_name -> dtmgimp.DtmTransOptions - 4, // 1: dtmgimp.DtmBranchRequest.Data:type_name -> dtmgimp.DtmBranchRequest.DataEntry - 5, // 2: dtmgimp.Dtm.NewGid:input_type -> google.protobuf.Empty - 1, // 3: dtmgimp.Dtm.Submit:input_type -> dtmgimp.DtmRequest - 1, // 4: dtmgimp.Dtm.Prepare:input_type -> dtmgimp.DtmRequest - 1, // 5: dtmgimp.Dtm.Abort:input_type -> dtmgimp.DtmRequest - 3, // 6: dtmgimp.Dtm.RegisterBranch:input_type -> dtmgimp.DtmBranchRequest - 2, // 7: dtmgimp.Dtm.NewGid:output_type -> dtmgimp.DtmGidReply - 5, // 8: dtmgimp.Dtm.Submit:output_type -> google.protobuf.Empty - 5, // 9: dtmgimp.Dtm.Prepare:output_type -> google.protobuf.Empty - 5, // 10: dtmgimp.Dtm.Abort:output_type -> google.protobuf.Empty - 5, // 11: dtmgimp.Dtm.RegisterBranch:output_type -> google.protobuf.Empty - 7, // [7:12] is the sub-list for method output_type - 2, // [2:7] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 4, // 0: dtmgimp.DtmTransOptions.BranchHeaders:type_name -> dtmgimp.DtmTransOptions.BranchHeadersEntry + 0, // 1: dtmgimp.DtmRequest.TransOptions:type_name -> dtmgimp.DtmTransOptions + 5, // 2: dtmgimp.DtmBranchRequest.Data:type_name -> dtmgimp.DtmBranchRequest.DataEntry + 6, // 3: dtmgimp.Dtm.NewGid:input_type -> google.protobuf.Empty + 1, // 4: dtmgimp.Dtm.Submit:input_type -> dtmgimp.DtmRequest + 1, // 5: dtmgimp.Dtm.Prepare:input_type -> dtmgimp.DtmRequest + 1, // 6: dtmgimp.Dtm.Abort:input_type -> dtmgimp.DtmRequest + 3, // 7: dtmgimp.Dtm.RegisterBranch:input_type -> dtmgimp.DtmBranchRequest + 2, // 8: dtmgimp.Dtm.NewGid:output_type -> dtmgimp.DtmGidReply + 6, // 9: dtmgimp.Dtm.Submit:output_type -> google.protobuf.Empty + 6, // 10: dtmgimp.Dtm.Prepare:output_type -> google.protobuf.Empty + 6, // 11: dtmgimp.Dtm.Abort:output_type -> google.protobuf.Empty + 6, // 12: dtmgimp.Dtm.RegisterBranch:output_type -> google.protobuf.Empty + 8, // [8:13] is the sub-list for method output_type + 3, // [3:8] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_dtmgrpc_dtmgpb_dtmgimp_proto_init() } @@ -488,7 +519,7 @@ func file_dtmgrpc_dtmgpb_dtmgimp_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_dtmgrpc_dtmgpb_dtmgimp_proto_rawDesc, NumEnums: 0, - NumMessages: 5, + NumMessages: 6, NumExtensions: 0, NumServices: 1, }, diff --git a/dtmgrpc/dtmgpb/dtmgimp.proto b/dtmgrpc/dtmgpb/dtmgimp.proto index 84e3105..f97b277 100644 --- a/dtmgrpc/dtmgpb/dtmgimp.proto +++ b/dtmgrpc/dtmgpb/dtmgimp.proto @@ -18,6 +18,8 @@ message DtmTransOptions { bool WaitResult = 1; int64 TimeoutToFail = 2; int64 RetryInterval = 3; + repeated string PassthroughHeaders = 4; + map BranchHeaders = 5; } // DtmRequest request sent to dtm server diff --git a/dtmgrpc/tcc.go b/dtmgrpc/tcc.go index d4c0592..3f39676 100644 --- a/dtmgrpc/tcc.go +++ b/dtmgrpc/tcc.go @@ -14,6 +14,7 @@ import ( "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "github.com/dtm-labs/dtmdriver" + "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" ) @@ -30,13 +31,14 @@ type TccGlobalFunc func(tcc *TccGrpc) error // gid 全局事务id // tccFunc tcc事务函数,里面会定义全局事务的分支 func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr error) { + return TccGlobalTransaction2(dtm, gid, func(tg *TccGrpc) {}, tccFunc) +} + +// TccGlobalTransaction2 new version of TccGlobalTransaction +func TccGlobalTransaction2(dtm string, gid string, custom func(*TccGrpc), tccFunc TccGlobalFunc) (rerr error) { tcc := &TccGrpc{TransBase: *dtmimp.NewTransBase(gid, "tcc", dtm, "")} - dc := dtmgimp.MustGetDtmClient(tcc.Dtm) - dr := &dtmgpb.DtmRequest{ - Gid: tcc.Gid, - TransType: tcc.TransType, - } - _, rerr = dc.Prepare(context.Background(), dr) + custom(tcc) + rerr = dtmgimp.DtmGrpcCall(&tcc.TransBase, "Prepare") if rerr != nil { return rerr } @@ -44,10 +46,10 @@ func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr e defer func() { x := recover() if x == nil && rerr == nil { - _, rerr = dc.Submit(context.Background(), dr) + rerr = dtmgimp.DtmGrpcCall(&tcc.TransBase, "Submit") return } - _, err := dc.Abort(context.Background(), dr) + err := dtmgimp.DtmGrpcCall(&tcc.TransBase, "Abort") if rerr == nil { rerr = err } @@ -87,6 +89,7 @@ func (t *TccGrpc) CallBranch(busiMsg proto.Message, tryURL string, confirmURL st if err != nil { return err } - return dtmgimp.MustGetGrpcConn(server, false).Invoke( - dtmgimp.TransInfo2Ctx(t.Gid, t.TransType, branchID, "try", t.Dtm), method, busiMsg, reply) + ctx := dtmgimp.TransInfo2Ctx(t.Gid, t.TransType, branchID, "try", t.Dtm) + ctx = metadata.AppendToOutgoingContext(ctx, dtmgimp.Map2Kvs(t.BranchHeaders)...) + return dtmgimp.MustGetGrpcConn(server, false).Invoke(ctx, method, busiMsg, reply) } diff --git a/dtmgrpc/type.go b/dtmgrpc/type.go index c2b7fa7..d166b5c 100644 --- a/dtmgrpc/type.go +++ b/dtmgrpc/type.go @@ -9,10 +9,10 @@ package dtmgrpc import ( context "context" - "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtmdriver" + grpc "google.golang.org/grpc" emptypb "google.golang.org/protobuf/types/known/emptypb" ) @@ -24,16 +24,11 @@ func MustGenGid(grpcServer string) string { return r.Gid } -// SetCurrentDBType set the current db type -func SetCurrentDBType(dbType string) { - dtmcli.SetCurrentDBType(dbType) -} - -// GetCurrentDBType set the current db type -func GetCurrentDBType() string { - return dtmcli.GetCurrentDBType() -} - +// UseDriver use the specified driver to handle grpc urls func UseDriver(driverName string) error { return dtmdriver.Use(driverName) } + +func AddUnaryInterceptor(interceptor grpc.UnaryClientInterceptor) { + dtmgimp.ClientInterceptors = append(dtmgimp.ClientInterceptors, interceptor) +} diff --git a/dtmgrpc/type_test.go b/dtmgrpc/type_test.go index 7c44e4a..c54583e 100644 --- a/dtmgrpc/type_test.go +++ b/dtmgrpc/type_test.go @@ -10,7 +10,6 @@ import ( "context" "testing" - "github.com/dtm-labs/dtm/dtmcli" "github.com/stretchr/testify/assert" ) @@ -21,10 +20,6 @@ func TestType(t *testing.T) { _, err = TccFromGrpc(context.Background()) assert.Error(t, err) - old := GetCurrentDBType() - SetCurrentDBType(dtmcli.DBTypeMysql) - SetCurrentDBType(old) - err = UseDriver("default") assert.Nil(t, err) } diff --git a/dtmgrpc/xa.go b/dtmgrpc/xa.go index 95a97a1..3cfd8bf 100644 --- a/dtmgrpc/xa.go +++ b/dtmgrpc/xa.go @@ -92,7 +92,13 @@ func (xc *XaGrpcClient) XaLocalTransaction(ctx context.Context, msg proto.Messag // XaGlobalTransaction start a xa global transaction func (xc *XaGrpcClient) XaGlobalTransaction(gid string, xaFunc XaGrpcGlobalFunc) error { - xa := XaGrpc{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.Server, "")} + return xc.XaGlobalTransaction2(gid, func(xg *XaGrpc) {}, xaFunc) +} + +// XaGlobalTransaction2 new version of XaGlobalTransaction. support custom +func (xc *XaGrpcClient) XaGlobalTransaction2(gid string, custom func(*XaGrpc), xaFunc XaGrpcGlobalFunc) error { + xa := &XaGrpc{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.Server, "")} + custom(xa) dc := dtmgimp.MustGetDtmClient(xa.Dtm) req := &dtmgpb.DtmRequest{ Gid: gid, @@ -107,7 +113,7 @@ func (xc *XaGrpcClient) XaGlobalTransaction(gid string, xaFunc XaGrpcGlobalFunc) _, err := f(context.Background(), req) return err }, func() error { - return xaFunc(&xa) + return xaFunc(xa) }) } diff --git a/dtmsvr/api_grpc.go b/dtmsvr/api_grpc.go index 461b251..8cd48d3 100644 --- a/dtmsvr/api_grpc.go +++ b/dtmsvr/api_grpc.go @@ -25,17 +25,17 @@ func (s *dtmServer) NewGid(ctx context.Context, in *emptypb.Empty) (*pb.DtmGidRe } func (s *dtmServer) Submit(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { - r, err := svcSubmit(TransFromDtmRequest(in)) + r, err := svcSubmit(TransFromDtmRequest(ctx, in)) return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } func (s *dtmServer) Prepare(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { - r, err := svcPrepare(TransFromDtmRequest(in)) + r, err := svcPrepare(TransFromDtmRequest(ctx, in)) return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } func (s *dtmServer) Abort(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { - r, err := svcAbort(TransFromDtmRequest(in)) + r, err := svcAbort(TransFromDtmRequest(ctx, in)) return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 9acc8f5..5aad90f 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -24,16 +24,18 @@ type MicroService struct { } type Store struct { - Driver string `yaml:"Driver" default:"boltdb"` - Host string `yaml:"Host"` - Port int64 `yaml:"Port"` - User string `yaml:"User"` - Password string `yaml:"Password"` - MaxOpenConns int64 `yaml:"MaxOpenConns" default:"500"` - MaxIdleConns int64 `yaml:"MaxIdleConns" default:"500"` - ConnMaxLifeTime int64 `yaml:"ConnMaxLifeTime" default:"5"` - DataExpire int64 `yaml:"DataExpire" default:"604800"` // Trans data will expire in 7 days. only for redis/boltdb. - RedisPrefix string `yaml:"RedisPrefix" default:"{a}"` // Redis storage prefix. store data to only one slot in cluster + Driver string `yaml:"Driver" default:"boltdb"` + Host string `yaml:"Host"` + Port int64 `yaml:"Port"` + User string `yaml:"User"` + Password string `yaml:"Password"` + MaxOpenConns int64 `yaml:"MaxOpenConns" default:"500"` + MaxIdleConns int64 `yaml:"MaxIdleConns" default:"500"` + ConnMaxLifeTime int64 `yaml:"ConnMaxLifeTime" default:"5"` + DataExpire int64 `yaml:"DataExpire" default:"604800"` // Trans data will expire in 7 days. only for redis/boltdb. + RedisPrefix string `yaml:"RedisPrefix" default:"{a}"` // Redis storage prefix. store data to only one slot in cluster + TransGlobalTable string `yaml:"TransGlobalTable" default:"dtm.trans_global"` + TransBranchOpTable string `yaml:"BranchTransOpTable" default:"dtm.trans_branch_op"` } func (s *Store) IsDB() bool { @@ -77,7 +79,7 @@ func MustLoadConfig(confFile string) { scont, err := json.MarshalIndent(&Config, "", " ") logger.FatalIfError(err) logger.Infof("config file: %s loaded config is: \n%s", confFile, scont) - err = checkConfig() + err = checkConfig(&Config) logger.FatalfIf(err != nil, `config error: '%v'. please visit http://d.dtm.pub to see the config document.`, err) } diff --git a/dtmsvr/config/config_test.go b/dtmsvr/config/config_test.go index 8088bef..f7ac1e8 100644 --- a/dtmsvr/config/config_test.go +++ b/dtmsvr/config/config_test.go @@ -17,38 +17,47 @@ func TestLoadFromEnv(t *testing.T) { assert.Equal(t, "d1", ms.Driver) } -func TestCheckConfig(t *testing.T) { +func TestLoadConfig(t *testing.T) { MustLoadConfig("../../conf.sample.yml") - config := &Config - config.RetryInterval = 1 - retryIntervalErr := checkConfig() +} +func TestCheckConfig(t *testing.T) { + conf := Config + conf.RetryInterval = 1 + retryIntervalErr := checkConfig(&conf) retryIntervalExpect := errors.New("RetryInterval should not be less than 10") assert.Equal(t, retryIntervalErr, retryIntervalExpect) - config.RetryInterval = 10 - config.TimeoutToFail = 5 - timeoutToFailErr := checkConfig() + conf.RetryInterval = 10 + conf.TimeoutToFail = 5 + timeoutToFailErr := checkConfig(&conf) timeoutToFailExpect := errors.New("TimeoutToFail should not be less than RetryInterval") assert.Equal(t, timeoutToFailErr, timeoutToFailExpect) - config.TimeoutToFail = 20 - driverErr := checkConfig() + conf.TimeoutToFail = 20 + driverErr := checkConfig(&conf) assert.Equal(t, driverErr, nil) - config.Store = Store{Driver: Mysql} - hostErr := checkConfig() + conf.Store = Store{Driver: Mysql} + hostErr := checkConfig(&conf) hostExpect := errors.New("Db host not valid ") assert.Equal(t, hostErr, hostExpect) - config.Store = Store{Driver: Mysql, Host: "127.0.0.1"} - portErr := checkConfig() + conf.Store = Store{Driver: Mysql, Host: "127.0.0.1"} + portErr := checkConfig(&conf) portExpect := errors.New("Db port not valid ") assert.Equal(t, portErr, portExpect) - config.Store = Store{Driver: Mysql, Host: "127.0.0.1", Port: 8686} - userErr := checkConfig() + conf.Store = Store{Driver: Mysql, Host: "127.0.0.1", Port: 8686} + userErr := checkConfig(&conf) userExpect := errors.New("Db user not valid ") assert.Equal(t, userErr, userExpect) + + conf.Store = Store{Driver: Redis, Host: "", Port: 8686} + assert.Equal(t, errors.New("Redis host not valid"), checkConfig(&conf)) + + conf.Store = Store{Driver: Redis, Host: "127.0.0.1", Port: 0} + assert.Equal(t, errors.New("Redis port not valid"), checkConfig(&conf)) + } func TestConfig(t *testing.T) { @@ -61,7 +70,7 @@ func TestConfig(t *testing.T) { func testConfigStringField(fd *string, val string, t *testing.T) { old := *fd *fd = val - str := checkConfig() + str := checkConfig(&Config) assert.NotEqual(t, "", str) *fd = old } @@ -69,7 +78,7 @@ func testConfigStringField(fd *string, val string, t *testing.T) { func testConfigIntField(fd *int64, val int64, t *testing.T) { old := *fd *fd = val - str := checkConfig() + str := checkConfig(&Config) assert.NotEqual(t, "", str) *fd = old } diff --git a/dtmsvr/config/config_utils.go b/dtmsvr/config/config_utils.go index 1dc991f..e5b1785 100644 --- a/dtmsvr/config/config_utils.go +++ b/dtmsvr/config/config_utils.go @@ -55,32 +55,32 @@ func toUnderscoreUpper(key string) string { return strings.ToUpper(s2) } -func checkConfig() error { - if Config.RetryInterval < 10 { +func checkConfig(conf *configType) error { + if conf.RetryInterval < 10 { return errors.New("RetryInterval should not be less than 10") } - if Config.TimeoutToFail < Config.RetryInterval { + if conf.TimeoutToFail < conf.RetryInterval { return errors.New("TimeoutToFail should not be less than RetryInterval") } - switch Config.Store.Driver { + switch conf.Store.Driver { case BoltDb: return nil case Mysql: - if Config.Store.Host == "" { + if conf.Store.Host == "" { return errors.New("Db host not valid ") } - if Config.Store.Port == 0 { + if conf.Store.Port == 0 { return errors.New("Db port not valid ") } - if Config.Store.User == "" { + if conf.Store.User == "" { return errors.New("Db user not valid ") } case Redis: - if Config.Store.Host == "" { - return errors.New("Redis host not valid ") + if conf.Store.Host == "" { + return errors.New("Redis host not valid") } - if Config.Store.Port == 0 { - return errors.New("Redis port not valid ") + if conf.Store.Port == 0 { + return errors.New("Redis port not valid") } } return nil diff --git a/dtmsvr/storage/trans.go b/dtmsvr/storage/trans.go index e1f3fa3..80663c9 100644 --- a/dtmsvr/storage/trans.go +++ b/dtmsvr/storage/trans.go @@ -5,9 +5,14 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmutil" ) +type TransGlobalExt struct { + Headers map[string]string `json:"headers,omitempty" gorm:"-"` +} + type TransGlobalStore struct { dtmutil.ModelBase Gid string `json:"gid,omitempty"` @@ -18,7 +23,6 @@ type TransGlobalStore struct { Status string `json:"status,omitempty"` QueryPrepared string `json:"query_prepared,omitempty"` Protocol string `json:"protocol,omitempty"` - CommitTime *time.Time `json:"commit_time,omitempty"` FinishTime *time.Time `json:"finish_time,omitempty"` RollbackTime *time.Time `json:"rollback_time,omitempty"` Options string `json:"options,omitempty"` @@ -26,12 +30,14 @@ type TransGlobalStore struct { NextCronInterval int64 `json:"next_cron_interval,omitempty"` NextCronTime *time.Time `json:"next_cron_time,omitempty"` Owner string `json:"owner,omitempty"` + Ext TransGlobalExt `json:"-" gorm:"-"` + ExtData string `json:"ext_data,omitempty"` // storage of ext. a db field to store many values. like Options dtmcli.TransOptions } // TableName TableName func (g *TransGlobalStore) TableName() string { - return "dtm.trans_global" + return config.Config.Store.TransGlobalTable } func (g *TransGlobalStore) String() string { @@ -53,7 +59,7 @@ type TransBranchStore struct { // TableName TableName func (b *TransBranchStore) TableName() string { - return "dtm.trans_branch_op" + return config.Config.Store.TransBranchOpTable } func (b *TransBranchStore) String() string { diff --git a/dtmsvr/trans_class.go b/dtmsvr/trans_class.go index 977f44b..50f9b01 100644 --- a/dtmsvr/trans_class.go +++ b/dtmsvr/trans_class.go @@ -7,11 +7,13 @@ package dtmsvr import ( + "context" "time" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "github.com/dtm-labs/dtm/dtmsvr/storage" "github.com/gin-gonic/gin" @@ -69,11 +71,21 @@ func TransFromContext(c *gin.Context) *TransGlobal { } } m.Protocol = "http" + + m.Ext.Headers = map[string]string{} + if len(m.PassthroughHeaders) > 0 { + for _, h := range m.PassthroughHeaders { + v := c.GetHeader(h) + if v != "" { + m.Ext.Headers[h] = v + } + } + } return &m } // TransFromDtmRequest TransFromContext -func TransFromDtmRequest(c *dtmgpb.DtmRequest) *TransGlobal { +func TransFromDtmRequest(ctx context.Context, c *dtmgpb.DtmRequest) *TransGlobal { o := &dtmgpb.DtmTransOptions{} if c.TransOptions != nil { o = c.TransOptions @@ -85,13 +97,24 @@ func TransFromDtmRequest(c *dtmgpb.DtmRequest) *TransGlobal { Protocol: "grpc", BinPayloads: c.BinPayloads, TransOptions: dtmcli.TransOptions{ - WaitResult: o.WaitResult, - TimeoutToFail: o.TimeoutToFail, - RetryInterval: o.RetryInterval, + WaitResult: o.WaitResult, + TimeoutToFail: o.TimeoutToFail, + RetryInterval: o.RetryInterval, + PassthroughHeaders: o.PassthroughHeaders, + BranchHeaders: o.BranchHeaders, }, }} if c.Steps != "" { dtmimp.MustUnmarshalString(c.Steps, &r.Steps) } + if len(o.PassthroughHeaders) > 0 { + r.Ext.Headers = map[string]string{} + for _, h := range o.PassthroughHeaders { + v := dtmgimp.GetMetaFromContext(ctx, h) + if v != "" { + r.Ext.Headers[h] = v + } + } + } return &r } diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index cac4c96..db6243c 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -26,6 +26,9 @@ func (t *TransGlobal) process(branches []TransBranch) map[string]interface{} { if t.Options != "" { dtmimp.MustUnmarshalString(t.Options, &t.TransOptions) } + if t.ExtData != "" { + dtmimp.MustUnmarshalString(t.ExtData, &t.Ext) + } if !t.WaitResult { go t.processInner(branches) @@ -63,6 +66,10 @@ func (t *TransGlobal) processInner(branches []TransBranch) (rerr error) { func (t *TransGlobal) saveNew() ([]TransBranch, error) { t.NextCronInterval = t.getNextCronInterval(cronReset) t.NextCronTime = dtmutil.GetNextTime(t.NextCronInterval) + t.ExtData = dtmimp.MustMarshalString(t.Ext) + if t.ExtData == "{}" { + t.ExtData = "" + } t.Options = dtmimp.MustMarshalString(t.TransOptions) if t.Options == "{}" { t.Options = "" diff --git a/dtmsvr/trans_status.go b/dtmsvr/trans_status.go index 6f1dea0..c04110a 100644 --- a/dtmsvr/trans_status.go +++ b/dtmsvr/trans_status.go @@ -17,6 +17,7 @@ import ( "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtmdriver" "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) @@ -83,6 +84,9 @@ func (t *TransGlobal) getURLResult(url string, branchID, op string, branchPayloa } conn := dtmgimp.MustGetGrpcConn(server, true) ctx := dtmgimp.TransInfo2Ctx(t.Gid, t.TransType, branchID, op, "") + kvs := dtmgimp.Map2Kvs(t.Ext.Headers) + kvs = append(kvs, dtmgimp.Map2Kvs(t.BranchHeaders)...) + ctx = metadata.AppendToOutgoingContext(ctx, kvs...) err = conn.Invoke(ctx, method, branchPayload, &[]byte{}) if err == nil { return dtmcli.ResultSuccess, nil @@ -106,6 +110,8 @@ func (t *TransGlobal) getURLResult(url string, branchID, op string, branchPayloa "op": op, }). SetHeader("Content-type", "application/json"). + SetHeaders(t.Ext.Headers). + SetHeaders(t.TransOptions.BranchHeaders). Execute(dtmimp.If(branchPayload != nil || t.TransType == "xa", "POST", "GET").(string), url) if err != nil { return "", err diff --git a/go.mod b/go.mod index 0d19a2f..306fad3 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,6 @@ require ( github.com/dtm-labs/dtmdriver-polaris v0.0.2 github.com/dtm-labs/dtmdriver-protocol1 v0.0.1 github.com/gin-gonic/gin v1.6.3 - github.com/go-redis/redis/v8 v8.11.4 github.com/go-resty/resty/v2 v2.7.0 github.com/go-sql-driver/mysql v1.6.0 diff --git a/go.sum b/go.sum index 09eb829..d37ef25 100644 --- a/go.sum +++ b/go.sum @@ -509,6 +509,12 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/ychensha/dtmdriver-polaris v0.0.1/go.mod h1:0BdQvxXlGOlF6YVlsDoVvu8jyxdTlJZ9Kyh5t9lRA94= +github.com/yedf/dtm v1.7.2 h1:qGjio5O+Zm5CmMfga9Eb0rsUu9nkNHxGuJwc7PEkMfc= +github.com/yedf/dtm v1.7.2/go.mod h1:R1Q55spqLh7yHMVJhGI8RpS1iG7OvRX99pWZRlsAtME= +github.com/yedf/dtmdriver v0.0.0-20211203060147-29426c663b6e/go.mod h1:aeo6ZWiVI0x8P8O18r6uB1cG2uw9BCQyYZaH15MlRDI= +github.com/yedf/dtmdriver-gozero v0.0.0-20211204083751-a14485949435/go.mod h1:RYtA6oZny6LzlIRb1tPGt5bHfgqws/JaU6ogFly8ByQ= +github.com/yedf/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e/go.mod h1:kB3NPnDKSGioVjgdfj6qgbqYJinOml45GnlHqR46Ycc= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= diff --git a/helper/sync-dtmcli.sh b/helper/sync-dtmcli.sh index 3ac42b0..dd70a5a 100755 --- a/helper/sync-dtmcli.sh +++ b/helper/sync-dtmcli.sh @@ -30,8 +30,6 @@ go build || exit 1 git add . git commit -m"update from dtm to version $ver" git push -git tag $ver -git push --tags cd ../dtmgrpc diff --git a/sqls/dtmsvr.storage.mysql.sql b/sqls/dtmsvr.storage.mysql.sql index 59d61dd..09c82f5 100644 --- a/sqls/dtmsvr.storage.mysql.sql +++ b/sqls/dtmsvr.storage.mysql.sql @@ -12,14 +12,14 @@ CREATE TABLE if not EXISTS dtm.trans_global ( `protocol` varchar(45) not null comment '通信协议 http | grpc', `create_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL, - `commit_time` datetime DEFAULT NULL, `finish_time` datetime DEFAULT NULL, `rollback_time` datetime DEFAULT NULL, - `options` varchar(256) DEFAULT '', + `options` varchar(1024) DEFAULT '', `custom_data` varchar(256) DEFAULT '', `next_cron_interval` int(11) default null comment '下次定时处理的间隔', `next_cron_time` datetime default null comment '下次定时处理的时间', `owner` varchar(128) not null default '' comment '正在处理全局事务的锁定者', + `ext_data` TEXT comment 'global扩展字段的数据', PRIMARY KEY (`id`), UNIQUE KEY `gid` (`gid`), key `owner`(`owner`), diff --git a/sqls/dtmsvr.storage.postgres.sql b/sqls/dtmsvr.storage.postgres.sql index bccb8be..f19d25e 100644 --- a/sqls/dtmsvr.storage.postgres.sql +++ b/sqls/dtmsvr.storage.postgres.sql @@ -13,14 +13,14 @@ CREATE TABLE if not EXISTS dtm.trans_global ( protocol varchar(45) not null, create_time timestamp(0) with time zone DEFAULT NULL, update_time timestamp(0) with time zone DEFAULT NULL, - commit_time timestamp(0) with time zone DEFAULT NULL, finish_time timestamp(0) with time zone DEFAULT NULL, rollback_time timestamp(0) with time zone DEFAULT NULL, - options varchar(256) DEFAULT '', + options varchar(1024) DEFAULT '', custom_data varchar(256) DEFAULT '', next_cron_interval int default null, next_cron_time timestamp(0) with time zone default null, owner varchar(128) not null default '', + ext_data text, PRIMARY KEY (id), CONSTRAINT gid UNIQUE (gid) ); diff --git a/test/busi/base_grpc.go b/test/busi/base_grpc.go index dcfca4e..6fd3790 100644 --- a/test/busi/base_grpc.go +++ b/test/busi/base_grpc.go @@ -9,6 +9,7 @@ package busi import ( "context" "database/sql" + "errors" "fmt" "net" @@ -123,3 +124,19 @@ func (s *busiServer) TransInTccNested(ctx context.Context, in *BusiReq) (*emptyp func (s *busiServer) XaNotify(ctx context.Context, in *emptypb.Empty) (*emptypb.Empty, error) { return XaGrpcClient.HandleCallback(ctx) } + +func (s *busiServer) TransOutHeaderYes(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + meta := dtmgimp.GetMetaFromContext(ctx, "test_header") + if meta == "" { + return &emptypb.Empty{}, errors.New("no header found in HeaderYes") + } + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransOutResult.Fetch(), in.TransOutResult, dtmimp.GetFuncName()) +} + +func (s *busiServer) TransOutHeaderNo(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + meta := dtmgimp.GetMetaFromContext(ctx, "test_header") + if meta != "" { + return &emptypb.Empty{}, errors.New("header found in HeaderNo") + } + return &emptypb.Empty{}, nil +} diff --git a/test/busi/base_http.go b/test/busi/base_http.go index 4518d0e..fe47dd7 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -154,4 +154,18 @@ func BaseAddRoute(app *gin.Engine) { app.POST(BusiAPI+"/TccBSleepCancel", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return sleepCancelHandler(c) })) + app.POST(BusiAPI+"/TransOutHeaderYes", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + h := c.GetHeader("test_header") + if h == "" { + return nil, errors.New("no test_header found in TransOutHeaderYes") + } + return handleGeneralBusiness(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") + })) + app.POST(BusiAPI+"/TransOutHeaderNo", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + h := c.GetHeader("test_header") + if h != "" { + return nil, errors.New("test_header found in TransOutHeaderNo") + } + return dtmcli.MapSuccess, nil + })) } diff --git a/test/busi/busi.pb.go b/test/busi/busi.pb.go index fa73c00..cfa8766 100644 --- a/test/busi/busi.pb.go +++ b/test/busi/busi.pb.go @@ -148,7 +148,7 @@ var file_test_busi_busi_proto_rawDesc = []byte{ 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x25, 0x0a, 0x09, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x32, 0xd3, 0x07, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x2d, 0x0a, 0x09, 0x43, 0x61, + 0x65, 0x32, 0xce, 0x08, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x2d, 0x0a, 0x09, 0x43, 0x61, 0x6e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x72, 0x61, @@ -209,8 +209,16 @@ var file_test_busi_busi_proto_rawDesc = []byte{ 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x62, 0x75, 0x73, - 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x4f, 0x75, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x59, 0x65, 0x73, 0x12, 0x0d, 0x2e, 0x62, + 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, + 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, + 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x62, 0x75, 0x73, 0x69, 0x62, 0x06, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -249,25 +257,29 @@ var file_test_busi_busi_proto_depIdxs = []int32{ 0, // 14: busi.Busi.TransOutBSaga:input_type -> busi.BusiReq 0, // 15: busi.Busi.TransInRevertBSaga:input_type -> busi.BusiReq 0, // 16: busi.Busi.TransOutRevertBSaga:input_type -> busi.BusiReq - 1, // 17: busi.Busi.CanSubmit:output_type -> busi.BusiReply - 2, // 18: busi.Busi.TransIn:output_type -> google.protobuf.Empty - 2, // 19: busi.Busi.TransOut:output_type -> google.protobuf.Empty - 2, // 20: busi.Busi.TransInRevert:output_type -> google.protobuf.Empty - 2, // 21: busi.Busi.TransOutRevert:output_type -> google.protobuf.Empty - 2, // 22: busi.Busi.TransInConfirm:output_type -> google.protobuf.Empty - 2, // 23: busi.Busi.TransOutConfirm:output_type -> google.protobuf.Empty - 2, // 24: busi.Busi.XaNotify:output_type -> google.protobuf.Empty - 2, // 25: busi.Busi.TransInXa:output_type -> google.protobuf.Empty - 2, // 26: busi.Busi.TransOutXa:output_type -> google.protobuf.Empty - 2, // 27: busi.Busi.TransInTcc:output_type -> google.protobuf.Empty - 2, // 28: busi.Busi.TransOutTcc:output_type -> google.protobuf.Empty - 2, // 29: busi.Busi.TransInTccNested:output_type -> google.protobuf.Empty - 2, // 30: busi.Busi.TransInBSaga:output_type -> google.protobuf.Empty - 2, // 31: busi.Busi.TransOutBSaga:output_type -> google.protobuf.Empty - 2, // 32: busi.Busi.TransInRevertBSaga:output_type -> google.protobuf.Empty - 2, // 33: busi.Busi.TransOutRevertBSaga:output_type -> google.protobuf.Empty - 17, // [17:34] is the sub-list for method output_type - 0, // [0:17] is the sub-list for method input_type + 0, // 17: busi.Busi.TransOutHeaderYes:input_type -> busi.BusiReq + 0, // 18: busi.Busi.TransOutHeaderNo:input_type -> busi.BusiReq + 1, // 19: busi.Busi.CanSubmit:output_type -> busi.BusiReply + 2, // 20: busi.Busi.TransIn:output_type -> google.protobuf.Empty + 2, // 21: busi.Busi.TransOut:output_type -> google.protobuf.Empty + 2, // 22: busi.Busi.TransInRevert:output_type -> google.protobuf.Empty + 2, // 23: busi.Busi.TransOutRevert:output_type -> google.protobuf.Empty + 2, // 24: busi.Busi.TransInConfirm:output_type -> google.protobuf.Empty + 2, // 25: busi.Busi.TransOutConfirm:output_type -> google.protobuf.Empty + 2, // 26: busi.Busi.XaNotify:output_type -> google.protobuf.Empty + 2, // 27: busi.Busi.TransInXa:output_type -> google.protobuf.Empty + 2, // 28: busi.Busi.TransOutXa:output_type -> google.protobuf.Empty + 2, // 29: busi.Busi.TransInTcc:output_type -> google.protobuf.Empty + 2, // 30: busi.Busi.TransOutTcc:output_type -> google.protobuf.Empty + 2, // 31: busi.Busi.TransInTccNested:output_type -> google.protobuf.Empty + 2, // 32: busi.Busi.TransInBSaga:output_type -> google.protobuf.Empty + 2, // 33: busi.Busi.TransOutBSaga:output_type -> google.protobuf.Empty + 2, // 34: busi.Busi.TransInRevertBSaga:output_type -> google.protobuf.Empty + 2, // 35: busi.Busi.TransOutRevertBSaga:output_type -> google.protobuf.Empty + 2, // 36: busi.Busi.TransOutHeaderYes:output_type -> google.protobuf.Empty + 2, // 37: busi.Busi.TransOutHeaderNo:output_type -> google.protobuf.Empty + 19, // [19:38] is the sub-list for method output_type + 0, // [0:19] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/test/busi/busi.proto b/test/busi/busi.proto index 0e421b0..9d43abd 100644 --- a/test/busi/busi.proto +++ b/test/busi/busi.proto @@ -36,5 +36,7 @@ service Busi { rpc TransOutBSaga(BusiReq) returns (google.protobuf.Empty) {} rpc TransInRevertBSaga(BusiReq) returns (google.protobuf.Empty) {} rpc TransOutRevertBSaga(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutHeaderYes(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutHeaderNo(BusiReq) returns (google.protobuf.Empty) {} } diff --git a/test/busi/busi_grpc.pb.go b/test/busi/busi_grpc.pb.go index bc612b1..095b295 100644 --- a/test/busi/busi_grpc.pb.go +++ b/test/busi/busi_grpc.pb.go @@ -36,6 +36,8 @@ type BusiClient interface { TransOutBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransInRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransOutRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutHeaderYes(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutHeaderNo(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) } type busiClient struct { @@ -199,6 +201,24 @@ func (c *busiClient) TransOutRevertBSaga(ctx context.Context, in *BusiReq, opts return out, nil } +func (c *busiClient) TransOutHeaderYes(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutHeaderYes", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *busiClient) TransOutHeaderNo(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/busi.Busi/TransOutHeaderNo", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // BusiServer is the server API for Busi service. // All implementations must embed UnimplementedBusiServer // for forward compatibility @@ -220,6 +240,8 @@ type BusiServer interface { TransOutBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) TransInRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) TransOutRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutHeaderYes(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutHeaderNo(context.Context, *BusiReq) (*emptypb.Empty, error) mustEmbedUnimplementedBusiServer() } @@ -278,6 +300,12 @@ func (UnimplementedBusiServer) TransInRevertBSaga(context.Context, *BusiReq) (*e func (UnimplementedBusiServer) TransOutRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutRevertBSaga not implemented") } +func (UnimplementedBusiServer) TransOutHeaderYes(context.Context, *BusiReq) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method TransOutHeaderYes not implemented") +} +func (UnimplementedBusiServer) TransOutHeaderNo(context.Context, *BusiReq) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method TransOutHeaderNo not implemented") +} func (UnimplementedBusiServer) mustEmbedUnimplementedBusiServer() {} // UnsafeBusiServer may be embedded to opt out of forward compatibility for this service. @@ -597,6 +625,42 @@ func _Busi_TransOutRevertBSaga_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Busi_TransOutHeaderYes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BusiReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BusiServer).TransOutHeaderYes(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/busi.Busi/TransOutHeaderYes", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BusiServer).TransOutHeaderYes(ctx, req.(*BusiReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Busi_TransOutHeaderNo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BusiReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BusiServer).TransOutHeaderNo(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/busi.Busi/TransOutHeaderNo", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BusiServer).TransOutHeaderNo(ctx, req.(*BusiReq)) + } + return interceptor(ctx, in, info, handler) +} + // Busi_ServiceDesc is the grpc.ServiceDesc for Busi service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -672,6 +736,14 @@ var Busi_ServiceDesc = grpc.ServiceDesc{ MethodName: "TransOutRevertBSaga", Handler: _Busi_TransOutRevertBSaga_Handler, }, + { + MethodName: "TransOutHeaderYes", + Handler: _Busi_TransOutHeaderYes_Handler, + }, + { + MethodName: "TransOutHeaderNo", + Handler: _Busi_TransOutHeaderNo_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "test/busi/busi.proto", diff --git a/test/busi/utils.go b/test/busi/utils.go index 2b13712..5df72d1 100644 --- a/test/busi/utils.go +++ b/test/busi/utils.go @@ -4,27 +4,32 @@ import ( "context" "database/sql" "fmt" + "strings" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "github.com/dtm-labs/dtm/dtmutil" "github.com/gin-gonic/gin" + "github.com/go-resty/resty/v2" + grpc "google.golang.org/grpc" + "google.golang.org/grpc/metadata" ) func dbGet() *dtmutil.DB { return dtmutil.DbGet(BusiConf) } -func sdbGet() *sql.DB { +func pdbGet() *sql.DB { db, err := dtmimp.PooledDB(BusiConf) logger.FatalIfError(err) return db } func txGet() *sql.Tx { - db := sdbGet() + db := pdbGet() tx, err := db.Begin() logger.FatalIfError(err) return tx @@ -59,3 +64,22 @@ func MustBarrierFromGrpc(ctx context.Context) *dtmcli.BranchBarrier { logger.FatalIfError(err) return ti } + +// SetGrpcHeaderForHeadersYes interceptor to set head for HeadersYes +func SetGrpcHeaderForHeadersYes(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + if r, ok := req.(*dtmgpb.DtmRequest); ok && strings.HasSuffix(r.Gid, "HeadersYes") { + logger.Debugf("writing test_header:test to ctx") + md := metadata.New(map[string]string{"test_header": "test"}) + ctx = metadata.NewOutgoingContext(ctx, md) + } + return invoker(ctx, method, req, reply, cc, opts...) +} + +// SetHttpHeaderForHeadersYes interceptor to set head for HeadersYes +func SetHttpHeaderForHeadersYes(c *resty.Client, r *resty.Request) error { + if b, ok := r.Body.(*dtmcli.Saga); ok && strings.HasSuffix(b.Gid, "HeadersYes") { + logger.Debugf("set test_header for url: %s", r.URL) + r.SetHeader("test_header", "yes") + } + return nil +} diff --git a/test/dtmsvr_test.go b/test/dtmsvr_test.go index 7af9144..28da6e2 100644 --- a/test/dtmsvr_test.go +++ b/test/dtmsvr_test.go @@ -10,7 +10,6 @@ import ( "testing" "time" - "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmsvr" "github.com/dtm-labs/dtm/dtmutil" @@ -45,7 +44,7 @@ func TestUpdateBranchAsync(t *testing.T) { } conf.UpdateBranchSync = 0 saga := genSaga1(dtmimp.GetFuncName(), false, false) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) + saga.WaitResult = true err := saga.Submit() assert.Nil(t, err) waitTransProcessed(saga.Gid) diff --git a/test/main_test.go b/test/main_test.go index e7d7ca9..31bf4be 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -13,6 +13,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" "github.com/dtm-labs/dtm/dtmsvr" "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/test/busi" @@ -33,6 +34,9 @@ func TestMain(m *testing.M) { dtmsvr.CronForwardDuration = 180 * time.Second conf.UpdateBranchSync = 1 + dtmgrpc.AddUnaryInterceptor(busi.SetGrpcHeaderForHeadersYes) + dtmcli.OnBeforeRequest(busi.SetHttpHeaderForHeadersYes) + tenv := os.Getenv("TEST_STORE") if tenv == "boltdb" { conf.Store.Driver = "boltdb" diff --git a/test/msg_grpc_test.go b/test/msg_grpc_test.go index 44af2ab..e228fbb 100644 --- a/test/msg_grpc_test.go +++ b/test/msg_grpc_test.go @@ -38,7 +38,8 @@ func TestMsgGrpcTimeoutSuccess(t *testing.T) { cronTransOnceForwardNow(180) assert.Equal(t, StatusSubmitted, getTransStatus(msg.Gid)) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(msg.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, msg.Gid, g) assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) assert.Equal(t, []string{StatusSucceed, StatusSucceed}, getBranchesStatus(msg.Gid)) } diff --git a/test/msg_options_test.go b/test/msg_options_test.go index f69b8c9..97cfbe3 100644 --- a/test/msg_options_test.go +++ b/test/msg_options_test.go @@ -18,7 +18,8 @@ import ( func TestMsgOptionsTimeout(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, msg.Gid, g) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) cronTransOnceForwardNow(60) assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) @@ -28,7 +29,8 @@ func TestMsgOptionsTimeoutCustom(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.TimeoutToFail = 120 msg.Prepare("") - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, msg.Gid, g) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) cronTransOnceForwardNow(60) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) @@ -40,7 +42,8 @@ func TestMsgOptionsTimeoutFailed(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.TimeoutToFail = 120 msg.Prepare("") - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, msg.Gid, g) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) cronTransOnceForwardNow(60) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) diff --git a/test/msg_test.go b/test/msg_test.go index fa29923..e9c1475 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -35,7 +35,8 @@ func TestMsgTimeoutSuccess(t *testing.T) { busi.MainSwitch.TransInResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusSubmitted, getTransStatus(msg.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, msg.Gid, g) assert.Equal(t, []string{StatusSucceed, StatusSucceed}, getBranchesStatus(msg.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) } @@ -60,7 +61,7 @@ func TestMsgAbnormal(t *testing.T) { assert.Nil(t, err) err = msg.Submit() assert.Nil(t, err) - + waitTransProcessed(msg.Gid) err = msg.Prepare("") assert.Error(t, err) } diff --git a/test/saga_concurrent_test.go b/test/saga_concurrent_test.go index 7ae5635..e8c32c0 100644 --- a/test/saga_concurrent_test.go +++ b/test/saga_concurrent_test.go @@ -34,7 +34,8 @@ func TestSagaConRollbackNormal(t *testing.T) { assert.Nil(t, err) waitTransProcessed(sagaCon.Gid) assert.Equal(t, StatusAborting, getTransStatus(sagaCon.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, sagaCon.Gid, g) assert.Equal(t, StatusFailed, getTransStatus(sagaCon.Gid)) // TODO should fix this // assert.Equal(t, []string{StatusSucceed, StatusFailed, StatusSucceed, StatusSucceed}, getBranchesStatus(sagaCon.Gid)) @@ -58,7 +59,8 @@ func TestSagaConCommittedOngoing(t *testing.T) { assert.Equal(t, []string{StatusPrepared, StatusPrepared, StatusPrepared, StatusSucceed}, getBranchesStatus(sagaCon.Gid)) assert.Equal(t, StatusSubmitted, getTransStatus(sagaCon.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, sagaCon.Gid, g) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(sagaCon.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(sagaCon.Gid)) } diff --git a/test/saga_cover_test.go b/test/saga_cover_test.go new file mode 100644 index 0000000..500f424 --- /dev/null +++ b/test/saga_cover_test.go @@ -0,0 +1,11 @@ +package test + +import ( + "testing" + + "github.com/dtm-labs/dtm/dtmcli" +) + +func TestSagaCover(t *testing.T) { + dtmcli.SetPassthroughHeaders([]string{}) +} diff --git a/test/saga_grpc_test.go b/test/saga_grpc_test.go index 831c649..74fd827 100644 --- a/test/saga_grpc_test.go +++ b/test/saga_grpc_test.go @@ -31,7 +31,8 @@ func TestSagaGrpcRollback(t *testing.T) { saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, StatusAborting, getTransStatus(saga.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, saga.Gid, g) assert.Equal(t, StatusFailed, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusSucceed, StatusSucceed, StatusSucceed, StatusFailed}, getBranchesStatus(saga.Gid)) } @@ -62,14 +63,15 @@ func TestSagaGrpcCommittedOngoing(t *testing.T) { waitTransProcessed(saga.Gid) assert.Equal(t, StatusSubmitted, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusPrepared, StatusPrepared, StatusPrepared, StatusPrepared}, getBranchesStatus(saga.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, saga.Gid, g) assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) } func TestSagaGrpcNormalWait(t *testing.T) { saga := genSagaGrpc(dtmimp.GetFuncName(), false, false) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) + saga.WaitResult = true saga.Submit() assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) @@ -94,3 +96,69 @@ func genSagaGrpc(gid string, outFailed bool, inFailed bool) *dtmgrpc.SagaGrpc { saga.Add(busi.BusiGrpc+"/busi.Busi/TransIn", busi.BusiGrpc+"/busi.Busi/TransInRevert", req) return saga } + +func TestSagaGrpcPassthroughHeadersYes(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, gidYes) + sagaYes.WaitResult = true + sagaYes.PassthroughHeaders = []string{"test_header"} + sagaYes.Add(busi.BusiGrpc+"/busi.Busi/TransOutHeaderYes", "", nil) + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) +} + +func TestSagaGrpcCronPassthroughHeadersYes(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, gidYes) + sagaYes.PassthroughHeaders = []string{"test_header"} + sagaYes.Add(busi.BusiGrpc+"/busi.Busi/TransOutHeaderYes", "", nil) + busi.MainSwitch.TransOutResult.SetOnce("ONGOING") + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) + assert.Equal(t, StatusSubmitted, getTransStatus(gidYes)) + g := cronTransOnce() + assert.Equal(t, gidYes, g) + assert.Equal(t, StatusSucceed, getTransStatus(gidYes)) +} + +func TestSagaGrpcPassthroughHeadersNo(t *testing.T) { + gidNo := dtmimp.GetFuncName() + sagaNo := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, gidNo) + sagaNo.WaitResult = true + sagaNo.Add(busi.BusiGrpc+"/busi.Busi/TransOutHeaderNo", "", nil) + err := sagaNo.Submit() + assert.Nil(t, err) + waitTransProcessed(gidNo) +} + +func TestSagaGrpcHeaders(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, gidYes). + Add(busi.BusiGrpc+"/busi.Busi/TransOutHeaderYes", "", nil) + sagaYes.BranchHeaders = map[string]string{ + "test_header": "test", + } + sagaYes.WaitResult = true + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) +} + +func TestSagaGrpcCronHeaders(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmgrpc.NewSagaGrpc(dtmutil.DefaultGrpcServer, gidYes) + sagaYes.BranchHeaders = map[string]string{ + "test_header": "test", + } + sagaYes.Add(busi.BusiGrpc+"/busi.Busi/TransOutHeaderYes", "", nil) + busi.MainSwitch.TransOutResult.SetOnce("ONGOING") + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) + assert.Equal(t, StatusSubmitted, getTransStatus(gidYes)) + g := cronTransOnce() + assert.Equal(t, gidYes, g) + assert.Equal(t, StatusSucceed, getTransStatus(gidYes)) +} diff --git a/test/saga_options_test.go b/test/saga_options_test.go index bbd1689..73ecc24 100644 --- a/test/saga_options_test.go +++ b/test/saga_options_test.go @@ -11,6 +11,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmutil" "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -22,7 +23,8 @@ func TestSagaOptionsRetryOngoing(t *testing.T) { err := saga.Submit() assert.Nil(t, err) waitTransProcessed(saga.Gid) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, saga.Gid, g) assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) } @@ -34,10 +36,12 @@ func TestSagaOptionsRetryError(t *testing.T) { err := saga.Submit() assert.Nil(t, err) waitTransProcessed(saga.Gid) - cronTransOnce() assert.Equal(t, StatusSubmitted, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(saga.Gid)) - cronTransOnceForwardCron(360) + g := cronTransOnce() + assert.Equal(t, "", g) + g = cronTransOnceForwardCron(360) + assert.Equal(t, saga.Gid, g) assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) } @@ -55,7 +59,7 @@ func TestSagaOptionsTimeout(t *testing.T) { func TestSagaOptionsNormalWait(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, false) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) + saga.WaitResult = true err := saga.Submit() assert.Nil(t, err) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) @@ -66,23 +70,90 @@ func TestSagaOptionsNormalWait(t *testing.T) { func TestSagaOptionsCommittedOngoingWait(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, false) busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) + saga.WaitResult = true err := saga.Submit() assert.Error(t, err) assert.Equal(t, []string{StatusPrepared, StatusPrepared, StatusPrepared, StatusPrepared}, getBranchesStatus(saga.Gid)) assert.Equal(t, StatusSubmitted, getTransStatus(saga.Gid)) waitTransProcessed(saga.Gid) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, saga.Gid, g) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) } func TestSagaOptionsRollbackWait(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, true) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) + saga.WaitResult = true err := saga.Submit() assert.Error(t, err) waitTransProcessed(saga.Gid) assert.Equal(t, StatusFailed, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusSucceed, StatusSucceed, StatusSucceed, StatusFailed}, getBranchesStatus(saga.Gid)) } + +func TestSagaPassthroughHeadersYes(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes.WaitResult = true + sagaYes.PassthroughHeaders = []string{"test_header"} + sagaYes.Add(busi.Busi+"/TransOutHeaderYes", "", nil) + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) +} + +func TestSagaCronPassthroughHeadersYes(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes.PassthroughHeaders = []string{"test_header"} + sagaYes.Add(busi.Busi+"/TransOutHeaderYes", "", nil) + busi.MainSwitch.TransOutResult.SetOnce("ONGOING") + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) + assert.Equal(t, StatusSubmitted, getTransStatus(gidYes)) + g := cronTransOnce() + assert.Equal(t, gidYes, g) + assert.Equal(t, StatusSucceed, getTransStatus(gidYes)) +} + +func TestSagaPassthroughHeadersNo(t *testing.T) { + gidNo := dtmimp.GetFuncName() + sagaNo := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidNo) + sagaNo.WaitResult = true + sagaNo.Add(busi.Busi+"/TransOutHeaderNo", "", nil) + err := sagaNo.Submit() + assert.Nil(t, err) + waitTransProcessed(gidNo) +} + +func TestSagaHeaders(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes.BranchHeaders = map[string]string{ + "test_header": "test", + } + sagaYes.WaitResult = true + sagaYes.Add(busi.Busi+"/TransOutHeaderYes", "", nil) + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) +} + +func TestSagaHeadersYes1(t *testing.T) { + gidYes := dtmimp.GetFuncName() + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes.BranchHeaders = map[string]string{ + "test_header": "test", + } + sagaYes.Add(busi.Busi+"/TransOutHeaderYes", "", nil) + busi.MainSwitch.TransOutResult.SetOnce("ONGOING") + err := sagaYes.Submit() + assert.Nil(t, err) + waitTransProcessed(gidYes) + assert.Equal(t, StatusSubmitted, getTransStatus(gidYes)) + g := cronTransOnce() + assert.Equal(t, gidYes, g) + assert.Equal(t, StatusSucceed, getTransStatus(gidYes)) +} diff --git a/test/saga_test.go b/test/saga_test.go index 57d3a85..0fa3a97 100644 --- a/test/saga_test.go +++ b/test/saga_test.go @@ -31,7 +31,8 @@ func TestSagaOngoingSucceed(t *testing.T) { waitTransProcessed(saga.Gid) assert.Equal(t, []string{StatusPrepared, StatusPrepared, StatusPrepared, StatusPrepared}, getBranchesStatus(saga.Gid)) assert.Equal(t, StatusSubmitted, getTransStatus(saga.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, saga.Gid, g) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) } @@ -43,15 +44,18 @@ func TestSagaFailed(t *testing.T) { assert.Nil(t, err) waitTransProcessed(saga.Gid) assert.Equal(t, StatusAborting, getTransStatus(saga.Gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, saga.Gid, g) assert.Equal(t, StatusFailed, getTransStatus(saga.Gid)) assert.Equal(t, []string{StatusSucceed, StatusSucceed, StatusSucceed, StatusFailed}, getBranchesStatus(saga.Gid)) } func TestSagaAbnormal(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, false) + busi.MainSwitch.TransOutResult.SetOnce("ONGOING") err := saga.Submit() assert.Nil(t, err) + waitTransProcessed(saga.Gid) err = saga.Submit() // submit twice, ignored assert.Nil(t, err) waitTransProcessed(saga.Gid) diff --git a/test/tcc_cover_test.go b/test/tcc_cover_test.go index 9ca4285..3683f23 100644 --- a/test/tcc_cover_test.go +++ b/test/tcc_cover_test.go @@ -27,4 +27,5 @@ func TestTccCoverPanic(t *testing.T) { assert.FailNow(t, "not executed") }) assert.Contains(t, err.Error(), "user panic") + waitTransProcessed(gid) } diff --git a/test/tcc_grpc_cover_test.go b/test/tcc_grpc_cover_test.go index 6056b9e..192d491 100644 --- a/test/tcc_grpc_cover_test.go +++ b/test/tcc_grpc_cover_test.go @@ -28,6 +28,7 @@ func TestTccGrpcCoverPanic(t *testing.T) { assert.FailNow(t, "not executed") }) assert.Contains(t, err.Error(), "user panic") + waitTransProcessed(gid) } func TestTccGrpcCoverCallBranch(t *testing.T) { @@ -46,4 +47,6 @@ func TestTccGrpcCoverCallBranch(t *testing.T) { return err }) assert.Error(t, err) + g := cronTransOnceForwardNow(300) + assert.Equal(t, gid, g) } diff --git a/test/tcc_grpc_test.go b/test/tcc_grpc_test.go index a9fc40b..b3a8169 100644 --- a/test/tcc_grpc_test.go +++ b/test/tcc_grpc_test.go @@ -49,7 +49,8 @@ func TestTccGrpcRollback(t *testing.T) { assert.Error(t, err) waitTransProcessed(gid) assert.Equal(t, StatusAborting, getTransStatus(gid)) - cronTransOnce() + g2 := cronTransOnce() + assert.Equal(t, gid, g2) assert.Equal(t, StatusFailed, getTransStatus(gid)) assert.Equal(t, []string{StatusSucceed, StatusPrepared, StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) } @@ -76,3 +77,22 @@ func TestTccGrpcType(t *testing.T) { err = dtmgrpc.TccGlobalTransaction("-", "", func(tcc *dtmgrpc.TccGrpc) error { return nil }) assert.Error(t, err) } + +func TestTccGrpcHeaders(t *testing.T) { + gid := dtmimp.GetFuncName() + err := dtmgrpc.TccGlobalTransaction2(dtmutil.DefaultGrpcServer, gid, func(tg *dtmgrpc.TccGrpc) { + tg.BranchHeaders = map[string]string{ + "test_header": "test", + } + tg.WaitResult = true + }, func(tcc *dtmgrpc.TccGrpc) error { + data := &busi.BusiReq{Amount: 30} + r := &emptypb.Empty{} + return tcc.CallBranch(data, busi.BusiGrpc+"/busi.Busi/TransOutHeaderYes", "", "", r) + }) + assert.Nil(t, err) + waitTransProcessed(gid) + assert.Equal(t, StatusSucceed, getTransStatus(gid)) + assert.Equal(t, []string{StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) + +} diff --git a/test/tcc_test.go b/test/tcc_test.go index 3766c59..4324769 100644 --- a/test/tcc_test.go +++ b/test/tcc_test.go @@ -43,7 +43,8 @@ func TestTccRollback(t *testing.T) { assert.Error(t, err) waitTransProcessed(gid) assert.Equal(t, StatusAborting, getTransStatus(gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, gid, g) assert.Equal(t, StatusFailed, getTransStatus(gid)) assert.Equal(t, []string{StatusSucceed, StatusPrepared, StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) } @@ -84,3 +85,19 @@ func TestTccCompatible(t *testing.T) { assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) } + +func TestTccHeaders(t *testing.T) { + req := busi.GenTransReq(30, false, false) + gid := dtmimp.GetFuncName() + err := dtmcli.TccGlobalTransaction2(dtmutil.DefaultHttpServer, gid, func(t *dtmcli.Tcc) { + t.BranchHeaders = map[string]string{ + "test_header": "test", + } + }, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + return tcc.CallBranch(req, Busi+"/TransOutHeaderYes", "", "") + }) + assert.Nil(t, err) + waitTransProcessed(gid) + assert.Equal(t, StatusSucceed, getTransStatus(gid)) + assert.Equal(t, []string{StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) +} diff --git a/test/types.go b/test/types.go index 8ed65c8..4fcbe34 100644 --- a/test/types.go +++ b/test/types.go @@ -29,21 +29,19 @@ func waitTransProcessed(gid string) { logger.Debugf("waiting for gid %s", gid) select { case id := <-dtmsvr.TransProcessedTestChan: - for id != gid { - logger.Warnf("------- expecting: %s but %s found", gid, id) - id = <-dtmsvr.TransProcessedTestChan - } + logger.FatalfIf(id != gid, "------- expecting: %s but %s found", gid, id) logger.Debugf("finish for gid %s", gid) case <-time.After(time.Duration(time.Second * 3)): logger.FatalfIf(true, "Wait Trans timeout") } } -func cronTransOnce() { +func cronTransOnce() string { gid := dtmsvr.CronTransOnce() if dtmsvr.TransProcessedTestChan != nil && gid != "" { waitTransProcessed(gid) } + return gid } var e2p = dtmimp.E2P @@ -54,18 +52,20 @@ type TransGlobal = dtmsvr.TransGlobal // TransBranch alias type TransBranch = dtmsvr.TransBranch -func cronTransOnceForwardNow(seconds int) { +func cronTransOnceForwardNow(seconds int) string { old := dtmsvr.NowForwardDuration dtmsvr.NowForwardDuration = time.Duration(seconds) * time.Second - cronTransOnce() + gid := cronTransOnce() dtmsvr.NowForwardDuration = old + return gid } -func cronTransOnceForwardCron(seconds int) { +func cronTransOnceForwardCron(seconds int) string { old := dtmsvr.CronForwardDuration dtmsvr.CronForwardDuration = time.Duration(seconds) * time.Second - cronTransOnce() + gid := cronTransOnce() dtmsvr.CronForwardDuration = old + return gid } const ( diff --git a/test/xa_cover_test.go b/test/xa_cover_test.go index fddada6..0103539 100644 --- a/test/xa_cover_test.go +++ b/test/xa_cover_test.go @@ -43,7 +43,7 @@ func TestXaCoverDTMError(t *testing.T) { } func TestXaCoverGidError(t *testing.T) { - gid := "errgid-' '" + gid := dtmimp.GetFuncName() + "-' '" err := getXc().XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { req := busi.GenTransReq(30, false, false) _, err := xa.CallBranch(req, busi.Busi+"/TransOutXa") @@ -51,4 +51,5 @@ func TestXaCoverGidError(t *testing.T) { return nil, err }) assert.Error(t, err) + waitTransProcessed(gid) } diff --git a/test/xa_grpc_test.go b/test/xa_grpc_test.go index 586e3db..890d129 100644 --- a/test/xa_grpc_test.go +++ b/test/xa_grpc_test.go @@ -56,6 +56,7 @@ func TestXaGrpcRollback(t *testing.T) { } func TestXaGrpcType(t *testing.T) { + gid := dtmimp.GetFuncName() _, err := dtmgrpc.XaGrpcFromRequest(context.Background()) assert.Error(t, err) @@ -63,15 +64,18 @@ func TestXaGrpcType(t *testing.T) { assert.Error(t, err) err = dtmimp.CatchP(func() { - busi.XaGrpcClient.XaGlobalTransaction("id1", func(xa *dtmgrpc.XaGrpc) error { panic(fmt.Errorf("hello")) }) + busi.XaGrpcClient.XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { panic(fmt.Errorf("hello")) }) }) assert.Error(t, err) + waitTransProcessed(gid) } func TestXaGrpcLocalError(t *testing.T) { + gid := dtmimp.GetFuncName() xc := busi.XaGrpcClient - err := xc.XaGlobalTransaction(dtmimp.GetFuncName(), func(xa *dtmgrpc.XaGrpc) error { + err := xc.XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { return fmt.Errorf("an error") }) assert.Error(t, err, fmt.Errorf("an error")) + waitTransProcessed(gid) } diff --git a/test/xa_test.go b/test/xa_test.go index 0515c02..fcb460c 100644 --- a/test/xa_test.go +++ b/test/xa_test.go @@ -118,7 +118,8 @@ func TestXaNotTimeout(t *testing.T) { assert.Nil(t, err) waitTransProcessed(gid) assert.Equal(t, StatusSubmitted, getTransStatus(gid)) - cronTransOnce() + g := cronTransOnce() + assert.Equal(t, gid, g) assert.Equal(t, StatusSucceed, getTransStatus(gid)) assert.Equal(t, []string{StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) } From aae384e597f98e5c21b151ccee9fb4f1431f8fc9 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 1 Jan 2022 11:37:48 +0800 Subject: [PATCH 059/124] cover OnAfterResponse --- test/main_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/main_test.go b/test/main_test.go index 31bf4be..2fa6a1c 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -17,6 +17,7 @@ import ( "github.com/dtm-labs/dtm/dtmsvr" "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/test/busi" + "github.com/go-resty/resty/v2" ) func exitIf(code int) { @@ -36,6 +37,7 @@ func TestMain(m *testing.M) { dtmgrpc.AddUnaryInterceptor(busi.SetGrpcHeaderForHeadersYes) dtmcli.OnBeforeRequest(busi.SetHttpHeaderForHeadersYes) + dtmcli.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { return nil }) tenv := os.Getenv("TEST_STORE") if tenv == "boltdb" { From 4224cbff71b1ef9283e711cc4bd9992e1baea30c Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 1 Jan 2022 12:06:50 +0800 Subject: [PATCH 060/124] update xa base comment --- dtmcli/dtmimp/trans_xa_base.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmcli/dtmimp/trans_xa_base.go b/dtmcli/dtmimp/trans_xa_base.go index 95a8811..cc7e604 100644 --- a/dtmcli/dtmimp/trans_xa_base.go +++ b/dtmcli/dtmimp/trans_xa_base.go @@ -11,7 +11,7 @@ import ( "strings" ) -// XaClientBase XaClient/XaGrpcClient base +// XaClientBase XaClient/XaGrpcClient base. shared by http and grpc type XaClientBase struct { Server string Conf DBConf From 19e24816aae0168ee4047d45799d4354cd67658b Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 1 Jan 2022 19:17:41 +0800 Subject: [PATCH 061/124] add github author --- README-cn.md | 3 +++ README.md | 2 ++ 2 files changed, 5 insertions(+) diff --git a/README-cn.md b/README-cn.md index a339308..a5acf06 100644 --- a/README-cn.md +++ b/README-cn.md @@ -133,5 +133,8 @@ dtm官方公众号:分布式事务,大量干货分享,以及dtm的最新 ![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) +### github +作者github: [https://github.com/yedf2](https://github.com/yedf2) + 欢迎使用[dtm](https://github.com/dtm-labs/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 diff --git a/README.md b/README.md index a339308..fc83704 100644 --- a/README.md +++ b/README.md @@ -133,5 +133,7 @@ dtm官方公众号:分布式事务,大量干货分享,以及dtm的最新 ![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) +作者github: [https://github.com/yedf2](https://github.com/yedf2) + 欢迎使用[dtm](https://github.com/dtm-labs/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 From e42b67fd8e880f49e513ea2e33163f3cb0fcd858 Mon Sep 17 00:00:00 2001 From: fsdfsffdsf Date: Sun, 2 Jan 2022 15:08:44 +0800 Subject: [PATCH 062/124] feature:support tencent distributed database tdsql --- dtmsvr/svr.go | 1 + dtmsvr/trans_status.go | 2 +- dtmsvr/trans_type_saga.go | 12 ++++++--- dtmsvr/utils.go | 1 + sqls/dtmsvr.storage.tdsql.sql | 46 +++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 sqls/dtmsvr.storage.tdsql.sql diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index be40e1c..f891a6f 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -70,6 +70,7 @@ func updateBranchAsync() { case updateBranch := <-updateBranchAsyncChan: updates = append(updates, TransBranch{ ModelBase: dtmutil.ModelBase{ID: updateBranch.id}, + Gid: updateBranch.gid, Status: updateBranch.status, FinishTime: updateBranch.finishTime, }) diff --git a/dtmsvr/trans_status.go b/dtmsvr/trans_status.go index c04110a..ec78533 100644 --- a/dtmsvr/trans_status.go +++ b/dtmsvr/trans_status.go @@ -53,7 +53,7 @@ func (t *TransGlobal) changeBranchStatus(b *TransBranch, status string, branchPo logger.Infof("LockGlobalSaveBranches ok: gid: %s old status: %s branches: %s", b.Gid, dtmcli.StatusPrepared, b.String()) } else { // 为了性能优化,把branch的status更新异步化 - updateBranchAsyncChan <- branchStatus{id: b.ID, status: status, finishTime: &now} + updateBranchAsyncChan <- branchStatus{id: b.ID, gid: t.Gid, status: status, finishTime: &now} } } diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index b74dce4..a02e8bc 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -20,7 +20,8 @@ type transSagaProcessor struct { } func init() { - registorProcessorCreator("saga", func(trans *TransGlobal) transProcessor { return &transSagaProcessor{TransGlobal: trans} }) + registorProcessorCreator("saga", func(trans *TransGlobal) transProcessor { + return &transSagaProcessor{TransGlobal: trans} }) } func (t *transSagaProcessor) GenBranches() []TransBranch { @@ -114,7 +115,8 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { toRun := []int{} for current := 0; current < n; current++ { br := &branchResults[current] - if br.op == dtmcli.BranchAction && !br.started && isPreconditionsSucceed(current) && br.status == dtmcli.StatusPrepared { + if br.op == dtmcli.BranchAction && !br.started && isPreconditionsSucceed(current) && + br.status == dtmcli.StatusPrepared { toRun = append(toRun, current) } } @@ -132,11 +134,13 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } pickAndRunCompensates := func(toRunActions []int) { for _, b := range toRunActions { - // these branches may have run. so flag them to status succeed, then run the corresponding compensate + // these branches may have run. so flag them to status succeed, then run the corresponding + // compensate branchResults[b].status = dtmcli.StatusSucceed } for i, b := range branchResults { - if b.op == dtmcli.BranchCompensate && b.status != dtmcli.StatusSucceed && branchResults[i+1].status != dtmcli.StatusPrepared { + if b.op == dtmcli.BranchCompensate && b.status != dtmcli.StatusSucceed && + branchResults[i+1].status != dtmcli.StatusPrepared { rsCToStart++ go asyncExecBranch(i) } diff --git a/dtmsvr/utils.go b/dtmsvr/utils.go index 37d938c..c52dce0 100644 --- a/dtmsvr/utils.go +++ b/dtmsvr/utils.go @@ -19,6 +19,7 @@ import ( type branchStatus struct { id uint64 + gid string status string finishTime *time.Time } diff --git a/sqls/dtmsvr.storage.tdsql.sql b/sqls/dtmsvr.storage.tdsql.sql new file mode 100644 index 0000000..09cf816 --- /dev/null +++ b/sqls/dtmsvr.storage.tdsql.sql @@ -0,0 +1,46 @@ +CREATE DATABASE IF NOT EXISTS dtm +/*!40100 DEFAULT CHARACTER SET utf8mb4 */ +; +drop table IF EXISTS dtm.trans_global; +CREATE TABLE if not EXISTS dtm.trans_global ( + `id` bigint(22) NOT NULL AUTO_INCREMENT, + `gid` varchar(128) NOT NULL COMMENT '事务全局id', + `trans_type` varchar(45) not null COMMENT '事务类型: saga | xa | tcc | msg', + -- `data` TEXT COMMENT '事务携带的数据', -- 影响性能,不必要存储 + `status` varchar(12) NOT NULL COMMENT '全局事务的状态 prepared | submitted | aborting | finished | rollbacked', + `query_prepared` varchar(128) NOT NULL COMMENT 'prepared状态事务的查询api', + `protocol` varchar(45) not null comment '通信协议 http | grpc', + `create_time` datetime DEFAULT NULL, + `update_time` datetime DEFAULT NULL, + `commit_time` datetime DEFAULT NULL, + `finish_time` datetime DEFAULT NULL, + `rollback_time` datetime DEFAULT NULL, + `options` varchar(256) DEFAULT '', + `custom_data` varchar(256) DEFAULT '', + `next_cron_interval` int(11) default null comment '下次定时处理的间隔', + `next_cron_time` datetime default null comment '下次定时处理的时间', + `owner` varchar(128) not null default '' comment '正在处理全局事务的锁定者', + PRIMARY KEY (`id`,`gid`), + UNIQUE KEY `id` (`id`,`gid`), + UNIQUE KEY `gid` (`gid`), + key `owner`(`owner`), + key `status_next_cron_time` (`status`, `next_cron_time`) comment '这个索引用于查询超时的全局事务,能够合理的走索引' +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 shardkey=gid; +drop table IF EXISTS dtm.trans_branch_op; +CREATE TABLE IF NOT EXISTS dtm.trans_branch_op ( + `id` bigint(22) NOT NULL AUTO_INCREMENT, + `gid` varchar(128) NOT NULL COMMENT '事务全局id', + `url` varchar(128) NOT NULL COMMENT '动作关联的url', + `data` TEXT COMMENT '请求所携带的数据', + `bin_data` BLOB COMMENT 'grpc的二进制数据', + `branch_id` VARCHAR(128) NOT NULL COMMENT '事务分支ID', + `op` varchar(45) NOT NULL COMMENT '事务分支类型 saga_action | saga_compensate | xa', + `status` varchar(45) NOT NULL COMMENT '步骤的状态 submitted | finished | rollbacked', + `finish_time` datetime DEFAULT NULL, + `rollback_time` datetime DEFAULT NULL, + `create_time` datetime DEFAULT NULL, + `update_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`,`gid`), + UNIQUE KEY `id` (`id`,`gid`), + UNIQUE KEY `gid_uniq` (`gid`, `branch_id`, `op`) +) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 shardkey=gid; From 25428a9379ceff1274ec144ac968e29f9ccb164f Mon Sep 17 00:00:00 2001 From: wondarchan Date: Sun, 2 Jan 2022 22:53:49 +0800 Subject: [PATCH 063/124] =?UTF-8?q?dtmsvr/storage=E4=B8=8B=E7=9A=84store.g?= =?UTF-8?q?o=E6=96=87=E4=BB=B6=E6=B7=BB=E5=8A=A0=E5=BC=80=E6=BA=90?= =?UTF-8?q?=E7=89=88=E6=9D=83=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dtmsvr/storage/store.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dtmsvr/storage/store.go b/dtmsvr/storage/store.go index 1a9da9c..79a9b0e 100644 --- a/dtmsvr/storage/store.go +++ b/dtmsvr/storage/store.go @@ -1,3 +1,9 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + package storage import ( From d5f7cf70d4ada3e6275f93a34637d59bdf358559 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 3 Jan 2022 12:22:40 +0800 Subject: [PATCH 064/124] add Table to TransBranchOp --- conf.sample.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf.sample.yml b/conf.sample.yml index 807d582..31ba6d5 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -31,7 +31,7 @@ # MaxIdleConns: 500 # ConnMaxLifeTime 5 # default value is 5 (minutes) # TransGlobalTable: 'dtm.trans_global' -# TransBranchOp: 'dtm.trans_branch_op' +# TransBranchOpTable: 'dtm.trans_branch_op' ### flollowing config is only for some Driver # DataExpire: 604800 # Trans data will expire in 7 days. only for redis/boltdb. From c15709c79dba718a0606422dc11915195ed3dfb7 Mon Sep 17 00:00:00 2001 From: jxlwqq Date: Wed, 5 Jan 2022 12:15:28 +0800 Subject: [PATCH 065/124] update goreleaser --- helper/.goreleaser.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/helper/.goreleaser.yml b/helper/.goreleaser.yml index 5c5a639..83e0158 100644 --- a/helper/.goreleaser.yml +++ b/helper/.goreleaser.yml @@ -1,14 +1,24 @@ # .goreleaser.yml project_name: dtm builds: - - env: [CGO_ENABLED=0] + - id: dtm_amd64 + env: [CGO_ENABLED=0] goos: - linux - windows - darwin goarch: - amd64 - id: 'dtm' + dir: . + main: main.go + ldflags: + - -s -w -X main.Version={{.Version}} + - id: dtm_arm64 + env: [ CGO_ENABLED=0 ] + goos: + - darwin + goarch: + - arm64 dir: . main: main.go ldflags: From 886965f5cd77b06719ea4ddcbbfc11d385bf21b5 Mon Sep 17 00:00:00 2001 From: liulei Date: Wed, 5 Jan 2022 15:04:43 +0800 Subject: [PATCH 066/124] add logger interface defination#153 --- dtmcli/logger/log.go | 18 ++++++++++++++++-- dtmcli/logger/logger_test.go | 12 ++++++++++++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/dtmcli/logger/log.go b/dtmcli/logger/log.go index 7d3650a..81466b3 100644 --- a/dtmcli/logger/log.go +++ b/dtmcli/logger/log.go @@ -8,13 +8,27 @@ import ( "go.uber.org/zap/zapcore" ) -var logger *zap.SugaredLogger = nil +//var logger *zap.SugaredLogger = nil + +var logger Logger = nil func init() { InitLog("info") } -// InitLog is a initialization for a logger +// Logger logger interface +type Logger interface { + Debugf(format string, args ...interface{}) + Infof(format string, args ...interface{}) + Warnf(format string, args ...interface{}) + Errorf(format string, args ...interface{}) +} + +func WithLogger(log Logger) { + logger = log +} + +// InitLog is an initialization for a logger // level can be: debug info warn error func InitLog(level string) { config := zap.NewProductionConfig() diff --git a/dtmcli/logger/logger_test.go b/dtmcli/logger/logger_test.go index 669a39f..6320b58 100644 --- a/dtmcli/logger/logger_test.go +++ b/dtmcli/logger/logger_test.go @@ -1,6 +1,7 @@ package logger import ( + "github.com/sirupsen/logrus" "os" "testing" ) @@ -15,3 +16,14 @@ func TestInitLog(t *testing.T) { FatalfIf(false, "nothing") FatalIfError(nil) } + +func TestWithLogger(t *testing.T) { + logger := logrus.New() + WithLogger(logger) + Debugf("a debug msg") + Infof("a info msg") + Warnf("a warn msg") + Errorf("a error msg") + FatalfIf(false, "nothing") + FatalIfError(nil) +} \ No newline at end of file From 1b44b6f77e264d87184a12835a18892b1a603fba Mon Sep 17 00:00:00 2001 From: liulei Date: Wed, 5 Jan 2022 15:16:09 +0800 Subject: [PATCH 067/124] chore: to correct comment and func name --- dtmsvr/config/config.go | 1 + dtmsvr/config/config_utils.go | 2 +- go.mod | 1 + go.sum | 1 + test/store_test.go | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 5aad90f..80acd60 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -14,6 +14,7 @@ const ( Mysql = "mysql" Redis = "redis" BoltDb = "boltdb" + Postgres = "postgres" ) // MicroService config type for micro service diff --git a/dtmsvr/config/config_utils.go b/dtmsvr/config/config_utils.go index e5b1785..3d37b0c 100644 --- a/dtmsvr/config/config_utils.go +++ b/dtmsvr/config/config_utils.go @@ -65,7 +65,7 @@ func checkConfig(conf *configType) error { switch conf.Store.Driver { case BoltDb: return nil - case Mysql: + case Mysql, Postgres: if conf.Store.Host == "" { return errors.New("Db host not valid ") } diff --git a/go.mod b/go.mod index 306fad3..2a5fe3f 100644 --- a/go.mod +++ b/go.mod @@ -17,6 +17,7 @@ require ( github.com/lithammer/shortuuid/v3 v3.0.7 github.com/onsi/gomega v1.16.0 github.com/prometheus/client_golang v1.11.0 + github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.9.0 // indirect diff --git a/go.sum b/go.sum index d37ef25..d67335c 100644 --- a/go.sum +++ b/go.sum @@ -476,6 +476,7 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= diff --git a/test/store_test.go b/test/store_test.go index 486b807..c2413f7 100644 --- a/test/store_test.go +++ b/test/store_test.go @@ -92,7 +92,7 @@ func TestStoreWait(t *testing.T) { registry.WaitStoreUp() } -func TestUpdateBranchSql(t *testing.T) { +func TestUpdateBranches(t *testing.T) { if !conf.Store.IsDB() { _, err := registry.GetStore().UpdateBranches(nil, nil) assert.Nil(t, err) From d2393b60c1d64cf963ca3066ff20c0d6d9c0103d Mon Sep 17 00:00:00 2001 From: liulei Date: Wed, 5 Jan 2022 15:28:41 +0800 Subject: [PATCH 068/124] remove logrus dep --- dtmcli/logger/logger_test.go | 4 ++-- go.mod | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/dtmcli/logger/logger_test.go b/dtmcli/logger/logger_test.go index 6320b58..08f8b04 100644 --- a/dtmcli/logger/logger_test.go +++ b/dtmcli/logger/logger_test.go @@ -1,7 +1,7 @@ package logger import ( - "github.com/sirupsen/logrus" + "go.uber.org/zap" "os" "testing" ) @@ -18,7 +18,7 @@ func TestInitLog(t *testing.T) { } func TestWithLogger(t *testing.T) { - logger := logrus.New() + logger := zap.NewExample().Sugar() WithLogger(logger) Debugf("a debug msg") Infof("a info msg") diff --git a/go.mod b/go.mod index 2a5fe3f..306fad3 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,6 @@ require ( github.com/lithammer/shortuuid/v3 v3.0.7 github.com/onsi/gomega v1.16.0 github.com/prometheus/client_golang v1.11.0 - github.com/sirupsen/logrus v1.8.1 github.com/stretchr/testify v1.7.0 go.etcd.io/bbolt v1.3.6 go.uber.org/atomic v1.9.0 // indirect From ec8d2832d09cf62880a5b7b907f40f4bbf60eca9 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 5 Jan 2022 21:23:16 +0800 Subject: [PATCH 069/124] add PrepareAndSubmit --- dtmcli/barrier.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index 62f59b2..f515550 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -100,3 +100,37 @@ func (bb *BranchBarrier) CallWithDB(db *sql.DB, busiCall BarrierBusiFunc) error } return bb.Call(tx, busiCall) } + +func (bb *BranchBarrier) QueryPrepared(db *sql.DB) error { + affected, err := insertBarrier(db, bb.TransType, bb.Gid, bb.BranchID, BranchAction, bb.BranchID, bb.Op) + if err != nil { + return err + } + if affected > 0 { + return ErrFailure + } + return nil +} + +func (bb *BranchBarrier) PrepareAndSubmit(msg *Msg, queryPrepared string, db *sql.DB, busiCall BarrierBusiFunc) (err error) { + var tx *sql.Tx + tx, err = db.Begin() + if err == nil { + defer func() { + if err != nil { + _ = tx.Rollback() + } + }() + err = busiCall(tx) + } + if err == nil { + err = msg.Prepare(queryPrepared) + } + if err == nil { + err = tx.Commit() + } + if err == nil { + return msg.Submit() // should not assign err. or else defer may try to rollback a committed tx + } + return err +} From cd13dfd2af220be33ecf89cff825a240dab693e8 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 5 Jan 2022 21:23:32 +0800 Subject: [PATCH 070/124] rename CanSubmit to QueryPrepared --- test/busi/base_grpc.go | 6 +- test/busi/base_http.go | 6 +- test/busi/base_types.go | 2 +- test/busi/busi.pb.go | 178 ++++++++++++++++++++------------------ test/busi/busi.proto | 3 +- test/busi/busi_grpc.pb.go | 108 +++++++++++++++-------- test/msg_grpc_test.go | 8 +- test/msg_options_test.go | 2 +- test/msg_test.go | 8 +- 9 files changed, 182 insertions(+), 139 deletions(-) diff --git a/test/busi/base_grpc.go b/test/busi/base_grpc.go index 6fd3790..b1da93e 100644 --- a/test/busi/base_grpc.go +++ b/test/busi/base_grpc.go @@ -63,9 +63,9 @@ type busiServer struct { UnimplementedBusiServer } -func (s *busiServer) CanSubmit(ctx context.Context, in *BusiReq) (*BusiReply, error) { - res := MainSwitch.CanSubmitResult.Fetch() - return &BusiReply{Message: "a sample"}, dtmgimp.Result2Error(res, nil) +func (s *busiServer) QueryPrepared(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + res := MainSwitch.QueryPreparedResult.Fetch() + return &emptypb.Empty{}, dtmgimp.Result2Error(res, nil) } func (s *busiServer) TransIn(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { diff --git a/test/busi/base_http.go b/test/busi/base_http.go index fe47dd7..7a9838b 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -99,9 +99,9 @@ func BaseAddRoute(app *gin.Engine) { app.POST(BusiAPI+"/TransOutRevert", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusiness(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) - app.GET(BusiAPI+"/CanSubmit", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - logger.Debugf("%s CanSubmit", c.Query("gid")) - return dtmimp.OrString(MainSwitch.CanSubmitResult.Fetch(), dtmcli.ResultSuccess), nil + app.GET(BusiAPI+"/QueryPrepared", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + logger.Debugf("%s QueryPrepared", c.Query("gid")) + return dtmimp.OrString(MainSwitch.QueryPreparedResult.Fetch(), dtmcli.ResultSuccess), nil })) app.POST(BusiAPI+"/TransInXa", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { diff --git a/test/busi/base_types.go b/test/busi/base_types.go index 471bbe3..f0d29fb 100644 --- a/test/busi/base_types.go +++ b/test/busi/base_types.go @@ -118,7 +118,7 @@ type mainSwitchType struct { TransOutConfirmResult AutoEmptyString TransInRevertResult AutoEmptyString TransOutRevertResult AutoEmptyString - CanSubmitResult AutoEmptyString + QueryPreparedResult AutoEmptyString NextResult AutoEmptyString } diff --git a/test/busi/busi.pb.go b/test/busi/busi.pb.go index cfa8766..975a949 100644 --- a/test/busi/busi.pb.go +++ b/test/busi/busi.pb.go @@ -148,77 +148,81 @@ var file_test_busi_busi_proto_rawDesc = []byte{ 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x25, 0x0a, 0x09, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x32, 0xce, 0x08, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x2d, 0x0a, 0x09, 0x43, 0x61, - 0x6e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, - 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, - 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x49, 0x6e, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, - 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x33, 0x0a, - 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, - 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x76, - 0x65, 0x72, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, - 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0e, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x0d, - 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x49, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, - 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, + 0x65, 0x32, 0x94, 0x09, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, - 0x0a, 0x08, 0x58, 0x61, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x34, 0x0a, 0x09, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x58, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, - 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x58, 0x61, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x33, + 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, + 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, + 0x76, 0x65, 0x72, 0x74, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, + 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, + 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, + 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x49, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, + 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x00, 0x12, 0x3a, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x43, + 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, + 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x3c, 0x0a, 0x08, 0x58, 0x61, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x34, 0x0a, + 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x58, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, + 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x58, + 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, + 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x00, 0x12, 0x36, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x54, 0x63, 0x63, + 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x0d, 0x2e, + 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, + 0x6e, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, + 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, + 0x38, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x0a, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, - 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, - 0x12, 0x36, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x54, 0x63, 0x63, 0x12, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x12, 0x54, 0x72, 0x61, + 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x4e, 0x65, 0x73, 0x74, 0x65, 0x64, 0x12, 0x0d, 0x2e, 0x62, - 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, - 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, - 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x38, - 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3d, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x49, 0x6e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, - 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x13, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x0d, - 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x4f, 0x75, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x59, 0x65, 0x73, 0x12, 0x0d, 0x2e, 0x62, - 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, - 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, - 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, - 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, - 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x62, 0x75, 0x73, 0x69, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x4f, 0x75, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x59, 0x65, 0x73, 0x12, 0x0d, 0x2e, + 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, + 0x75, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, + 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, + 0x61, 0x72, 0x65, 0x64, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, + 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, + 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x42, 0x12, + 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x62, 0x75, + 0x73, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -240,26 +244,26 @@ var file_test_busi_busi_proto_goTypes = []interface{}{ (*emptypb.Empty)(nil), // 2: google.protobuf.Empty } var file_test_busi_busi_proto_depIdxs = []int32{ - 0, // 0: busi.Busi.CanSubmit:input_type -> busi.BusiReq - 0, // 1: busi.Busi.TransIn:input_type -> busi.BusiReq - 0, // 2: busi.Busi.TransOut:input_type -> busi.BusiReq - 0, // 3: busi.Busi.TransInRevert:input_type -> busi.BusiReq - 0, // 4: busi.Busi.TransOutRevert:input_type -> busi.BusiReq - 0, // 5: busi.Busi.TransInConfirm:input_type -> busi.BusiReq - 0, // 6: busi.Busi.TransOutConfirm:input_type -> busi.BusiReq - 2, // 7: busi.Busi.XaNotify:input_type -> google.protobuf.Empty - 0, // 8: busi.Busi.TransInXa:input_type -> busi.BusiReq - 0, // 9: busi.Busi.TransOutXa:input_type -> busi.BusiReq - 0, // 10: busi.Busi.TransInTcc:input_type -> busi.BusiReq - 0, // 11: busi.Busi.TransOutTcc:input_type -> busi.BusiReq - 0, // 12: busi.Busi.TransInTccNested:input_type -> busi.BusiReq - 0, // 13: busi.Busi.TransInBSaga:input_type -> busi.BusiReq - 0, // 14: busi.Busi.TransOutBSaga:input_type -> busi.BusiReq - 0, // 15: busi.Busi.TransInRevertBSaga:input_type -> busi.BusiReq - 0, // 16: busi.Busi.TransOutRevertBSaga:input_type -> busi.BusiReq - 0, // 17: busi.Busi.TransOutHeaderYes:input_type -> busi.BusiReq - 0, // 18: busi.Busi.TransOutHeaderNo:input_type -> busi.BusiReq - 1, // 19: busi.Busi.CanSubmit:output_type -> busi.BusiReply + 0, // 0: busi.Busi.TransIn:input_type -> busi.BusiReq + 0, // 1: busi.Busi.TransOut:input_type -> busi.BusiReq + 0, // 2: busi.Busi.TransInRevert:input_type -> busi.BusiReq + 0, // 3: busi.Busi.TransOutRevert:input_type -> busi.BusiReq + 0, // 4: busi.Busi.TransInConfirm:input_type -> busi.BusiReq + 0, // 5: busi.Busi.TransOutConfirm:input_type -> busi.BusiReq + 2, // 6: busi.Busi.XaNotify:input_type -> google.protobuf.Empty + 0, // 7: busi.Busi.TransInXa:input_type -> busi.BusiReq + 0, // 8: busi.Busi.TransOutXa:input_type -> busi.BusiReq + 0, // 9: busi.Busi.TransInTcc:input_type -> busi.BusiReq + 0, // 10: busi.Busi.TransOutTcc:input_type -> busi.BusiReq + 0, // 11: busi.Busi.TransInTccNested:input_type -> busi.BusiReq + 0, // 12: busi.Busi.TransInBSaga:input_type -> busi.BusiReq + 0, // 13: busi.Busi.TransOutBSaga:input_type -> busi.BusiReq + 0, // 14: busi.Busi.TransInRevertBSaga:input_type -> busi.BusiReq + 0, // 15: busi.Busi.TransOutRevertBSaga:input_type -> busi.BusiReq + 0, // 16: busi.Busi.TransOutHeaderYes:input_type -> busi.BusiReq + 0, // 17: busi.Busi.TransOutHeaderNo:input_type -> busi.BusiReq + 0, // 18: busi.Busi.QueryPrepared:input_type -> busi.BusiReq + 0, // 19: busi.Busi.QueryPreparedB:input_type -> busi.BusiReq 2, // 20: busi.Busi.TransIn:output_type -> google.protobuf.Empty 2, // 21: busi.Busi.TransOut:output_type -> google.protobuf.Empty 2, // 22: busi.Busi.TransInRevert:output_type -> google.protobuf.Empty @@ -278,8 +282,10 @@ var file_test_busi_busi_proto_depIdxs = []int32{ 2, // 35: busi.Busi.TransOutRevertBSaga:output_type -> google.protobuf.Empty 2, // 36: busi.Busi.TransOutHeaderYes:output_type -> google.protobuf.Empty 2, // 37: busi.Busi.TransOutHeaderNo:output_type -> google.protobuf.Empty - 19, // [19:38] is the sub-list for method output_type - 0, // [0:19] is the sub-list for method input_type + 2, // 38: busi.Busi.QueryPrepared:output_type -> google.protobuf.Empty + 2, // 39: busi.Busi.QueryPreparedB:output_type -> google.protobuf.Empty + 20, // [20:40] is the sub-list for method output_type + 0, // [0:20] is the sub-list for method input_type 0, // [0:0] is the sub-list for extension type_name 0, // [0:0] is the sub-list for extension extendee 0, // [0:0] is the sub-list for field type_name diff --git a/test/busi/busi.proto b/test/busi/busi.proto index 9d43abd..123ff33 100644 --- a/test/busi/busi.proto +++ b/test/busi/busi.proto @@ -17,7 +17,6 @@ message BusiReply { } // The dtm service definition. service Busi { - rpc CanSubmit(BusiReq) returns (BusiReply) {} rpc TransIn(BusiReq) returns (google.protobuf.Empty) {} rpc TransOut(BusiReq) returns (google.protobuf.Empty) {} rpc TransInRevert(BusiReq) returns (google.protobuf.Empty) {} @@ -38,5 +37,7 @@ service Busi { rpc TransOutRevertBSaga(BusiReq) returns (google.protobuf.Empty) {} rpc TransOutHeaderYes(BusiReq) returns (google.protobuf.Empty) {} rpc TransOutHeaderNo(BusiReq) returns (google.protobuf.Empty) {} + rpc QueryPrepared(BusiReq) returns (google.protobuf.Empty) {} + rpc QueryPreparedB(BusiReq) returns (google.protobuf.Empty) {} } diff --git a/test/busi/busi_grpc.pb.go b/test/busi/busi_grpc.pb.go index 095b295..be3a769 100644 --- a/test/busi/busi_grpc.pb.go +++ b/test/busi/busi_grpc.pb.go @@ -19,7 +19,6 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type BusiClient interface { - CanSubmit(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*BusiReply, error) TransIn(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransOut(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransInRevert(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) @@ -38,6 +37,8 @@ type BusiClient interface { TransOutRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransOutHeaderYes(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransOutHeaderNo(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + QueryPrepared(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + QueryPreparedB(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) } type busiClient struct { @@ -48,15 +49,6 @@ func NewBusiClient(cc grpc.ClientConnInterface) BusiClient { return &busiClient{cc} } -func (c *busiClient) CanSubmit(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*BusiReply, error) { - out := new(BusiReply) - err := c.cc.Invoke(ctx, "/busi.Busi/CanSubmit", in, out, opts...) - if err != nil { - return nil, err - } - return out, nil -} - func (c *busiClient) TransIn(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) err := c.cc.Invoke(ctx, "/busi.Busi/TransIn", in, out, opts...) @@ -219,11 +211,28 @@ func (c *busiClient) TransOutHeaderNo(ctx context.Context, in *BusiReq, opts ... return out, nil } +func (c *busiClient) QueryPrepared(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/busi.Busi/QueryPrepared", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *busiClient) QueryPreparedB(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/busi.Busi/QueryPreparedB", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // BusiServer is the server API for Busi service. // All implementations must embed UnimplementedBusiServer // for forward compatibility type BusiServer interface { - CanSubmit(context.Context, *BusiReq) (*BusiReply, error) TransIn(context.Context, *BusiReq) (*emptypb.Empty, error) TransOut(context.Context, *BusiReq) (*emptypb.Empty, error) TransInRevert(context.Context, *BusiReq) (*emptypb.Empty, error) @@ -242,6 +251,8 @@ type BusiServer interface { TransOutRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) TransOutHeaderYes(context.Context, *BusiReq) (*emptypb.Empty, error) TransOutHeaderNo(context.Context, *BusiReq) (*emptypb.Empty, error) + QueryPrepared(context.Context, *BusiReq) (*emptypb.Empty, error) + QueryPreparedB(context.Context, *BusiReq) (*emptypb.Empty, error) mustEmbedUnimplementedBusiServer() } @@ -249,9 +260,6 @@ type BusiServer interface { type UnimplementedBusiServer struct { } -func (UnimplementedBusiServer) CanSubmit(context.Context, *BusiReq) (*BusiReply, error) { - return nil, status.Errorf(codes.Unimplemented, "method CanSubmit not implemented") -} func (UnimplementedBusiServer) TransIn(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransIn not implemented") } @@ -306,6 +314,12 @@ func (UnimplementedBusiServer) TransOutHeaderYes(context.Context, *BusiReq) (*em func (UnimplementedBusiServer) TransOutHeaderNo(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutHeaderNo not implemented") } +func (UnimplementedBusiServer) QueryPrepared(context.Context, *BusiReq) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryPrepared not implemented") +} +func (UnimplementedBusiServer) QueryPreparedB(context.Context, *BusiReq) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method QueryPreparedB not implemented") +} func (UnimplementedBusiServer) mustEmbedUnimplementedBusiServer() {} // UnsafeBusiServer may be embedded to opt out of forward compatibility for this service. @@ -319,24 +333,6 @@ func RegisterBusiServer(s grpc.ServiceRegistrar, srv BusiServer) { s.RegisterService(&Busi_ServiceDesc, srv) } -func _Busi_CanSubmit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(BusiReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(BusiServer).CanSubmit(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/busi.Busi/CanSubmit", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).CanSubmit(ctx, req.(*BusiReq)) - } - return interceptor(ctx, in, info, handler) -} - func _Busi_TransIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(BusiReq) if err := dec(in); err != nil { @@ -661,6 +657,42 @@ func _Busi_TransOutHeaderNo_Handler(srv interface{}, ctx context.Context, dec fu return interceptor(ctx, in, info, handler) } +func _Busi_QueryPrepared_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BusiReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BusiServer).QueryPrepared(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/busi.Busi/QueryPrepared", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BusiServer).QueryPrepared(ctx, req.(*BusiReq)) + } + return interceptor(ctx, in, info, handler) +} + +func _Busi_QueryPreparedB_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(BusiReq) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BusiServer).QueryPreparedB(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/busi.Busi/QueryPreparedB", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BusiServer).QueryPreparedB(ctx, req.(*BusiReq)) + } + return interceptor(ctx, in, info, handler) +} + // Busi_ServiceDesc is the grpc.ServiceDesc for Busi service. // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) @@ -668,10 +700,6 @@ var Busi_ServiceDesc = grpc.ServiceDesc{ ServiceName: "busi.Busi", HandlerType: (*BusiServer)(nil), Methods: []grpc.MethodDesc{ - { - MethodName: "CanSubmit", - Handler: _Busi_CanSubmit_Handler, - }, { MethodName: "TransIn", Handler: _Busi_TransIn_Handler, @@ -744,6 +772,14 @@ var Busi_ServiceDesc = grpc.ServiceDesc{ MethodName: "TransOutHeaderNo", Handler: _Busi_TransOutHeaderNo_Handler, }, + { + MethodName: "QueryPrepared", + Handler: _Busi_QueryPrepared_Handler, + }, + { + MethodName: "QueryPreparedB", + Handler: _Busi_QueryPreparedB_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "test/busi/busi.proto", diff --git a/test/msg_grpc_test.go b/test/msg_grpc_test.go index e228fbb..4701903 100644 --- a/test/msg_grpc_test.go +++ b/test/msg_grpc_test.go @@ -31,7 +31,7 @@ func TestMsgGrpcTimeoutSuccess(t *testing.T) { msg := genGrpcMsg(dtmimp.GetFuncName()) err := msg.Prepare("") assert.Nil(t, err) - busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) @@ -48,10 +48,10 @@ func TestMsgGrpcTimeoutFailed(t *testing.T) { msg := genGrpcMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultFailure) cronTransOnceForwardNow(180) assert.Equal(t, StatusFailed, getTransStatus(msg.Gid)) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(msg.Gid)) @@ -62,6 +62,6 @@ func genGrpcMsg(gid string) *dtmgrpc.MsgGrpc { msg := dtmgrpc.NewMsgGrpc(dtmutil.DefaultGrpcServer, gid). Add(busi.BusiGrpc+"/busi.Busi/TransOut", req). Add(busi.BusiGrpc+"/busi.Busi/TransIn", req) - msg.QueryPrepared = fmt.Sprintf("%s/busi.Busi/CanSubmit", busi.BusiGrpc) + msg.QueryPrepared = fmt.Sprintf("%s/busi.Busi/QueryPrepared", busi.BusiGrpc) return msg } diff --git a/test/msg_options_test.go b/test/msg_options_test.go index 97cfbe3..1f60810 100644 --- a/test/msg_options_test.go +++ b/test/msg_options_test.go @@ -47,7 +47,7 @@ func TestMsgOptionsTimeoutFailed(t *testing.T) { assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) cronTransOnceForwardNow(60) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultFailure) cronTransOnceForwardNow(180) assert.Equal(t, StatusFailed, getTransStatus(msg.Gid)) } diff --git a/test/msg_test.go b/test/msg_test.go index e9c1475..0ef4197 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -29,7 +29,7 @@ func TestMsgTimeoutSuccess(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) busi.MainSwitch.TransInResult.SetOnce(dtmcli.ResultOngoing) @@ -45,10 +45,10 @@ func TestMsgTimeoutFailed(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultFailure) cronTransOnceForwardNow(180) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(msg.Gid)) assert.Equal(t, StatusFailed, getTransStatus(msg.Gid)) @@ -71,6 +71,6 @@ func genMsg(gid string) *dtmcli.Msg { msg := dtmcli.NewMsg(dtmutil.DefaultHttpServer, gid). Add(busi.Busi+"/TransOut", &req). Add(busi.Busi+"/TransIn", &req) - msg.QueryPrepared = busi.Busi + "/CanSubmit" + msg.QueryPrepared = busi.Busi + "/QueryPrepared" return msg } From aa9358028fa1c367c2c5b73019e6bccb21fedc5f Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 5 Jan 2022 23:08:00 +0800 Subject: [PATCH 071/124] first test case ok --- dtmcli/barrier.go | 33 ++++++--------------------------- dtmcli/msg.go | 23 ++++++++++++++++++++++- dtmutil/utils.go | 2 +- test/busi/barrier.go | 32 ++++++++++++++++---------------- test/busi/base_grpc.go | 4 ++-- test/busi/base_http.go | 12 +++++++++--- test/busi/base_types.go | 11 +++-------- test/busi/busi.go | 6 +++--- test/msg_barrier_test.go | 26 ++++++++++++++++++++++++++ test/tcc_barrier_test.go | 6 ++---- test/types.go | 22 ++++++++++++++++++++++ 11 files changed, 112 insertions(+), 65 deletions(-) create mode 100644 test/msg_barrier_test.go diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index f515550..92aab5b 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -102,35 +102,14 @@ func (bb *BranchBarrier) CallWithDB(db *sql.DB, busiCall BarrierBusiFunc) error } func (bb *BranchBarrier) QueryPrepared(db *sql.DB) error { - affected, err := insertBarrier(db, bb.TransType, bb.Gid, bb.BranchID, BranchAction, bb.BranchID, bb.Op) - if err != nil { - return err - } - if affected > 0 { - return ErrFailure - } - return nil -} - -func (bb *BranchBarrier) PrepareAndSubmit(msg *Msg, queryPrepared string, db *sql.DB, busiCall BarrierBusiFunc) (err error) { - var tx *sql.Tx - tx, err = db.Begin() + _, err := insertBarrier(db, bb.TransType, bb.Gid, bb.BranchID, BranchAction, bb.BranchID, "rollback") + var reason string if err == nil { - defer func() { - if err != nil { - _ = tx.Rollback() - } - }() - err = busiCall(tx) + sql := fmt.Sprintf("select reason from %s where gid=? and branch_id=? and op=? and barrier_id=?", dtmimp.BarrierTableName) + err = db.QueryRow(sql, bb.Gid, bb.BranchID, bb.Op, bb.BarrierID).Scan(&reason) } - if err == nil { - err = msg.Prepare(queryPrepared) - } - if err == nil { - err = tx.Commit() - } - if err == nil { - return msg.Submit() // should not assign err. or else defer may try to rollback a committed tx + if reason == "rollback" { + return ErrFailure } return err } diff --git a/dtmcli/msg.go b/dtmcli/msg.go index a461ea2..815b97d 100644 --- a/dtmcli/msg.go +++ b/dtmcli/msg.go @@ -6,7 +6,11 @@ package dtmcli -import "github.com/dtm-labs/dtm/dtmcli/dtmimp" +import ( + "database/sql" + + "github.com/dtm-labs/dtm/dtmcli/dtmimp" +) // Msg reliable msg type type Msg struct { @@ -35,3 +39,20 @@ func (s *Msg) Prepare(queryPrepared string) error { func (s *Msg) Submit() error { return dtmimp.TransCallDtm(&s.TransBase, s, "submit") } + +func (s *Msg) PrepareAndSubmit(queryPrepared string, db *sql.DB, busiCall BarrierBusiFunc) error { + bb, err := BarrierFrom(s.TransType, s.Gid, "00", "msg") // a special barrier for msg QueryPrepared + if err == nil { + err = bb.CallWithDB(db, func(tx *sql.Tx) error { + err := busiCall(tx) + if err == nil { + err = s.Prepare(queryPrepared) + } + return err + }) + } + if err == nil { + err = s.Submit() + } + return err +} diff --git a/dtmutil/utils.go b/dtmutil/utils.go index 4fbbc7d..0b08915 100644 --- a/dtmutil/utils.go +++ b/dtmutil/utils.go @@ -38,7 +38,7 @@ func GetGinApp() *gin.Engine { c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(rb)) } } - logger.Debugf("begin %s %s query: %s body: %s", c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) + logger.Debugf("begin %s %s body: %s", c.Request.Method, c.Request.URL, body) c.Next() }) app.Any("/api/ping", func(c *gin.Context) { c.JSON(200, map[string]interface{}{"msg": "pong"}) }) diff --git a/test/busi/barrier.go b/test/busi/barrier.go index df30145..8ca19de 100644 --- a/test/busi/barrier.go +++ b/test/busi/barrier.go @@ -17,29 +17,29 @@ import ( ) func init() { - setupFuncs["TccBarrierSetup"] = func(app *gin.Engine) { + setupFuncs["BarrierSetup"] = func(app *gin.Engine) { app.POST(BusiAPI+"/SagaBTransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { barrier := MustBarrierFromGin(c) return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaAdjustBalance(tx, transInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) + return SagaAdjustBalance(tx, TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) })) app.POST(BusiAPI+"/SagaBTransInCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { barrier := MustBarrierFromGin(c) return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaAdjustBalance(tx, transInUID, -reqFrom(c).Amount, "") + return SagaAdjustBalance(tx, TransInUID, -reqFrom(c).Amount, "") }) })) app.POST(BusiAPI+"/SagaBTransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { barrier := MustBarrierFromGin(c) return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaAdjustBalance(tx, transOutUID, -reqFrom(c).Amount, reqFrom(c).TransOutResult) + return SagaAdjustBalance(tx, TransOutUID, -reqFrom(c).Amount, reqFrom(c).TransOutResult) }) })) app.POST(BusiAPI+"/SagaBTransOutCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { barrier := MustBarrierFromGin(c) return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaAdjustBalance(tx, transOutUID, reqFrom(c).Amount, "") + return SagaAdjustBalance(tx, TransOutUID, reqFrom(c).Amount, "") }) })) app.POST(BusiAPI+"/SagaBTransOutGorm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { @@ -47,7 +47,7 @@ func init() { barrier := MustBarrierFromGin(c) tx := dbGet().DB.Begin() return dtmcli.MapSuccess, barrier.Call(tx.Statement.ConnPool.(*sql.Tx), func(tx1 *sql.Tx) error { - return tx.Exec("update dtm_busi.user_account set balance = balance + ? where user_id = ?", -req.Amount, transOutUID).Error + return tx.Exec("update dtm_busi.user_account set balance = balance + ? where user_id = ?", -req.Amount, TransOutUID).Error }) })) @@ -57,17 +57,17 @@ func init() { return req.TransInResult, nil } return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return tccAdjustTrading(tx, transInUID, req.Amount) + return tccAdjustTrading(tx, TransInUID, req.Amount) }) })) app.POST(BusiAPI+"/TccBTransInConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return tccAdjustBalance(tx, transInUID, reqFrom(c).Amount) + return tccAdjustBalance(tx, TransInUID, reqFrom(c).Amount) }) })) app.POST(BusiAPI+"/TccBTransInCancel", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return tccAdjustTrading(tx, transInUID, -reqFrom(c).Amount) + return tccAdjustTrading(tx, TransInUID, -reqFrom(c).Amount) }) })) app.POST(BusiAPI+"/TccBTransOutTry", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { @@ -76,12 +76,12 @@ func init() { return req.TransOutResult, nil } return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return tccAdjustTrading(tx, transOutUID, -req.Amount) + return tccAdjustTrading(tx, TransOutUID, -req.Amount) }) })) app.POST(BusiAPI+"/TccBTransOutConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return tccAdjustBalance(tx, transOutUID, -reqFrom(c).Amount) + return tccAdjustBalance(tx, TransOutUID, -reqFrom(c).Amount) }) })) app.POST(BusiAPI+"/TccBTransOutCancel", dtmutil.WrapHandler(TccBarrierTransOutCancel)) @@ -91,34 +91,34 @@ func init() { // TccBarrierTransOutCancel will be use in test func TccBarrierTransOutCancel(c *gin.Context) (interface{}, error) { return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { - return tccAdjustTrading(tx, transOutUID, reqFrom(c).Amount) + return tccAdjustTrading(tx, TransOutUID, reqFrom(c).Amount) }) } func (s *busiServer) TransInBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { barrier := MustBarrierFromGrpc(ctx) return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcAdjustBalance(tx, transInUID, in.Amount, in.TransInResult) + return sagaGrpcAdjustBalance(tx, TransInUID, in.Amount, in.TransInResult) }) } func (s *busiServer) TransOutBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { barrier := MustBarrierFromGrpc(ctx) return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcAdjustBalance(tx, transOutUID, -in.Amount, in.TransOutResult) + return sagaGrpcAdjustBalance(tx, TransOutUID, -in.Amount, in.TransOutResult) }) } func (s *busiServer) TransInRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { barrier := MustBarrierFromGrpc(ctx) return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcAdjustBalance(tx, transInUID, -in.Amount, "") + return sagaGrpcAdjustBalance(tx, TransInUID, -in.Amount, "") }) } func (s *busiServer) TransOutRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { barrier := MustBarrierFromGrpc(ctx) return &emptypb.Empty{}, barrier.Call(txGet(), func(tx *sql.Tx) error { - return sagaGrpcAdjustBalance(tx, transOutUID, in.Amount, "") + return sagaGrpcAdjustBalance(tx, TransOutUID, in.Amount, "") }) } diff --git a/test/busi/base_grpc.go b/test/busi/base_grpc.go index b1da93e..c858a1f 100644 --- a/test/busi/base_grpc.go +++ b/test/busi/base_grpc.go @@ -102,13 +102,13 @@ func (s *busiServer) TransOutTcc(ctx context.Context, in *BusiReq) (*emptypb.Emp func (s *busiServer) TransInXa(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { return &emptypb.Empty{}, XaGrpcClient.XaLocalTransaction(ctx, in, func(db *sql.DB, xa *dtmgrpc.XaGrpc) error { - return sagaGrpcAdjustBalance(db, transInUID, in.Amount, in.TransInResult) + return sagaGrpcAdjustBalance(db, TransInUID, in.Amount, in.TransInResult) }) } func (s *busiServer) TransOutXa(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { return &emptypb.Empty{}, XaGrpcClient.XaLocalTransaction(ctx, in, func(db *sql.DB, xa *dtmgrpc.XaGrpc) error { - return sagaGrpcAdjustBalance(db, transOutUID, in.Amount, in.TransOutResult) + return sagaGrpcAdjustBalance(db, TransOutUID, in.Amount, in.TransOutResult) }) } diff --git a/test/busi/base_http.go b/test/busi/base_http.go index 7a9838b..83da433 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -103,15 +103,21 @@ func BaseAddRoute(app *gin.Engine) { logger.Debugf("%s QueryPrepared", c.Query("gid")) return dtmimp.OrString(MainSwitch.QueryPreparedResult.Fetch(), dtmcli.ResultSuccess), nil })) + app.GET(BusiAPI+"/QueryPreparedB", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + logger.Debugf("%s QueryPreparedB", c.Query("gid")) + bb := MustBarrierFromGin(c) + db := dbGet().ToSQLDB() + return error2Resp(bb.QueryPrepared(db)) + })) app.POST(BusiAPI+"/TransInXa", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { - return sagaAdjustBalance(db, transInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) + return SagaAdjustBalance(db, TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) return error2Resp(err) })) app.POST(BusiAPI+"/TransOutXa", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { - return sagaAdjustBalance(db, transOutUID, reqFrom(c).Amount, reqFrom(c).TransOutResult) + return SagaAdjustBalance(db, TransOutUID, reqFrom(c).Amount, reqFrom(c).TransOutResult) }) return error2Resp(err) })) @@ -137,7 +143,7 @@ func BaseAddRoute(app *gin.Engine) { if err != nil { return err } - dbr := gdb.Exec("update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, transOutUID) + dbr := gdb.Exec("update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, TransOutUID) return dbr.Error }) return error2Resp(err) diff --git a/test/busi/base_types.go b/test/busi/base_types.go index f0d29fb..5aaaed9 100644 --- a/test/busi/base_types.go +++ b/test/busi/base_types.go @@ -32,15 +32,10 @@ func (*UserAccount) TableName() string { return "dtm_busi.user_account" } -func GetUserAccountByUid(uid int) *UserAccount { +func GetBalanceByUid(uid int) int { ua := UserAccount{} - dbr := dbGet().Must().Model(&ua).Where("user_id=?", uid).First(&ua) - dtmimp.E2P(dbr.Error) - return &ua -} - -func IsEqual(ua1, ua2 *UserAccount) bool { - return ua1.UserId == ua2.UserId && ua1.Balance == ua2.Balance && ua1.TradingBalance == ua2.TradingBalance + _ = dbGet().Must().Model(&ua).Where("user_id=?", uid).First(&ua) + return dtmimp.MustAtoi(ua.Balance[:len(ua.Balance)-3]) } // TransReq transaction request payload diff --git a/test/busi/busi.go b/test/busi/busi.go index 13eb7e8..7d6c064 100644 --- a/test/busi/busi.go +++ b/test/busi/busi.go @@ -13,8 +13,8 @@ import ( status "google.golang.org/grpc/status" ) -const transOutUID = 1 -const transInUID = 2 +const TransOutUID = 1 +const TransInUID = 2 func handleGrpcBusiness(in *BusiReq, result1 string, result2 string, busi string) error { res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) @@ -59,7 +59,7 @@ func sagaGrpcAdjustBalance(db dtmcli.DB, uid int, amount int64, result string) e } -func sagaAdjustBalance(db dtmcli.DB, uid int, amount int, result string) error { +func SagaAdjustBalance(db dtmcli.DB, uid int, amount int, result string) error { if strings.Contains(result, dtmcli.ResultFailure) { return dtmcli.ErrFailure } diff --git a/test/msg_barrier_test.go b/test/msg_barrier_test.go new file mode 100644 index 0000000..7a77b7a --- /dev/null +++ b/test/msg_barrier_test.go @@ -0,0 +1,26 @@ +package test + +import ( + "database/sql" + "testing" + + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/test/busi" + "github.com/stretchr/testify/assert" +) + +func TestMsgPrepareAndSubmit(t *testing.T) { + before := getBeforeBalances() + gid := dtmcli.MustGenGid(DtmServer) + req := busi.GenTransReq(30, false, false) + msg := dtmcli.NewMsg(DtmServer, gid). + Add(busi.Busi+"/SagaBTransIn1", req) + err := msg.PrepareAndSubmit(Busi+"/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { + return busi.SagaAdjustBalance(tx, busi.TransOutUID, -req.Amount, "SUCCESS") + }) + assert.Nil(t, err) + waitTransProcessed(msg.Gid) + assert.Equal(t, []string{StatusSucceed}, getBranchesStatus(msg.Gid)) + assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) + assertNotSameBalance(t, before) +} diff --git a/test/tcc_barrier_test.go b/test/tcc_barrier_test.go index 87c3aea..376b3ca 100644 --- a/test/tcc_barrier_test.go +++ b/test/tcc_barrier_test.go @@ -51,8 +51,7 @@ func TestTccBarrierRollback(t *testing.T) { } func TestTccBarrierDisorder(t *testing.T) { - ua1 := busi.GetUserAccountByUid(1) - ua2 := busi.GetUserAccountByUid(2) + before := getBeforeBalances() cancelFinishedChan := make(chan string, 2) cancelCanReturnChan := make(chan string, 2) gid := dtmimp.GetFuncName() @@ -123,8 +122,7 @@ func TestTccBarrierDisorder(t *testing.T) { assert.Error(t, err, fmt.Errorf("a cancelled tcc")) assert.Equal(t, []string{StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) assert.Equal(t, StatusFailed, getTransStatus(gid)) - assert.True(t, busi.IsEqual(ua1, busi.GetUserAccountByUid(1))) - assert.True(t, busi.IsEqual(ua2, busi.GetUserAccountByUid(2))) + assertSameBalance(t, before) } func TestTccBarrierPanic(t *testing.T) { diff --git a/test/types.go b/test/types.go index 4fcbe34..c583a28 100644 --- a/test/types.go +++ b/test/types.go @@ -7,6 +7,7 @@ package test import ( + "testing" "time" "github.com/dtm-labs/dtm/dtmcli" @@ -16,6 +17,7 @@ import ( "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmutil" "github.com/dtm-labs/dtm/test/busi" + "github.com/stretchr/testify/assert" ) var conf = &config.Config @@ -80,3 +82,23 @@ const ( // StatusAborting status for global trans status. StatusAborting = dtmcli.StatusAborting ) + +func getBeforeBalances() []int { + b1 := busi.GetBalanceByUid(busi.TransOutUID) + b2 := busi.GetBalanceByUid(busi.TransInUID) + return []int{b1, b2} +} + +func assertSameBalance(t *testing.T, before []int) { + b1 := busi.GetBalanceByUid(busi.TransOutUID) + b2 := busi.GetBalanceByUid(busi.TransInUID) + assert.Equal(t, before[0], b1) + assert.Equal(t, before[1], b2) +} + +func assertNotSameBalance(t *testing.T, before []int) { + b1 := busi.GetBalanceByUid(busi.TransOutUID) + b2 := busi.GetBalanceByUid(busi.TransInUID) + assert.NotEqual(t, before[0], b1) + assert.Equal(t, before[0]+before[1], b1+b2) +} From 3cc3895b78f563f19952dfc3f26754a7a474ab5e Mon Sep 17 00:00:00 2001 From: liulei Date: Thu, 6 Jan 2022 09:57:00 +0800 Subject: [PATCH 072/124] fix dtmsrv(not contain subpackage) relevant golangci lint error --- dtmsvr/cron.go | 4 ++-- dtmsvr/svr.go | 9 +++++++-- dtmsvr/trans_process.go | 7 ++++++- dtmsvr/trans_type_saga.go | 3 ++- dtmsvr/utils.go | 6 ++++-- 5 files changed, 21 insertions(+), 8 deletions(-) diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index 8b1520a..66ff0b5 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -17,10 +17,10 @@ import ( ) // NowForwardDuration will be set in test, trans may be timeout -var NowForwardDuration time.Duration = time.Duration(0) +var NowForwardDuration = time.Duration(0) // CronForwardDuration will be set in test. cron will fetch trans which expire in CronForwardDuration -var CronForwardDuration time.Duration = time.Duration(0) +var CronForwardDuration = time.Duration(0) // CronTransOnce cron expired trans. use expireIn as expire time func CronTransOnce() (gid string) { diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index f891a6f..7f141df 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -27,7 +27,12 @@ func StartSvr() { app = httpMetrics(app) addRoute(app) logger.Infof("dtmsvr listen at: %d", conf.HttpPort) - go app.Run(fmt.Sprintf(":%d", conf.HttpPort)) + go func() { + err := app.Run(fmt.Sprintf(":%d", conf.HttpPort)) + if err != nil { + logger.Errorf("start server err: %v", err) + } + }() lis, err := net.Listen("tcp", fmt.Sprintf(":%d", conf.GrpcPort)) logger.FatalIfError(err) @@ -60,8 +65,8 @@ var UpdateBranchAsyncInterval = 200 * time.Millisecond var updateBranchAsyncChan chan branchStatus = make(chan branchStatus, 1000) func updateBranchAsync() { + defer dtmutil.RecoverPanic(nil) for { // flush branches every second - defer dtmutil.RecoverPanic(nil) updates := []TransBranch{} started := time.Now() checkInterval := 20 * time.Millisecond diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index db6243c..fc48513 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -31,7 +31,12 @@ func (t *TransGlobal) process(branches []TransBranch) map[string]interface{} { } if !t.WaitResult { - go t.processInner(branches) + go func() { + err := t.processInner(branches) + if err != nil { + logger.Errorf("processInner err: %v", err) + } + }() return dtmcli.MapSuccess } submitting := t.Status == dtmcli.StatusSubmitted diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index a02e8bc..abaa801 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -21,7 +21,8 @@ type transSagaProcessor struct { func init() { registorProcessorCreator("saga", func(trans *TransGlobal) transProcessor { - return &transSagaProcessor{TransGlobal: trans} }) + return &transSagaProcessor{TransGlobal: trans} + }) } func (t *transSagaProcessor) GenBranches() []TransBranch { diff --git a/dtmsvr/utils.go b/dtmsvr/utils.go index c52dce0..3afac50 100644 --- a/dtmsvr/utils.go +++ b/dtmsvr/utils.go @@ -24,17 +24,17 @@ type branchStatus struct { finishTime *time.Time } -var p2e = dtmimp.P2E var e2p = dtmimp.E2P var conf = &config.Config +// GetStore returns storage.Store func GetStore() storage.Store { return registry.GetStore() } // TransProcessedTestChan only for test usage. when transaction processed once, write gid to this chan -var TransProcessedTestChan chan string = nil +var TransProcessedTestChan chan string // GenGid generate gid, use uuid func GenGid() string { @@ -44,6 +44,8 @@ func GenGid() string { // GetTransGlobal construct trans from db func GetTransGlobal(gid string) *TransGlobal { trans := GetStore().FindTransGlobalStore(gid) + //nolint:staticcheck dtmimp.PanicIf(trans == nil, fmt.Errorf("no TransGlobal with gid: %s found", gid)) + //nolint:staticcheck return &TransGlobal{TransGlobalStore: *trans} } From 50b8b5b16c4ce75492cd2a6c7b5764e9b5419780 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 6 Jan 2022 10:23:51 +0800 Subject: [PATCH 073/124] PrepareAndCommit seems ok --- dtmcli/barrier.go | 6 ++-- dtmsvr/trans_type_msg.go | 4 +-- go.mod | 1 + go.sum | 2 ++ test/msg_barrier_test.go | 74 +++++++++++++++++++++++++++++++++++++++- 5 files changed, 81 insertions(+), 6 deletions(-) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index 92aab5b..5cffeba 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -72,7 +72,7 @@ func (bb *BranchBarrier) Call(tx *sql.Tx, busiCall BarrierBusiFunc) (rerr error) } else if rerr != nil { tx.Rollback() } else { - tx.Commit() + rerr = tx.Commit() } }() ti := bb @@ -102,11 +102,11 @@ func (bb *BranchBarrier) CallWithDB(db *sql.DB, busiCall BarrierBusiFunc) error } func (bb *BranchBarrier) QueryPrepared(db *sql.DB) error { - _, err := insertBarrier(db, bb.TransType, bb.Gid, bb.BranchID, BranchAction, bb.BranchID, "rollback") + _, err := insertBarrier(db, bb.TransType, bb.Gid, "00", "msg", "01", "rollback") var reason string if err == nil { sql := fmt.Sprintf("select reason from %s where gid=? and branch_id=? and op=? and barrier_id=?", dtmimp.BarrierTableName) - err = db.QueryRow(sql, bb.Gid, bb.BranchID, bb.Op, bb.BarrierID).Scan(&reason) + err = db.QueryRow(sql, bb.Gid, "00", "msg", "01").Scan(&reason) } if reason == "rollback" { return ErrFailure diff --git a/dtmsvr/trans_type_msg.go b/dtmsvr/trans_type_msg.go index 3f62f74..69152f3 100644 --- a/dtmsvr/trans_type_msg.go +++ b/dtmsvr/trans_type_msg.go @@ -42,7 +42,7 @@ func (t *TransGlobal) mayQueryPrepared() { if !t.needProcess() || t.Status == dtmcli.StatusSubmitted { return } - body, err := t.getURLResult(t.QueryPrepared, "", "", nil) + body, err := t.getURLResult(t.QueryPrepared, "00", "msg", nil) if strings.Contains(body, dtmcli.ResultSuccess) { t.changeStatus(dtmcli.StatusSubmitted) } else if strings.Contains(body, dtmcli.ResultFailure) { @@ -50,7 +50,7 @@ func (t *TransGlobal) mayQueryPrepared() { } else if strings.Contains(body, dtmcli.ResultOngoing) { t.touchCronTime(cronReset) } else { - logger.Errorf("getting result failed for %s. error: %s", t.QueryPrepared, err.Error()) + logger.Errorf("getting result failed for %s. error: %w", t.QueryPrepared, err) t.touchCronTime(cronBackoff) } } diff --git a/go.mod b/go.mod index 306fad3..f62a410 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/dtm-labs/dtm go 1.15 require ( + bou.ke/monkey v1.0.2 // indirect github.com/dtm-labs/dtmdriver v0.0.1 github.com/dtm-labs/dtmdriver-gozero v0.0.1 github.com/dtm-labs/dtmdriver-polaris v0.0.2 diff --git a/go.sum b/go.sum index d67335c..609d7e6 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +bou.ke/monkey v1.0.2 h1:kWcnsrCNUatbxncxR/ThdYqbytgOIArtYWqcQLQzKLI= +bou.ke/monkey v1.0.2/go.mod h1:OqickVX3tNx6t33n1xvtTtu85YN5s6cKwVug+oHMaIA= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= diff --git a/test/msg_barrier_test.go b/test/msg_barrier_test.go index 7a77b7a..40b38af 100644 --- a/test/msg_barrier_test.go +++ b/test/msg_barrier_test.go @@ -2,9 +2,13 @@ package test import ( "database/sql" + "errors" + "reflect" "testing" + "bou.ke/monkey" "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" ) @@ -14,7 +18,7 @@ func TestMsgPrepareAndSubmit(t *testing.T) { gid := dtmcli.MustGenGid(DtmServer) req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). - Add(busi.Busi+"/SagaBTransIn1", req) + Add(busi.Busi+"/SagaBTransIn", req) err := msg.PrepareAndSubmit(Busi+"/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { return busi.SagaAdjustBalance(tx, busi.TransOutUID, -req.Amount, "SUCCESS") }) @@ -24,3 +28,71 @@ func TestMsgPrepareAndSubmit(t *testing.T) { assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) assertNotSameBalance(t, before) } + +func TestMsgPrepareAndSubmitBusiFailed(t *testing.T) { + before := getBeforeBalances() + gid := dtmcli.MustGenGid(DtmServer) + req := busi.GenTransReq(30, false, false) + msg := dtmcli.NewMsg(DtmServer, gid). + Add(busi.Busi+"/SagaBTransIn", req) + err := msg.PrepareAndSubmit(Busi+"/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { + return errors.New("an error") + }) + assert.Error(t, err) + assertSameBalance(t, before) +} + +func TestMsgPrepareAndSubmitPrepareFailed(t *testing.T) { + before := getBeforeBalances() + gid := dtmcli.MustGenGid(DtmServer) + req := busi.GenTransReq(30, false, false) + msg := dtmcli.NewMsg(DtmServer+"not-exists", gid). + Add(busi.Busi+"/SagaBTransIn", req) + err := msg.PrepareAndSubmit(Busi+"/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { + return busi.SagaAdjustBalance(tx, busi.TransOutUID, -req.Amount, "SUCCESS") + }) + assert.Error(t, err) + assertSameBalance(t, before) +} + +func TestMsgPrepareAndSubmitCommitFailed(t *testing.T) { + before := getBeforeBalances() + gid := dtmcli.MustGenGid(DtmServer) + req := busi.GenTransReq(30, false, false) + msg := dtmcli.NewMsg(DtmServer, gid). + Add(busi.Busi+"/SagaBTransIn", req) + var g *monkey.PatchGuard + err := msg.PrepareAndSubmit(Busi+"/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { + g = monkey.PatchInstanceMethod(reflect.TypeOf(tx), "Commit", func(tx *sql.Tx) error { + logger.Debugf("tx.Commit rollback and return error in test") + _ = tx.Rollback() + return errors.New("test error for patch") + }) + return busi.SagaAdjustBalance(tx, busi.TransOutUID, -req.Amount, "SUCCESS") + }) + g.Unpatch() + assert.Error(t, err) + cronTransOnceForwardNow(180) + assertSameBalance(t, before) +} + +func TestMsgPrepareAndSubmitCommitAfterFailed(t *testing.T) { + before := getBeforeBalances() + gid := dtmcli.MustGenGid(DtmServer) + req := busi.GenTransReq(30, false, false) + msg := dtmcli.NewMsg(DtmServer, gid). + Add(busi.Busi+"/SagaBTransIn", req) + var guard *monkey.PatchGuard + err := msg.PrepareAndSubmit(Busi+"/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { + err := busi.SagaAdjustBalance(tx, busi.TransOutUID, -req.Amount, "SUCCESS") + guard = monkey.PatchInstanceMethod(reflect.TypeOf(tx), "Commit", func(tx *sql.Tx) error { + guard.Unpatch() + _ = tx.Commit() + return errors.New("test error for patch") + }) + return err + }) + assert.Error(t, err) + cronTransOnceForwardNow(180) + assertNotSameBalance(t, before) +} From 91ed420f067f0e3d902e3fd9a08294d9fa527ad6 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 6 Jan 2022 10:47:35 +0800 Subject: [PATCH 074/124] cover unexpected result for queryPrepared --- dtmsvr/trans_type_msg.go | 2 +- test/msg_barrier_test.go | 11 ++++++----- test/msg_test.go | 5 ++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/dtmsvr/trans_type_msg.go b/dtmsvr/trans_type_msg.go index 69152f3..3435042 100644 --- a/dtmsvr/trans_type_msg.go +++ b/dtmsvr/trans_type_msg.go @@ -50,7 +50,7 @@ func (t *TransGlobal) mayQueryPrepared() { } else if strings.Contains(body, dtmcli.ResultOngoing) { t.touchCronTime(cronReset) } else { - logger.Errorf("getting result failed for %s. error: %w", t.QueryPrepared, err) + logger.Errorf("getting result failed for %s. error: %v body %s", t.QueryPrepared, err, body) t.touchCronTime(cronBackoff) } } diff --git a/test/msg_barrier_test.go b/test/msg_barrier_test.go index 40b38af..29970dd 100644 --- a/test/msg_barrier_test.go +++ b/test/msg_barrier_test.go @@ -8,6 +8,7 @@ import ( "bou.ke/monkey" "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/test/busi" "github.com/stretchr/testify/assert" @@ -15,7 +16,7 @@ import ( func TestMsgPrepareAndSubmit(t *testing.T) { before := getBeforeBalances() - gid := dtmcli.MustGenGid(DtmServer) + gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). Add(busi.Busi+"/SagaBTransIn", req) @@ -31,7 +32,7 @@ func TestMsgPrepareAndSubmit(t *testing.T) { func TestMsgPrepareAndSubmitBusiFailed(t *testing.T) { before := getBeforeBalances() - gid := dtmcli.MustGenGid(DtmServer) + gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). Add(busi.Busi+"/SagaBTransIn", req) @@ -44,7 +45,7 @@ func TestMsgPrepareAndSubmitBusiFailed(t *testing.T) { func TestMsgPrepareAndSubmitPrepareFailed(t *testing.T) { before := getBeforeBalances() - gid := dtmcli.MustGenGid(DtmServer) + gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer+"not-exists", gid). Add(busi.Busi+"/SagaBTransIn", req) @@ -57,7 +58,7 @@ func TestMsgPrepareAndSubmitPrepareFailed(t *testing.T) { func TestMsgPrepareAndSubmitCommitFailed(t *testing.T) { before := getBeforeBalances() - gid := dtmcli.MustGenGid(DtmServer) + gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). Add(busi.Busi+"/SagaBTransIn", req) @@ -78,7 +79,7 @@ func TestMsgPrepareAndSubmitCommitFailed(t *testing.T) { func TestMsgPrepareAndSubmitCommitAfterFailed(t *testing.T) { before := getBeforeBalances() - gid := dtmcli.MustGenGid(DtmServer) + gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). Add(busi.Busi+"/SagaBTransIn", req) diff --git a/test/msg_test.go b/test/msg_test.go index 0ef4197..2330364 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -45,9 +45,12 @@ func TestMsgTimeoutFailed(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultOngoing) + busi.MainSwitch.QueryPreparedResult.SetOnce("OTHER_ERROR") cronTransOnceForwardNow(180) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) + busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultOngoing) + cronTransOnceForwardNow(360) + assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultFailure) cronTransOnceForwardNow(180) assert.Equal(t, []string{StatusPrepared, StatusPrepared}, getBranchesStatus(msg.Gid)) From 9b94eb51f899948dc5ebe6dade5c119f68115daf Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 6 Jan 2022 11:57:15 +0800 Subject: [PATCH 075/124] cover Ping and RawCodec --- dtmgrpc/dtmgimp/grpc_clients.go | 5 ----- test/busi/base_grpc.go | 4 ++-- test/busi/busi.pb.go | 20 ++++++++++---------- test/busi/busi.proto | 2 +- test/busi/busi_grpc.pb.go | 10 +++++----- test/main_test.go | 3 +++ test/store_test.go | 4 ---- 7 files changed, 21 insertions(+), 27 deletions(-) diff --git a/dtmgrpc/dtmgimp/grpc_clients.go b/dtmgrpc/dtmgimp/grpc_clients.go index dc21e81..b299b9a 100644 --- a/dtmgrpc/dtmgimp/grpc_clients.go +++ b/dtmgrpc/dtmgimp/grpc_clients.go @@ -43,11 +43,6 @@ func MustGetDtmClient(grpcServer string) dtmgpb.DtmClient { return dtmgpb.NewDtmClient(MustGetGrpcConn(grpcServer, false)) } -// MustGetRawDtmClient must get raw codec grpc conn -func MustGetRawDtmClient(grpcServer string) dtmgpb.DtmClient { - return dtmgpb.NewDtmClient(MustGetGrpcConn(grpcServer, true)) -} - // GetGrpcConn 1 func GetGrpcConn(grpcServer string, isRaw bool) (conn *grpc.ClientConn, rerr error) { clients := &normalClients diff --git a/test/busi/base_grpc.go b/test/busi/base_grpc.go index c858a1f..3c71a50 100644 --- a/test/busi/base_grpc.go +++ b/test/busi/base_grpc.go @@ -63,9 +63,9 @@ type busiServer struct { UnimplementedBusiServer } -func (s *busiServer) QueryPrepared(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { +func (s *busiServer) QueryPrepared(ctx context.Context, in *BusiReq) (*BusiReply, error) { res := MainSwitch.QueryPreparedResult.Fetch() - return &emptypb.Empty{}, dtmgimp.Result2Error(res, nil) + return &BusiReply{Message: "a sample data"}, dtmgimp.Result2Error(res, nil) } func (s *busiServer) TransIn(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { diff --git a/test/busi/busi.pb.go b/test/busi/busi.pb.go index 975a949..759886f 100644 --- a/test/busi/busi.pb.go +++ b/test/busi/busi.pb.go @@ -148,7 +148,7 @@ var file_test_busi_busi_proto_rawDesc = []byte{ 0x6e, 0x73, 0x49, 0x6e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x22, 0x25, 0x0a, 0x09, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, - 0x65, 0x32, 0x94, 0x09, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x72, + 0x65, 0x32, 0x8d, 0x09, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x32, 0x0a, 0x07, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x33, @@ -214,15 +214,15 @@ var file_test_busi_busi_proto_rawDesc = []byte{ 0x75, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x4e, 0x6f, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, + 0x79, 0x22, 0x00, 0x12, 0x31, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, - 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, - 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x42, 0x12, - 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x62, 0x75, - 0x73, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x71, 0x1a, 0x0f, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0e, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, + 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x42, 0x12, 0x0d, 0x2e, 0x62, 0x75, 0x73, 0x69, 0x2e, + 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x00, 0x42, 0x08, 0x5a, 0x06, 0x2e, 0x2f, 0x62, 0x75, 0x73, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } var ( @@ -282,7 +282,7 @@ var file_test_busi_busi_proto_depIdxs = []int32{ 2, // 35: busi.Busi.TransOutRevertBSaga:output_type -> google.protobuf.Empty 2, // 36: busi.Busi.TransOutHeaderYes:output_type -> google.protobuf.Empty 2, // 37: busi.Busi.TransOutHeaderNo:output_type -> google.protobuf.Empty - 2, // 38: busi.Busi.QueryPrepared:output_type -> google.protobuf.Empty + 1, // 38: busi.Busi.QueryPrepared:output_type -> busi.BusiReply 2, // 39: busi.Busi.QueryPreparedB:output_type -> google.protobuf.Empty 20, // [20:40] is the sub-list for method output_type 0, // [0:20] is the sub-list for method input_type diff --git a/test/busi/busi.proto b/test/busi/busi.proto index 123ff33..c94d8df 100644 --- a/test/busi/busi.proto +++ b/test/busi/busi.proto @@ -37,7 +37,7 @@ service Busi { rpc TransOutRevertBSaga(BusiReq) returns (google.protobuf.Empty) {} rpc TransOutHeaderYes(BusiReq) returns (google.protobuf.Empty) {} rpc TransOutHeaderNo(BusiReq) returns (google.protobuf.Empty) {} - rpc QueryPrepared(BusiReq) returns (google.protobuf.Empty) {} + rpc QueryPrepared(BusiReq) returns (BusiReply) {} rpc QueryPreparedB(BusiReq) returns (google.protobuf.Empty) {} } diff --git a/test/busi/busi_grpc.pb.go b/test/busi/busi_grpc.pb.go index be3a769..f7db854 100644 --- a/test/busi/busi_grpc.pb.go +++ b/test/busi/busi_grpc.pb.go @@ -37,7 +37,7 @@ type BusiClient interface { TransOutRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransOutHeaderYes(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) TransOutHeaderNo(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) - QueryPrepared(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + QueryPrepared(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*BusiReply, error) QueryPreparedB(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) } @@ -211,8 +211,8 @@ func (c *busiClient) TransOutHeaderNo(ctx context.Context, in *BusiReq, opts ... return out, nil } -func (c *busiClient) QueryPrepared(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { - out := new(emptypb.Empty) +func (c *busiClient) QueryPrepared(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*BusiReply, error) { + out := new(BusiReply) err := c.cc.Invoke(ctx, "/busi.Busi/QueryPrepared", in, out, opts...) if err != nil { return nil, err @@ -251,7 +251,7 @@ type BusiServer interface { TransOutRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) TransOutHeaderYes(context.Context, *BusiReq) (*emptypb.Empty, error) TransOutHeaderNo(context.Context, *BusiReq) (*emptypb.Empty, error) - QueryPrepared(context.Context, *BusiReq) (*emptypb.Empty, error) + QueryPrepared(context.Context, *BusiReq) (*BusiReply, error) QueryPreparedB(context.Context, *BusiReq) (*emptypb.Empty, error) mustEmbedUnimplementedBusiServer() } @@ -314,7 +314,7 @@ func (UnimplementedBusiServer) TransOutHeaderYes(context.Context, *BusiReq) (*em func (UnimplementedBusiServer) TransOutHeaderNo(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutHeaderNo not implemented") } -func (UnimplementedBusiServer) QueryPrepared(context.Context, *BusiReq) (*emptypb.Empty, error) { +func (UnimplementedBusiServer) QueryPrepared(context.Context, *BusiReq) (*BusiReply, error) { return nil, status.Errorf(codes.Unimplemented, "method QueryPrepared not implemented") } func (UnimplementedBusiServer) QueryPreparedB(context.Context, *BusiReq) (*emptypb.Empty, error) { diff --git a/test/main_test.go b/test/main_test.go index 2fa6a1c..9d0036c 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -16,6 +16,7 @@ import ( "github.com/dtm-labs/dtm/dtmgrpc" "github.com/dtm-labs/dtm/dtmsvr" "github.com/dtm-labs/dtm/dtmsvr/config" + "github.com/dtm-labs/dtm/dtmsvr/storage/registry" "github.com/dtm-labs/dtm/test/busi" "github.com/go-resty/resty/v2" ) @@ -55,6 +56,8 @@ func TestMain(m *testing.M) { conf.Store.Password = "" conf.Store.Port = 6379 } + registry.WaitStoreUp() + dtmsvr.PopulateDB(false) go dtmsvr.StartSvr() diff --git a/test/store_test.go b/test/store_test.go index c2413f7..b711c76 100644 --- a/test/store_test.go +++ b/test/store_test.go @@ -88,10 +88,6 @@ func TestStoreLockTrans(t *testing.T) { assert.Nil(t, g2) } -func TestStoreWait(t *testing.T) { - registry.WaitStoreUp() -} - func TestUpdateBranches(t *testing.T) { if !conf.Store.IsDB() { _, err := registry.GetStore().UpdateBranches(nil, nil) From b24576e1f2e3c1bb8c6a7f2475a40dd2647c822d Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 6 Jan 2022 12:55:36 +0800 Subject: [PATCH 076/124] fix mysql test fail --- helper/test-cover.sh | 2 +- test/main_test.go | 7 +++++-- test/msg_barrier_test.go | 6 ++++++ 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/helper/test-cover.sh b/helper/test-cover.sh index ca14aa6..13bd654 100644 --- a/helper/test-cover.sh +++ b/helper/test-cover.sh @@ -2,7 +2,7 @@ set -x echo "" > coverage.txt for store in redis mysql boltdb; do for d in $(go list ./... | grep -v vendor); do - TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/dtm-labs/dtm/dtmcli,github.com/dtm-labs/dtm/dtmcli/dtmimp,github.com/dtm-labs/dtm/dtmcli/logger,github.com/dtm-labs/dtm/dtmgrpc,github.com/dtm-labs/dtm/dtmgrpc/dtmgimp,github.com/dtm-labs/dtm/dtmsvr,github.com/dtm-labs/dtm/dtmsvr/config,github.com/dtm-labs/dtm/dtmsvr/storage,github.com/dtm-labs/dtm/dtmsvr/storage/boltdb,github.com/dtm-labs/dtm/dtmsvr/storage/redis,github.com/dtm-labs/dtm/dtmsvr/storage/registry,github.com/dtm-labs/dtm/dtmsvr/storage/sql,github.com/dtm-labs/dtm/dtmutil -gcflags=-l $d + TEST_STORE=$store go test -covermode count -coverprofile=profile.out -coverpkg=github.com/dtm-labs/dtm/dtmcli,github.com/dtm-labs/dtm/dtmcli/dtmimp,github.com/dtm-labs/dtm/dtmcli/logger,github.com/dtm-labs/dtm/dtmgrpc,github.com/dtm-labs/dtm/dtmgrpc/dtmgimp,github.com/dtm-labs/dtm/dtmsvr,github.com/dtm-labs/dtm/dtmsvr/config,github.com/dtm-labs/dtm/dtmsvr/storage,github.com/dtm-labs/dtm/dtmsvr/storage/boltdb,github.com/dtm-labs/dtm/dtmsvr/storage/redis,github.com/dtm-labs/dtm/dtmsvr/storage/registry,github.com/dtm-labs/dtm/dtmsvr/storage/sql,github.com/dtm-labs/dtm/dtmutil -gcflags=-l $d || exit 1 if [ -f profile.out ]; then cat profile.out >> coverage.txt echo > profile.out diff --git a/test/main_test.go b/test/main_test.go index 9d0036c..0f4add2 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -63,6 +63,9 @@ func TestMain(m *testing.M) { busi.PopulateDB(false) _ = busi.Startup() - exitIf(m.Run()) - + r := m.Run() + exitIf(r) + close(dtmsvr.TransProcessedTestChan) + gid, more := <-dtmsvr.TransProcessedTestChan + logger.FatalfIf(more, "extra gid: %s in test chan", gid) } diff --git a/test/msg_barrier_test.go b/test/msg_barrier_test.go index 29970dd..fe586e0 100644 --- a/test/msg_barrier_test.go +++ b/test/msg_barrier_test.go @@ -57,6 +57,9 @@ func TestMsgPrepareAndSubmitPrepareFailed(t *testing.T) { } func TestMsgPrepareAndSubmitCommitFailed(t *testing.T) { + if conf.Store.IsDB() { // cannot patch tx.Commit, because Prepare also do Commit + return + } before := getBeforeBalances() gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) @@ -78,6 +81,9 @@ func TestMsgPrepareAndSubmitCommitFailed(t *testing.T) { } func TestMsgPrepareAndSubmitCommitAfterFailed(t *testing.T) { + if conf.Store.IsDB() { // cannot patch tx.Commit, because Prepare also do Commit + return + } before := getBeforeBalances() gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) From 704e7bc96064f99557baedd944de6007f64479f1 Mon Sep 17 00:00:00 2001 From: jxlwqq Date: Thu, 6 Jan 2022 12:58:29 +0800 Subject: [PATCH 077/124] keep Go version consistent --- .github/workflows/tests.yml | 4 ++-- go.mod | 2 +- go.sum | 12 ------------ helper/Dockerfile-release | 4 ++-- 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2282245..c267a52 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -29,10 +29,10 @@ jobs: ports: - 6379:6379 steps: - - name: Set up Go 1.15 + - name: Set up Go 1.16 uses: actions/setup-go@v2 with: - go-version: '1.15' + go-version: '1.16' - name: Check out code uses: actions/checkout@v2 diff --git a/go.mod b/go.mod index 306fad3..241649c 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/dtm-labs/dtm -go 1.15 +go 1.16 require ( github.com/dtm-labs/dtmdriver v0.0.1 diff --git a/go.sum b/go.sum index d67335c..519c6a2 100644 --- a/go.sum +++ b/go.sum @@ -363,7 +363,6 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.3 h1:v9QZf2Sn6AmjXtQeFpdoq/eaNtYP6IN+7lcrygsIAtg= github.com/lib/pq v1.10.3/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lithammer/shortuuid v1.0.0 h1:kdcbvjGVEgqeVeDIRtnANOi/F6ftbKrtbxY+cjQmK1Q= github.com/lithammer/shortuuid v2.0.3+incompatible h1:ao1r3cQ9AUX+c6dZXwbCM/ELGf10EoO4SyqqxBXTyHc= github.com/lithammer/shortuuid v2.0.3+incompatible/go.mod h1:FR74pbAuElzOUuenUHTK2Tciko1/vKuIKS9dSkDrA4w= github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8= @@ -476,7 +475,6 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -510,12 +508,6 @@ github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/X github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/ychensha/dtmdriver-polaris v0.0.1/go.mod h1:0BdQvxXlGOlF6YVlsDoVvu8jyxdTlJZ9Kyh5t9lRA94= -github.com/yedf/dtm v1.7.2 h1:qGjio5O+Zm5CmMfga9Eb0rsUu9nkNHxGuJwc7PEkMfc= -github.com/yedf/dtm v1.7.2/go.mod h1:R1Q55spqLh7yHMVJhGI8RpS1iG7OvRX99pWZRlsAtME= -github.com/yedf/dtmdriver v0.0.0-20211203060147-29426c663b6e/go.mod h1:aeo6ZWiVI0x8P8O18r6uB1cG2uw9BCQyYZaH15MlRDI= -github.com/yedf/dtmdriver-gozero v0.0.0-20211204083751-a14485949435/go.mod h1:RYtA6oZny6LzlIRb1tPGt5bHfgqws/JaU6ogFly8ByQ= -github.com/yedf/dtmdriver-protocol1 v0.0.0-20211205112411-d7a7052dc90e/go.mod h1:kB3NPnDKSGioVjgdfj6qgbqYJinOml45GnlHqR46Ycc= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= @@ -608,7 +600,6 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= 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-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 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= @@ -618,7 +609,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -780,7 +770,6 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -884,7 +873,6 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.20.12 h1:LfRpmRkJLwPP8eaYehsVVmIIfg1yCBIIUHaSsdqCgHA= k8s.io/api v0.20.12/go.mod h1:A2brwyEkVLM3wQGNnzoAa5JsQRzHK0uoOQ+bsnv7V68= diff --git a/helper/Dockerfile-release b/helper/Dockerfile-release index 0dd5bf1..2b7ed79 100644 --- a/helper/Dockerfile-release +++ b/helper/Dockerfile-release @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM --platform=$TARGETPLATFORM golang:1.16.6-alpine3.14 as builder +FROM --platform=$TARGETPLATFORM golang:1.16-alpine as builder ARG TARGETARCH ARG TARGETOS WORKDIR /app/dtm @@ -8,7 +8,7 @@ EXPOSE 8080 COPY . . RUN CGO_ENABLED=0 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags="-s -w" -FROM --platform=$TARGETPLATFORM alpine:3.14 +FROM --platform=$TARGETPLATFORM alpine COPY --from=builder /app/dtm/dtm /app/dtm/ ENV IS_DOCKER=1 WORKDIR /app/dtm From ccfe91937ec1759000714c9e3961f3ca37ec33d6 Mon Sep 17 00:00:00 2001 From: liulei Date: Thu, 6 Jan 2022 16:04:14 +0800 Subject: [PATCH 078/124] fix dtmsvr/storage golangci lint --- dtmsvr/storage/boltdb/boltdb.go | 79 ++++++++++++++++++++--------- dtmsvr/storage/redis/redis.go | 40 ++++++++++----- dtmsvr/storage/registry/registry.go | 9 ++-- dtmsvr/storage/sql/sql.go | 39 +++++++++----- dtmsvr/storage/store.go | 3 +- dtmsvr/storage/trans.go | 2 + 6 files changed, 116 insertions(+), 56 deletions(-) diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index eb3454d..7f86056 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -23,10 +23,11 @@ import ( var conf = &config.Config -type BoltdbStore struct { +// Store implements storage.Store, and storage with boltdb +type Store struct { } -var boltDb *bolt.DB = nil +var boltDb *bolt.DB var boltOnce sync.Once func boltGet() *bolt.DB { @@ -110,7 +111,9 @@ func cleanupGlobalWithGids(t *bolt.Tx, gids map[string]struct{}) { logger.Debugf("Start to cleanup %d gids", len(gids)) for gid := range gids { logger.Debugf("Start to delete gid: %s", gid) - bucket.Delete([]byte(gid)) + if err := bucket.Delete([]byte(gid)); err != nil { + logger.Errorf("boltdb.cleanupGlobalWithGids delete gid err: %v", err) + } } } @@ -139,7 +142,9 @@ func cleanupBranchWithGids(t *bolt.Tx, gids map[string]struct{}) { logger.Debugf("Start to cleanup %d branches", len(branchKeys)) for _, key := range branchKeys { logger.Debugf("Start to delete branch: %s", key) - bucket.Delete([]byte(key)) + if err := bucket.Delete([]byte(key)); err != nil { + logger.Errorf("boltdb.cleanupBranchWithGids delete key err: %v", err) + } } } @@ -165,7 +170,9 @@ func cleanupIndexWithGids(t *bolt.Tx, gids map[string]struct{}) { logger.Debugf("Start to cleanup %d indexes", len(indexKeys)) for _, key := range indexKeys { logger.Debugf("Start to delete index: %s", key) - bucket.Delete([]byte(key)) + if err := bucket.Delete([]byte(key)); err != nil { + logger.Errorf("boltdb.cleanupIndexWithGids delete key err: %v", err) + } } } @@ -232,19 +239,34 @@ func tPutIndex(t *bolt.Tx, unix int64, gid string) { dtmimp.E2P(err) } -func (s *BoltdbStore) Ping() error { +// Ping execs ping cmd to boltdb +func (s *Store) Ping() error { return nil } -func (s *BoltdbStore) PopulateData(skipDrop bool) { +// PopulateData populates data to boltdb +func (s *Store) PopulateData(skipDrop bool) { if !skipDrop { err := boltGet().Update(func(t *bolt.Tx) error { - t.DeleteBucket(bucketIndex) - t.DeleteBucket(bucketBranches) - t.DeleteBucket(bucketGlobal) - t.CreateBucket(bucketIndex) - t.CreateBucket(bucketBranches) - t.CreateBucket(bucketGlobal) + if err := t.DeleteBucket(bucketIndex); err != nil { + return err + } + if err := t.DeleteBucket(bucketBranches); err != nil { + return err + } + if err := t.DeleteBucket(bucketGlobal); err != nil { + return err + } + if _, err := t.CreateBucket(bucketIndex); err != nil { + return err + } + if _, err := t.CreateBucket(bucketBranches); err != nil { + return err + } + if _, err := t.CreateBucket(bucketGlobal); err != nil { + return err + } + return nil }) dtmimp.E2P(err) @@ -252,7 +274,8 @@ func (s *BoltdbStore) PopulateData(skipDrop bool) { } } -func (s *BoltdbStore) FindTransGlobalStore(gid string) (trans *storage.TransGlobalStore) { +// FindTransGlobalStore finds GlobalTrans data by gid +func (s *Store) FindTransGlobalStore(gid string) (trans *storage.TransGlobalStore) { err := boltGet().View(func(t *bolt.Tx) error { trans = tGetGlobal(t, gid) return nil @@ -261,7 +284,8 @@ func (s *BoltdbStore) FindTransGlobalStore(gid string) (trans *storage.TransGlob return } -func (s *BoltdbStore) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { +// ScanTransGlobalStores lists GlobalTrans data +func (s *Store) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { globals := []storage.TransGlobalStore{} err := boltGet().View(func(t *bolt.Tx) error { cursor := t.Bucket(bucketGlobal).Cursor() @@ -287,8 +311,9 @@ func (s *BoltdbStore) ScanTransGlobalStores(position *string, limit int64) []sto return globals } -func (s *BoltdbStore) FindBranches(gid string) []storage.TransBranchStore { - var branches []storage.TransBranchStore = nil +// FindBranches finds Branch data by gid +func (s *Store) FindBranches(gid string) []storage.TransBranchStore { + var branches []storage.TransBranchStore err := boltGet().View(func(t *bolt.Tx) error { branches = tGetBranches(t, gid) return nil @@ -297,11 +322,13 @@ func (s *BoltdbStore) FindBranches(gid string) []storage.TransBranchStore { return branches } -func (s *BoltdbStore) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { +// UpdateBranches update branches info +func (s *Store) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { return 0, nil // not implemented } -func (s *BoltdbStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { +// LockGlobalSaveBranches creates branches +func (s *Store) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { err := boltGet().Update(func(t *bolt.Tx) error { g := tGetGlobal(t, gid) if g == nil { @@ -316,7 +343,8 @@ func (s *BoltdbStore) LockGlobalSaveBranches(gid string, status string, branches dtmimp.E2P(err) } -func (s *BoltdbStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { +// MaySaveNewTrans creates a new trans +func (s *Store) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { return boltGet().Update(func(t *bolt.Tx) error { g := tGetGlobal(t, global.Gid) if g != nil { @@ -329,7 +357,8 @@ func (s *BoltdbStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches }) } -func (s *BoltdbStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { +// ChangeGlobalStatus changes global trans status +func (s *Store) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus err := boltGet().Update(func(t *bolt.Tx) error { @@ -346,7 +375,8 @@ func (s *BoltdbStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newSt dtmimp.E2P(err) } -func (s *BoltdbStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { +// TouchCronTime updates cronTime +func (s *Store) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { oldUnix := global.NextCronTime.Unix() global.NextCronTime = dtmutil.GetNextTime(nextCronInterval) global.UpdateTime = dtmutil.GetNextTime(0) @@ -364,8 +394,9 @@ func (s *BoltdbStore) TouchCronTime(global *storage.TransGlobalStore, nextCronIn dtmimp.E2P(err) } -func (s *BoltdbStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { - var trans *storage.TransGlobalStore = nil +// LockOneGlobalTrans finds GlobalTrans +func (s *Store) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { + var trans *storage.TransGlobalStore min := fmt.Sprintf("%d", time.Now().Add(expireIn).Unix()) next := time.Now().Add(time.Duration(conf.RetryInterval) * time.Second) err := boltGet().Update(func(t *bolt.Tx) error { diff --git a/dtmsvr/storage/redis/redis.go b/dtmsvr/storage/redis/redis.go index 12ff277..e0903a5 100644 --- a/dtmsvr/storage/redis/redis.go +++ b/dtmsvr/storage/redis/redis.go @@ -2,6 +2,7 @@ package redis import ( "context" + "errors" "fmt" "sync" "time" @@ -21,16 +22,18 @@ var conf = &config.Config // TODO: optimize this, all function should have context as first parameter var ctx = context.Background() -// RedisStore is the storage with redis, all transaction information will bachend with redis -type RedisStore struct { +// Store is the storage with redis, all transaction information will bachend with redis +type Store struct { } -func (s *RedisStore) Ping() error { +// Ping execs ping cmd to redis +func (s *Store) Ping() error { _, err := redisGet().Ping(ctx).Result() return err } -func (s *RedisStore) PopulateData(skipDrop bool) { +// PopulateData populates data to redis +func (s *Store) PopulateData(skipDrop bool) { if !skipDrop { _, err := redisGet().FlushAll(ctx).Result() logger.Infof("call redis flushall. result: %v", err) @@ -38,7 +41,8 @@ func (s *RedisStore) PopulateData(skipDrop bool) { } } -func (s *RedisStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { +// FindTransGlobalStore finds GlobalTrans data by gid +func (s *Store) FindTransGlobalStore(gid string) *storage.TransGlobalStore { logger.Debugf("calling FindTransGlobalStore: %s", gid) r, err := redisGet().Get(ctx, conf.Store.RedisPrefix+"_g_"+gid).Result() if err == redis.Nil { @@ -50,7 +54,8 @@ func (s *RedisStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore return trans } -func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { +// ScanTransGlobalStores lists GlobalTrans data +func (s *Store) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { logger.Debugf("calling ScanTransGlobalStores: %s %d", *position, limit) lid := uint64(0) if *position != "" { @@ -76,7 +81,8 @@ func (s *RedisStore) ScanTransGlobalStores(position *string, limit int64) []stor return globals } -func (s *RedisStore) FindBranches(gid string) []storage.TransBranchStore { +// FindBranches finds Branch data by gid +func (s *Store) FindBranches(gid string) []storage.TransBranchStore { logger.Debugf("calling FindBranches: %s", gid) sa, err := redisGet().LRange(ctx, conf.Store.RedisPrefix+"_b_"+gid, 0, -1).Result() dtmimp.E2P(err) @@ -87,7 +93,8 @@ func (s *RedisStore) FindBranches(gid string) []storage.TransBranchStore { return branches } -func (s *RedisStore) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { +// UpdateBranches updates branches info +func (s *Store) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { return 0, nil // not implemented } @@ -144,7 +151,8 @@ func callLua(a *argList, lua string) (string, error) { return handleRedisResult(ret, err) } -func (s *RedisStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { +// MaySaveNewTrans creates a new trans +func (s *Store) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { a := newArgList(). AppendGid(global.Gid). AppendObject(global). @@ -171,7 +179,8 @@ redis.call('EXPIRE', KEYS[2], ARGV[2]) return err } -func (s *RedisStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { +// LockGlobalSaveBranches creates branches +func (s *Store) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { args := newArgList(). AppendGid(gid). AppendRaw(status). @@ -195,7 +204,8 @@ redis.call('EXPIRE', KEYS[2], ARGV[2]) dtmimp.E2P(err) } -func (s *RedisStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { +// ChangeGlobalStatus changes global trans status +func (s *Store) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus args := newArgList(). @@ -219,7 +229,8 @@ end dtmimp.E2P(err) } -func (s *RedisStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { +// LockOneGlobalTrans finds GlobalTrans +func (s *Store) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { expired := time.Now().Add(expireIn).Unix() next := time.Now().Add(time.Duration(conf.RetryInterval) * time.Second).Unix() args := newArgList().AppendGid("").AppendRaw(expired).AppendRaw(next) @@ -238,7 +249,7 @@ return gid ` for { r, err := callLua(args, lua) - if err == storage.ErrNotFound { + if errors.Is(err, storage.ErrNotFound) { return nil } dtmimp.E2P(err) @@ -249,7 +260,8 @@ return gid } } -func (s *RedisStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { +// TouchCronTime updates cronTime +func (s *Store) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { global.NextCronTime = dtmutil.GetNextTime(nextCronInterval) global.UpdateTime = dtmutil.GetNextTime(0) global.NextCronInterval = nextCronInterval diff --git a/dtmsvr/storage/registry/registry.go b/dtmsvr/storage/registry/registry.go index d65f2e1..1788456 100644 --- a/dtmsvr/storage/registry/registry.go +++ b/dtmsvr/storage/registry/registry.go @@ -13,12 +13,13 @@ import ( var conf = &config.Config var stores map[string]storage.Store = map[string]storage.Store{ - "redis": &redis.RedisStore{}, - "mysql": &sql.SqlStore{}, - "postgres": &sql.SqlStore{}, - "boltdb": &boltdb.BoltdbStore{}, + "redis": &redis.Store{}, + "mysql": &sql.Store{}, + "postgres": &sql.Store{}, + "boltdb": &boltdb.Store{}, } +// GetStore returns storage.Store func GetStore() storage.Store { return stores[conf.Store.Driver] } diff --git a/dtmsvr/storage/sql/sql.go b/dtmsvr/storage/sql/sql.go index 02f85c0..cda8d44 100644 --- a/dtmsvr/storage/sql/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -17,22 +17,26 @@ import ( var conf = &config.Config -type SqlStore struct { +// Store implements storage.Store, and storage with db +type Store struct { } -func (s *SqlStore) Ping() error { +// Ping execs ping cmd to db +func (s *Store) Ping() error { db, err := dtmimp.StandaloneDB(conf.Store.GetDBConf()) dtmimp.E2P(err) _, err = db.Exec("select 1") return err } -func (s *SqlStore) PopulateData(skipDrop bool) { +// PopulateData populates data to db +func (s *Store) PopulateData(skipDrop bool) { file := fmt.Sprintf("%s/dtmsvr.storage.%s.sql", dtmutil.GetSqlDir(), conf.Store.Driver) dtmutil.RunSQLScript(conf.Store.GetDBConf(), file, skipDrop) } -func (s *SqlStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { +// FindTransGlobalStore finds GlobalTrans data by gid +func (s *Store) FindTransGlobalStore(gid string) *storage.TransGlobalStore { trans := &storage.TransGlobalStore{} dbr := dbGet().Model(trans).Where("gid=?", gid).First(trans) if dbr.Error == gorm.ErrRecordNotFound { @@ -42,7 +46,8 @@ func (s *SqlStore) FindTransGlobalStore(gid string) *storage.TransGlobalStore { return trans } -func (s *SqlStore) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { +// ScanTransGlobalStores lists GlobalTrans data +func (s *Store) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { globals := []storage.TransGlobalStore{} lid := math.MaxInt64 if *position != "" { @@ -57,13 +62,15 @@ func (s *SqlStore) ScanTransGlobalStores(position *string, limit int64) []storag return globals } -func (s *SqlStore) FindBranches(gid string) []storage.TransBranchStore { +// FindBranches finds Branch data by gid +func (s *Store) FindBranches(gid string) []storage.TransBranchStore { branches := []storage.TransBranchStore{} dbGet().Must().Where("gid=?", gid).Order("id asc").Find(&branches) return branches } -func (s *SqlStore) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { +// UpdateBranches update branches info +func (s *Store) UpdateBranches(branches []storage.TransBranchStore, updates []string) (int, error) { db := dbGet().Clauses(clause.OnConflict{ OnConstraint: "trans_branch_op_pkey", DoUpdates: clause.AssignmentColumns(updates), @@ -71,7 +78,8 @@ func (s *SqlStore) UpdateBranches(branches []storage.TransBranchStore, updates [ return int(db.RowsAffected), db.Error } -func (s *SqlStore) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { +// LockGlobalSaveBranches creates branches +func (s *Store) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { err := dbGet().Transaction(func(tx *gorm.DB) error { g := &storage.TransGlobalStore{} dbr := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Model(g).Where("gid=? and status=?", gid, status).First(g) @@ -83,7 +91,8 @@ func (s *SqlStore) LockGlobalSaveBranches(gid string, status string, branches [] dtmimp.E2P(err) } -func (s *SqlStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { +// MaySaveNewTrans creates a new trans +func (s *Store) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { return dbGet().Transaction(func(db1 *gorm.DB) error { db := &dtmutil.DB{DB: db1} dbr := db.Must().Clauses(clause.OnConflict{ @@ -101,7 +110,8 @@ func (s *SqlStore) MaySaveNewTrans(global *storage.TransGlobalStore, branches [] }) } -func (s *SqlStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { +// ChangeGlobalStatus changes global trans status +func (s *Store) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus dbr := dbGet().Must().Model(global).Where("status=? and gid=?", old, global.Gid).Select(updates).Updates(global) @@ -110,7 +120,8 @@ func (s *SqlStore) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatu } } -func (s *SqlStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { +// TouchCronTime updates cronTime +func (s *Store) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval int64) { global.NextCronTime = dtmutil.GetNextTime(nextCronInterval) global.UpdateTime = dtmutil.GetNextTime(0) global.NextCronInterval = nextCronInterval @@ -118,7 +129,8 @@ func (s *SqlStore) TouchCronTime(global *storage.TransGlobalStore, nextCronInter Select([]string{"next_cron_time", "update_time", "next_cron_interval"}).Updates(global) } -func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { +// LockOneGlobalTrans finds GlobalTrans +func (s *Store) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { db := dbGet() getTime := func(second int) string { return map[string]string{ @@ -141,10 +153,11 @@ func (s *SqlStore) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlob if dbr.RowsAffected == 0 { return nil } - dbr = db.Must().Where("owner=?", owner).First(global) + db.Must().Where("owner=?", owner).First(global) return global } +// SetDBConn sets db conn pool func SetDBConn(db *gorm.DB) { sqldb, _ := db.DB() sqldb.SetMaxOpenConns(int(conf.Store.MaxOpenConns)) diff --git a/dtmsvr/storage/store.go b/dtmsvr/storage/store.go index 79a9b0e..eca4d38 100644 --- a/dtmsvr/storage/store.go +++ b/dtmsvr/storage/store.go @@ -3,7 +3,7 @@ * Use of this source code is governed by a BSD-style * license that can be found in the LICENSE file. */ - + package storage import ( @@ -17,6 +17,7 @@ var ErrNotFound = errors.New("storage: NotFound") // ErrUniqueConflict defines the item is conflict with unique key in storage implement. var ErrUniqueConflict = errors.New("storage: UniqueKeyConflict") +// Store defines storage relevant interface type Store interface { Ping() error PopulateData(skipDrop bool) diff --git a/dtmsvr/storage/trans.go b/dtmsvr/storage/trans.go index 80663c9..077bd0d 100644 --- a/dtmsvr/storage/trans.go +++ b/dtmsvr/storage/trans.go @@ -9,10 +9,12 @@ import ( "github.com/dtm-labs/dtm/dtmutil" ) +// TransGlobalExt defines Header info type TransGlobalExt struct { Headers map[string]string `json:"headers,omitempty" gorm:"-"` } +// TransGlobalStore defines GlobalStore storage info type TransGlobalStore struct { dtmutil.ModelBase Gid string `json:"gid,omitempty"` From 1c58feb44978f63427e0f38354e45cfd34beb360 Mon Sep 17 00:00:00 2001 From: liulei Date: Thu, 6 Jan 2022 20:57:35 +0800 Subject: [PATCH 079/124] change err check to dtmimp.E2P --- dtmsvr/storage/boltdb/boltdb.go | 39 ++++++++++----------------------- 1 file changed, 12 insertions(+), 27 deletions(-) diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index 7f86056..19f0607 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -111,9 +111,7 @@ func cleanupGlobalWithGids(t *bolt.Tx, gids map[string]struct{}) { logger.Debugf("Start to cleanup %d gids", len(gids)) for gid := range gids { logger.Debugf("Start to delete gid: %s", gid) - if err := bucket.Delete([]byte(gid)); err != nil { - logger.Errorf("boltdb.cleanupGlobalWithGids delete gid err: %v", err) - } + dtmimp.E2P(bucket.Delete([]byte(gid))) } } @@ -142,9 +140,7 @@ func cleanupBranchWithGids(t *bolt.Tx, gids map[string]struct{}) { logger.Debugf("Start to cleanup %d branches", len(branchKeys)) for _, key := range branchKeys { logger.Debugf("Start to delete branch: %s", key) - if err := bucket.Delete([]byte(key)); err != nil { - logger.Errorf("boltdb.cleanupBranchWithGids delete key err: %v", err) - } + dtmimp.E2P(bucket.Delete([]byte(key))) } } @@ -170,9 +166,7 @@ func cleanupIndexWithGids(t *bolt.Tx, gids map[string]struct{}) { logger.Debugf("Start to cleanup %d indexes", len(indexKeys)) for _, key := range indexKeys { logger.Debugf("Start to delete index: %s", key) - if err := bucket.Delete([]byte(key)); err != nil { - logger.Errorf("boltdb.cleanupIndexWithGids delete key err: %v", err) - } + dtmimp.E2P(bucket.Delete([]byte(key))) } } @@ -248,24 +242,15 @@ func (s *Store) Ping() error { func (s *Store) PopulateData(skipDrop bool) { if !skipDrop { err := boltGet().Update(func(t *bolt.Tx) error { - if err := t.DeleteBucket(bucketIndex); err != nil { - return err - } - if err := t.DeleteBucket(bucketBranches); err != nil { - return err - } - if err := t.DeleteBucket(bucketGlobal); err != nil { - return err - } - if _, err := t.CreateBucket(bucketIndex); err != nil { - return err - } - if _, err := t.CreateBucket(bucketBranches); err != nil { - return err - } - if _, err := t.CreateBucket(bucketGlobal); err != nil { - return err - } + dtmimp.E2P(t.DeleteBucket(bucketIndex)) + dtmimp.E2P(t.DeleteBucket(bucketBranches)) + dtmimp.E2P(t.DeleteBucket(bucketGlobal)) + _, err := t.CreateBucket(bucketIndex) + dtmimp.E2P(err) + _, err = t.CreateBucket(bucketBranches) + dtmimp.E2P(err) + _, err = t.CreateBucket(bucketGlobal) + dtmimp.E2P(err) return nil }) From da84c58c0065f302eae64d0087cab221473cefad Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Thu, 6 Jan 2022 17:18:47 +0800 Subject: [PATCH 080/124] fix updateBranchAsync panic handling --- dtmsvr/svr.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 7f141df..fe5b1ca 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -65,8 +65,8 @@ var UpdateBranchAsyncInterval = 200 * time.Millisecond var updateBranchAsyncChan chan branchStatus = make(chan branchStatus, 1000) func updateBranchAsync() { - defer dtmutil.RecoverPanic(nil) - for { // flush branches every second + flushBranchs := func() { + defer dtmutil.RecoverPanic(nil) updates := []TransBranch{} started := time.Now() checkInterval := 20 * time.Millisecond @@ -93,5 +93,9 @@ func updateBranchAsync() { updates = []TransBranch{} } } + + } + for { // flush branches every 200ms + flushBranchs() } } From cd929d8db84c6e6f5cb2b51a3b11cc29e1d85e7d Mon Sep 17 00:00:00 2001 From: liulei Date: Thu, 6 Jan 2022 22:14:53 +0800 Subject: [PATCH 081/124] fix dtmsvr/config golangci lint error --- dtmsvr/config/config.go | 18 +++++++++++++----- dtmsvr/svr.go | 4 ++-- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 80acd60..0f3ce54 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -10,11 +10,16 @@ import ( ) const ( + // DtmMetricsPort is metric port DtmMetricsPort = 8889 - Mysql = "mysql" - Redis = "redis" - BoltDb = "boltdb" - Postgres = "postgres" + // Mysql is mysql driver + Mysql = "mysql" + // Redis is redis driver + Redis = "redis" + // BoltDb is boltdb driver + BoltDb = "boltdb" + // Postgres is postgres driver + Postgres = "postgres" ) // MicroService config type for micro service @@ -24,6 +29,7 @@ type MicroService struct { EndPoint string `yaml:"EndPoint"` } +// Store defines storage relevant info type Store struct { Driver string `yaml:"Driver" default:"boltdb"` Host string `yaml:"Host"` @@ -39,10 +45,12 @@ type Store struct { TransBranchOpTable string `yaml:"BranchTransOpTable" default:"dtm.trans_branch_op"` } +// IsDB checks config driver is mysql or postgres func (s *Store) IsDB() bool { return s.Driver == dtmcli.DBTypeMysql || s.Driver == dtmcli.DBTypePostgres } +// GetDBConf returns db conf info func (s *Store) GetDBConf() dtmcli.DBConf { return dtmcli.DBConf{ Driver: s.Driver, @@ -58,7 +66,7 @@ type configType struct { TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` RetryInterval int64 `yaml:"RetryInterval" default:"10"` - HttpPort int64 `yaml:"HttpPort" default:"36789"` + HTTPPort int64 `yaml:"HTTPPort" default:"36789"` GrpcPort int64 `yaml:"GrpcPort" default:"36790"` MicroService MicroService `yaml:"MicroService"` UpdateBranchSync int64 `yaml:"UpdateBranchSync"` diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 7f141df..f6569fc 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -26,9 +26,9 @@ func StartSvr() { app := dtmutil.GetGinApp() app = httpMetrics(app) addRoute(app) - logger.Infof("dtmsvr listen at: %d", conf.HttpPort) + logger.Infof("dtmsvr listen at: %d", conf.HTTPPort) go func() { - err := app.Run(fmt.Sprintf(":%d", conf.HttpPort)) + err := app.Run(fmt.Sprintf(":%d", conf.HTTPPort)) if err != nil { logger.Errorf("start server err: %v", err) } From de1355dd233d5157f4f07a6f844e1903f58a49f2 Mon Sep 17 00:00:00 2001 From: liulei Date: Thu, 6 Jan 2022 22:17:33 +0800 Subject: [PATCH 082/124] fix dtmsvr/config golangci lint error --- dtmsvr/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 0f3ce54..60f3803 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -66,7 +66,7 @@ type configType struct { TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` RetryInterval int64 `yaml:"RetryInterval" default:"10"` - HTTPPort int64 `yaml:"HTTPPort" default:"36789"` + HTTPPort int64 `yaml:"HttpPort" default:"36789"` GrpcPort int64 `yaml:"GrpcPort" default:"36790"` MicroService MicroService `yaml:"MicroService"` UpdateBranchSync int64 `yaml:"UpdateBranchSync"` From a0d4c00da609865654b2f24ae551b092e04161fa Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 7 Jan 2022 08:16:51 +0800 Subject: [PATCH 083/124] barrier use if err == nil --- dtmcli/barrier.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index 5cffeba..c502742 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -95,10 +95,10 @@ func (bb *BranchBarrier) Call(tx *sql.Tx, busiCall BarrierBusiFunc) (rerr error) // CallWithDB the same as Call, but with *sql.DB func (bb *BranchBarrier) CallWithDB(db *sql.DB, busiCall BarrierBusiFunc) error { tx, err := db.Begin() - if err != nil { - return err + if err == nil { + err = bb.Call(tx, busiCall) } - return bb.Call(tx, busiCall) + return err } func (bb *BranchBarrier) QueryPrepared(db *sql.DB) error { From 960d6912e2990b08301ea9a4e23c78ebd54539d7 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 7 Jan 2022 08:51:00 +0800 Subject: [PATCH 084/124] add HttpPort special process --- conf.sample.yml | 5 +++-- dtmcli/logger/log.go | 2 +- dtmsvr/config/config_utils.go | 7 +++++-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/conf.sample.yml b/conf.sample.yml index 31ba6d5..d410988 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -2,7 +2,7 @@ ### dtm can be run without any config. ### all config in this file is optional. the default value is as specified in each line ### all configs can be specified from env. for example: -### Store.MaxOpenConns can also specified from env: STORE_MAX_OPEN_CONNS +### MicroService.EndPoint => MICRO_SERVICE_END_POINT ##################################################################### # Store: # specify which engine to store trans status @@ -49,4 +49,5 @@ # RetryInterval: 10 # the subtrans branch will be retried after this interval # LogLevel: 'info' # default: info. can be debug|info|warn|error - +# HttpPort: 36789 +# GrpcPort: 36790 diff --git a/dtmcli/logger/log.go b/dtmcli/logger/log.go index 81466b3..5fb0a03 100644 --- a/dtmcli/logger/log.go +++ b/dtmcli/logger/log.go @@ -13,7 +13,7 @@ import ( var logger Logger = nil func init() { - InitLog("info") + InitLog(os.Getenv("LOG_LEVEL")) } // Logger logger interface diff --git a/dtmsvr/config/config_utils.go b/dtmsvr/config/config_utils.go index 3d37b0c..f588eee 100644 --- a/dtmsvr/config/config_utils.go +++ b/dtmsvr/config/config_utils.go @@ -49,9 +49,12 @@ func loadFromEnvInner(prefix string, conf reflect.Value, defaultValue string) { func toUnderscoreUpper(key string) string { key = strings.Trim(key, "_") + matchLastCap := regexp.MustCompile("([A-Z])([A-Z][a-z])") + s2 := matchLastCap.ReplaceAllString(key, "${1}_${2}") + matchFirstCap := regexp.MustCompile("([a-z])([A-Z]+)") - s2 := matchFirstCap.ReplaceAllString(key, "${1}_${2}") - // logger.Debugf("loading from env: %s", strings.ToUpper(s2)) + s2 = matchFirstCap.ReplaceAllString(s2, "${1}_${2}") + // logger.Infof("loading from env: %s", strings.ToUpper(s2)) return strings.ToUpper(s2) } From 30873368df959b8bc4cc0575bc895b7d1b5e2691 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 7 Jan 2022 09:00:03 +0800 Subject: [PATCH 085/124] expose GetRestyClient --- dtmcli/types.go | 11 +++-------- test/main_test.go | 4 ++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/dtmcli/types.go b/dtmcli/types.go index 482651a..f0f6536 100644 --- a/dtmcli/types.go +++ b/dtmcli/types.go @@ -55,14 +55,9 @@ func SetBarrierTableName(tablename string) { dtmimp.BarrierTableName = tablename } -// OnBeforeRequest add before request middleware -func OnBeforeRequest(middleware func(c *resty.Client, r *resty.Request) error) { - dtmimp.RestyClient.OnBeforeRequest(middleware) -} - -// OnAfterResponse add after request middleware -func OnAfterResponse(middleware func(c *resty.Client, resp *resty.Response) error) { - dtmimp.RestyClient.OnAfterResponse(middleware) +// GetRestyClient get the resty.Client for http request +func GetRestyClient() *resty.Client { + return dtmimp.RestyClient } // SetPassthroughHeaders experimental. diff --git a/test/main_test.go b/test/main_test.go index 0f4add2..69d29cf 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -37,8 +37,8 @@ func TestMain(m *testing.M) { conf.UpdateBranchSync = 1 dtmgrpc.AddUnaryInterceptor(busi.SetGrpcHeaderForHeadersYes) - dtmcli.OnBeforeRequest(busi.SetHttpHeaderForHeadersYes) - dtmcli.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { return nil }) + dtmcli.GetRestyClient().OnBeforeRequest(busi.SetHttpHeaderForHeadersYes) + dtmcli.GetRestyClient().OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { return nil }) tenv := os.Getenv("TEST_STORE") if tenv == "boltdb" { From 9bcda551e8aeef2de63a52f487428f6684cccd05 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 7 Jan 2022 09:18:44 +0800 Subject: [PATCH 086/124] grpc PrepareAndSubmit added --- dtmcli/msg.go | 1 + dtmgrpc/msg.go | 20 +++++++++++++ test/busi/barrier.go | 5 ++++ test/dtmsvr_test.go | 1 + test/msg_grpc_barrier_test.go | 54 +++++++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+) create mode 100644 test/msg_grpc_barrier_test.go diff --git a/dtmcli/msg.go b/dtmcli/msg.go index 815b97d..66ac5eb 100644 --- a/dtmcli/msg.go +++ b/dtmcli/msg.go @@ -40,6 +40,7 @@ func (s *Msg) Submit() error { return dtmimp.TransCallDtm(&s.TransBase, s, "submit") } +// PrepareAndSubmit one method for the entire busi->prepare->submit func (s *Msg) PrepareAndSubmit(queryPrepared string, db *sql.DB, busiCall BarrierBusiFunc) error { bb, err := BarrierFrom(s.TransType, s.Gid, "00", "msg") // a special barrier for msg QueryPrepared if err == nil { diff --git a/dtmgrpc/msg.go b/dtmgrpc/msg.go index e112713..cbb8842 100644 --- a/dtmgrpc/msg.go +++ b/dtmgrpc/msg.go @@ -7,6 +7,8 @@ package dtmgrpc import ( + "database/sql" + "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" @@ -40,3 +42,21 @@ func (s *MsgGrpc) Prepare(queryPrepared string) error { func (s *MsgGrpc) Submit() error { return dtmgimp.DtmGrpcCall(&s.TransBase, "Submit") } + +// PrepareAndSubmit one method for the entire busi->prepare->submit +func (s *MsgGrpc) PrepareAndSubmit(queryPrepared string, db *sql.DB, busiCall dtmcli.BarrierBusiFunc) error { + bb, err := dtmcli.BarrierFrom(s.TransType, s.Gid, "00", "msg") // a special barrier for msg QueryPrepared + if err == nil { + err = bb.CallWithDB(db, func(tx *sql.Tx) error { + err := busiCall(tx) + if err == nil { + err = s.Prepare(queryPrepared) + } + return err + }) + } + if err == nil { + err = s.Submit() + } + return err +} diff --git a/test/busi/barrier.go b/test/busi/barrier.go index 8ca19de..ce1d7ce 100644 --- a/test/busi/barrier.go +++ b/test/busi/barrier.go @@ -122,3 +122,8 @@ func (s *busiServer) TransOutRevertBSaga(ctx context.Context, in *BusiReq) (*emp return sagaGrpcAdjustBalance(tx, TransOutUID, in.Amount, "") }) } + +func (s *busiServer) QueryPreparedB(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.QueryPrepared(dbGet().ToSQLDB()) +} diff --git a/test/dtmsvr_test.go b/test/dtmsvr_test.go index 28da6e2..185008f 100644 --- a/test/dtmsvr_test.go +++ b/test/dtmsvr_test.go @@ -18,6 +18,7 @@ import ( ) var DtmServer = dtmutil.DefaultHttpServer +var DtmGrpcServer = dtmutil.DefaultGrpcServer var Busi = busi.Busi func getTransStatus(gid string) string { diff --git a/test/msg_grpc_barrier_test.go b/test/msg_grpc_barrier_test.go new file mode 100644 index 0000000..ca1b93d --- /dev/null +++ b/test/msg_grpc_barrier_test.go @@ -0,0 +1,54 @@ +package test + +import ( + "database/sql" + "errors" + "reflect" + "testing" + + "bou.ke/monkey" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmgrpc" + "github.com/dtm-labs/dtm/test/busi" + "github.com/stretchr/testify/assert" +) + +func TestMsgGrpcPrepareAndSubmit(t *testing.T) { + before := getBeforeBalances() + gid := dtmimp.GetFuncName() + req := busi.GenBusiReq(30, false, false) + msg := dtmgrpc.NewMsgGrpc(DtmGrpcServer, gid). + Add(busi.BusiGrpc+"/busi.Busi/TransInBSaga", req) + err := msg.PrepareAndSubmit(busi.BusiGrpc+"/busi.Busi/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { + return busi.SagaAdjustBalance(tx, busi.TransOutUID, -int(req.Amount), "SUCCESS") + }) + assert.Nil(t, err) + waitTransProcessed(msg.Gid) + assert.Equal(t, []string{StatusSucceed}, getBranchesStatus(msg.Gid)) + assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) + assertNotSameBalance(t, before) +} + +func TestMsgGrpcPrepareAndSubmitCommitAfterFailed(t *testing.T) { + if conf.Store.IsDB() { // cannot patch tx.Commit, because Prepare also do Commit + return + } + before := getBeforeBalances() + gid := dtmimp.GetFuncName() + req := busi.GenBusiReq(30, false, false) + msg := dtmgrpc.NewMsgGrpc(DtmGrpcServer, gid). + Add(busi.BusiGrpc+"/busi.Busi/TransInBSaga", req) + var guard *monkey.PatchGuard + err := msg.PrepareAndSubmit(busi.BusiGrpc+"/busi.Busi/QueryPreparedB", dbGet().ToSQLDB(), func(tx *sql.Tx) error { + err := busi.SagaAdjustBalance(tx, busi.TransOutUID, -int(req.Amount), "SUCCESS") + guard = monkey.PatchInstanceMethod(reflect.TypeOf(tx), "Commit", func(tx *sql.Tx) error { + guard.Unpatch() + _ = tx.Commit() + return errors.New("test error for patch") + }) + return err + }) + assert.Error(t, err) + cronTransOnceForwardNow(180) + assertNotSameBalance(t, before) +} From a222faecb48a057b663e76429ffedb616fd68f0d Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 10:29:40 +0800 Subject: [PATCH 087/124] fix dtmutil relevant ci lint error --- bench/svr/http.go | 4 ++-- dtmsvr/storage/sql/sql.go | 2 +- dtmutil/consts.go | 4 ++-- dtmutil/db.go | 4 ++-- dtmutil/utils.go | 8 +++++--- dtmutil/utils_test.go | 4 ++-- test/api_test.go | 12 ++++++------ test/busi/base_http.go | 2 +- test/busi/quick_start.go | 2 +- test/busi/startup.go | 4 ++-- test/common_test.go | 2 +- test/dtmsvr_test.go | 2 +- test/msg_test.go | 2 +- test/saga_compatible_test.go | 2 +- test/saga_options_test.go | 10 +++++----- test/saga_test.go | 6 +++--- test/tcc_cover_test.go | 2 +- test/tcc_test.go | 10 +++++----- 18 files changed, 42 insertions(+), 40 deletions(-) diff --git a/bench/svr/http.go b/bench/svr/http.go index 92fd44d..427c245 100644 --- a/bench/svr/http.go +++ b/bench/svr/http.go @@ -158,7 +158,7 @@ func benchAddRoute(app *gin.Engine) { params2 := fmt.Sprintf("?uid=%s", suid2) logger.Debugf("mode: %s contains dtm: %t", mode, strings.Contains(mode, "dtm")) if strings.Contains(mode, "dtm") { - saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, fmt.Sprintf("bench-%d", uid)). + saga := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, fmt.Sprintf("bench-%d", uid)). Add(benchBusi+"/TransOut"+params, benchBusi+"/TransOutCompensate"+params, req). Add(benchBusi+"/TransIn"+params2, benchBusi+"/TransInCompensate"+params2, req) saga.WaitResult = true @@ -175,7 +175,7 @@ func benchAddRoute(app *gin.Engine) { app.Any(benchAPI+"/benchEmptyUrl", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { gid := shortuuid.New() req := gin.H{} - saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gid). + saga := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gid). Add("", "", req). Add("", "", req) saga.WaitResult = true diff --git a/dtmsvr/storage/sql/sql.go b/dtmsvr/storage/sql/sql.go index cda8d44..3c807af 100644 --- a/dtmsvr/storage/sql/sql.go +++ b/dtmsvr/storage/sql/sql.go @@ -31,7 +31,7 @@ func (s *Store) Ping() error { // PopulateData populates data to db func (s *Store) PopulateData(skipDrop bool) { - file := fmt.Sprintf("%s/dtmsvr.storage.%s.sql", dtmutil.GetSqlDir(), conf.Store.Driver) + file := fmt.Sprintf("%s/dtmsvr.storage.%s.sql", dtmutil.GetSQLDir(), conf.Store.Driver) dtmutil.RunSQLScript(conf.Store.GetDBConf(), file, skipDrop) } diff --git a/dtmutil/consts.go b/dtmutil/consts.go index 5dfd9a6..9f1afe4 100644 --- a/dtmutil/consts.go +++ b/dtmutil/consts.go @@ -7,8 +7,8 @@ package dtmutil const ( - // DefaultHttpServer default url for http server. used by test and examples - DefaultHttpServer = "http://localhost:36789/api/dtmsvr" + // DefaultHTTPServer default url for http server. used by test and examples + DefaultHTTPServer = "http://localhost:36789/api/dtmsvr" // DefaultGrpcServer default url for grpc server. used by test and examples DefaultGrpcServer = "localhost:36790" ) diff --git a/dtmutil/db.go b/dtmutil/db.go index da41468..2931104 100644 --- a/dtmutil/db.go +++ b/dtmutil/db.go @@ -28,7 +28,7 @@ func getGormDialetor(driver string, dsn string) gorm.Dialector { if driver == dtmcli.DBTypePostgres { return postgres.Open(dsn) } - dtmimp.PanicIf(driver != dtmcli.DBTypeMysql, fmt.Errorf("unkown driver: %s", driver)) + dtmimp.PanicIf(driver != dtmcli.DBTypeMysql, fmt.Errorf("unknown driver: %s", driver)) return mysql.Open(dsn) } @@ -106,7 +106,7 @@ func DbGet(conf dtmcli.DBConf, ops ...func(*gorm.DB)) *DB { SkipDefaultTransaction: true, }) dtmimp.E2P(err) - db1.Use(&tracePlugin{}) + dtmimp.E2P(db1.Use(&tracePlugin{})) db = &DB{DB: db1} for _, op := range ops { op(db1) diff --git a/dtmutil/utils.go b/dtmutil/utils.go index 4fbbc7d..398d2fa 100644 --- a/dtmutil/utils.go +++ b/dtmutil/utils.go @@ -80,8 +80,8 @@ func MustGetwd() string { return wd } -// GetSqlDir 获取调用该函数的caller源代码的目录,主要用于测试时,查找相关文件 -func GetSqlDir() string { +// GetSQLDir 获取调用该函数的caller源代码的目录,主要用于测试时,查找相关文件 +func GetSQLDir() string { wd := MustGetwd() if filepath.Base(wd) == "test" { wd = filepath.Dir(wd) @@ -89,6 +89,7 @@ func GetSqlDir() string { return wd + "/sqls" } +// RecoverPanic execs recovery operation func RecoverPanic(err *error) { if x := recover(); x != nil { e := dtmimp.AsError(x) @@ -98,6 +99,7 @@ func RecoverPanic(err *error) { } } +// GetNextTime gets next time from second func GetNextTime(second int64) *time.Time { next := time.Now().Add(time.Duration(second) * time.Second) return &next @@ -107,7 +109,7 @@ func GetNextTime(second int64) *time.Time { func RunSQLScript(conf dtmcli.DBConf, script string, skipDrop bool) { con, err := dtmimp.StandaloneDB(conf) logger.FatalIfError(err) - defer func() { con.Close() }() + defer func() { _ = con.Close() }() content, err := ioutil.ReadFile(script) logger.FatalIfError(err) sqls := strings.Split(string(content), ";") diff --git a/dtmutil/utils_test.go b/dtmutil/utils_test.go index 6900796..714f217 100644 --- a/dtmutil/utils_test.go +++ b/dtmutil/utils_test.go @@ -31,7 +31,7 @@ func TestGin(t *testing.T) { req, _ := http.NewRequest("GET", api, body) w := httptest.NewRecorder() app.ServeHTTP(w, req) - return string(w.Body.Bytes()) + return w.Body.String() } assert.Equal(t, "{\"msg\":\"pong\"}", getResultString("/api/ping", nil)) assert.Equal(t, "1", getResultString("/api/sample", nil)) @@ -42,7 +42,7 @@ func TestFuncs(t *testing.T) { wd := MustGetwd() assert.NotEqual(t, "", wd) - dir1 := GetSqlDir() + dir1 := GetSQLDir() assert.Equal(t, true, strings.HasSuffix(dir1, "/sqls")) } diff --git a/test/api_test.go b/test/api_test.go index 92d3058..c864101 100644 --- a/test/api_test.go +++ b/test/api_test.go @@ -20,7 +20,7 @@ func TestAPIQuery(t *testing.T) { err := genMsg(gid).Submit() assert.Nil(t, err) waitTransProcessed(gid) - resp, err := dtmimp.RestyClient.R().SetQueryParam("gid", gid).Get(dtmutil.DefaultHttpServer + "/query") + resp, err := dtmimp.RestyClient.R().SetQueryParam("gid", gid).Get(dtmutil.DefaultHTTPServer + "/query") assert.Nil(t, err) m := map[string]interface{}{} assert.Equal(t, resp.StatusCode(), 200) @@ -28,11 +28,11 @@ func TestAPIQuery(t *testing.T) { assert.NotEqual(t, nil, m["transaction"]) assert.Equal(t, 2, len(m["branches"].([]interface{}))) - resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "").Get(dtmutil.DefaultHttpServer + "/query") + resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "").Get(dtmutil.DefaultHTTPServer + "/query") e2p(err) assert.Equal(t, resp.StatusCode(), 500) - resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "1").Get(dtmutil.DefaultHttpServer + "/query") + resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "1").Get(dtmutil.DefaultHTTPServer + "/query") e2p(err) assert.Equal(t, resp.StatusCode(), 200) dtmimp.MustUnmarshalString(resp.String(), &m) @@ -47,7 +47,7 @@ func TestAPIAll(t *testing.T) { assert.Nil(t, err) waitTransProcessed(gid) } - resp, err := dtmimp.RestyClient.R().SetQueryParam("limit", "1").Get(dtmutil.DefaultHttpServer + "/all") + resp, err := dtmimp.RestyClient.R().SetQueryParam("limit", "1").Get(dtmutil.DefaultHTTPServer + "/all") assert.Nil(t, err) m := map[string]interface{}{} dtmimp.MustUnmarshalString(resp.String(), &m) @@ -57,7 +57,7 @@ func TestAPIAll(t *testing.T) { resp, err = dtmimp.RestyClient.R().SetQueryParams(map[string]string{ "limit": "1", "position": nextPos, - }).Get(dtmutil.DefaultHttpServer + "/all") + }).Get(dtmutil.DefaultHTTPServer + "/all") assert.Nil(t, err) dtmimp.MustUnmarshalString(resp.String(), &m) nextPos2 := m["next_position"].(string) @@ -67,7 +67,7 @@ func TestAPIAll(t *testing.T) { resp, err = dtmimp.RestyClient.R().SetQueryParams(map[string]string{ "limit": "1000", "position": nextPos, - }).Get(dtmutil.DefaultHttpServer + "/all") + }).Get(dtmutil.DefaultHTTPServer + "/all") assert.Nil(t, err) dtmimp.MustUnmarshalString(resp.String(), &m) nextPos3 := m["next_position"].(string) diff --git a/test/busi/base_http.go b/test/busi/base_http.go index fe47dd7..59d0b57 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -61,7 +61,7 @@ func BaseAppStartup() *gin.Engine { c.Next() }) var err error - XaClient, err = dtmcli.NewXaClient(dtmutil.DefaultHttpServer, BusiConf, Busi+"/xa", func(path string, xa *dtmcli.XaClient) { + XaClient, err = dtmcli.NewXaClient(dtmutil.DefaultHTTPServer, BusiConf, Busi+"/xa", func(path string, xa *dtmcli.XaClient) { app.POST(path, dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { return xa.HandleCallback(c.Query("gid"), c.Query("branch_id"), c.Query("op")) })) diff --git a/test/busi/quick_start.go b/test/busi/quick_start.go index 8e12cb9..db3c188 100644 --- a/test/busi/quick_start.go +++ b/test/busi/quick_start.go @@ -35,7 +35,7 @@ func QsStartSvr() { func QsFireRequest() string { req := &gin.H{"amount": 30} // 微服务的载荷 // DtmServer为DTM服务的地址 - saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, dtmcli.MustGenGid(dtmutil.DefaultHttpServer)). + saga := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, dtmcli.MustGenGid(dtmutil.DefaultHTTPServer)). // 添加一个TransOut的子事务,正向操作为url: qsBusi+"/TransOut", 逆向操作为url: qsBusi+"/TransOutCompensate" Add(qsBusi+"/TransOut", qsBusi+"/TransOutCompensate", req). // 添加一个TransIn的子事务,正向操作为url: qsBusi+"/TransOut", 逆向操作为url: qsBusi+"/TransInCompensate" diff --git a/test/busi/startup.go b/test/busi/startup.go index 7b85772..0c6e329 100644 --- a/test/busi/startup.go +++ b/test/busi/startup.go @@ -16,8 +16,8 @@ func Startup() *gin.Engine { // PopulateDB populate example mysql data func PopulateDB(skipDrop bool) { resetXaData() - file := fmt.Sprintf("%s/busi.%s.sql", dtmutil.GetSqlDir(), BusiConf.Driver) + file := fmt.Sprintf("%s/busi.%s.sql", dtmutil.GetSQLDir(), BusiConf.Driver) dtmutil.RunSQLScript(BusiConf, file, skipDrop) - file = fmt.Sprintf("%s/dtmcli.barrier.%s.sql", dtmutil.GetSqlDir(), BusiConf.Driver) + file = fmt.Sprintf("%s/dtmcli.barrier.%s.sql", dtmutil.GetSQLDir(), BusiConf.Driver) dtmutil.RunSQLScript(BusiConf, file, skipDrop) } diff --git a/test/common_test.go b/test/common_test.go index b042fb5..2a9b917 100644 --- a/test/common_test.go +++ b/test/common_test.go @@ -44,5 +44,5 @@ func testDbAlone(t *testing.T) { func TestMustGenGid(t *testing.T) { dtmgrpc.MustGenGid(dtmutil.DefaultGrpcServer) - dtmcli.MustGenGid(dtmutil.DefaultHttpServer) + dtmcli.MustGenGid(dtmutil.DefaultHTTPServer) } diff --git a/test/dtmsvr_test.go b/test/dtmsvr_test.go index 28da6e2..ae4cf17 100644 --- a/test/dtmsvr_test.go +++ b/test/dtmsvr_test.go @@ -17,7 +17,7 @@ import ( "github.com/stretchr/testify/assert" ) -var DtmServer = dtmutil.DefaultHttpServer +var DtmServer = dtmutil.DefaultHTTPServer var Busi = busi.Busi func getTransStatus(gid string) string { diff --git a/test/msg_test.go b/test/msg_test.go index e9c1475..121bfd4 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -68,7 +68,7 @@ func TestMsgAbnormal(t *testing.T) { func genMsg(gid string) *dtmcli.Msg { req := busi.GenTransReq(30, false, false) - msg := dtmcli.NewMsg(dtmutil.DefaultHttpServer, gid). + msg := dtmcli.NewMsg(dtmutil.DefaultHTTPServer, gid). Add(busi.Busi+"/TransOut", &req). Add(busi.Busi+"/TransIn", &req) msg.QueryPrepared = busi.Busi + "/CanSubmit" diff --git a/test/saga_compatible_test.go b/test/saga_compatible_test.go index fbf81cd..98ebf75 100644 --- a/test/saga_compatible_test.go +++ b/test/saga_compatible_test.go @@ -20,7 +20,7 @@ func TestSagaCompatibleNormal(t *testing.T) { // compatible with old http, which gid := dtmimp.GetFuncName() body := fmt.Sprintf(`{"gid":"%s","trans_type":"saga","steps":[{"action":"%s/TransOut","compensate":"%s/TransOutRevert","data":"{\"amount\":30,\"transInResult\":\"SUCCESS\",\"transOutResult\":\"SUCCESS\"}"},{"action":"%s/TransIn","compensate":"%s/TransInRevert","data":"{\"amount\":30,\"transInResult\":\"SUCCESS\",\"transOutResult\":\"SUCCESS\"}"}]}`, gid, busi.Busi, busi.Busi, busi.Busi, busi.Busi) - dtmimp.RestyClient.R().SetBody(body).Post(fmt.Sprintf("%s/submit", dtmutil.DefaultHttpServer)) + dtmimp.RestyClient.R().SetBody(body).Post(fmt.Sprintf("%s/submit", dtmutil.DefaultHTTPServer)) waitTransProcessed(gid) assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) assert.Equal(t, StatusSucceed, getTransStatus(gid)) diff --git a/test/saga_options_test.go b/test/saga_options_test.go index 73ecc24..783823c 100644 --- a/test/saga_options_test.go +++ b/test/saga_options_test.go @@ -94,7 +94,7 @@ func TestSagaOptionsRollbackWait(t *testing.T) { func TestSagaPassthroughHeadersYes(t *testing.T) { gidYes := dtmimp.GetFuncName() - sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gidYes) sagaYes.WaitResult = true sagaYes.PassthroughHeaders = []string{"test_header"} sagaYes.Add(busi.Busi+"/TransOutHeaderYes", "", nil) @@ -105,7 +105,7 @@ func TestSagaPassthroughHeadersYes(t *testing.T) { func TestSagaCronPassthroughHeadersYes(t *testing.T) { gidYes := dtmimp.GetFuncName() - sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gidYes) sagaYes.PassthroughHeaders = []string{"test_header"} sagaYes.Add(busi.Busi+"/TransOutHeaderYes", "", nil) busi.MainSwitch.TransOutResult.SetOnce("ONGOING") @@ -120,7 +120,7 @@ func TestSagaCronPassthroughHeadersYes(t *testing.T) { func TestSagaPassthroughHeadersNo(t *testing.T) { gidNo := dtmimp.GetFuncName() - sagaNo := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidNo) + sagaNo := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gidNo) sagaNo.WaitResult = true sagaNo.Add(busi.Busi+"/TransOutHeaderNo", "", nil) err := sagaNo.Submit() @@ -130,7 +130,7 @@ func TestSagaPassthroughHeadersNo(t *testing.T) { func TestSagaHeaders(t *testing.T) { gidYes := dtmimp.GetFuncName() - sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gidYes) sagaYes.BranchHeaders = map[string]string{ "test_header": "test", } @@ -143,7 +143,7 @@ func TestSagaHeaders(t *testing.T) { func TestSagaHeadersYes1(t *testing.T) { gidYes := dtmimp.GetFuncName() - sagaYes := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gidYes) + sagaYes := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gidYes) sagaYes.BranchHeaders = map[string]string{ "test_header": "test", } diff --git a/test/saga_test.go b/test/saga_test.go index 0fa3a97..9b6f0e4 100644 --- a/test/saga_test.go +++ b/test/saga_test.go @@ -64,7 +64,7 @@ func TestSagaAbnormal(t *testing.T) { } func TestSagaEmptyUrl(t *testing.T) { - saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, dtmimp.GetFuncName()) + saga := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, dtmimp.GetFuncName()) req := busi.GenTransReq(30, false, false) saga.Add(busi.Busi+"/TransOut", "", &req) saga.Add("", "", &req) @@ -75,7 +75,7 @@ func TestSagaEmptyUrl(t *testing.T) { } func genSaga(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { - saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gid) + saga := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gid) req := busi.GenTransReq(30, outFailed, inFailed) saga.Add(busi.Busi+"/TransOut", busi.Busi+"/TransOutRevert", &req) saga.Add(busi.Busi+"/TransIn", busi.Busi+"/TransInRevert", &req) @@ -83,7 +83,7 @@ func genSaga(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { } func genSaga1(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { - saga := dtmcli.NewSaga(dtmutil.DefaultHttpServer, gid) + saga := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gid) req := busi.GenTransReq(30, outFailed, inFailed) saga.Add(busi.Busi+"/TransOut", busi.Busi+"/TransOutRevert", &req) return saga diff --git a/test/tcc_cover_test.go b/test/tcc_cover_test.go index 3683f23..c8d93d8 100644 --- a/test/tcc_cover_test.go +++ b/test/tcc_cover_test.go @@ -21,7 +21,7 @@ func TestTccCoverNotConnected(t *testing.T) { func TestTccCoverPanic(t *testing.T) { gid := dtmimp.GetFuncName() err := dtmimp.CatchP(func() { - _ = dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + _ = dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { panic("user panic") }) assert.FailNow(t, "not executed") diff --git a/test/tcc_test.go b/test/tcc_test.go index 4324769..8264d43 100644 --- a/test/tcc_test.go +++ b/test/tcc_test.go @@ -20,7 +20,7 @@ import ( func TestTccNormal(t *testing.T) { req := busi.GenTransReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, err) return tcc.CallBranch(req, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") @@ -34,7 +34,7 @@ func TestTccNormal(t *testing.T) { func TestTccRollback(t *testing.T) { gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, true) - err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, rerr := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, rerr) busi.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) @@ -54,7 +54,7 @@ func TestTccTimeout(t *testing.T) { gid := dtmimp.GetFuncName() timeoutChan := make(chan int, 1) - err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, err) go func() { @@ -74,7 +74,7 @@ func TestTccTimeout(t *testing.T) { func TestTccCompatible(t *testing.T) { req := busi.GenTransReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHttpServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, err) return tcc.CallBranch(req, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") @@ -89,7 +89,7 @@ func TestTccCompatible(t *testing.T) { func TestTccHeaders(t *testing.T) { req := busi.GenTransReq(30, false, false) gid := dtmimp.GetFuncName() - err := dtmcli.TccGlobalTransaction2(dtmutil.DefaultHttpServer, gid, func(t *dtmcli.Tcc) { + err := dtmcli.TccGlobalTransaction2(dtmutil.DefaultHTTPServer, gid, func(t *dtmcli.Tcc) { t.BranchHeaders = map[string]string{ "test_header": "test", } From 8bfd6635db192665173e307a9607fb5e835e7bf8 Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 12:42:02 +0800 Subject: [PATCH 088/124] make e2p call simple --- dtmutil/db.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dtmutil/db.go b/dtmutil/db.go index 2931104..86973b2 100644 --- a/dtmutil/db.go +++ b/dtmutil/db.go @@ -106,7 +106,8 @@ func DbGet(conf dtmcli.DBConf, ops ...func(*gorm.DB)) *DB { SkipDefaultTransaction: true, }) dtmimp.E2P(err) - dtmimp.E2P(db1.Use(&tracePlugin{})) + err = db1.Use(&tracePlugin{}) + dtmimp.E2P(err) db = &DB{DB: db1} for _, op := range ops { op(db1) From 616d0d4b04f87ac414113b22c2e2d606f46acc16 Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 17:00:03 +0800 Subject: [PATCH 089/124] fix: dtmcli ci lint error --- dtmcli/barrier.go | 7 ++++--- dtmcli/dtmimp/trans_xa_base.go | 6 ++++-- dtmcli/dtmimp/types.go | 1 + dtmcli/dtmimp/types_test.go | 1 + dtmcli/dtmimp/vars.go | 4 ++-- dtmcli/logger/log.go | 3 ++- dtmcli/logger/logger_test.go | 5 +++-- dtmcli/msg.go | 1 + dtmcli/types.go | 14 ++++++++------ dtmcli/types_test.go | 4 ++-- dtmcli/xa.go | 2 +- go.mod | 2 +- 12 files changed, 30 insertions(+), 20 deletions(-) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index 5cffeba..bc64940 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -45,7 +45,7 @@ func BarrierFrom(transType, gid, branchID, op string) (*BranchBarrier, error) { Op: op, } if ti.TransType == "" || ti.Gid == "" || ti.BranchID == "" || ti.Op == "" { - return nil, fmt.Errorf("invlid trans info: %v", ti) + return nil, fmt.Errorf("invalid trans info: %v", ti) } return ti, nil } @@ -67,10 +67,10 @@ func (bb *BranchBarrier) Call(tx *sql.Tx, busiCall BarrierBusiFunc) (rerr error) defer func() { // Logf("barrier call error is %v", rerr) if x := recover(); x != nil { - tx.Rollback() + rerr = tx.Rollback() panic(x) } else if rerr != nil { - tx.Rollback() + rerr = tx.Rollback() } else { rerr = tx.Commit() } @@ -101,6 +101,7 @@ func (bb *BranchBarrier) CallWithDB(db *sql.DB, busiCall BarrierBusiFunc) error return bb.Call(tx, busiCall) } +// QueryPrepared queries prepared data func (bb *BranchBarrier) QueryPrepared(db *sql.DB) error { _, err := insertBarrier(db, bb.TransType, bb.Gid, "00", "msg", "01", "rollback") var reason string diff --git a/dtmcli/dtmimp/trans_xa_base.go b/dtmcli/dtmimp/trans_xa_base.go index cc7e604..28f92a7 100644 --- a/dtmcli/dtmimp/trans_xa_base.go +++ b/dtmcli/dtmimp/trans_xa_base.go @@ -24,7 +24,9 @@ func (xc *XaClientBase) HandleCallback(gid string, branchID string, action strin if err != nil { return err } - defer db.Close() + defer func() { + _ = db.Close() + }() xaID := gid + "-" + branchID _, err = DBExec(db, GetDBSpecial().GetXaSQL(action, xaID)) if err != nil && @@ -41,7 +43,7 @@ func (xc *XaClientBase) HandleLocalTrans(xa *TransBase, cb func(*sql.DB) error) if rerr != nil { return } - defer func() { db.Close() }() + defer func() { _ = db.Close() }() defer func() { x := recover() _, err := DBExec(db, GetDBSpecial().GetXaSQL("end", xaBranch)) diff --git a/dtmcli/dtmimp/types.go b/dtmcli/dtmimp/types.go index ef7133a..a0738f8 100644 --- a/dtmcli/dtmimp/types.go +++ b/dtmcli/dtmimp/types.go @@ -14,6 +14,7 @@ type DB interface { QueryRow(query string, args ...interface{}) *sql.Row } +// DBConf defines db config type DBConf struct { Driver string `yaml:"Driver"` Host string `yaml:"Host"` diff --git a/dtmcli/dtmimp/types_test.go b/dtmcli/dtmimp/types_test.go index 4da1654..6d58f4a 100644 --- a/dtmcli/dtmimp/types_test.go +++ b/dtmcli/dtmimp/types_test.go @@ -22,4 +22,5 @@ func TestTypes(t *testing.T) { idGen := BranchIDGen{subBranchID: 99} idGen.NewSubBranchID() }) + assert.Error(t, err) } diff --git a/dtmcli/dtmimp/vars.go b/dtmcli/dtmimp/vars.go index fc51d70..d414b0b 100644 --- a/dtmcli/dtmimp/vars.go +++ b/dtmcli/dtmimp/vars.go @@ -19,8 +19,8 @@ var ErrFailure = errors.New("FAILURE") // ErrOngoing error of ONGOING var ErrOngoing = errors.New("ONGOING") -// XaSqlTimeoutMs milliseconds for Xa sql to timeout -var XaSqlTimeoutMs = 15000 +// XaSQLTimeoutMs milliseconds for Xa sql to timeout +var XaSQLTimeoutMs = 15000 // MapSuccess HTTP result of SUCCESS var MapSuccess = map[string]interface{}{"dtm_result": ResultSuccess} diff --git a/dtmcli/logger/log.go b/dtmcli/logger/log.go index 5fb0a03..59b3d43 100644 --- a/dtmcli/logger/log.go +++ b/dtmcli/logger/log.go @@ -10,7 +10,7 @@ import ( //var logger *zap.SugaredLogger = nil -var logger Logger = nil +var logger Logger func init() { InitLog(os.Getenv("LOG_LEVEL")) @@ -24,6 +24,7 @@ type Logger interface { Errorf(format string, args ...interface{}) } +// WithLogger replaces default logger func WithLogger(log Logger) { logger = log } diff --git a/dtmcli/logger/logger_test.go b/dtmcli/logger/logger_test.go index 08f8b04..26797e0 100644 --- a/dtmcli/logger/logger_test.go +++ b/dtmcli/logger/logger_test.go @@ -1,9 +1,10 @@ package logger import ( - "go.uber.org/zap" "os" "testing" + + "go.uber.org/zap" ) func TestInitLog(t *testing.T) { @@ -26,4 +27,4 @@ func TestWithLogger(t *testing.T) { Errorf("a error msg") FatalfIf(false, "nothing") FatalIfError(nil) -} \ No newline at end of file +} diff --git a/dtmcli/msg.go b/dtmcli/msg.go index 815b97d..0998ed7 100644 --- a/dtmcli/msg.go +++ b/dtmcli/msg.go @@ -40,6 +40,7 @@ func (s *Msg) Submit() error { return dtmimp.TransCallDtm(&s.TransBase, s, "submit") } +// PrepareAndSubmit execs prepare and submit operation func (s *Msg) PrepareAndSubmit(queryPrepared string, db *sql.DB, busiCall BarrierBusiFunc) error { bb, err := BarrierFrom(s.TransType, s.Gid, "00", "msg") // a special barrier for msg QueryPrepared if err == nil { diff --git a/dtmcli/types.go b/dtmcli/types.go index 482651a..46d399a 100644 --- a/dtmcli/types.go +++ b/dtmcli/types.go @@ -29,6 +29,7 @@ type DB = dtmimp.DB // TransOptions transaction option type TransOptions = dtmimp.TransOptions +// DBConf declares db configuration type DBConf = dtmimp.DBConf // SetCurrentDBType set currentDBType @@ -41,16 +42,17 @@ func GetCurrentDBType() string { return dtmimp.GetCurrentDBType() } -// SetXaSqlTimeoutMs set XaSqlTimeoutMs -func SetXaSqlTimeoutMs(ms int) { - dtmimp.XaSqlTimeoutMs = ms +// SetXaSQLTimeoutMs set XaSQLTimeoutMs +func SetXaSQLTimeoutMs(ms int) { + dtmimp.XaSQLTimeoutMs = ms } -// GetXaSqlTimeoutMs get XaSqlTimeoutMs -func GetXaSqlTimeoutMs() int { - return dtmimp.XaSqlTimeoutMs +// GetXaSQLTimeoutMs get XaSQLTimeoutMs +func GetXaSQLTimeoutMs() int { + return dtmimp.XaSQLTimeoutMs } +// SetBarrierTableName sets barrier table name func SetBarrierTableName(tablename string) { dtmimp.BarrierTableName = tablename } diff --git a/dtmcli/types_test.go b/dtmcli/types_test.go index 269c54b..213d9a3 100644 --- a/dtmcli/types_test.go +++ b/dtmcli/types_test.go @@ -26,7 +26,7 @@ func TestTypes(t *testing.T) { } func TestXaSqlTimeout(t *testing.T) { - old := GetXaSqlTimeoutMs() - SetXaSqlTimeoutMs(old) + old := GetXaSQLTimeoutMs() + SetXaSQLTimeoutMs(old) SetBarrierTableName(dtmimp.BarrierTableName) // just cover this func } diff --git a/dtmcli/xa.go b/dtmcli/xa.go index c74b4d1..1f4137c 100644 --- a/dtmcli/xa.go +++ b/dtmcli/xa.go @@ -86,7 +86,7 @@ func (xc *XaClient) XaGlobalTransaction(gid string, xaFunc XaGlobalFunc) (rerr e return xc.XaGlobalTransaction2(gid, func(x *Xa) {}, xaFunc) } -// XaGlobalTransaction start a xa global transaction +// XaGlobalTransaction2 start a xa global transaction func (xc *XaClient) XaGlobalTransaction2(gid string, custom func(*Xa), xaFunc XaGlobalFunc) (rerr error) { xa := &Xa{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.XaClientBase.Server, "")} custom(xa) diff --git a/go.mod b/go.mod index 7e0187e..9527249 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/dtm-labs/dtm go 1.16 require ( - bou.ke/monkey v1.0.2 // indirect + bou.ke/monkey v1.0.2 github.com/dtm-labs/dtmdriver v0.0.1 github.com/dtm-labs/dtmdriver-gozero v0.0.1 github.com/dtm-labs/dtmdriver-polaris v0.0.2 From c9b8d2a1f0017edb4ef65c27a09293fdf584829a Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 17:22:10 +0800 Subject: [PATCH 090/124] fix: test trigger failed --- dtmcli/barrier.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index bc64940..731f508 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -67,10 +67,12 @@ func (bb *BranchBarrier) Call(tx *sql.Tx, busiCall BarrierBusiFunc) (rerr error) defer func() { // Logf("barrier call error is %v", rerr) if x := recover(); x != nil { - rerr = tx.Rollback() + err := tx.Rollback() + dtmimp.E2P(err) panic(x) } else if rerr != nil { - rerr = tx.Rollback() + err := tx.Rollback() + dtmimp.E2P(err) } else { rerr = tx.Commit() } From 2a063792c3e7eae6a9878fdab07df500dc4ee815 Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 17:38:28 +0800 Subject: [PATCH 091/124] fix: change rollback err assert --- dtmcli/barrier.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index 731f508..48e5ae3 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -67,12 +67,10 @@ func (bb *BranchBarrier) Call(tx *sql.Tx, busiCall BarrierBusiFunc) (rerr error) defer func() { // Logf("barrier call error is %v", rerr) if x := recover(); x != nil { - err := tx.Rollback() - dtmimp.E2P(err) + _ = tx.Rollback() panic(x) } else if rerr != nil { - err := tx.Rollback() - dtmimp.E2P(err) + _ = tx.Rollback() } else { rerr = tx.Commit() } From 08f7c7b32dfbc742a9a1bfd67a740804deed470f Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 17:50:24 +0800 Subject: [PATCH 092/124] fix: dtmgrpc relevant golangci lint error --- dtmgrpc/dtmgimp/grpc_clients.go | 6 +++--- dtmgrpc/tcc.go | 3 +++ dtmgrpc/type.go | 1 + main.go | 3 ++- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/dtmgrpc/dtmgimp/grpc_clients.go b/dtmgrpc/dtmgimp/grpc_clients.go index b299b9a..44e755b 100644 --- a/dtmgrpc/dtmgimp/grpc_clients.go +++ b/dtmgrpc/dtmgimp/grpc_clients.go @@ -26,9 +26,8 @@ func (cb rawCodec) Marshal(v interface{}) ([]byte, error) { func (cb rawCodec) Unmarshal(data []byte, v interface{}) error { ba, ok := v.(*[]byte) dtmimp.PanicIf(!ok, fmt.Errorf("please pass in *[]byte")) - for _, byte := range data { - *ba = append(*ba, byte) - } + *ba = append(*ba, data...) + return nil } @@ -36,6 +35,7 @@ func (cb rawCodec) Name() string { return "dtm_raw" } var normalClients, rawClients sync.Map +// ClientInterceptors declares grpc.UnaryClientInterceptors slice var ClientInterceptors = []grpc.UnaryClientInterceptor{} // MustGetDtmClient 1 diff --git a/dtmgrpc/tcc.go b/dtmgrpc/tcc.go index 3f39676..0fd5b7d 100644 --- a/dtmgrpc/tcc.go +++ b/dtmgrpc/tcc.go @@ -75,6 +75,9 @@ func TccFromGrpc(ctx context.Context) (*TccGrpc, error) { func (t *TccGrpc) CallBranch(busiMsg proto.Message, tryURL string, confirmURL string, cancelURL string, reply interface{}) error { branchID := t.NewSubBranchID() bd, err := proto.Marshal(busiMsg) + if err != nil { + return err + } _, err = dtmgimp.MustGetDtmClient(t.Dtm).RegisterBranch(context.Background(), &dtmgpb.DtmBranchRequest{ Gid: t.Gid, TransType: t.TransType, diff --git a/dtmgrpc/type.go b/dtmgrpc/type.go index d166b5c..f900170 100644 --- a/dtmgrpc/type.go +++ b/dtmgrpc/type.go @@ -29,6 +29,7 @@ func UseDriver(driverName string) error { return dtmdriver.Use(driverName) } +// AddUnaryInterceptor adds grpc.UnaryClientInterceptor func AddUnaryInterceptor(interceptor grpc.UnaryClientInterceptor) { dtmgimp.ClientInterceptors = append(dtmgimp.ClientInterceptors, interceptor) } diff --git a/main.go b/main.go index 013441d..1b088e1 100644 --- a/main.go +++ b/main.go @@ -25,6 +25,7 @@ import ( _ "github.com/dtm-labs/dtmdriver-protocol1" ) +// Version declares version info var Version string func version() { @@ -63,7 +64,7 @@ func main() { if *isReset { dtmsvr.PopulateDB(false) } - maxprocs.Set(maxprocs.Logger(logger.Infof)) + _, _ = maxprocs.Set(maxprocs.Logger(logger.Infof)) registry.WaitStoreUp() dtmsvr.StartSvr() // 启动dtmsvr的api服务 go dtmsvr.CronExpiredTrans(-1) // 启动dtmsvr的定时过期查询 From a44ab00e07e5f05913b5c1a8386c442e7c13f348 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 7 Jan 2022 18:14:43 +0800 Subject: [PATCH 093/124] use err==nil in tcc callbranch --- dtmgrpc/tcc.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/dtmgrpc/tcc.go b/dtmgrpc/tcc.go index 0fd5b7d..bd1b336 100644 --- a/dtmgrpc/tcc.go +++ b/dtmgrpc/tcc.go @@ -75,16 +75,15 @@ func TccFromGrpc(ctx context.Context) (*TccGrpc, error) { func (t *TccGrpc) CallBranch(busiMsg proto.Message, tryURL string, confirmURL string, cancelURL string, reply interface{}) error { branchID := t.NewSubBranchID() bd, err := proto.Marshal(busiMsg) - if err != nil { - return err + if err == nil { + _, err = dtmgimp.MustGetDtmClient(t.Dtm).RegisterBranch(context.Background(), &dtmgpb.DtmBranchRequest{ + Gid: t.Gid, + TransType: t.TransType, + BranchID: branchID, + BusiPayload: bd, + Data: map[string]string{"confirm": confirmURL, "cancel": cancelURL}, + }) } - _, err = dtmgimp.MustGetDtmClient(t.Dtm).RegisterBranch(context.Background(), &dtmgpb.DtmBranchRequest{ - Gid: t.Gid, - TransType: t.TransType, - BranchID: branchID, - BusiPayload: bd, - Data: map[string]string{"confirm": confirmURL, "cancel": cancelURL}, - }) if err != nil { return err } From ce76ded47da9428e6e7635c0bbd8bbd46fc25677 Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 18:16:12 +0800 Subject: [PATCH 094/124] fix: bench dir ci error and enable ci lint check --- .github/workflows/tests.yml | 5 ++++- .golangci.yml | 6 +++--- bench/main.go | 2 +- bench/svr/http.go | 19 ++++++++++++------- 4 files changed, 20 insertions(+), 12 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c267a52..7028864 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,5 +41,8 @@ jobs: run: | go mod download + - name: Run ci lint + run: make lint + - name: Run test cover - run: sh helper/test-cover.sh + run: sh helper/test-cover.sh \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index 5d5bf7b..58479dc 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,8 +1,8 @@ run: deadline: 5m - # skip-dirs: - # - test - # - examples + skip-dirs: + - test +# - bench linter-settings: goconst: diff --git a/bench/main.go b/bench/main.go index 310af87..34bd859 100644 --- a/bench/main.go +++ b/bench/main.go @@ -21,7 +21,7 @@ usage: ` func hintAndExit() { - fmt.Printf(usage) + fmt.Print(usage) os.Exit(0) } diff --git a/bench/svr/http.go b/bench/svr/http.go index 427c245..ed3f3cc 100644 --- a/bench/svr/http.go +++ b/bench/svr/http.go @@ -65,10 +65,11 @@ func reloadData() { logger.Debugf("%d users inserted. used: %dms", total, time.Since(began).Milliseconds()) } -var uidCounter int32 = 0 -var mode string = "" -var sqls int = 1 +var uidCounter int32 +var mode string +var sqls = 1 +// PrepareBenchDB prepares db data for bench func PrepareBenchDB() { db := pdbGet() _, err := dtmimp.DBExec(db, "drop table if exists dtm_busi.user_account_log") @@ -95,7 +96,9 @@ func StartSvr() { app := dtmutil.GetGinApp() benchAddRoute(app) logger.Debugf("bench listening at %d", benchPort) - go app.Run(fmt.Sprintf(":%s", benchPort)) + go func() { + _ = app.Run(fmt.Sprintf(":%s", benchPort)) + }() } func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { @@ -116,11 +119,13 @@ func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { if strings.Contains(mode, "barrier") { barrier, err := dtmcli.BarrierFromQuery(c.Request.URL.Query()) logger.FatalIfError(err) - barrier.Call(txGet(), f) + err = barrier.Call(txGet(), f) + logger.FatalIfError(err) } else { tx := txGet() - f(tx) - err := tx.Commit() + err := f(tx) + logger.FatalIfError(err) + err = tx.Commit() logger.FatalIfError(err) } From b725c2154b82bf264b9c7bb8e4b0a677386f4ea1 Mon Sep 17 00:00:00 2001 From: liulei Date: Fri, 7 Jan 2022 18:20:24 +0800 Subject: [PATCH 095/124] change workflow name --- .github/workflows/tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 7028864..f0495e2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -41,7 +41,7 @@ jobs: run: | go mod download - - name: Run ci lint + - name: Run CI lint run: make lint - name: Run test cover From 00153963cd230a720295e3dfa702e30b3bd7a70a Mon Sep 17 00:00:00 2001 From: fsdfsffdsf Date: Sun, 9 Jan 2022 09:15:20 +0800 Subject: [PATCH 096/124] optimization: config async update branch goroutine num --- conf.sample.yml | 1 + dtmsvr/config/config.go | 19 ++++++++++--------- dtmsvr/svr.go | 5 ++++- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/conf.sample.yml b/conf.sample.yml index d410988..3c055f4 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -48,6 +48,7 @@ # TimeoutToFail: 35 # timeout for XA, TCC to fail. saga's timeout default to infinite, which can be overwritten in saga options # RetryInterval: 10 # the subtrans branch will be retried after this interval +# UpdateBranchAsyncGoroutineNum: 1 # num of async goroutine to update branch status # LogLevel: 'info' # default: info. can be debug|info|warn|error # HttpPort: 36789 # GrpcPort: 36790 diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 60f3803..f1877c0 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -62,15 +62,16 @@ func (s *Store) GetDBConf() dtmcli.DBConf { } type configType struct { - Store Store `yaml:"Store"` - TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` - TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` - RetryInterval int64 `yaml:"RetryInterval" default:"10"` - HTTPPort int64 `yaml:"HttpPort" default:"36789"` - GrpcPort int64 `yaml:"GrpcPort" default:"36790"` - MicroService MicroService `yaml:"MicroService"` - UpdateBranchSync int64 `yaml:"UpdateBranchSync"` - LogLevel string `yaml:"LogLevel" default:"info"` + Store Store `yaml:"Store"` + TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` + TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` + RetryInterval int64 `yaml:"RetryInterval" default:"10"` + HTTPPort int64 `yaml:"HttpPort" default:"36789"` + GrpcPort int64 `yaml:"GrpcPort" default:"36790"` + MicroService MicroService `yaml:"MicroService"` + UpdateBranchSync int64 `yaml:"UpdateBranchSync"` + UpdateBranchAsyncGoroutineNum int64 `yaml:"UpdateBranchAsyncGoroutineNum" default:"1"` + LogLevel string `yaml:"LogLevel" default:"info"` } // Config 配置 diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index ac28c4b..c8fba19 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -46,7 +46,10 @@ func StartSvr() { err := s.Serve(lis) logger.FatalIfError(err) }() - go updateBranchAsync() + + for i := 0; i < int(conf.UpdateBranchAsyncGoroutineNum); i++ { + go updateBranchAsync() + } time.Sleep(100 * time.Millisecond) err = dtmdriver.Use(conf.MicroService.Driver) From 20e22fa1f24fcb4e5f2fa2726d2f79395a25f9ea Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sun, 9 Jan 2022 14:45:36 +0800 Subject: [PATCH 097/124] LockOnceGlobalTrans for boltdb fixed --- dtmsvr/storage/boltdb/boltdb.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index 19f0607..f8b83cb 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -14,6 +14,7 @@ import ( bolt "go.etcd.io/bbolt" + "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmsvr/config" @@ -386,7 +387,7 @@ func (s *Store) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalS next := time.Now().Add(time.Duration(conf.RetryInterval) * time.Second) err := boltGet().Update(func(t *bolt.Tx) error { cursor := t.Bucket(bucketIndex).Cursor() - for trans == nil { + for trans == nil || trans.Status == dtmcli.StatusSucceed || trans.Status == dtmcli.StatusFailed { k, v := cursor.First() if k == nil || string(k) > min { return storage.ErrNotFound From 2221bbf74e9f95bec909f1ee148aa2de44b36793 Mon Sep 17 00:00:00 2001 From: lsytj0413 <511121939@qq.com> Date: Sun, 9 Jan 2022 16:02:35 +0800 Subject: [PATCH 098/124] refactor(*): migrate boltdb to factory pattern --- dtmsvr/storage/boltdb/boltdb.go | 70 +++++++++++++++-------------- dtmsvr/storage/registry/factory.go | 25 +++++++++++ dtmsvr/storage/registry/registry.go | 34 +++++++++++--- 3 files changed, 89 insertions(+), 40 deletions(-) create mode 100644 dtmsvr/storage/registry/factory.go diff --git a/dtmsvr/storage/boltdb/boltdb.go b/dtmsvr/storage/boltdb/boltdb.go index 19f0607..95d78fe 100644 --- a/dtmsvr/storage/boltdb/boltdb.go +++ b/dtmsvr/storage/boltdb/boltdb.go @@ -9,48 +9,50 @@ package boltdb import ( "fmt" "strings" - "sync" "time" bolt "go.etcd.io/bbolt" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" - "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage" "github.com/dtm-labs/dtm/dtmutil" ) -var conf = &config.Config - // Store implements storage.Store, and storage with boltdb type Store struct { + boltDb *bolt.DB + + dataExpire int64 + retryInterval int64 } -var boltDb *bolt.DB -var boltOnce sync.Once +// NewStore will return the boltdb implement +// TODO: change to options +func NewStore(dataExpire int64, retryInterval int64) *Store { + s := &Store{ + dataExpire: dataExpire, + retryInterval: retryInterval, + } -func boltGet() *bolt.DB { - boltOnce.Do(func() { - db, err := bolt.Open("./dtm.bolt", 0666, &bolt.Options{Timeout: 1 * time.Second}) - dtmimp.E2P(err) + db, err := bolt.Open("./dtm.bolt", 0666, &bolt.Options{Timeout: 1 * time.Second}) + dtmimp.E2P(err) - // NOTE: we must ensure all buckets is exists before we use it - err = initializeBuckets(db) - dtmimp.E2P(err) + // NOTE: we must ensure all buckets is exists before we use it + err = initializeBuckets(db) + dtmimp.E2P(err) - // TODO: - // 1. refactor this code - // 2. make cleanup run period, to avoid the file growup when server long-running - err = cleanupExpiredData( - time.Duration(conf.Store.DataExpire)*time.Second, - db, - ) - dtmimp.E2P(err) + // TODO: + // 1. refactor this code + // 2. make cleanup run period, to avoid the file growup when server long-running + err = cleanupExpiredData( + time.Duration(dataExpire)*time.Second, + db, + ) + dtmimp.E2P(err) - boltDb = db - }) - return boltDb + s.boltDb = db + return s } func initializeBuckets(db *bolt.DB) error { @@ -241,7 +243,7 @@ func (s *Store) Ping() error { // PopulateData populates data to boltdb func (s *Store) PopulateData(skipDrop bool) { if !skipDrop { - err := boltGet().Update(func(t *bolt.Tx) error { + err := s.boltDb.Update(func(t *bolt.Tx) error { dtmimp.E2P(t.DeleteBucket(bucketIndex)) dtmimp.E2P(t.DeleteBucket(bucketBranches)) dtmimp.E2P(t.DeleteBucket(bucketGlobal)) @@ -261,7 +263,7 @@ func (s *Store) PopulateData(skipDrop bool) { // FindTransGlobalStore finds GlobalTrans data by gid func (s *Store) FindTransGlobalStore(gid string) (trans *storage.TransGlobalStore) { - err := boltGet().View(func(t *bolt.Tx) error { + err := s.boltDb.View(func(t *bolt.Tx) error { trans = tGetGlobal(t, gid) return nil }) @@ -272,7 +274,7 @@ func (s *Store) FindTransGlobalStore(gid string) (trans *storage.TransGlobalStor // ScanTransGlobalStores lists GlobalTrans data func (s *Store) ScanTransGlobalStores(position *string, limit int64) []storage.TransGlobalStore { globals := []storage.TransGlobalStore{} - err := boltGet().View(func(t *bolt.Tx) error { + err := s.boltDb.View(func(t *bolt.Tx) error { cursor := t.Bucket(bucketGlobal).Cursor() for k, v := cursor.First(); k != nil; k, v = cursor.Next() { if string(k) == *position { @@ -299,7 +301,7 @@ func (s *Store) ScanTransGlobalStores(position *string, limit int64) []storage.T // FindBranches finds Branch data by gid func (s *Store) FindBranches(gid string) []storage.TransBranchStore { var branches []storage.TransBranchStore - err := boltGet().View(func(t *bolt.Tx) error { + err := s.boltDb.View(func(t *bolt.Tx) error { branches = tGetBranches(t, gid) return nil }) @@ -314,7 +316,7 @@ func (s *Store) UpdateBranches(branches []storage.TransBranchStore, updates []st // LockGlobalSaveBranches creates branches func (s *Store) LockGlobalSaveBranches(gid string, status string, branches []storage.TransBranchStore, branchStart int) { - err := boltGet().Update(func(t *bolt.Tx) error { + err := s.boltDb.Update(func(t *bolt.Tx) error { g := tGetGlobal(t, gid) if g == nil { return storage.ErrNotFound @@ -330,7 +332,7 @@ func (s *Store) LockGlobalSaveBranches(gid string, status string, branches []sto // MaySaveNewTrans creates a new trans func (s *Store) MaySaveNewTrans(global *storage.TransGlobalStore, branches []storage.TransBranchStore) error { - return boltGet().Update(func(t *bolt.Tx) error { + return s.boltDb.Update(func(t *bolt.Tx) error { g := tGetGlobal(t, global.Gid) if g != nil { return storage.ErrUniqueConflict @@ -346,7 +348,7 @@ func (s *Store) MaySaveNewTrans(global *storage.TransGlobalStore, branches []sto func (s *Store) ChangeGlobalStatus(global *storage.TransGlobalStore, newStatus string, updates []string, finished bool) { old := global.Status global.Status = newStatus - err := boltGet().Update(func(t *bolt.Tx) error { + err := s.boltDb.Update(func(t *bolt.Tx) error { g := tGetGlobal(t, global.Gid) if g == nil || g.Status != old { return storage.ErrNotFound @@ -366,7 +368,7 @@ func (s *Store) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval global.NextCronTime = dtmutil.GetNextTime(nextCronInterval) global.UpdateTime = dtmutil.GetNextTime(0) global.NextCronInterval = nextCronInterval - err := boltGet().Update(func(t *bolt.Tx) error { + err := s.boltDb.Update(func(t *bolt.Tx) error { g := tGetGlobal(t, global.Gid) if g == nil || g.Gid != global.Gid { return storage.ErrNotFound @@ -383,8 +385,8 @@ func (s *Store) TouchCronTime(global *storage.TransGlobalStore, nextCronInterval func (s *Store) LockOneGlobalTrans(expireIn time.Duration) *storage.TransGlobalStore { var trans *storage.TransGlobalStore min := fmt.Sprintf("%d", time.Now().Add(expireIn).Unix()) - next := time.Now().Add(time.Duration(conf.RetryInterval) * time.Second) - err := boltGet().Update(func(t *bolt.Tx) error { + next := time.Now().Add(time.Duration(s.retryInterval) * time.Second) + err := s.boltDb.Update(func(t *bolt.Tx) error { cursor := t.Bucket(bucketIndex).Cursor() for trans == nil { k, v := cursor.First() diff --git a/dtmsvr/storage/registry/factory.go b/dtmsvr/storage/registry/factory.go new file mode 100644 index 0000000..811bbf0 --- /dev/null +++ b/dtmsvr/storage/registry/factory.go @@ -0,0 +1,25 @@ +package registry + +import ( + "sync" + + "github.com/dtm-labs/dtm/dtmsvr/storage" +) + +// SingletonFactory is the factory to build store in SINGLETON pattern. +type SingletonFactory struct { + once sync.Once + + store storage.Store + + creatorFunction func() storage.Store +} + +// GetStorage implement the StorageFactory.GetStorage +func (f *SingletonFactory) GetStorage() storage.Store { + f.once.Do(func() { + f.store = f.creatorFunction() + }) + + return f.store +} diff --git a/dtmsvr/storage/registry/registry.go b/dtmsvr/storage/registry/registry.go index 1788456..003fd69 100644 --- a/dtmsvr/storage/registry/registry.go +++ b/dtmsvr/storage/registry/registry.go @@ -12,16 +12,38 @@ import ( var conf = &config.Config -var stores map[string]storage.Store = map[string]storage.Store{ - "redis": &redis.Store{}, - "mysql": &sql.Store{}, - "postgres": &sql.Store{}, - "boltdb": &boltdb.Store{}, +// StorageFactory is factory to get storage instance. +type StorageFactory interface { + // GetStorage will return the Storage instance. + GetStorage() storage.Store +} + +var storeFactorys = map[string]StorageFactory{ + "boltdb": &SingletonFactory{ + creatorFunction: func() storage.Store { + return boltdb.NewStore(conf.Store.DataExpire, conf.RetryInterval) + }, + }, + "redis": &SingletonFactory{ + creatorFunction: func() storage.Store { + return &redis.Store{} + }, + }, + "mysql": &SingletonFactory{ + creatorFunction: func() storage.Store { + return &sql.Store{} + }, + }, + "postgres": &SingletonFactory{ + creatorFunction: func() storage.Store { + return &sql.Store{} + }, + }, } // GetStore returns storage.Store func GetStore() storage.Store { - return stores[conf.Store.Driver] + return storeFactorys[conf.Store.Driver].GetStorage() } // WaitStoreUp wait for db to go up From 0e59ccb5126355d0389fb2bf0379ed79ce389121 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 10 Jan 2022 15:06:54 +0800 Subject: [PATCH 099/124] change to new error protocal ok --- README-cn.md | 4 +- README.md | 4 +- bench/svr/http.go | 27 ++++++------ dtmcli/dtmimp/trans_base.go | 8 +++- dtmcli/dtmimp/utils.go | 45 ++++++-------------- dtmcli/types.go | 10 +++++ dtmcli/xa.go | 4 +- dtmgrpc/dtmgimp/types.go | 15 ------- dtmgrpc/type.go | 14 +++++++ dtmsvr/api.go | 27 ++++++------ dtmsvr/api_grpc.go | 18 ++++---- dtmsvr/api_http.go | 40 +++++++++--------- dtmsvr/cron.go | 3 +- dtmsvr/trans_process.go | 15 +++---- dtmsvr/trans_status.go | 38 ++++++++--------- dtmsvr/trans_type_msg.go | 12 +++--- dtmsvr/trans_type_saga.go | 3 +- dtmutil/utils.go | 63 ++++++++++++++++++++-------- dtmutil/utils_test.go | 10 ++--- test/busi/barrier.go | 52 +++++++++++------------ test/busi/base_grpc.go | 5 ++- test/busi/base_http.go | 82 +++++++++++++++++++++++-------------- test/busi/busi.go | 23 +++++------ test/busi/quick_start.go | 16 ++++---- test/busi/utils.go | 30 ++++++++++++++ test/msg_test.go | 3 -- test/tcc_barrier_test.go | 6 +-- test/tcc_old_test.go | 66 +++++++++++++++++++++++++++++ 28 files changed, 393 insertions(+), 250 deletions(-) create mode 100644 test/tcc_old_test.go diff --git a/README-cn.md b/README-cn.md index a5acf06..fd3f602 100644 --- a/README-cn.md +++ b/README-cn.md @@ -111,8 +111,8 @@ go run main.go 在实际的业务中,子事务可能出现失败,例如转入的子账号被冻结导致转账失败。我们对业务代码进行修改,让TransIn的正向操作失败,然后看看结果 ``` go - app.POST(qsBusiAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return M{"dtm_result": "FAILURE"}, nil + app.POST(qsBusiAPI+"/TransIn", common.WrapHandler2(func(c *gin.Context) interface{} { + return dtmcli.ErrFailure })) ``` diff --git a/README.md b/README.md index fc83704..760cff9 100644 --- a/README.md +++ b/README.md @@ -111,8 +111,8 @@ go run main.go 在实际的业务中,子事务可能出现失败,例如转入的子账号被冻结导致转账失败。我们对业务代码进行修改,让TransIn的正向操作失败,然后看看结果 ``` go - app.POST(qsBusiAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return M{"dtm_result": "FAILURE"}, nil + app.POST(qsBusiAPI+"/TransIn", common.WrapHandler2(func(c *gin.Context) interface{} { + return dtmcli.ErrFailure })) ``` diff --git a/bench/svr/http.go b/bench/svr/http.go index ed3f3cc..158b263 100644 --- a/bench/svr/http.go +++ b/bench/svr/http.go @@ -101,9 +101,9 @@ func StartSvr() { }() } -func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { +func qsAdjustBalance(uid int, amount int, c *gin.Context) error { if strings.Contains(mode, "empty") || sqls == 0 { - return dtmcli.MapSuccess, nil + return nil } tb := dtmimp.TransBaseFromQuery(c.Request.URL.Query()) f := func(tx *sql.Tx) error { @@ -129,32 +129,32 @@ func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { logger.FatalIfError(err) } - return dtmcli.MapSuccess, nil + return nil } func benchAddRoute(app *gin.Engine) { - app.POST(benchAPI+"/TransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), 1, c) })) - app.POST(benchAPI+"/TransInCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransInCompensate", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), -1, c) })) - app.POST(benchAPI+"/TransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), -1, c) })) - app.POST(benchAPI+"/TransOutCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(benchAPI+"/TransOutCompensate", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), 30, c) })) - app.Any(benchAPI+"/reloadData", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.Any(benchAPI+"/reloadData", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { reloadData() mode = c.Query("m") s := c.Query("sqls") if s != "" { sqls = dtmimp.MustAtoi(s) } - return nil, nil + return nil })) - app.Any(benchAPI+"/bench", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.Any(benchAPI+"/bench", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { uid := (atomic.AddInt32(&uidCounter, 1)-1)%total + 1 suid := fmt.Sprintf("%d", uid) suid2 := fmt.Sprintf("%d", total+1-uid) @@ -175,16 +175,15 @@ func benchAddRoute(app *gin.Engine) { _, err = dtmimp.RestyClient.R().SetBody(gin.H{}).SetQueryParam("uid", suid).Post(benchBusi + "/TransIn") dtmimp.E2P(err) } - return nil, nil + return nil })) - app.Any(benchAPI+"/benchEmptyUrl", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.Any(benchAPI+"/benchEmptyUrl", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { gid := shortuuid.New() req := gin.H{} saga := dtmcli.NewSaga(dtmutil.DefaultHTTPServer, gid). Add("", "", req). Add("", "", req) saga.WaitResult = true - err := saga.Submit() - return nil, err + return saga.Submit() })) } diff --git a/dtmcli/dtmimp/trans_base.go b/dtmcli/dtmimp/trans_base.go index 9c89a9f..ad0b9d1 100644 --- a/dtmcli/dtmimp/trans_base.go +++ b/dtmcli/dtmimp/trans_base.go @@ -9,6 +9,7 @@ package dtmimp import ( "errors" "fmt" + "net/http" "net/url" "strings" @@ -87,7 +88,7 @@ func TransCallDtm(tb *TransBase, body interface{}, operation string) error { if err != nil { return err } - if !strings.Contains(resp.String(), ResultSuccess) { + if resp.StatusCode() != http.StatusOK || strings.Contains(resp.String(), ResultFailure) { return errors.New(resp.String()) } return nil @@ -118,5 +119,8 @@ func TransRequestBranch(t *TransBase, body interface{}, branchID string, op stri }). SetHeaders(t.BranchHeaders). Post(url) - return resp, CheckResponse(resp, err) + if err == nil { + err = RespAsErrorCompatible(resp) + } + return resp, err } diff --git a/dtmcli/dtmimp/utils.go b/dtmcli/dtmimp/utils.go index e2576e2..8038b61 100644 --- a/dtmcli/dtmimp/utils.go +++ b/dtmcli/dtmimp/utils.go @@ -11,6 +11,7 @@ import ( "encoding/json" "errors" "fmt" + "net/http" "os" "runtime" "strconv" @@ -204,37 +205,17 @@ func GetDsn(conf DBConf) string { return dsn } -// CheckResponse is check response, and return corresponding error by the condition of resp when err is nil. Otherwise, return err directly. -func CheckResponse(resp *resty.Response, err error) error { - if err == nil && resp != nil { - if resp.IsError() { - return errors.New(resp.String()) - } else if strings.Contains(resp.String(), ResultFailure) { - return ErrFailure - } else if strings.Contains(resp.String(), ResultOngoing) { - return ErrOngoing - } - } - return err -} - -// CheckResult is check result. Return err directly if err is not nil. And return corresponding error by calling CheckResponse if resp is the type of *resty.Response. -// Otherwise, return error by value of str, the string after marshal. -func CheckResult(res interface{}, err error) error { - if err != nil { - return err +// RespAsErrorCompatible translate a resty response to error +// compatible with version < v1.10 +func RespAsErrorCompatible(resp *resty.Response) error { + code := resp.StatusCode() + str := resp.String() + if code == http.StatusTooEarly || strings.Contains(str, ResultOngoing) { + return fmt.Errorf("%s. %w", str, ErrOngoing) + } else if code == http.StatusConflict || strings.Contains(str, ResultFailure) { + return fmt.Errorf("%s. %w", str, ErrFailure) + } else if code != http.StatusOK { + return errors.New(str) } - resp, ok := res.(*resty.Response) - if ok { - return CheckResponse(resp, err) - } - if res != nil { - str := MustMarshalString(res) - if strings.Contains(str, ResultFailure) { - return ErrFailure - } else if strings.Contains(str, ResultOngoing) { - return ErrOngoing - } - } - return err + return nil } diff --git a/dtmcli/types.go b/dtmcli/types.go index dbe2129..f48e30f 100644 --- a/dtmcli/types.go +++ b/dtmcli/types.go @@ -32,6 +32,16 @@ type TransOptions = dtmimp.TransOptions // DBConf declares db configuration type DBConf = dtmimp.DBConf +// String2DtmError translate string to dtm error +func String2DtmError(str string) error { + return map[string]error{ + ResultFailure: ErrFailure, + ResultOngoing: ErrOngoing, + ResultSuccess: nil, + "": nil, + }[str] +} + // SetCurrentDBType set currentDBType func SetCurrentDBType(dbType string) { dtmimp.SetCurrentDBType(dbType) diff --git a/dtmcli/xa.go b/dtmcli/xa.go index 1f4137c..2b48ecb 100644 --- a/dtmcli/xa.go +++ b/dtmcli/xa.go @@ -59,8 +59,8 @@ func NewXaClient(server string, mysqlConf DBConf, notifyURL string, register XaR } // HandleCallback 处理commit/rollback的回调 -func (xc *XaClient) HandleCallback(gid string, branchID string, action string) (interface{}, error) { - return MapSuccess, xc.XaClientBase.HandleCallback(gid, branchID, action) +func (xc *XaClient) HandleCallback(gid string, branchID string, action string) interface{} { + return xc.XaClientBase.HandleCallback(gid, branchID, action) } // XaLocalTransaction start a xa local transaction diff --git a/dtmgrpc/dtmgimp/types.go b/dtmgrpc/dtmgimp/types.go index a11fe71..535e924 100644 --- a/dtmgrpc/dtmgimp/types.go +++ b/dtmgrpc/dtmgimp/types.go @@ -11,12 +11,9 @@ import ( "fmt" "time" - "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" ) // GrpcServerLog 打印grpc服务端的日志 @@ -49,15 +46,3 @@ func GrpcClientLog(ctx context.Context, method string, req, reply interface{}, c } return err } - -// Result2Error 将通用的result转成grpc的error -func Result2Error(res interface{}, err error) error { - e := dtmimp.CheckResult(res, err) - if e == dtmimp.ErrFailure { - logger.Errorf("failure: res: %v, err: %v", res, e) - return status.New(codes.Aborted, dtmcli.ResultFailure).Err() - } else if e == dtmimp.ErrOngoing { - return status.New(codes.Aborted, dtmcli.ResultOngoing).Err() - } - return e -} diff --git a/dtmgrpc/type.go b/dtmgrpc/type.go index f900170..194ff59 100644 --- a/dtmgrpc/type.go +++ b/dtmgrpc/type.go @@ -9,13 +9,27 @@ package dtmgrpc import ( context "context" + "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtmdriver" grpc "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" emptypb "google.golang.org/protobuf/types/known/emptypb" ) +// DtmError2GrpcError translate dtm error to grpc error +func DtmError2GrpcError(res interface{}) error { + e, ok := res.(error) + if ok && e == dtmimp.ErrFailure { + return status.New(codes.Aborted, dtmcli.ResultFailure).Err() + } else if ok && e == dtmimp.ErrOngoing { + return status.New(codes.FailedPrecondition, dtmcli.ResultOngoing).Err() + } + return e +} + // MustGenGid must gen a gid from grpcServer func MustGenGid(grpcServer string) string { dc := dtmgimp.MustGetDtmClient(grpcServer) diff --git a/dtmsvr/api.go b/dtmsvr/api.go index 7fb5673..83a1056 100644 --- a/dtmsvr/api.go +++ b/dtmsvr/api.go @@ -15,7 +15,7 @@ import ( "github.com/dtm-labs/dtm/dtmsvr/storage" ) -func svcSubmit(t *TransGlobal) (interface{}, error) { +func svcSubmit(t *TransGlobal) interface{} { t.Status = dtmcli.StatusSubmitted branches, err := t.saveNew() @@ -25,35 +25,36 @@ func svcSubmit(t *TransGlobal) (interface{}, error) { dbt.changeStatus(t.Status) branches = GetStore().FindBranches(t.Gid) } else if dbt.Status != dtmcli.StatusSubmitted { - return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status '%s', cannot sumbmit", dbt.Status)}, nil + return fmt.Errorf("current status '%s', cannot sumbmit. %w", dbt.Status, dtmcli.ErrFailure) } } - return t.Process(branches), nil + return t.Process(branches) } -func svcPrepare(t *TransGlobal) (interface{}, error) { +func svcPrepare(t *TransGlobal) interface{} { t.Status = dtmcli.StatusPrepared _, err := t.saveNew() if err == storage.ErrUniqueConflict { dbt := GetTransGlobal(t.Gid) if dbt.Status != dtmcli.StatusPrepared { - return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status '%s', cannot prepare", dbt.Status)}, nil + return fmt.Errorf("current status '%s', cannot prepare. %w", dbt.Status, dtmcli.ErrFailure) } + return nil } - return dtmcli.MapSuccess, nil + return err } -func svcAbort(t *TransGlobal) (interface{}, error) { +func svcAbort(t *TransGlobal) interface{} { dbt := GetTransGlobal(t.Gid) if t.TransType != "xa" && t.TransType != "tcc" || dbt.Status != dtmcli.StatusPrepared && dbt.Status != dtmcli.StatusAborting { - return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("trans type: '%s' current status '%s', cannot abort", dbt.TransType, dbt.Status)}, nil + return fmt.Errorf("trans type: '%s' current status '%s', cannot abort. %w", dbt.TransType, dbt.Status, dtmcli.ErrFailure) } dbt.changeStatus(dtmcli.StatusAborting) branches := GetStore().FindBranches(t.Gid) - return dbt.Process(branches), nil + return dbt.Process(branches) } -func svcRegisterBranch(transType string, branch *TransBranch, data map[string]string) (ret interface{}, rerr error) { +func svcRegisterBranch(transType string, branch *TransBranch, data map[string]string) error { branches := []TransBranch{*branch, *branch} if transType == "tcc" { for i, b := range []string{dtmcli.BranchCancel, dtmcli.BranchConfirm} { @@ -66,7 +67,7 @@ func svcRegisterBranch(transType string, branch *TransBranch, data map[string]st branches[1].Op = dtmcli.BranchCommit branches[1].URL = data["url"] } else { - return nil, fmt.Errorf("unknow trans type: %s", transType) + return fmt.Errorf("unknow trans type: %s", transType) } err := dtmimp.CatchP(func() { @@ -75,9 +76,9 @@ func svcRegisterBranch(transType string, branch *TransBranch, data map[string]st if err == storage.ErrNotFound { msg := fmt.Sprintf("no trans with gid: %s status: %s found", branch.Gid, dtmcli.StatusPrepared) logger.Errorf(msg) - return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": msg}, nil + return fmt.Errorf("message: %s %w", msg, dtmcli.ErrFailure) } logger.Infof("LockGlobalSaveBranches result: %v: gid: %s old status: %s branches: %s", err, branch.Gid, dtmcli.StatusPrepared, dtmimp.MustMarshalString(branches)) - return dtmimp.If(err != nil, nil, dtmcli.MapSuccess), err + return err } diff --git a/dtmsvr/api_grpc.go b/dtmsvr/api_grpc.go index 8cd48d3..8bc840a 100644 --- a/dtmsvr/api_grpc.go +++ b/dtmsvr/api_grpc.go @@ -10,7 +10,7 @@ import ( "context" "github.com/dtm-labs/dtm/dtmcli" - "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" + "github.com/dtm-labs/dtm/dtmgrpc" pb "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "google.golang.org/protobuf/types/known/emptypb" ) @@ -25,26 +25,26 @@ func (s *dtmServer) NewGid(ctx context.Context, in *emptypb.Empty) (*pb.DtmGidRe } func (s *dtmServer) Submit(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { - r, err := svcSubmit(TransFromDtmRequest(ctx, in)) - return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) + r := svcSubmit(TransFromDtmRequest(ctx, in)) + return &emptypb.Empty{}, dtmgrpc.DtmError2GrpcError(r) } func (s *dtmServer) Prepare(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { - r, err := svcPrepare(TransFromDtmRequest(ctx, in)) - return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) + r := svcPrepare(TransFromDtmRequest(ctx, in)) + return &emptypb.Empty{}, dtmgrpc.DtmError2GrpcError(r) } func (s *dtmServer) Abort(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { - r, err := svcAbort(TransFromDtmRequest(ctx, in)) - return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) + r := svcAbort(TransFromDtmRequest(ctx, in)) + return &emptypb.Empty{}, dtmgrpc.DtmError2GrpcError(r) } func (s *dtmServer) RegisterBranch(ctx context.Context, in *pb.DtmBranchRequest) (*emptypb.Empty, error) { - r, err := svcRegisterBranch(in.TransType, &TransBranch{ + r := svcRegisterBranch(in.TransType, &TransBranch{ Gid: in.Gid, BranchID: in.BranchID, Status: dtmcli.StatusPrepared, BinData: in.BusiPayload, }, in.Data) - return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) + return &emptypb.Empty{}, dtmgrpc.DtmError2GrpcError(r) } diff --git a/dtmsvr/api_http.go b/dtmsvr/api_http.go index fa98498..6027100 100644 --- a/dtmsvr/api_http.go +++ b/dtmsvr/api_http.go @@ -17,15 +17,15 @@ import ( ) func addRoute(engine *gin.Engine) { - engine.GET("/api/dtmsvr/newGid", dtmutil.WrapHandler(newGid)) - engine.POST("/api/dtmsvr/prepare", dtmutil.WrapHandler(prepare)) - engine.POST("/api/dtmsvr/submit", dtmutil.WrapHandler(submit)) - engine.POST("/api/dtmsvr/abort", dtmutil.WrapHandler(abort)) - engine.POST("/api/dtmsvr/registerBranch", dtmutil.WrapHandler(registerBranch)) - engine.POST("/api/dtmsvr/registerXaBranch", dtmutil.WrapHandler(registerBranch)) // compatible for old sdk - engine.POST("/api/dtmsvr/registerTccBranch", dtmutil.WrapHandler(registerBranch)) // compatible for old sdk - engine.GET("/api/dtmsvr/query", dtmutil.WrapHandler(query)) - engine.GET("/api/dtmsvr/all", dtmutil.WrapHandler(all)) + engine.GET("/api/dtmsvr/newGid", dtmutil.WrapHandler2(newGid)) + engine.POST("/api/dtmsvr/prepare", dtmutil.WrapHandler2(prepare)) + engine.POST("/api/dtmsvr/submit", dtmutil.WrapHandler2(submit)) + engine.POST("/api/dtmsvr/abort", dtmutil.WrapHandler2(abort)) + engine.POST("/api/dtmsvr/registerBranch", dtmutil.WrapHandler2(registerBranch)) + engine.POST("/api/dtmsvr/registerXaBranch", dtmutil.WrapHandler2(registerBranch)) // compatible for old sdk + engine.POST("/api/dtmsvr/registerTccBranch", dtmutil.WrapHandler2(registerBranch)) // compatible for old sdk + engine.GET("/api/dtmsvr/query", dtmutil.WrapHandler2(query)) + engine.GET("/api/dtmsvr/all", dtmutil.WrapHandler2(all)) // add prometheus exporter h := promhttp.Handler() @@ -34,23 +34,23 @@ func addRoute(engine *gin.Engine) { }) } -func newGid(c *gin.Context) (interface{}, error) { - return map[string]interface{}{"gid": GenGid(), "dtm_result": dtmcli.ResultSuccess}, nil +func newGid(c *gin.Context) interface{} { + return map[string]interface{}{"gid": GenGid(), "dtm_result": dtmcli.ResultSuccess} } -func prepare(c *gin.Context) (interface{}, error) { +func prepare(c *gin.Context) interface{} { return svcPrepare(TransFromContext(c)) } -func submit(c *gin.Context) (interface{}, error) { +func submit(c *gin.Context) interface{} { return svcSubmit(TransFromContext(c)) } -func abort(c *gin.Context) (interface{}, error) { +func abort(c *gin.Context) interface{} { return svcAbort(TransFromContext(c)) } -func registerBranch(c *gin.Context) (interface{}, error) { +func registerBranch(c *gin.Context) interface{} { data := map[string]string{} err := c.BindJSON(&data) e2p(err) @@ -63,19 +63,19 @@ func registerBranch(c *gin.Context) (interface{}, error) { return svcRegisterBranch(data["trans_type"], &branch, data) } -func query(c *gin.Context) (interface{}, error) { +func query(c *gin.Context) interface{} { gid := c.Query("gid") if gid == "" { - return nil, errors.New("no gid specified") + return errors.New("no gid specified") } trans := GetStore().FindTransGlobalStore(gid) branches := GetStore().FindBranches(gid) - return map[string]interface{}{"transaction": trans, "branches": branches}, nil + return map[string]interface{}{"transaction": trans, "branches": branches} } -func all(c *gin.Context) (interface{}, error) { +func all(c *gin.Context) interface{} { position := c.Query("position") slimit := dtmimp.OrString(c.Query("limit"), "100") globals := GetStore().ScanTransGlobalStores(&position, int64(dtmimp.MustAtoi(slimit))) - return map[string]interface{}{"transactions": globals, "next_position": position}, nil + return map[string]interface{}{"transactions": globals, "next_position": position} } diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index 66ff0b5..8ffff26 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -32,7 +32,8 @@ func CronTransOnce() (gid string) { gid = trans.Gid trans.WaitResult = true branches := GetStore().FindBranches(gid) - trans.Process(branches) + err := trans.Process(branches) + dtmimp.E2P(err) return } diff --git a/dtmsvr/trans_process.go b/dtmsvr/trans_process.go index fc48513..7a8fe46 100644 --- a/dtmsvr/trans_process.go +++ b/dtmsvr/trans_process.go @@ -7,6 +7,7 @@ package dtmsvr import ( + "fmt" "time" "github.com/dtm-labs/dtm/dtmcli" @@ -16,13 +17,13 @@ import ( ) // Process process global transaction once -func (t *TransGlobal) Process(branches []TransBranch) map[string]interface{} { +func (t *TransGlobal) Process(branches []TransBranch) error { r := t.process(branches) - transactionMetrics(t, r["dtm_result"] == dtmcli.ResultSuccess) + transactionMetrics(t, r == nil) return r } -func (t *TransGlobal) process(branches []TransBranch) map[string]interface{} { +func (t *TransGlobal) process(branches []TransBranch) error { if t.Options != "" { dtmimp.MustUnmarshalString(t.Options, &t.TransOptions) } @@ -37,17 +38,17 @@ func (t *TransGlobal) process(branches []TransBranch) map[string]interface{} { logger.Errorf("processInner err: %v", err) } }() - return dtmcli.MapSuccess + return nil } submitting := t.Status == dtmcli.StatusSubmitted err := t.processInner(branches) if err != nil { - return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": err.Error()} + return err } if submitting && t.Status != dtmcli.StatusSucceed { - return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": "trans failed by user"} + return fmt.Errorf("wait result not return success: %w", dtmcli.ErrFailure) } - return dtmcli.MapSuccess + return nil } func (t *TransGlobal) processInner(branches []TransBranch) (rerr error) { diff --git a/dtmsvr/trans_status.go b/dtmsvr/trans_status.go index ec78533..c70e5f2 100644 --- a/dtmsvr/trans_status.go +++ b/dtmsvr/trans_status.go @@ -7,6 +7,7 @@ package dtmsvr import ( + "errors" "fmt" "strings" "time" @@ -72,15 +73,15 @@ func (t *TransGlobal) needProcess() bool { return t.Status == dtmcli.StatusSubmitted || t.Status == dtmcli.StatusAborting || t.Status == dtmcli.StatusPrepared && t.isTimeout() } -func (t *TransGlobal) getURLResult(url string, branchID, op string, branchPayload []byte) (string, error) { +func (t *TransGlobal) getURLResult(url string, branchID, op string, branchPayload []byte) error { if url == "" { // empty url is success - return dtmcli.ResultSuccess, nil + return nil } if t.Protocol == "grpc" { dtmimp.PanicIf(strings.HasPrefix(url, "http"), fmt.Errorf("bad url for grpc: %s", url)) server, method, err := dtmdriver.GetDriver().ParseServerMethod(url) if err != nil { - return "", err + return err } conn := dtmgimp.MustGetGrpcConn(server, true) ctx := dtmgimp.TransInfo2Ctx(t.Gid, t.TransType, branchID, op, "") @@ -89,17 +90,19 @@ func (t *TransGlobal) getURLResult(url string, branchID, op string, branchPayloa ctx = metadata.AppendToOutgoingContext(ctx, kvs...) err = conn.Invoke(ctx, method, branchPayload, &[]byte{}) if err == nil { - return dtmcli.ResultSuccess, nil + return nil } st, ok := status.FromError(err) if ok && st.Code() == codes.Aborted { + // version lower then v1.10, will specify Ongoing in code Aborted if st.Message() == dtmcli.ResultOngoing { - return dtmcli.ResultOngoing, nil - } else if st.Message() == dtmcli.ResultFailure { - return dtmcli.ResultFailure, nil + return dtmcli.ErrOngoing } + return dtmcli.ErrFailure + } else if ok && st.Code() == codes.FailedPrecondition { + return dtmcli.ErrOngoing } - return "", err + return err } dtmimp.PanicIf(!strings.HasPrefix(url, "http"), fmt.Errorf("bad url for http: %s", url)) resp, err := dtmimp.RestyClient.R().SetBody(string(branchPayload)). @@ -114,24 +117,21 @@ func (t *TransGlobal) getURLResult(url string, branchID, op string, branchPayloa SetHeaders(t.TransOptions.BranchHeaders). Execute(dtmimp.If(branchPayload != nil || t.TransType == "xa", "POST", "GET").(string), url) if err != nil { - return "", err + return err } - return resp.String(), nil + return dtmimp.RespAsErrorCompatible(resp) } func (t *TransGlobal) getBranchResult(branch *TransBranch) (string, error) { - body, err := t.getURLResult(branch.URL, branch.BranchID, branch.Op, branch.BinData) - if err != nil { - return "", err - } - if strings.Contains(body, dtmcli.ResultSuccess) { + err := t.getURLResult(branch.URL, branch.BranchID, branch.Op, branch.BinData) + if err == nil { return dtmcli.StatusSucceed, nil - } else if strings.HasSuffix(t.TransType, "saga") && branch.Op == dtmcli.BranchAction && strings.Contains(body, dtmcli.ResultFailure) { + } else if t.TransType == "saga" && branch.Op == dtmcli.BranchAction && errors.Is(err, dtmcli.ErrFailure) { return dtmcli.StatusFailed, nil - } else if strings.Contains(body, dtmcli.ResultOngoing) { - return "", dtmimp.ErrOngoing + } else if errors.Is(err, dtmcli.ErrOngoing) { + return "", dtmcli.ErrOngoing } - return "", fmt.Errorf("http result should contains SUCCESS|FAILURE|ONGOING. grpc error should return nil|Aborted with message(FAILURE|ONGOING). \nrefer to: https://dtm.pub/summary/arch.html#http\nunkown result will be retried: %s", body) + return "", fmt.Errorf("http/grpc result should be specified as in:\nhttps://dtm.pub/summary/arch.html#http\nunkown result will be retried: %s", err) } func (t *TransGlobal) execBranch(branch *TransBranch, branchPos int) error { diff --git a/dtmsvr/trans_type_msg.go b/dtmsvr/trans_type_msg.go index 3435042..5fe3eb2 100644 --- a/dtmsvr/trans_type_msg.go +++ b/dtmsvr/trans_type_msg.go @@ -7,8 +7,8 @@ package dtmsvr import ( + "errors" "fmt" - "strings" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/logger" @@ -42,15 +42,15 @@ func (t *TransGlobal) mayQueryPrepared() { if !t.needProcess() || t.Status == dtmcli.StatusSubmitted { return } - body, err := t.getURLResult(t.QueryPrepared, "00", "msg", nil) - if strings.Contains(body, dtmcli.ResultSuccess) { + err := t.getURLResult(t.QueryPrepared, "00", "msg", nil) + if err == nil { t.changeStatus(dtmcli.StatusSubmitted) - } else if strings.Contains(body, dtmcli.ResultFailure) { + } else if errors.Is(err, dtmcli.ErrFailure) { t.changeStatus(dtmcli.StatusFailed) - } else if strings.Contains(body, dtmcli.ResultOngoing) { + } else if errors.Is(err, dtmcli.ErrOngoing) { t.touchCronTime(cronReset) } else { - logger.Errorf("getting result failed for %s. error: %v body %s", t.QueryPrepared, err, body) + logger.Errorf("getting result failed for %s. error: %v", t.QueryPrepared, err) t.touchCronTime(cronBackoff) } } diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index abaa801..f2a88fd 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -7,6 +7,7 @@ package dtmsvr import ( + "errors" "fmt" "time" @@ -106,7 +107,7 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { err = dtmimp.AsError(x) } resultChan <- branchResult{index: i, status: branches[i].Status, op: branches[i].Op} - if err != nil && err != dtmcli.ErrOngoing { + if err != nil && !errors.Is(err, dtmcli.ErrOngoing) { logger.Errorf("exec branch error: %v", err) } }() diff --git a/dtmutil/utils.go b/dtmutil/utils.go index 288c424..d673c53 100644 --- a/dtmutil/utils.go +++ b/dtmutil/utils.go @@ -9,7 +9,9 @@ package dtmutil import ( "bytes" "encoding/json" + "errors" "io/ioutil" + "net/http" "os" "path/filepath" "strings" @@ -45,31 +47,60 @@ func GetGinApp() *gin.Engine { return app } -// WrapHandler name is clear -func WrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc { +// WrapHandler2 wrap a function te bo the handler of gin request +func WrapHandler2(fn func(*gin.Context) interface{}) gin.HandlerFunc { return func(c *gin.Context) { began := time.Now() - r, err := func() (r interface{}, rerr error) { - defer dtmimp.P2E(&rerr) + var err error + r := func() interface{} { + defer dtmimp.P2E(&err) return fn(c) }() - var b = []byte{} - if resp, ok := r.(*resty.Response); ok { // 如果是response,则取出body直接处理 - b = resp.Body() - } else if err == nil { - b, err = json.Marshal(r) + + status := http.StatusOK + + // in dtm test/busi, there are some functions, which will return a resty response + // pass resty response as gin's response + if resp, ok := r.(*resty.Response); ok { + b := resp.Body() + status = resp.StatusCode() + err = json.Unmarshal(b, &r) + } + + // error maybe returned in r, assign it to err + if ne, ok := r.(error); ok && err == nil { + err = ne } + // if err != nil || r == nil. then set the status and dtm_result + // dtm_result is for compatible with version lower than v1.10 + // when >= v1.10, result test should base on status, not dtm_result. + result := map[string]interface{}{} if err != nil { - logger.Errorf("%2dms 500 %s %s %s %s", time.Since(began).Milliseconds(), err.Error(), c.Request.Method, c.Request.RequestURI, string(b)) - c.JSON(500, map[string]interface{}{"code": 500, "message": err.Error()}) + if errors.Is(err, dtmcli.ErrFailure) { + status = http.StatusConflict + result["dtm_result"] = dtmcli.ResultFailure + } else if errors.Is(err, dtmcli.ErrOngoing) { + status = http.StatusTooEarly + result["dtm_result"] = dtmcli.ResultOngoing + } else if err != nil { + status = http.StatusInternalServerError + } + result["message"] = err.Error() + r = result + } else if r == nil { + result["dtm_result"] = dtmcli.ResultSuccess + r = result + } + + b, _ := json.Marshal(r) + cont := string(b) + if status == http.StatusOK || status == http.StatusTooEarly { + logger.Infof("%2dms %d %s %s %s", time.Since(began).Milliseconds(), status, c.Request.Method, c.Request.RequestURI, cont) } else { - logger.Infof("%2dms 200 %s %s %s", time.Since(began).Milliseconds(), c.Request.Method, c.Request.RequestURI, string(b)) - c.Status(200) - c.Writer.Header().Add("Content-Type", "application/json") - _, err = c.Writer.Write(b) - dtmimp.E2P(err) + logger.Errorf("%2dms %d %s %s %s", time.Since(began).Milliseconds(), status, c.Request.Method, c.Request.RequestURI, cont) } + c.JSON(status, r) } } diff --git a/dtmutil/utils_test.go b/dtmutil/utils_test.go index 714f217..4ce1507 100644 --- a/dtmutil/utils_test.go +++ b/dtmutil/utils_test.go @@ -21,11 +21,11 @@ import ( func TestGin(t *testing.T) { app := GetGinApp() - app.GET("/api/sample", WrapHandler(func(c *gin.Context) (interface{}, error) { - return 1, nil + app.GET("/api/sample", WrapHandler2(func(c *gin.Context) interface{} { + return 1 })) - app.GET("/api/error", WrapHandler(func(c *gin.Context) (interface{}, error) { - return nil, errors.New("err1") + app.GET("/api/error", WrapHandler2(func(c *gin.Context) interface{} { + return errors.New("err1") })) getResultString := func(api string, body io.Reader) string { req, _ := http.NewRequest("GET", api, body) @@ -35,7 +35,7 @@ func TestGin(t *testing.T) { } assert.Equal(t, "{\"msg\":\"pong\"}", getResultString("/api/ping", nil)) assert.Equal(t, "1", getResultString("/api/sample", nil)) - assert.Equal(t, "{\"code\":500,\"message\":\"err1\"}", getResultString("/api/error", strings.NewReader("{}"))) + assert.Equal(t, "{\"message\":\"err1\"}", getResultString("/api/error", strings.NewReader("{}"))) } func TestFuncs(t *testing.T) { diff --git a/test/busi/barrier.go b/test/busi/barrier.go index ce1d7ce..46463f7 100644 --- a/test/busi/barrier.go +++ b/test/busi/barrier.go @@ -18,79 +18,79 @@ import ( func init() { setupFuncs["BarrierSetup"] = func(app *gin.Engine) { - app.POST(BusiAPI+"/SagaBTransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/SagaBTransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) })) - app.POST(BusiAPI+"/SagaBTransInCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/SagaBTransInCompensate", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransInUID, -reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/SagaBTransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/SagaBTransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransOutUID, -reqFrom(c).Amount, reqFrom(c).TransOutResult) }) })) - app.POST(BusiAPI+"/SagaBTransOutCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/SagaBTransOutCompensate", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { barrier := MustBarrierFromGin(c) - return dtmcli.MapSuccess, barrier.Call(txGet(), func(tx *sql.Tx) error { + return barrier.Call(txGet(), func(tx *sql.Tx) error { return SagaAdjustBalance(tx, TransOutUID, reqFrom(c).Amount, "") }) })) - app.POST(BusiAPI+"/SagaBTransOutGorm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/SagaBTransOutGorm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { req := reqFrom(c) barrier := MustBarrierFromGin(c) tx := dbGet().DB.Begin() - return dtmcli.MapSuccess, barrier.Call(tx.Statement.ConnPool.(*sql.Tx), func(tx1 *sql.Tx) error { + return barrier.Call(tx.Statement.ConnPool.(*sql.Tx), func(tx1 *sql.Tx) error { return tx.Exec("update dtm_busi.user_account set balance = balance + ? where user_id = ?", -req.Amount, TransOutUID).Error }) })) - app.POST(BusiAPI+"/TccBTransInTry", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - req := reqFrom(c) // 去重构一下,改成可以重复使用的输入 + app.POST(BusiAPI+"/TccBTransInTry", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + req := reqFrom(c) if req.TransInResult != "" { - return req.TransInResult, nil + return dtmcli.String2DtmError(req.TransInResult) } - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustTrading(tx, TransInUID, req.Amount) }) })) - app.POST(BusiAPI+"/TccBTransInConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + app.POST(BusiAPI+"/TccBTransInConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustBalance(tx, TransInUID, reqFrom(c).Amount) }) })) - app.POST(BusiAPI+"/TccBTransInCancel", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + app.POST(BusiAPI+"/TccBTransInCancel", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustTrading(tx, TransInUID, -reqFrom(c).Amount) }) })) - app.POST(BusiAPI+"/TccBTransOutTry", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TccBTransOutTry", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { req := reqFrom(c) if req.TransOutResult != "" { - return req.TransOutResult, nil + return dtmcli.String2DtmError(req.TransOutResult) } - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustTrading(tx, TransOutUID, -req.Amount) }) })) - app.POST(BusiAPI+"/TccBTransOutConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { + app.POST(BusiAPI+"/TccBTransOutConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustBalance(tx, TransOutUID, -reqFrom(c).Amount) }) })) - app.POST(BusiAPI+"/TccBTransOutCancel", dtmutil.WrapHandler(TccBarrierTransOutCancel)) + app.POST(BusiAPI+"/TccBTransOutCancel", dtmutil.WrapHandler2(TccBarrierTransOutCancel)) } } // TccBarrierTransOutCancel will be use in test -func TccBarrierTransOutCancel(c *gin.Context) (interface{}, error) { - return dtmcli.MapSuccess, MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { +func TccBarrierTransOutCancel(c *gin.Context) interface{} { + return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustTrading(tx, TransOutUID, reqFrom(c).Amount) }) } diff --git a/test/busi/base_grpc.go b/test/busi/base_grpc.go index 3c71a50..63099e1 100644 --- a/test/busi/base_grpc.go +++ b/test/busi/base_grpc.go @@ -13,6 +13,7 @@ import ( "fmt" "net" + "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" "github.com/dtm-labs/dtm/dtmgrpc" @@ -65,7 +66,9 @@ type busiServer struct { func (s *busiServer) QueryPrepared(ctx context.Context, in *BusiReq) (*BusiReply, error) { res := MainSwitch.QueryPreparedResult.Fetch() - return &BusiReply{Message: "a sample data"}, dtmgimp.Result2Error(res, nil) + err := dtmcli.String2DtmError(res) + + return &BusiReply{Message: "a sample data"}, dtmgrpc.DtmError2GrpcError(err) } func (s *busiServer) TransIn(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { diff --git a/test/busi/base_http.go b/test/busi/base_http.go index b39d4ae..6c5bdd3 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -39,7 +39,7 @@ var Busi string = fmt.Sprintf("http://localhost:%d%s", BusiPort, BusiAPI) var XaClient *dtmcli.XaClient = nil -type SleepCancelHandler func(c *gin.Context) (interface{}, error) +type SleepCancelHandler func(c *gin.Context) interface{} var sleepCancelHandler SleepCancelHandler = nil @@ -62,7 +62,7 @@ func BaseAppStartup() *gin.Engine { }) var err error XaClient, err = dtmcli.NewXaClient(dtmutil.DefaultHTTPServer, BusiConf, Busi+"/xa", func(path string, xa *dtmcli.XaClient) { - app.POST(path, dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(path, dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return xa.HandleCallback(c.Query("gid"), c.Query("branch_id"), c.Query("op")) })) }) @@ -81,55 +81,76 @@ func BaseAppStartup() *gin.Engine { // BaseAddRoute add base route handler func BaseAddRoute(app *gin.Engine) { - app.POST(BusiAPI+"/TransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransInResult.Fetch(), reqFrom(c).TransInResult, "transIn") })) - app.POST(BusiAPI+"/TransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") })) - app.POST(BusiAPI+"/TransInConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransInConfirmResult.Fetch(), "", "TransInConfirm") })) - app.POST(BusiAPI+"/TransOutConfirm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutConfirmResult.Fetch(), "", "TransOutConfirm") })) - app.POST(BusiAPI+"/TransInRevert", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInRevert", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransInRevertResult.Fetch(), "", "TransInRevert") })) - app.POST(BusiAPI+"/TransOutRevert", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutRevert", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) - app.GET(BusiAPI+"/QueryPrepared", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + return handleGeneralBusinessCompatible(c, MainSwitch.TransInResult.Fetch(), reqFrom(c).TransInResult, "transIn") + })) + app.POST(BusiAPI+"/TransOutOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + return handleGeneralBusinessCompatible(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") + })) + app.POST(BusiAPI+"/TransInConfirmOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + return handleGeneralBusinessCompatible(c, MainSwitch.TransInConfirmResult.Fetch(), "", "TransInConfirm") + })) + app.POST(BusiAPI+"/TransOutConfirmOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + return handleGeneralBusinessCompatible(c, MainSwitch.TransOutConfirmResult.Fetch(), "", "TransOutConfirm") + })) + app.POST(BusiAPI+"/TransInRevertOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + return handleGeneralBusinessCompatible(c, MainSwitch.TransInRevertResult.Fetch(), "", "TransInRevert") + })) + app.POST(BusiAPI+"/TransOutRevertOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + return handleGeneralBusinessCompatible(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") + })) + + app.GET(BusiAPI+"/QueryPrepared", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { logger.Debugf("%s QueryPrepared", c.Query("gid")) - return dtmimp.OrString(MainSwitch.QueryPreparedResult.Fetch(), dtmcli.ResultSuccess), nil + return dtmcli.String2DtmError(dtmimp.OrString(MainSwitch.QueryPreparedResult.Fetch(), dtmcli.ResultSuccess)) })) - app.GET(BusiAPI+"/QueryPreparedB", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.GET(BusiAPI+"/QueryPreparedB", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { logger.Debugf("%s QueryPreparedB", c.Query("gid")) bb := MustBarrierFromGin(c) db := dbGet().ToSQLDB() - return error2Resp(bb.QueryPrepared(db)) + return bb.QueryPrepared(db) })) - app.POST(BusiAPI+"/TransInXa", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { + app.POST(BusiAPI+"/TransInXa", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { return SagaAdjustBalance(db, TransInUID, reqFrom(c).Amount, reqFrom(c).TransInResult) }) - return error2Resp(err) })) - app.POST(BusiAPI+"/TransOutXa", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { + app.POST(BusiAPI+"/TransOutXa", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { return SagaAdjustBalance(db, TransOutUID, reqFrom(c).Amount, reqFrom(c).TransOutResult) }) - return error2Resp(err) })) - app.POST(BusiAPI+"/TransInTccParent", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInTccParent", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { tcc, err := dtmcli.TccFromQuery(c.Request.URL.Query()) logger.FatalIfError(err) logger.Debugf("TransInTccParent ") - return tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") + resp, err := tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") + if err != nil { + return err + } + return resp })) - app.POST(BusiAPI+"/TransOutXaGorm", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { - err := XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { + app.POST(BusiAPI+"/TransOutXaGorm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { if reqFrom(c).TransOutResult == dtmcli.ResultFailure { return dtmcli.ErrFailure } @@ -146,32 +167,31 @@ func BaseAddRoute(app *gin.Engine) { dbr := gdb.Exec("update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, TransOutUID) return dbr.Error }) - return error2Resp(err) })) - app.POST(BusiAPI+"/TestPanic", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TestPanic", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { if c.Query("panic_error") != "" { panic(errors.New("panic_error")) } else if c.Query("panic_string") != "" { panic("panic_string") } - return "SUCCESS", nil + return nil })) - app.POST(BusiAPI+"/TccBSleepCancel", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TccBSleepCancel", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return sleepCancelHandler(c) })) - app.POST(BusiAPI+"/TransOutHeaderYes", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutHeaderYes", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { h := c.GetHeader("test_header") if h == "" { - return nil, errors.New("no test_header found in TransOutHeaderYes") + return errors.New("no test_header found in TransOutHeaderYes") } return handleGeneralBusiness(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") })) - app.POST(BusiAPI+"/TransOutHeaderNo", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutHeaderNo", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { h := c.GetHeader("test_header") if h != "" { - return nil, errors.New("test_header found in TransOutHeaderNo") + return errors.New("test_header found in TransOutHeaderNo") } - return dtmcli.MapSuccess, nil + return nil })) } diff --git a/test/busi/busi.go b/test/busi/busi.go index 7d6c064..5a41192 100644 --- a/test/busi/busi.go +++ b/test/busi/busi.go @@ -29,25 +29,25 @@ func handleGrpcBusiness(in *BusiReq, result1 string, result2 string, busi string return status.New(codes.Internal, fmt.Sprintf("unknow result %s", res)).Err() } -func handleGeneralBusiness(c *gin.Context, result1 string, result2 string, busi string) (interface{}, error) { +func handleGeneralBusiness(c *gin.Context, result1 string, result2 string, busi string) interface{} { info := infoFromContext(c) res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) logger.Debugf("%s %s result: %s", busi, info.String(), res) if res == "ERROR" { - return nil, errors.New("ERROR from user") + return errors.New("ERROR from user") } - return map[string]interface{}{"dtm_result": res}, nil + return dtmcli.String2DtmError(res) } -func error2Resp(err error) (interface{}, error) { - if err != nil { - s := err.Error() - if strings.Contains(s, dtmcli.ResultFailure) || strings.Contains(s, dtmcli.ResultOngoing) { - return gin.H{"dtm_result": s}, nil - } - return nil, err +// old business handler. for compatible usage +func handleGeneralBusinessCompatible(c *gin.Context, result1 string, result2 string, busi string) (interface{}, error) { + info := infoFromContext(c) + res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) + logger.Debugf("%s %s result: %s", busi, info.String(), res) + if res == "ERROR" { + return nil, errors.New("ERROR from user") } - return gin.H{"dtm_result": dtmcli.ResultSuccess}, nil + return map[string]interface{}{"dtm_result": res}, nil } func sagaGrpcAdjustBalance(db dtmcli.DB, uid int, amount int64, result string) error { @@ -56,7 +56,6 @@ func sagaGrpcAdjustBalance(db dtmcli.DB, uid int, amount int64, result string) e } _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) return err - } func SagaAdjustBalance(db dtmcli.DB, uid int, amount int, result string) error { diff --git a/test/busi/quick_start.go b/test/busi/quick_start.go index db3c188..da939ec 100644 --- a/test/busi/quick_start.go +++ b/test/busi/quick_start.go @@ -49,20 +49,20 @@ func QsFireRequest() string { } func qsAddRoute(app *gin.Engine) { - app.POST(qsBusiAPI+"/TransIn", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(qsBusiAPI+"/TransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { logger.Infof("TransIn") - return dtmcli.MapSuccess, nil + return nil })) - app.POST(qsBusiAPI+"/TransInCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(qsBusiAPI+"/TransInCompensate", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { logger.Infof("TransInCompensate") - return dtmcli.MapSuccess, nil + return nil })) - app.POST(qsBusiAPI+"/TransOut", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(qsBusiAPI+"/TransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { logger.Infof("TransOut") - return dtmcli.MapSuccess, nil + return nil })) - app.POST(qsBusiAPI+"/TransOutCompensate", dtmutil.WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(qsBusiAPI+"/TransOutCompensate", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { logger.Infof("TransOutCompensate") - return dtmcli.MapSuccess, nil + return nil })) } diff --git a/test/busi/utils.go b/test/busi/utils.go index 5df72d1..bc5a77f 100644 --- a/test/busi/utils.go +++ b/test/busi/utils.go @@ -3,8 +3,10 @@ package busi import ( "context" "database/sql" + "encoding/json" "fmt" "strings" + "time" "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" @@ -83,3 +85,31 @@ func SetHttpHeaderForHeadersYes(c *resty.Client, r *resty.Request) error { } return nil } + +// oldWrapHandler old wrap handler for test use of dtm +func oldWrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc { + return func(c *gin.Context) { + began := time.Now() + r, err := func() (r interface{}, rerr error) { + defer dtmimp.P2E(&rerr) + return fn(c) + }() + var b = []byte{} + if resp, ok := r.(*resty.Response); ok { // 如果是response,则取出body直接处理 + b = resp.Body() + } else if err == nil { + b, err = json.Marshal(r) + } + + if err != nil { + logger.Errorf("%2dms 500 %s %s %s %s", time.Since(began).Milliseconds(), err.Error(), c.Request.Method, c.Request.RequestURI, string(b)) + c.JSON(500, map[string]interface{}{"code": 500, "message": err.Error()}) + } else { + logger.Infof("%2dms 200 %s %s %s", time.Since(began).Milliseconds(), c.Request.Method, c.Request.RequestURI, string(b)) + c.Status(200) + c.Writer.Header().Add("Content-Type", "application/json") + _, err = c.Writer.Write(b) + dtmimp.E2P(err) + } + } +} diff --git a/test/msg_test.go b/test/msg_test.go index a9b1152..8f26ad8 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -45,9 +45,6 @@ func TestMsgTimeoutFailed(t *testing.T) { msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) - busi.MainSwitch.QueryPreparedResult.SetOnce("OTHER_ERROR") - cronTransOnceForwardNow(180) - assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) busi.MainSwitch.QueryPreparedResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(360) assert.Equal(t, StatusPrepared, getTransStatus(msg.Gid)) diff --git a/test/tcc_barrier_test.go b/test/tcc_barrier_test.go index 376b3ca..2a4ec94 100644 --- a/test/tcc_barrier_test.go +++ b/test/tcc_barrier_test.go @@ -63,14 +63,14 @@ func TestTccBarrierDisorder(t *testing.T) { cancelURL := Busi + "/TccBSleepCancel" // 请参见子事务屏障里的时序图,这里为了模拟该时序图,手动拆解了callbranch branchID := tcc.NewSubBranchID() - busi.SetSleepCancelHandler(func(c *gin.Context) (interface{}, error) { - res, err := busi.TccBarrierTransOutCancel(c) + busi.SetSleepCancelHandler(func(c *gin.Context) interface{} { + res := busi.TccBarrierTransOutCancel(c) logger.Debugf("disorderHandler before cancel finish write") cancelFinishedChan <- "1" logger.Debugf("disorderHandler before cancel return read") <-cancelCanReturnChan logger.Debugf("disorderHandler after cancel return read") - return res, err + return res }) // 注册子事务 resp, err := dtmimp.RestyClient.R(). diff --git a/test/tcc_old_test.go b/test/tcc_old_test.go new file mode 100644 index 0000000..9a55611 --- /dev/null +++ b/test/tcc_old_test.go @@ -0,0 +1,66 @@ +package test + +import ( + "testing" + + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" + "github.com/go-resty/resty/v2" + "github.com/stretchr/testify/assert" +) + +func TestTccOldNormal(t *testing.T) { + req := busi.GenTransReq(30, false, false) + gid := dtmimp.GetFuncName() + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + _, err := tcc.CallBranch(req, Busi+"/TransOutOld", Busi+"/TransOutConfirmOld", Busi+"/TransOutRevertOld") + assert.Nil(t, err) + return tcc.CallBranch(req, Busi+"/TransInOld", Busi+"/TransInConfirmOld", Busi+"/TransInRevertOld") + }) + assert.Nil(t, err) + waitTransProcessed(gid) + assert.Equal(t, StatusSucceed, getTransStatus(gid)) + assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) +} + +func TestTccOldRollback(t *testing.T) { + gid := dtmimp.GetFuncName() + req := busi.GenTransReq(30, false, true) + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + _, rerr := tcc.CallBranch(req, Busi+"/TransOutOld", Busi+"/TransOutConfirmOld", Busi+"/TransOutRevertOld") + assert.Nil(t, rerr) + busi.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) + return tcc.CallBranch(req, Busi+"/TransInOld", Busi+"/TransInConfirmOld", Busi+"/TransInRevertOld") + }) + assert.Error(t, err) + waitTransProcessed(gid) + assert.Equal(t, StatusAborting, getTransStatus(gid)) + g := cronTransOnce() + assert.Equal(t, gid, g) + assert.Equal(t, StatusFailed, getTransStatus(gid)) + assert.Equal(t, []string{StatusSucceed, StatusPrepared, StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) +} + +func TestTccOldTimeout(t *testing.T) { + req := busi.GenTransReq(30, false, false) + gid := dtmimp.GetFuncName() + timeoutChan := make(chan int, 1) + + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + _, err := tcc.CallBranch(req, Busi+"/TransOutOld", Busi+"/TransOutConfirmOld", Busi+"/TransOutRevertOld") + assert.Nil(t, err) + go func() { + cronTransOnceForwardNow(300) + timeoutChan <- 0 + }() + <-timeoutChan + _, err = tcc.CallBranch(req, Busi+"/TransInOld", Busi+"/TransInConfirmOld", Busi+"/TransInRevertOld") + assert.Error(t, err) + return nil, err + }) + assert.Error(t, err) + assert.Equal(t, StatusFailed, getTransStatus(gid)) + assert.Equal(t, []string{StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) +} From f0be4e251748fa7e9dfe70a17d0c75a99265e91c Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 10 Jan 2022 15:16:20 +0800 Subject: [PATCH 100/124] fix test error --- bench/svr/http.go | 2 +- test/busi/base_http.go | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bench/svr/http.go b/bench/svr/http.go index 158b263..6e8d7bc 100644 --- a/bench/svr/http.go +++ b/bench/svr/http.go @@ -101,7 +101,7 @@ func StartSvr() { }() } -func qsAdjustBalance(uid int, amount int, c *gin.Context) error { +func qsAdjustBalance(uid int, amount int, c *gin.Context) error { // nolint: unparam if strings.Contains(mode, "empty") || sqls == 0 { return nil } diff --git a/test/busi/base_http.go b/test/busi/base_http.go index 6c5bdd3..bfcf2a9 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -99,22 +99,22 @@ func BaseAddRoute(app *gin.Engine) { app.POST(BusiAPI+"/TransOutRevert", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { return handleGeneralBusiness(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) - app.POST(BusiAPI+"/TransInOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInOld", oldWrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusinessCompatible(c, MainSwitch.TransInResult.Fetch(), reqFrom(c).TransInResult, "transIn") })) - app.POST(BusiAPI+"/TransOutOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutOld", oldWrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusinessCompatible(c, MainSwitch.TransOutResult.Fetch(), reqFrom(c).TransOutResult, "TransOut") })) - app.POST(BusiAPI+"/TransInConfirmOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInConfirmOld", oldWrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusinessCompatible(c, MainSwitch.TransInConfirmResult.Fetch(), "", "TransInConfirm") })) - app.POST(BusiAPI+"/TransOutConfirmOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutConfirmOld", oldWrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusinessCompatible(c, MainSwitch.TransOutConfirmResult.Fetch(), "", "TransOutConfirm") })) - app.POST(BusiAPI+"/TransInRevertOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransInRevertOld", oldWrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusinessCompatible(c, MainSwitch.TransInRevertResult.Fetch(), "", "TransInRevert") })) - app.POST(BusiAPI+"/TransOutRevertOld", WrapHandler(func(c *gin.Context) (interface{}, error) { + app.POST(BusiAPI+"/TransOutRevertOld", oldWrapHandler(func(c *gin.Context) (interface{}, error) { return handleGeneralBusinessCompatible(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) From 7c28d5acee2c4d2f985e8c2d4d3365891dabf433 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 10 Jan 2022 16:10:50 +0800 Subject: [PATCH 101/124] cover nested --- dtmutil/utils.go | 2 ++ test/busi/base_http.go | 4 ++-- test/tcc_cover_test.go | 15 +++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/dtmutil/utils.go b/dtmutil/utils.go index d673c53..d690cd6 100644 --- a/dtmutil/utils.go +++ b/dtmutil/utils.go @@ -14,6 +14,7 @@ import ( "net/http" "os" "path/filepath" + "reflect" "strings" "time" @@ -64,6 +65,7 @@ func WrapHandler2(fn func(*gin.Context) interface{}) gin.HandlerFunc { if resp, ok := r.(*resty.Response); ok { b := resp.Body() status = resp.StatusCode() + r = nil err = json.Unmarshal(b, &r) } diff --git a/test/busi/base_http.go b/test/busi/base_http.go index bfcf2a9..0feee1e 100644 --- a/test/busi/base_http.go +++ b/test/busi/base_http.go @@ -139,10 +139,10 @@ func BaseAddRoute(app *gin.Engine) { }) })) - app.POST(BusiAPI+"/TransInTccParent", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + app.POST(BusiAPI+"/TransInTccNested", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { tcc, err := dtmcli.TccFromQuery(c.Request.URL.Query()) logger.FatalIfError(err) - logger.Debugf("TransInTccParent ") + logger.Debugf("TransInTccNested ") resp, err := tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") if err != nil { return err diff --git a/test/tcc_cover_test.go b/test/tcc_cover_test.go index c8d93d8..00ba711 100644 --- a/test/tcc_cover_test.go +++ b/test/tcc_cover_test.go @@ -6,6 +6,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmutil" + "github.com/dtm-labs/dtm/test/busi" "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" ) @@ -29,3 +30,17 @@ func TestTccCoverPanic(t *testing.T) { assert.Contains(t, err.Error(), "user panic") waitTransProcessed(gid) } + +func TestTccNested(t *testing.T) { + req := busi.GenTransReq(30, false, false) + gid := dtmimp.GetFuncName() + err := dtmcli.TccGlobalTransaction(dtmutil.DefaultHTTPServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { + _, err := tcc.CallBranch(req, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") + assert.Nil(t, err) + return tcc.CallBranch(req, Busi+"/TransInTccNested", Busi+"/TransInConfirm", Busi+"/TransInRevert") + }) + assert.Nil(t, err) + waitTransProcessed(gid) + assert.Equal(t, StatusSucceed, getTransStatus(gid)) + assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(gid)) +} From 8f5ec9a86afae3ad517fa1e693e1b54e178007c6 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 10 Jan 2022 16:17:17 +0800 Subject: [PATCH 102/124] fix build error --- dtmutil/utils.go | 1 - 1 file changed, 1 deletion(-) diff --git a/dtmutil/utils.go b/dtmutil/utils.go index d690cd6..849b539 100644 --- a/dtmutil/utils.go +++ b/dtmutil/utils.go @@ -14,7 +14,6 @@ import ( "net/http" "os" "path/filepath" - "reflect" "strings" "time" From 6933154f9c6300664f506caef32e7081591e68c0 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 10 Jan 2022 18:19:14 +0800 Subject: [PATCH 103/124] add timeout --- conf.sample.yml | 8 +++++--- dtmcli/dtmimp/vars.go | 3 --- dtmsvr/config/config.go | 1 + dtmsvr/svr.go | 9 +++++++++ 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/conf.sample.yml b/conf.sample.yml index 3c055f4..cd66cb6 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -42,13 +42,15 @@ # Target: 'etcd://localhost:2379/dtmservice' # register dtm server to this url # EndPoint: 'localhost:36790' -# the unit of following configurations is second - +### the unit of following configurations is second # TransCronInterval: 3 # the interval to poll unfinished global transaction for every dtm process # TimeoutToFail: 35 # timeout for XA, TCC to fail. saga's timeout default to infinite, which can be overwritten in saga options # RetryInterval: 10 # the subtrans branch will be retried after this interval +# RequestTimeout: 3 # the timeout of HTTP/gRPC request in dtm -# UpdateBranchAsyncGoroutineNum: 1 # num of async goroutine to update branch status # LogLevel: 'info' # default: info. can be debug|info|warn|error # HttpPort: 36789 # GrpcPort: 36790 + +### advanced options +# UpdateBranchAsyncGoroutineNum: 1 # num of async goroutine to update branch status diff --git a/dtmcli/dtmimp/vars.go b/dtmcli/dtmimp/vars.go index d414b0b..3cf31d3 100644 --- a/dtmcli/dtmimp/vars.go +++ b/dtmcli/dtmimp/vars.go @@ -38,9 +38,6 @@ var PassthroughHeaders = []string{} var BarrierTableName = "dtm_barrier.barrier" func init() { - // RestyClient.SetTimeout(3 * time.Second) - // RestyClient.SetRetryCount(2) - // RestyClient.SetRetryWaitTime(1 * time.Second) RestyClient.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error { r.URL = MayReplaceLocalhost(r.URL) logger.Debugf("requesting: %s %s %s", r.Method, r.URL, MustMarshalString(r.Body)) diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index f1877c0..721c74b 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -66,6 +66,7 @@ type configType struct { TransCronInterval int64 `yaml:"TransCronInterval" default:"3"` TimeoutToFail int64 `yaml:"TimeoutToFail" default:"35"` RetryInterval int64 `yaml:"RetryInterval" default:"10"` + RequestTimeout int64 `yaml:"RequestTimeout" default:"3"` HTTPPort int64 `yaml:"HttpPort" default:"36789"` GrpcPort int64 `yaml:"GrpcPort" default:"36790"` MicroService MicroService `yaml:"MicroService"` diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index c8fba19..56f288c 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -7,11 +7,14 @@ package dtmsvr import ( + "context" "fmt" "net" "time" + "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/dtm-labs/dtm/dtmgrpc" "github.com/dtm-labs/dtm/dtmgrpc/dtmgimp" "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "github.com/dtm-labs/dtm/dtmutil" @@ -23,6 +26,12 @@ import ( // StartSvr StartSvr func StartSvr() { logger.Infof("start dtmsvr") + dtmcli.GetRestyClient().SetTimeout(time.Duration(conf.RequestTimeout) * time.Second) + dtmgrpc.AddUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + ctx2, cancel := context.WithTimeout(ctx, time.Duration(conf.RequestTimeout)*time.Second) + defer cancel() + return invoker(ctx2, method, req, reply, cc, opts...) + }) app := dtmutil.GetGinApp() app = httpMetrics(app) addRoute(app) From eb1395223d678e0a9f2ab0669eae37e9ac19e3c2 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 10 Jan 2022 18:28:29 +0800 Subject: [PATCH 104/124] change wait process gid to 4 --- test/types.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/types.go b/test/types.go index c583a28..0db969d 100644 --- a/test/types.go +++ b/test/types.go @@ -33,7 +33,7 @@ func waitTransProcessed(gid string) { case id := <-dtmsvr.TransProcessedTestChan: logger.FatalfIf(id != gid, "------- expecting: %s but %s found", gid, id) logger.Debugf("finish for gid %s", gid) - case <-time.After(time.Duration(time.Second * 3)): + case <-time.After(time.Duration(time.Second * 4)): logger.FatalfIf(true, "Wait Trans timeout") } } From 259d09654388bd70cb7a2bc5a5b6e7b6465c1b45 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Tue, 11 Jan 2022 17:35:14 +0800 Subject: [PATCH 105/124] saga rollback order keeped --- dtmsvr/trans_type_saga.go | 87 ++++++++++++++++++++++++++------------- test/busi/busi.go | 2 +- test/saga_test.go | 9 ++++ 3 files changed, 69 insertions(+), 29 deletions(-) diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index f2a88fd..b7d15ca 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -47,6 +47,7 @@ func (t *transSagaProcessor) GenBranches() []TransBranch { type cSagaCustom struct { Orders map[int][]int `json:"orders"` Concurrent bool `json:"concurrent"` + cOrders map[int][]int } type branchResult struct { @@ -64,9 +65,14 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } n := len(branches) - csc := cSagaCustom{Orders: map[int][]int{}} + csc := cSagaCustom{Orders: map[int][]int{}, cOrders: map[int][]int{}} if t.CustomData != "" { dtmimp.MustUnmarshalString(t.CustomData, &csc) + for k, v := range csc.Orders { + for _, b := range v { + csc.cOrders[b] = append(csc.cOrders[b], k) + } + } } if csc.Concurrent || t.TimeoutToFail > 0 { // when saga is not normal, update branch sync t.updateBranchSync = true @@ -83,9 +89,9 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { rsAFailed++ } } - branchResults[i] = branchResult{status: branches[i].Status, op: branches[i].Op} + branchResults[i] = branchResult{index: i, status: branches[i].Status, op: branches[i].Op} } - isPreconditionsSucceed := func(current int) bool { + shouldRun := func(current int) bool { // if !csc.Concurrent,then check the branch in previous step is succeed if !csc.Concurrent && current >= 2 && branches[current-2].Status != dtmcli.StatusSucceed { return false @@ -98,7 +104,26 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } return true } - + shouldRollback := func(current int) bool { + rollbacked := func(i int) bool { + // current compensate op rollbacked or related action still prepared + return branches[i].Status == dtmcli.StatusSucceed || branches[i+1].Status == dtmcli.StatusPrepared + } + if rollbacked(current) { + return false + } + // if !csc.Concurrent,then check the branch in next step is rollbacked + if !csc.Concurrent && current < n-2 && !rollbacked(current+2) { + return false + } + // if csc.concurrent, then check the cOrders. origin one step correspond to 2 step in dtmsvr + for _, next := range csc.cOrders[current/2] { + if !rollbacked(next) { + return false + } + } + return true + } resultChan := make(chan branchResult, n) asyncExecBranch := func(i int) { var err error @@ -115,14 +140,24 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } pickToRunActions := func() []int { toRun := []int{} - for current := 0; current < n; current++ { + for current := 1; current < n; current += 2 { + br := &branchResults[current] + if !br.started && br.status == dtmcli.StatusPrepared && shouldRun(current) { + toRun = append(toRun, current) + } + } + logger.Debugf("toRun picked for action is: %v branchResults: %v compensate orders: %v", toRun, branchResults, csc.cOrders) + return toRun + } + pickToRunCompensates := func() []int { + toRun := []int{} + for current := n - 2; current >= 0; current -= 2 { br := &branchResults[current] - if br.op == dtmcli.BranchAction && !br.started && isPreconditionsSucceed(current) && - br.status == dtmcli.StatusPrepared { + if !br.started && br.status == dtmcli.StatusPrepared && shouldRollback(current) { toRun = append(toRun, current) } } - logger.Debugf("toRun picked for action is: %v", toRun) + logger.Debugf("toRun picked for compensate is: %v branchResults: %v compensate orders: %v", toRun, branchResults, csc.cOrders) return toRun } runBranches := func(toRun []int) { @@ -134,20 +169,6 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { go asyncExecBranch(b) } } - pickAndRunCompensates := func(toRunActions []int) { - for _, b := range toRunActions { - // these branches may have run. so flag them to status succeed, then run the corresponding - // compensate - branchResults[b].status = dtmcli.StatusSucceed - } - for i, b := range branchResults { - if b.op == dtmcli.BranchCompensate && b.status != dtmcli.StatusSucceed && - branchResults[i+1].status != dtmcli.StatusPrepared { - rsCToStart++ - go asyncExecBranch(i) - } - } - } waitDoneOnce := func() { select { case r := <-resultChan: @@ -172,7 +193,8 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } } - for t.Status == dtmcli.StatusSubmitted && !t.isTimeout() && rsAFailed == 0 && rsADone != rsAToStart { + timeLimit := time.Now().Add(time.Duration(conf.RequestTimeout+2) * time.Second) + for time.Now().Before(timeLimit) && t.Status == dtmcli.StatusSubmitted && !t.isTimeout() && rsAFailed == 0 { toRun := pickToRunActions() runBranches(toRun) if rsADone == rsAStarted { // no branch is running, so break @@ -187,13 +209,22 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { if t.Status == dtmcli.StatusSubmitted && (rsAFailed > 0 || t.isTimeout()) { t.changeStatus(dtmcli.StatusAborting) } - if t.Status == dtmcli.StatusAborting { - toRun := pickToRunActions() - pickAndRunCompensates(toRun) - for rsCDone != rsCToStart { - waitDoneOnce() + for i, b := range branchResults { + if b.op == dtmcli.BranchCompensate && b.status != dtmcli.StatusSucceed && + branchResults[i+1].status != dtmcli.StatusPrepared { + rsCToStart++ } } + logger.Debugf("rsCToStart: %d", rsCToStart) + for time.Now().Before(timeLimit) && t.Status == dtmcli.StatusAborting { + toRun := pickToRunCompensates() + runBranches(toRun) + if rsCDone == rsCToStart { // no branch is running, so break + break + } + logger.Debugf("rsCDone: %d rsCToStart: %d", rsCDone, rsCToStart) + waitDoneOnce() + } if t.Status == dtmcli.StatusAborting && rsCToStart == rsCSucceed { t.changeStatus(dtmcli.StatusFailed) } diff --git a/test/busi/busi.go b/test/busi/busi.go index 5a41192..3fda2f2 100644 --- a/test/busi/busi.go +++ b/test/busi/busi.go @@ -24,7 +24,7 @@ func handleGrpcBusiness(in *BusiReq, result1 string, result2 string, busi string } else if res == dtmcli.ResultFailure { return status.New(codes.Aborted, dtmcli.ResultFailure).Err() } else if res == dtmcli.ResultOngoing { - return status.New(codes.Aborted, dtmcli.ResultOngoing).Err() + return status.New(codes.FailedPrecondition, dtmcli.ResultOngoing).Err() } return status.New(codes.Internal, fmt.Sprintf("unknow result %s", res)).Err() } diff --git a/test/saga_test.go b/test/saga_test.go index 9b6f0e4..b7afd3a 100644 --- a/test/saga_test.go +++ b/test/saga_test.go @@ -24,6 +24,15 @@ func TestSagaNormal(t *testing.T) { assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) } +func TestSagaRollback(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, true) + err := saga.Submit() + assert.Nil(t, err) + waitTransProcessed(saga.Gid) + assert.Equal(t, []string{StatusSucceed, StatusSucceed, StatusSucceed, StatusFailed}, getBranchesStatus(saga.Gid)) + assert.Equal(t, StatusFailed, getTransStatus(saga.Gid)) +} + func TestSagaOngoingSucceed(t *testing.T) { saga := genSaga(dtmimp.GetFuncName(), false, false) busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) From 60698ac807719aa8087176197df39898153b23e1 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Tue, 11 Jan 2022 18:25:51 +0800 Subject: [PATCH 106/124] fix cOrders test in shouldRollback --- dtmsvr/trans_type_saga.go | 2 +- test/saga_concurrent_test.go | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index b7d15ca..7f43934 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -118,7 +118,7 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } // if csc.concurrent, then check the cOrders. origin one step correspond to 2 step in dtmsvr for _, next := range csc.cOrders[current/2] { - if !rollbacked(next) { + if !rollbacked(2 * next) { return false } } diff --git a/test/saga_concurrent_test.go b/test/saga_concurrent_test.go index e8c32c0..5c33770 100644 --- a/test/saga_concurrent_test.go +++ b/test/saga_concurrent_test.go @@ -51,6 +51,15 @@ func TestSagaConRollbackOrder(t *testing.T) { assert.Equal(t, []string{StatusSucceed, StatusFailed, StatusPrepared, StatusPrepared}, getBranchesStatus(sagaCon.Gid)) } +func TestSagaConRollbackOrder2(t *testing.T) { + sagaCon := genSagaCon(dtmimp.GetFuncName(), false, true) + sagaCon.AddBranchOrder(1, []int{0}) + err := sagaCon.Submit() + assert.Nil(t, err) + waitTransProcessed(sagaCon.Gid) + assert.Equal(t, StatusFailed, getTransStatus(sagaCon.Gid)) + assert.Equal(t, []string{StatusSucceed, StatusSucceed, StatusSucceed, StatusFailed}, getBranchesStatus(sagaCon.Gid)) +} func TestSagaConCommittedOngoing(t *testing.T) { sagaCon := genSagaCon(dtmimp.GetFuncName(), false, false) busi.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) From d355fc80fb46e40d033b6e88ba29296bd88d0e13 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Tue, 11 Jan 2022 20:00:20 +0800 Subject: [PATCH 107/124] fix shouldrollback --- dtmsvr/cron.go | 4 +++- dtmsvr/trans_type_saga.go | 30 ++++++++++++++++++++---------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index 8ffff26..a768fa1 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -7,11 +7,13 @@ package dtmsvr import ( + "errors" "fmt" "math/rand" "runtime/debug" "time" + "github.com/dtm-labs/dtm/dtmcli" "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" ) @@ -33,7 +35,7 @@ func CronTransOnce() (gid string) { trans.WaitResult = true branches := GetStore().FindBranches(gid) err := trans.Process(branches) - dtmimp.E2P(err) + dtmimp.PanicIf(err != nil && !errors.Is(err, dtmcli.ErrFailure), err) return } diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index 7f43934..15f8c6b 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -93,12 +93,12 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } shouldRun := func(current int) bool { // if !csc.Concurrent,then check the branch in previous step is succeed - if !csc.Concurrent && current >= 2 && branches[current-2].Status != dtmcli.StatusSucceed { + if !csc.Concurrent && current >= 2 && branchResults[current-2].status != dtmcli.StatusSucceed { return false } // if csc.concurrent, then check the Orders. origin one step correspond to 2 step in dtmsvr for _, pre := range csc.Orders[current/2] { - if branches[pre*2+1].Status != dtmcli.StatusSucceed { + if branchResults[pre*2+1].status != dtmcli.StatusSucceed { return false } } @@ -107,7 +107,7 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { shouldRollback := func(current int) bool { rollbacked := func(i int) bool { // current compensate op rollbacked or related action still prepared - return branches[i].Status == dtmcli.StatusSucceed || branches[i+1].Status == dtmcli.StatusPrepared + return branchResults[i].status == dtmcli.StatusSucceed || branchResults[i+1].status == dtmcli.StatusPrepared } if rollbacked(current) { return false @@ -192,7 +192,21 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { logger.Debugf("wait once for done") } } - + prepareToCompensate := func() { + toRunActions := pickToRunActions() + for _, b := range toRunActions { + // these branches may have run. so flag them to status succeed, then run the corresponding + // compensate + branchResults[b].status = dtmcli.StatusSucceed + } + for i, b := range branchResults { + if b.op == dtmcli.BranchCompensate && b.status != dtmcli.StatusSucceed && + branchResults[i+1].status != dtmcli.StatusPrepared { + rsCToStart++ + } + } + logger.Debugf("rsCToStart: %d branchResults: %v", rsCToStart, branchResults) + } timeLimit := time.Now().Add(time.Duration(conf.RequestTimeout+2) * time.Second) for time.Now().Before(timeLimit) && t.Status == dtmcli.StatusSubmitted && !t.isTimeout() && rsAFailed == 0 { toRun := pickToRunActions() @@ -209,13 +223,9 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { if t.Status == dtmcli.StatusSubmitted && (rsAFailed > 0 || t.isTimeout()) { t.changeStatus(dtmcli.StatusAborting) } - for i, b := range branchResults { - if b.op == dtmcli.BranchCompensate && b.status != dtmcli.StatusSucceed && - branchResults[i+1].status != dtmcli.StatusPrepared { - rsCToStart++ - } + if t.Status == dtmcli.StatusAborting { + prepareToCompensate() } - logger.Debugf("rsCToStart: %d", rsCToStart) for time.Now().Before(timeLimit) && t.Status == dtmcli.StatusAborting { toRun := pickToRunCompensates() runBranches(toRun) From 3e9a4ac7cbc3c2615b778188d3e9fdb63383d4bb Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 12 Jan 2022 17:42:26 +0800 Subject: [PATCH 108/124] update rollback image --- README-cn.md | 2 +- README.md | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/README-cn.md b/README-cn.md index fd3f602..ac76dc6 100644 --- a/README-cn.md +++ b/README-cn.md @@ -118,7 +118,7 @@ go run main.go 再运行这个例子,整个事务最终失败,时序图如下: -![saga_rollback](https://pic3.zhimg.com/80/v2-8d8f1476be8a1e2e09ce97a89b4116c2_1440w.jpg) + 在转入操作失败的情况下,TransIn和TransOut的补偿操作被执行,保证了最终的余额和转账前是一样的。 diff --git a/README.md b/README.md index 760cff9..ac76dc6 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ go run main.go 再运行这个例子,整个事务最终失败,时序图如下: -![saga_rollback](https://pic3.zhimg.com/80/v2-8d8f1476be8a1e2e09ce97a89b4116c2_1440w.jpg) + 在转入操作失败的情况下,TransIn和TransOut的补偿操作被执行,保证了最终的余额和转账前是一样的。 @@ -133,6 +133,7 @@ dtm官方公众号:分布式事务,大量干货分享,以及dtm的最新 ![yedf2008](http://service.ivydad.com/cover/dubbingb6b5e2c0-2d2a-cd59-f7c5-c6b90aceb6f1.jpeg) +### github 作者github: [https://github.com/yedf2](https://github.com/yedf2) 欢迎使用[dtm](https://github.com/dtm-labs/dtm),或者通过dtm学习实践分布式事务相关知识,欢迎star支持我们 From fa4c439cada8d70fdf4d0974873b46dcf510a9d7 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 12 Jan 2022 21:54:00 +0800 Subject: [PATCH 109/124] update doc links --- README-cn.md | 6 +++--- README.md | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README-cn.md b/README-cn.md index ac76dc6..b616b87 100644 --- a/README-cn.md +++ b/README-cn.md @@ -58,16 +58,16 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ## [教程与文档](https://dtm.pub) -## [各语言客户端及示例](https://dtm.pub/summary/code.html#go) +## [各语言客户端及示例](https://dtm.pub/ref/sdk.html#go) ## 微服务框架支持 - [go-zero](https://github.com/zeromicro/go-zero):一开源就非常火爆的微服务框架,首家接入dtm的微服务框架。感谢go-zero作者[kevwan](https://github.com/kevwan)的大力支持 - [polaris](https://github.com/polarismesh/polaris): 腾讯开源的注册发现组件,以及在其上构建的微服务框架。感谢腾讯同学[ychensha](https://github.com/ychensha)的PR -- 其他:看用户需求量,择机接入,参见[微服务支持](https://dtm.pub/protocol/intro.html) +- 其他:看用户需求量,择机接入,参见[微服务支持](https://dtm.pub/ref/proto.html) ## 快速开始 -如果您不是Go语言,可以跳转[各语言客户端及示例](https://dtm.pub/summary/code.html#go),里面有相关的快速开始示例 +如果您不是Go语言,可以跳转[各语言客户端及示例](https://dtm.pub/ref/sdk.html#go),里面有相关的快速开始示例 ### 运行dtm diff --git a/README.md b/README.md index ac76dc6..b616b87 100644 --- a/README.md +++ b/README.md @@ -58,16 +58,16 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ## [教程与文档](https://dtm.pub) -## [各语言客户端及示例](https://dtm.pub/summary/code.html#go) +## [各语言客户端及示例](https://dtm.pub/ref/sdk.html#go) ## 微服务框架支持 - [go-zero](https://github.com/zeromicro/go-zero):一开源就非常火爆的微服务框架,首家接入dtm的微服务框架。感谢go-zero作者[kevwan](https://github.com/kevwan)的大力支持 - [polaris](https://github.com/polarismesh/polaris): 腾讯开源的注册发现组件,以及在其上构建的微服务框架。感谢腾讯同学[ychensha](https://github.com/ychensha)的PR -- 其他:看用户需求量,择机接入,参见[微服务支持](https://dtm.pub/protocol/intro.html) +- 其他:看用户需求量,择机接入,参见[微服务支持](https://dtm.pub/ref/proto.html) ## 快速开始 -如果您不是Go语言,可以跳转[各语言客户端及示例](https://dtm.pub/summary/code.html#go),里面有相关的快速开始示例 +如果您不是Go语言,可以跳转[各语言客户端及示例](https://dtm.pub/ref/sdk.html#go),里面有相关的快速开始示例 ### 运行dtm From fb9908b0e06445f26538c34d645a6217475ce63a Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Wed, 12 Jan 2022 22:03:50 +0800 Subject: [PATCH 110/124] add readme for imp --- dtmcli/dtmimp/README.md | 2 ++ dtmgrpc/dtmgimp/README.md | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 dtmcli/dtmimp/README.md create mode 100644 dtmgrpc/dtmgimp/README.md diff --git a/dtmcli/dtmimp/README.md b/dtmcli/dtmimp/README.md new file mode 100644 index 0000000..ba4fb25 --- /dev/null +++ b/dtmcli/dtmimp/README.md @@ -0,0 +1,2 @@ +## 注意 +此包带imp后缀,主要被dtm内部使用,相关接口可能会发生变更,请勿使用这里的接口 \ No newline at end of file diff --git a/dtmgrpc/dtmgimp/README.md b/dtmgrpc/dtmgimp/README.md new file mode 100644 index 0000000..ba4fb25 --- /dev/null +++ b/dtmgrpc/dtmgimp/README.md @@ -0,0 +1,2 @@ +## 注意 +此包带imp后缀,主要被dtm内部使用,相关接口可能会发生变更,请勿使用这里的接口 \ No newline at end of file From 05c7181111d5414268100743b317bbe64599b2dd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 13 Jan 2022 01:34:32 +0000 Subject: [PATCH 111/124] Bump github.com/gin-gonic/gin from 1.6.3 to 1.7.0 Bumps [github.com/gin-gonic/gin](https://github.com/gin-gonic/gin) from 1.6.3 to 1.7.0. - [Release notes](https://github.com/gin-gonic/gin/releases) - [Changelog](https://github.com/gin-gonic/gin/blob/master/CHANGELOG.md) - [Commits](https://github.com/gin-gonic/gin/compare/v1.6.3...v1.7.0) --- updated-dependencies: - dependency-name: github.com/gin-gonic/gin dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 9527249..ef2be14 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/dtm-labs/dtmdriver-gozero v0.0.1 github.com/dtm-labs/dtmdriver-polaris v0.0.2 github.com/dtm-labs/dtmdriver-protocol1 v0.0.1 - github.com/gin-gonic/gin v1.6.3 + github.com/gin-gonic/gin v1.7.0 github.com/go-redis/redis/v8 v8.11.4 github.com/go-resty/resty/v2 v2.7.0 github.com/go-sql-driver/mysql v1.6.0 diff --git a/go.sum b/go.sum index 08905f5..297f49a 100644 --- a/go.sum +++ b/go.sum @@ -127,8 +127,8 @@ github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.0 h1:jGB9xAJQ12AIGNB4HguylppmDK1Am9ppF7XnGXXJuoU= +github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -155,8 +155,8 @@ github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8c github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0 h1:KgJ0snyC2R9VXYN2rneOtQcw5aHQB1Vv0sFl1UcHBOY= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= From e25977996819b64a41a59ce96da229f44fe92ce4 Mon Sep 17 00:00:00 2001 From: yedf2 <43027375+yedf2@users.noreply.github.com> Date: Thu, 13 Jan 2022 09:34:53 +0800 Subject: [PATCH 112/124] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 70 +++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 0000000..06ea3c7 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '25 19 * * 2' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'go' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 6d42505ad7f08fb35daf1b85e3abc64f69b137c3 Mon Sep 17 00:00:00 2001 From: fsdfsffdsf Date: Fri, 14 Jan 2022 17:22:52 +0800 Subject: [PATCH 113/124] optimization: reduce network interaction in db request --- dtmcli/dtmimp/utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmcli/dtmimp/utils.go b/dtmcli/dtmimp/utils.go index 8038b61..d4fb44e 100644 --- a/dtmcli/dtmimp/utils.go +++ b/dtmcli/dtmimp/utils.go @@ -196,7 +196,7 @@ func GetDsn(conf DBConf) string { host := MayReplaceLocalhost(conf.Host) driver := conf.Driver dsn := map[string]string{ - "mysql": fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&loc=Local", + "mysql": fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=true&loc=Local&interpolateParams=true", conf.User, conf.Password, host, conf.Port, ""), "postgres": fmt.Sprintf("host=%s user=%s password=%s dbname='%s' port=%d sslmode=disable", host, conf.User, conf.Password, "", conf.Port), From 4e11fffd868c655d88cb1bfb89d2fee0b2bd4b62 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 14 Jan 2022 20:33:17 +0800 Subject: [PATCH 114/124] barrier add RedisCheckAdjustAmount --- dtmcli/barrier.go | 45 +++++++++++++++++++++++++++++-- test/busi/barrier.go | 23 ++++++++++++++++ test/busi/base_types.go | 13 ++++++++- test/busi/utils.go | 27 +++++++++++++++++++ test/msg_barrier_test.go | 20 +++++++------- test/msg_grpc_barrier_test.go | 8 +++--- test/saga_barrier_redis_test.go | 48 +++++++++++++++++++++++++++++++++ test/tcc_barrier_test.go | 19 +++++++++---- test/types.go | 18 ++++++------- 9 files changed, 190 insertions(+), 31 deletions(-) create mode 100644 test/saga_barrier_redis_test.go diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index c264bd6..2e29383 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -13,6 +13,7 @@ import ( "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmcli/logger" + "github.com/go-redis/redis/v8" ) // BarrierBusiFunc type for busi func @@ -76,12 +77,12 @@ func (bb *BranchBarrier) Call(tx *sql.Tx, busiCall BarrierBusiFunc) (rerr error) } }() ti := bb - originType := map[string]string{ + originOp := map[string]string{ BranchCancel: BranchTry, BranchCompensate: BranchAction, }[ti.Op] - originAffected, _ := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, originType, bid, ti.Op) + originAffected, _ := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, originOp, bid, ti.Op) currentAffected, rerr := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, ti.Op, bid, ti.Op) logger.Debugf("originAffected: %d currentAffected: %d", originAffected, currentAffected) if (ti.Op == BranchCancel || ti.Op == BranchCompensate) && originAffected > 0 || // 这个是空补偿 @@ -114,3 +115,43 @@ func (bb *BranchBarrier) QueryPrepared(db *sql.DB) error { } return err } + +// RedisCheckAdjustAmount check the value of key is valid and >= amount. then adjust the amount +func (bb *BranchBarrier) RedisCheckAdjustAmount(rd *redis.Client, key string, amount int, barrierExpire int) error { + bkey1 := fmt.Sprintf("%s-%s-%s-%s-%02d", key, bb.Gid, bb.BranchID, bb.Op, bb.BarrierID) + originOp := map[string]string{ + BranchCancel: BranchTry, + BranchCompensate: BranchAction, + }[bb.Op] + bkey2 := fmt.Sprintf("%s-%s-%s-%s-%02d", key, bb.Gid, bb.BranchID, originOp, bb.BarrierID) + v, err := rd.Eval(rd.Context(), ` -- RedisCheckAdjustAmount +local v = redis.call('GET', KEYS[1]) +local e1 = redis.call('GET', KEYS[2]) + +if v == false or v + ARGV[1] < 0 then + return 'FAILURE' +end + +if e1 ~= false then + return +end + +if ARGV[2] ~= '' then + local e2 = redis.call('GET', KEYS[3]) + if e2 ~= false then + return + end + redis.call('SET', KEYS[3], 'origin', 'EX', ARGV[3]) +end +redis.call('INCRBY', KEYS[1], ARGV[1]) +redis.call('SET', KEYS[2], 'op', 'EX', ARGV[3]) +`, []string{key, bkey1, bkey2}, amount, originOp, barrierExpire).Result() + logger.Debugf("lua return v: %v err: %v", v, err) + if err == redis.Nil { + err = nil + } + if err == nil && v == ResultFailure { + err = ErrFailure + } + return err +} diff --git a/test/busi/barrier.go b/test/busi/barrier.go index 46463f7..9d8c30f 100644 --- a/test/busi/barrier.go +++ b/test/busi/barrier.go @@ -70,16 +70,35 @@ func init() { return tccAdjustTrading(tx, TransInUID, -reqFrom(c).Amount) }) })) + app.POST(BusiAPI+"/SagaRedisTransIn", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), getRedisAccountKey(TransInUID), reqFrom(c).Amount, 7*86400) + })) + app.POST(BusiAPI+"/SagaRedisTransInCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), getRedisAccountKey(TransInUID), -reqFrom(c).Amount, 7*86400) + })) + app.POST(BusiAPI+"/SagaRedisTransOut", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), getRedisAccountKey(TransOutUID), -reqFrom(c).Amount, 7*86400) + })) + app.POST(BusiAPI+"/SagaRedisTransOutCom", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), getRedisAccountKey(TransOutUID), reqFrom(c).Amount, 7*86400) + })) app.POST(BusiAPI+"/TccBTransOutTry", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { req := reqFrom(c) if req.TransOutResult != "" { return dtmcli.String2DtmError(req.TransOutResult) } + if req.Store == "redis" { + return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), getRedisAccountKey(TransOutUID), req.Amount, 7*86400) + } + return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustTrading(tx, TransOutUID, -req.Amount) }) })) app.POST(BusiAPI+"/TccBTransOutConfirm", dtmutil.WrapHandler2(func(c *gin.Context) interface{} { + if reqFrom(c).Store == "redis" { + return nil + } return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustBalance(tx, TransOutUID, -reqFrom(c).Amount) }) @@ -90,6 +109,10 @@ func init() { // TccBarrierTransOutCancel will be use in test func TccBarrierTransOutCancel(c *gin.Context) interface{} { + req := reqFrom(c) + if req.Store == "redis" { + return MustBarrierFromGin(c).RedisCheckAdjustAmount(RedisGet(), getRedisAccountKey(TransOutUID), -req.Amount, 7*86400) + } return MustBarrierFromGin(c).Call(txGet(), func(tx *sql.Tx) error { return tccAdjustTrading(tx, TransOutUID, reqFrom(c).Amount) }) diff --git a/test/busi/base_types.go b/test/busi/base_types.go index 5aaaed9..38b332d 100644 --- a/test/busi/base_types.go +++ b/test/busi/base_types.go @@ -32,7 +32,13 @@ func (*UserAccount) TableName() string { return "dtm_busi.user_account" } -func GetBalanceByUid(uid int) int { +func GetBalanceByUid(uid int, store string) int { + if store == "redis" { + rd := RedisGet() + accA, err := rd.Get(rd.Context(), getRedisAccountKey(uid)).Result() + dtmimp.E2P(err) + return dtmimp.MustAtoi(accA) + } ua := UserAccount{} _ = dbGet().Must().Model(&ua).Where("user_id=?", uid).First(&ua) return dtmimp.MustAtoi(ua.Balance[:len(ua.Balance)-3]) @@ -43,6 +49,7 @@ type TransReq struct { Amount int `json:"amount"` TransInResult string `json:"trans_in_result"` TransOutResult string `json:"trans_out_Result"` + Store string `json:"store"` // default mysql, value can be mysql|redis } func (t *TransReq) String() string { @@ -119,3 +126,7 @@ type mainSwitchType struct { // MainSwitch controls busi success or fail var MainSwitch mainSwitchType + +func getRedisAccountKey(uid int) string { + return fmt.Sprintf("{a}-redis-account-key-%d", uid) +} diff --git a/test/busi/utils.go b/test/busi/utils.go index bc5a77f..9441d07 100644 --- a/test/busi/utils.go +++ b/test/busi/utils.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "strings" + sync "sync" "time" "github.com/dtm-labs/dtm/dtmcli" @@ -15,6 +16,7 @@ import ( "github.com/dtm-labs/dtm/dtmgrpc/dtmgpb" "github.com/dtm-labs/dtm/dtmutil" "github.com/gin-gonic/gin" + "github.com/go-redis/redis/v8" "github.com/go-resty/resty/v2" grpc "google.golang.org/grpc" "google.golang.org/grpc/metadata" @@ -113,3 +115,28 @@ func oldWrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc } } } + +var ( + rdb *redis.Client + once sync.Once +) + +func RedisGet() *redis.Client { + once.Do(func() { + logger.Debugf("connecting to client redis") + rdb = redis.NewClient(&redis.Options{ + Addr: "localhost:6379", + Username: "root", + Password: "", + }) + }) + return rdb +} + +func SetRedisBothAccount(accountA int, accountB int) { + rd := RedisGet() + _, err := rd.Set(rd.Context(), getRedisAccountKey(TransOutUID), accountA, 0).Result() + dtmimp.E2P(err) + _, err = rd.Set(rd.Context(), getRedisAccountKey(TransInUID), accountB, 0).Result() + dtmimp.E2P(err) +} diff --git a/test/msg_barrier_test.go b/test/msg_barrier_test.go index fe586e0..cd274fb 100644 --- a/test/msg_barrier_test.go +++ b/test/msg_barrier_test.go @@ -15,7 +15,7 @@ import ( ) func TestMsgPrepareAndSubmit(t *testing.T) { - before := getBeforeBalances() + before := getBeforeBalances("mysql") gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). @@ -27,11 +27,11 @@ func TestMsgPrepareAndSubmit(t *testing.T) { waitTransProcessed(msg.Gid) assert.Equal(t, []string{StatusSucceed}, getBranchesStatus(msg.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) - assertNotSameBalance(t, before) + assertNotSameBalance(t, before, "mysql") } func TestMsgPrepareAndSubmitBusiFailed(t *testing.T) { - before := getBeforeBalances() + before := getBeforeBalances("mysql") gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). @@ -40,11 +40,11 @@ func TestMsgPrepareAndSubmitBusiFailed(t *testing.T) { return errors.New("an error") }) assert.Error(t, err) - assertSameBalance(t, before) + assertSameBalance(t, before, "mysql") } func TestMsgPrepareAndSubmitPrepareFailed(t *testing.T) { - before := getBeforeBalances() + before := getBeforeBalances("mysql") gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer+"not-exists", gid). @@ -53,14 +53,14 @@ func TestMsgPrepareAndSubmitPrepareFailed(t *testing.T) { return busi.SagaAdjustBalance(tx, busi.TransOutUID, -req.Amount, "SUCCESS") }) assert.Error(t, err) - assertSameBalance(t, before) + assertSameBalance(t, before, "mysql") } func TestMsgPrepareAndSubmitCommitFailed(t *testing.T) { if conf.Store.IsDB() { // cannot patch tx.Commit, because Prepare also do Commit return } - before := getBeforeBalances() + before := getBeforeBalances("mysql") gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). @@ -77,14 +77,14 @@ func TestMsgPrepareAndSubmitCommitFailed(t *testing.T) { g.Unpatch() assert.Error(t, err) cronTransOnceForwardNow(180) - assertSameBalance(t, before) + assertSameBalance(t, before, "mysql") } func TestMsgPrepareAndSubmitCommitAfterFailed(t *testing.T) { if conf.Store.IsDB() { // cannot patch tx.Commit, because Prepare also do Commit return } - before := getBeforeBalances() + before := getBeforeBalances("mysql") gid := dtmimp.GetFuncName() req := busi.GenTransReq(30, false, false) msg := dtmcli.NewMsg(DtmServer, gid). @@ -101,5 +101,5 @@ func TestMsgPrepareAndSubmitCommitAfterFailed(t *testing.T) { }) assert.Error(t, err) cronTransOnceForwardNow(180) - assertNotSameBalance(t, before) + assertNotSameBalance(t, before, "mysql") } diff --git a/test/msg_grpc_barrier_test.go b/test/msg_grpc_barrier_test.go index ca1b93d..50edd6c 100644 --- a/test/msg_grpc_barrier_test.go +++ b/test/msg_grpc_barrier_test.go @@ -14,7 +14,7 @@ import ( ) func TestMsgGrpcPrepareAndSubmit(t *testing.T) { - before := getBeforeBalances() + before := getBeforeBalances("mysql") gid := dtmimp.GetFuncName() req := busi.GenBusiReq(30, false, false) msg := dtmgrpc.NewMsgGrpc(DtmGrpcServer, gid). @@ -26,14 +26,14 @@ func TestMsgGrpcPrepareAndSubmit(t *testing.T) { waitTransProcessed(msg.Gid) assert.Equal(t, []string{StatusSucceed}, getBranchesStatus(msg.Gid)) assert.Equal(t, StatusSucceed, getTransStatus(msg.Gid)) - assertNotSameBalance(t, before) + assertNotSameBalance(t, before, "mysql") } func TestMsgGrpcPrepareAndSubmitCommitAfterFailed(t *testing.T) { if conf.Store.IsDB() { // cannot patch tx.Commit, because Prepare also do Commit return } - before := getBeforeBalances() + before := getBeforeBalances("mysql") gid := dtmimp.GetFuncName() req := busi.GenBusiReq(30, false, false) msg := dtmgrpc.NewMsgGrpc(DtmGrpcServer, gid). @@ -50,5 +50,5 @@ func TestMsgGrpcPrepareAndSubmitCommitAfterFailed(t *testing.T) { }) assert.Error(t, err) cronTransOnceForwardNow(180) - assertNotSameBalance(t, before) + assertNotSameBalance(t, before, "mysql") } diff --git a/test/saga_barrier_redis_test.go b/test/saga_barrier_redis_test.go new file mode 100644 index 0000000..c37dd29 --- /dev/null +++ b/test/saga_barrier_redis_test.go @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 yedf. All rights reserved. + * Use of this source code is governed by a BSD-style + * license that can be found in the LICENSE file. + */ + +package test + +import ( + "testing" + + "github.com/dtm-labs/dtm/dtmcli" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" + "github.com/dtm-labs/dtm/test/busi" + "github.com/stretchr/testify/assert" +) + +func TestSagaBarrierRedisNormal(t *testing.T) { + busi.SetRedisBothAccount(100, 100) + before := getBeforeBalances("redis") + saga := genSagaBarrierRedis(dtmimp.GetFuncName()) + err := saga.Submit() + assert.Nil(t, err) + waitTransProcessed(saga.Gid) + assert.Equal(t, []string{StatusPrepared, StatusSucceed, StatusPrepared, StatusSucceed}, getBranchesStatus(saga.Gid)) + assert.Equal(t, StatusSucceed, getTransStatus(saga.Gid)) + assertNotSameBalance(t, before, "redis") +} + +func TestSagaBarrierRedisRollback(t *testing.T) { + busi.SetRedisBothAccount(20, 20) + before := getBeforeBalances("redis") + saga := genSagaBarrierRedis(dtmimp.GetFuncName()) + err := saga.Submit() + assert.Nil(t, err) + waitTransProcessed(saga.Gid) + assert.Equal(t, StatusFailed, getTransStatus(saga.Gid)) + assert.Equal(t, []string{StatusSucceed, StatusSucceed, StatusSucceed, StatusFailed}, getBranchesStatus(saga.Gid)) + assertSameBalance(t, before, "redis") +} + +func genSagaBarrierRedis(gid string) *dtmcli.Saga { + req := busi.GenTransReq(30, false, false) + req.Store = "redis" + return dtmcli.NewSaga(DtmServer, gid). + Add(Busi+"/SagaRedisTransIn", Busi+"/SagaRedisTransInCom", req). + Add(Busi+"/SagaRedisTransOut", Busi+"/SagaRedisTransOutCom", req) +} diff --git a/test/tcc_barrier_test.go b/test/tcc_barrier_test.go index 2a4ec94..8a1ae57 100644 --- a/test/tcc_barrier_test.go +++ b/test/tcc_barrier_test.go @@ -50,14 +50,23 @@ func TestTccBarrierRollback(t *testing.T) { assert.Equal(t, []string{StatusSucceed, StatusPrepared, StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) } -func TestTccBarrierDisorder(t *testing.T) { - before := getBeforeBalances() +func TestTccBarrierDisorderMysql(t *testing.T) { + runTestTccBarrierDisorder(t, "mysql") +} + +func TestTccBarrierDisorderRedis(t *testing.T) { + busi.SetRedisBothAccount(200, 200) + runTestTccBarrierDisorder(t, "redis") +} + +func runTestTccBarrierDisorder(t *testing.T, store string) { + before := getBeforeBalances(store) cancelFinishedChan := make(chan string, 2) cancelCanReturnChan := make(chan string, 2) - gid := dtmimp.GetFuncName() + gid := dtmimp.GetFuncName() + store cronFinished := make(chan string, 2) err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { - body := &busi.TransReq{Amount: 30} + body := &busi.TransReq{Amount: 30, Store: store} tryURL := Busi + "/TccBTransOutTry" confirmURL := Busi + "/TccBTransOutConfirm" cancelURL := Busi + "/TccBSleepCancel" @@ -122,7 +131,7 @@ func TestTccBarrierDisorder(t *testing.T) { assert.Error(t, err, fmt.Errorf("a cancelled tcc")) assert.Equal(t, []string{StatusSucceed, StatusPrepared}, getBranchesStatus(gid)) assert.Equal(t, StatusFailed, getTransStatus(gid)) - assertSameBalance(t, before) + assertSameBalance(t, before, store) } func TestTccBarrierPanic(t *testing.T) { diff --git a/test/types.go b/test/types.go index 0db969d..adff1a6 100644 --- a/test/types.go +++ b/test/types.go @@ -83,22 +83,22 @@ const ( StatusAborting = dtmcli.StatusAborting ) -func getBeforeBalances() []int { - b1 := busi.GetBalanceByUid(busi.TransOutUID) - b2 := busi.GetBalanceByUid(busi.TransInUID) +func getBeforeBalances(store string) []int { + b1 := busi.GetBalanceByUid(busi.TransOutUID, store) + b2 := busi.GetBalanceByUid(busi.TransInUID, store) return []int{b1, b2} } -func assertSameBalance(t *testing.T, before []int) { - b1 := busi.GetBalanceByUid(busi.TransOutUID) - b2 := busi.GetBalanceByUid(busi.TransInUID) +func assertSameBalance(t *testing.T, before []int, store string) { + b1 := busi.GetBalanceByUid(busi.TransOutUID, store) + b2 := busi.GetBalanceByUid(busi.TransInUID, store) assert.Equal(t, before[0], b1) assert.Equal(t, before[1], b2) } -func assertNotSameBalance(t *testing.T, before []int) { - b1 := busi.GetBalanceByUid(busi.TransOutUID) - b2 := busi.GetBalanceByUid(busi.TransInUID) +func assertNotSameBalance(t *testing.T, before []int, store string) { + b1 := busi.GetBalanceByUid(busi.TransOutUID, store) + b2 := busi.GetBalanceByUid(busi.TransInUID, store) assert.NotEqual(t, before[0], b1) assert.Equal(t, before[0]+before[1], b1+b2) } From 52123493241f45671078995001d64971e4687692 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 14 Jan 2022 20:53:50 +0800 Subject: [PATCH 115/124] fix RedisCheckAdjustAmount --- dtmcli/barrier.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index 2e29383..c2b66d1 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -136,15 +136,16 @@ if e1 ~= false then return end +redis.call('SET', KEYS[2], 'op', 'EX', ARGV[3]) + if ARGV[2] ~= '' then local e2 = redis.call('GET', KEYS[3]) - if e2 ~= false then + if e2 == false then + redis.call('SET', KEYS[3], 'rollback', 'EX', ARGV[3]) return end - redis.call('SET', KEYS[3], 'origin', 'EX', ARGV[3]) end redis.call('INCRBY', KEYS[1], ARGV[1]) -redis.call('SET', KEYS[2], 'op', 'EX', ARGV[3]) `, []string{key, bkey1, bkey2}, amount, originOp, barrierExpire).Result() logger.Debugf("lua return v: %v err: %v", v, err) if err == redis.Nil { From fe227a03d6f0cdcffb38e61a3179085fe0640a59 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 14 Jan 2022 21:21:39 +0800 Subject: [PATCH 116/124] reset redis barrier data --- test/busi/startup.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/busi/startup.go b/test/busi/startup.go index 0c6e329..2b40a5c 100644 --- a/test/busi/startup.go +++ b/test/busi/startup.go @@ -1,8 +1,10 @@ package busi import ( + "context" "fmt" + "github.com/dtm-labs/dtm/dtmcli/dtmimp" "github.com/dtm-labs/dtm/dtmutil" "github.com/gin-gonic/gin" ) @@ -20,4 +22,6 @@ func PopulateDB(skipDrop bool) { dtmutil.RunSQLScript(BusiConf, file, skipDrop) file = fmt.Sprintf("%s/dtmcli.barrier.%s.sql", dtmutil.GetSQLDir(), BusiConf.Driver) dtmutil.RunSQLScript(BusiConf, file, skipDrop) + _, err := RedisGet().FlushAll(context.Background()).Result() // redis barrier need clear + dtmimp.E2P(err) } From aa8d48183a829594eb3a53bf7b3b50fe3edb9373 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 14 Jan 2022 21:51:18 +0800 Subject: [PATCH 117/124] use started not toRun --- dtmsvr/trans_type_saga.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/dtmsvr/trans_type_saga.go b/dtmsvr/trans_type_saga.go index 15f8c6b..513190c 100644 --- a/dtmsvr/trans_type_saga.go +++ b/dtmsvr/trans_type_saga.go @@ -193,11 +193,13 @@ func (t *transSagaProcessor) ProcessOnce(branches []TransBranch) error { } } prepareToCompensate := func() { - toRunActions := pickToRunActions() - for _, b := range toRunActions { + _ = pickToRunActions() // flag started + for i := 1; i < len(branchResults); i += 2 { // these branches may have run. so flag them to status succeed, then run the corresponding // compensate - branchResults[b].status = dtmcli.StatusSucceed + if branchResults[i].started && branchResults[i].status == dtmcli.StatusPrepared { + branchResults[i].status = dtmcli.StatusSucceed + } } for i, b := range branchResults { if b.op == dtmcli.BranchCompensate && b.status != dtmcli.StatusSucceed && From 5413b0d2bc203ec749911d5ac7d9da10c44b2f82 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Sat, 15 Jan 2022 22:16:29 +0800 Subject: [PATCH 118/124] move Prepare outof CallWithDB --- dtmcli/msg.go | 14 ++++++++------ dtmsvr/api.go | 4 ++++ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/dtmcli/msg.go b/dtmcli/msg.go index 66ac5eb..6fba805 100644 --- a/dtmcli/msg.go +++ b/dtmcli/msg.go @@ -44,13 +44,15 @@ func (s *Msg) Submit() error { func (s *Msg) PrepareAndSubmit(queryPrepared string, db *sql.DB, busiCall BarrierBusiFunc) error { bb, err := BarrierFrom(s.TransType, s.Gid, "00", "msg") // a special barrier for msg QueryPrepared if err == nil { - err = bb.CallWithDB(db, func(tx *sql.Tx) error { - err := busiCall(tx) - if err == nil { - err = s.Prepare(queryPrepared) + err = s.Prepare(queryPrepared) + } + if err == nil { + defer func() { + if err != nil && bb.QueryPrepared(db) == ErrFailure { + _ = dtmimp.TransCallDtm(&s.TransBase, s, "abort") } - return err - }) + }() + err = bb.CallWithDB(db, busiCall) } if err == nil { err = s.Submit() diff --git a/dtmsvr/api.go b/dtmsvr/api.go index 83a1056..f2855f9 100644 --- a/dtmsvr/api.go +++ b/dtmsvr/api.go @@ -46,6 +46,10 @@ func svcPrepare(t *TransGlobal) interface{} { func svcAbort(t *TransGlobal) interface{} { dbt := GetTransGlobal(t.Gid) + if dbt.TransType == "msg" && dbt.Status == dtmcli.StatusPrepared { + dbt.changeStatus(dtmcli.StatusFailed) + return nil + } if t.TransType != "xa" && t.TransType != "tcc" || dbt.Status != dtmcli.StatusPrepared && dbt.Status != dtmcli.StatusAborting { return fmt.Errorf("trans type: '%s' current status '%s', cannot abort. %w", dbt.TransType, dbt.Status, dtmcli.ErrFailure) } From 693714f55e475fe758a95d8fd1c6ddd4dff57fd4 Mon Sep 17 00:00:00 2001 From: authurguo Date: Sun, 16 Jan 2022 21:39:56 +0800 Subject: [PATCH 119/124] fix config spell #182 --- dtmsvr/config/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 721c74b..2e84887 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -42,7 +42,7 @@ type Store struct { DataExpire int64 `yaml:"DataExpire" default:"604800"` // Trans data will expire in 7 days. only for redis/boltdb. RedisPrefix string `yaml:"RedisPrefix" default:"{a}"` // Redis storage prefix. store data to only one slot in cluster TransGlobalTable string `yaml:"TransGlobalTable" default:"dtm.trans_global"` - TransBranchOpTable string `yaml:"BranchTransOpTable" default:"dtm.trans_branch_op"` + TransBranchOpTable string `yaml:"TransBranchOpTable" default:"dtm.trans_branch_op"` } // IsDB checks config driver is mysql or postgres From 8e743314e3dc4676b71a727c0e88bb5621c8eb97 Mon Sep 17 00:00:00 2001 From: tian Date: Mon, 17 Jan 2022 00:11:29 +0800 Subject: [PATCH 120/124] add log config for output to file. --- bench/main.go | 2 +- conf.sample.yml | 10 +++++++++- dtmcli/logger/log.go | 33 +++++++++++++++++++++++++++++++++ dtmsvr/config/config.go | 13 ++++++++++++- dtmsvr/svr.go | 11 +++++++++++ go.mod | 1 + main.go | 2 +- 7 files changed, 68 insertions(+), 4 deletions(-) diff --git a/bench/main.go b/bench/main.go index 34bd859..50e488b 100644 --- a/bench/main.go +++ b/bench/main.go @@ -33,7 +33,7 @@ func main() { } logger.Infof("starting bench server") config.MustLoadConfig("") - logger.InitLog(conf.LogLevel) + logger.InitLog(conf.Log.Level) if busi.BusiConf.Driver != "" { dtmcli.SetCurrentDBType(busi.BusiConf.Driver) svr.PrepareBenchDB() diff --git a/conf.sample.yml b/conf.sample.yml index cd66cb6..5c046ed 100644 --- a/conf.sample.yml +++ b/conf.sample.yml @@ -48,7 +48,15 @@ # RetryInterval: 10 # the subtrans branch will be retried after this interval # RequestTimeout: 3 # the timeout of HTTP/gRPC request in dtm -# LogLevel: 'info' # default: info. can be debug|info|warn|error +# Log: +# Level: 'info' # default: info. can be debug|info|warn|error +# Output: 'console' # default: console. can be console|file +# FileName: '/tmp/dtm.log' # default: /tmp/dtm.log. +# FileMaxSize: 10 # default: 10, unit: MB. +# FileMaxBackups: 5 # default: 5. +# FileMaxAge: 30 # default: 30, unit: days. +# FileCompress: 0 # default: 0. can by 0|1, means false|true + # HttpPort: 36789 # GrpcPort: 36790 diff --git a/dtmcli/logger/log.go b/dtmcli/logger/log.go index 59b3d43..54237df 100644 --- a/dtmcli/logger/log.go +++ b/dtmcli/logger/log.go @@ -1,9 +1,12 @@ package logger import ( + "fmt" "log" + "net/url" "os" + "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) @@ -24,6 +27,14 @@ type Logger interface { Errorf(format string, args ...interface{}) } +type lumberjackSink struct { + *lumberjack.Logger +} + +func (lumberjackSink) Sync() error { + return nil +} + // WithLogger replaces default logger func WithLogger(log Logger) { logger = log @@ -45,6 +56,28 @@ func InitLog(level string) { logger = p.Sugar() } +// InitRotateLog is an initialization for a rotated logger by lumberjack +func InitRotateLog(logLevel string, output, logFile string, ll *lumberjack.Logger) { + config := zap.NewProductionConfig() + err := config.Level.UnmarshalText([]byte(logLevel)) + FatalIfError(err) + config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder + config.Encoding = "console" + config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder + config.OutputPaths = []string{fmt.Sprintf("lumberjack:%s", logFile), "stdout"} + if output == "file" { + err := zap.RegisterSink("lumberjack", func(*url.URL) (zap.Sink, error) { + return lumberjackSink{ + Logger: ll, + }, nil + }) + FatalIfError(err) + } + p, err := config.Build(zap.AddCallerSkip(1)) + FatalIfError(err) + logger = p.Sugar() +} + // Debugf log to level debug func Debugf(fmt string, args ...interface{}) { logger.Debugf(fmt, args...) diff --git a/dtmsvr/config/config.go b/dtmsvr/config/config.go index 2e84887..cc74975 100644 --- a/dtmsvr/config/config.go +++ b/dtmsvr/config/config.go @@ -29,6 +29,17 @@ type MicroService struct { EndPoint string `yaml:"EndPoint"` } +// Log config customize log +type Log struct { + Level string `yaml:"Level" default:"info"` + Output string `yaml:"Output" default:"console"` + FileName string `yaml:"FileName" default:"/tmp/dtm.log"` + FileMaxSize int64 `yaml:"FileMaxSize" default:"10"` + FileMaxBackups int64 `yaml:"FileMaxBackups" default:"5"` + FileMaxAge int64 `yaml:"FileMaxAge" default:"30"` + FileCompress int64 `yaml:"FileCompress" default:"0"` +} + // Store defines storage relevant info type Store struct { Driver string `yaml:"Driver" default:"boltdb"` @@ -72,7 +83,7 @@ type configType struct { MicroService MicroService `yaml:"MicroService"` UpdateBranchSync int64 `yaml:"UpdateBranchSync"` UpdateBranchAsyncGoroutineNum int64 `yaml:"UpdateBranchAsyncGoroutineNum" default:"1"` - LogLevel string `yaml:"LogLevel" default:"info"` + Log Log `yaml:"Log"` } // Config 配置 diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 56f288c..0470f0a 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -20,12 +20,23 @@ import ( "github.com/dtm-labs/dtm/dtmutil" "github.com/dtm-labs/dtmdriver" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" + "github.com/natefinch/lumberjack" "google.golang.org/grpc" ) // StartSvr StartSvr func StartSvr() { logger.Infof("start dtmsvr") + if conf.Log.Output == "file" { + ll := lumberjack.Logger{ + Filename: conf.Log.FileName, + MaxSize: int(conf.Log.FileMaxSize), + MaxBackups: int(conf.Log.FileMaxBackups), + MaxAge: int(conf.Log.FileMaxAge), + Compress: conf.Log.FileCompress != 0, + } + logger.InitRotateLog(conf.Log.Level, conf.Log.Output, conf.Log.FileName, &ll) + } dtmcli.GetRestyClient().SetTimeout(time.Duration(conf.RequestTimeout) * time.Second) dtmgrpc.AddUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { ctx2, cancel := context.WithTimeout(ctx, time.Duration(conf.RequestTimeout)*time.Second) diff --git a/go.mod b/go.mod index ef2be14..baf57ea 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/lib/pq v1.10.3 github.com/lithammer/shortuuid v2.0.3+incompatible github.com/lithammer/shortuuid/v3 v3.0.7 + github.com/natefinch/lumberjack v2.0.0+incompatible // indirect github.com/onsi/gomega v1.16.0 github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 diff --git a/main.go b/main.go index 1b088e1..43ce895 100644 --- a/main.go +++ b/main.go @@ -59,7 +59,7 @@ func main() { } config.MustLoadConfig(*confFile) if *isDebug { - config.Config.LogLevel = "debug" + config.Config.Log.Level = "debug" } if *isReset { dtmsvr.PopulateDB(false) From 5d280c31db822a0a189cc711c571ff1453521944 Mon Sep 17 00:00:00 2001 From: tian Date: Mon, 17 Jan 2022 00:41:22 +0800 Subject: [PATCH 121/124] add unit test for log. --- dtmcli/logger/log.go | 43 ++++++++++++++++++------------------ dtmcli/logger/logger_test.go | 20 +++++++++++++++++ dtmsvr/svr.go | 2 +- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/dtmcli/logger/log.go b/dtmcli/logger/log.go index 54237df..e2ef110 100644 --- a/dtmcli/logger/log.go +++ b/dtmcli/logger/log.go @@ -43,39 +43,38 @@ func WithLogger(log Logger) { // InitLog is an initialization for a logger // level can be: debug info warn error func InitLog(level string) { - config := zap.NewProductionConfig() - err := config.Level.UnmarshalText([]byte(level)) - FatalIfError(err) - config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - if os.Getenv("DTM_DEBUG") != "" { - config.Encoding = "console" - config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder - } + config := loadConfig(level) p, err := config.Build(zap.AddCallerSkip(1)) FatalIfError(err) logger = p.Sugar() } // InitRotateLog is an initialization for a rotated logger by lumberjack -func InitRotateLog(logLevel string, output, logFile string, ll *lumberjack.Logger) { +func InitRotateLog(logLevel string, ll *lumberjack.Logger) { + config := loadConfig(logLevel) + config.OutputPaths = []string{fmt.Sprintf("lumberjack:%s", ll.Filename), "stdout"} + err := zap.RegisterSink("lumberjack", func(*url.URL) (zap.Sink, error) { + return lumberjackSink{ + Logger: ll, + }, nil + }) + FatalIfError(err) + + p, err := config.Build(zap.AddCallerSkip(1)) + FatalIfError(err) + logger = p.Sugar() +} + +func loadConfig(logLevel string) zap.Config { config := zap.NewProductionConfig() err := config.Level.UnmarshalText([]byte(logLevel)) FatalIfError(err) config.EncoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder - config.Encoding = "console" - config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder - config.OutputPaths = []string{fmt.Sprintf("lumberjack:%s", logFile), "stdout"} - if output == "file" { - err := zap.RegisterSink("lumberjack", func(*url.URL) (zap.Sink, error) { - return lumberjackSink{ - Logger: ll, - }, nil - }) - FatalIfError(err) + if os.Getenv("DTM_DEBUG") != "" { + config.Encoding = "console" + config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder } - p, err := config.Build(zap.AddCallerSkip(1)) - FatalIfError(err) - logger = p.Sugar() + return config } // Debugf log to level debug diff --git a/dtmcli/logger/logger_test.go b/dtmcli/logger/logger_test.go index 26797e0..bcba763 100644 --- a/dtmcli/logger/logger_test.go +++ b/dtmcli/logger/logger_test.go @@ -4,6 +4,7 @@ import ( "os" "testing" + "github.com/natefinch/lumberjack" "go.uber.org/zap" ) @@ -28,3 +29,22 @@ func TestWithLogger(t *testing.T) { FatalfIf(false, "nothing") FatalIfError(nil) } + +func TestInitRotateLog(t *testing.T) { + os.Setenv("DTM_DEBUG", "1") + ll := lumberjack.Logger{ + Filename: "test.log", + MaxSize: 1, + MaxBackups: 1, + MaxAge: 1, + Compress: false, + } + InitRotateLog("debug", &ll) + Debugf("a debug msg") + Infof("a info msg") + Warnf("a warn msg") + Errorf("a error msg") + FatalfIf(false, "nothing") + FatalIfError(nil) + _ = os.Remove("test.log") +} diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 0470f0a..8f25501 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -35,7 +35,7 @@ func StartSvr() { MaxAge: int(conf.Log.FileMaxAge), Compress: conf.Log.FileCompress != 0, } - logger.InitRotateLog(conf.Log.Level, conf.Log.Output, conf.Log.FileName, &ll) + logger.InitRotateLog(conf.Log.Level, &ll) } dtmcli.GetRestyClient().SetTimeout(time.Duration(conf.RequestTimeout) * time.Second) dtmgrpc.AddUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { From 4c903aed6acf95d089895019d8017eb5dabc3a30 Mon Sep 17 00:00:00 2001 From: tina <11660793+tina-prog@users.noreply.github.com> Date: Mon, 17 Jan 2022 01:31:32 +0800 Subject: [PATCH 122/124] Create codeql-analysis1.yml --- .github/workflows/codeql-analysis1.yml | 70 ++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 .github/workflows/codeql-analysis1.yml diff --git a/.github/workflows/codeql-analysis1.yml b/.github/workflows/codeql-analysis1.yml new file mode 100644 index 0000000..5eb581e --- /dev/null +++ b/.github/workflows/codeql-analysis1.yml @@ -0,0 +1,70 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + schedule: + - cron: '19 3 * * 2' + workflow_dispatch: + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ 'go' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] + # Learn more about CodeQL language support at https://git.io/codeql-language-support + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 2971fbf2840961e852ef699aa82c27046e7c2d0a Mon Sep 17 00:00:00 2001 From: tian Date: Mon, 17 Jan 2022 01:57:33 +0800 Subject: [PATCH 123/124] delete useless file --- .github/workflows/codeql-analysis1.yml | 70 -------------------------- 1 file changed, 70 deletions(-) delete mode 100644 .github/workflows/codeql-analysis1.yml diff --git a/.github/workflows/codeql-analysis1.yml b/.github/workflows/codeql-analysis1.yml deleted file mode 100644 index 5eb581e..0000000 --- a/.github/workflows/codeql-analysis1.yml +++ /dev/null @@ -1,70 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] - schedule: - - cron: '19 3 * * 2' - workflow_dispatch: - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'go' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] - # Learn more about CodeQL language support at https://git.io/codeql-language-support - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # ℹ️ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 From 076b079bb21361b1d78171eb89b2ff20e88715bd Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Mon, 17 Jan 2022 08:35:29 +0800 Subject: [PATCH 124/124] cover more --- dtmcli/logger/logger_test.go | 2 ++ dtmsvr/svr.go | 11 ----------- main.go | 17 ++++++++++++++++- 3 files changed, 18 insertions(+), 12 deletions(-) diff --git a/dtmcli/logger/logger_test.go b/dtmcli/logger/logger_test.go index bcba763..a63920f 100644 --- a/dtmcli/logger/logger_test.go +++ b/dtmcli/logger/logger_test.go @@ -46,5 +46,7 @@ func TestInitRotateLog(t *testing.T) { Errorf("a error msg") FatalfIf(false, "nothing") FatalIfError(nil) + s := lumberjackSink{&ll} + _ = s.Sync() _ = os.Remove("test.log") } diff --git a/dtmsvr/svr.go b/dtmsvr/svr.go index 8f25501..56f288c 100644 --- a/dtmsvr/svr.go +++ b/dtmsvr/svr.go @@ -20,23 +20,12 @@ import ( "github.com/dtm-labs/dtm/dtmutil" "github.com/dtm-labs/dtmdriver" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" - "github.com/natefinch/lumberjack" "google.golang.org/grpc" ) // StartSvr StartSvr func StartSvr() { logger.Infof("start dtmsvr") - if conf.Log.Output == "file" { - ll := lumberjack.Logger{ - Filename: conf.Log.FileName, - MaxSize: int(conf.Log.FileMaxSize), - MaxBackups: int(conf.Log.FileMaxBackups), - MaxAge: int(conf.Log.FileMaxAge), - Compress: conf.Log.FileCompress != 0, - } - logger.InitRotateLog(conf.Log.Level, &ll) - } dtmcli.GetRestyClient().SetTimeout(time.Duration(conf.RequestTimeout) * time.Second) dtmgrpc.AddUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { ctx2, cancel := context.WithTimeout(ctx, time.Duration(conf.RequestTimeout)*time.Second) diff --git a/main.go b/main.go index 43ce895..4c6263f 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,7 @@ import ( "github.com/dtm-labs/dtm/dtmsvr" "github.com/dtm-labs/dtm/dtmsvr/config" "github.com/dtm-labs/dtm/dtmsvr/storage/registry" + "github.com/natefinch/lumberjack" // load the microserver driver _ "github.com/dtm-labs/dtmdriver-gozero" @@ -58,9 +59,23 @@ func main() { return } config.MustLoadConfig(*confFile) + conf := &config.Config if *isDebug { - config.Config.Log.Level = "debug" + conf.Log.Level = "debug" } + if conf.Log.Output == "file" { + ll := lumberjack.Logger{ + Filename: conf.Log.FileName, + MaxSize: int(conf.Log.FileMaxSize), + MaxBackups: int(conf.Log.FileMaxBackups), + MaxAge: int(conf.Log.FileMaxAge), + Compress: conf.Log.FileCompress != 0, + } + logger.InitRotateLog(conf.Log.Level, &ll) + } else { + logger.InitLog(conf.Log.Level) + } + if *isReset { dtmsvr.PopulateDB(false) }