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 1/5] 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 2/5] 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 3/5] 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 4/5] 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 5/5] 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要么全部成功,要么全部回滚,保证最终金额的正确性。 + ## 接入详解 ### 接入代码