From d284b92f1d9bcd376bea553355bf6090979b44b0 Mon Sep 17 00:00:00 2001 From: yedf2 <120050102@qq.com> Date: Fri, 5 Nov 2021 10:09:20 +0800 Subject: [PATCH] refactor to use new grpc interface --- README-cn.md | 10 +- app/main.go | 3 +- bench/http.go | 63 +- common/types.go | 27 +- common/types_test.go | 12 +- common/utils.go | 24 +- dtmcli/barrier.go | 14 +- dtmcli/consts.go | 26 +- dtmcli/dtmimp/consts.go | 14 + dtmcli/{ => dtmimp}/db_special.go | 2 +- dtmcli/{ => dtmimp}/db_special_test.go | 2 +- dtmcli/dtmimp/trans_base.go | 117 +++ .../{xa_base.go => dtmimp/trans_xa_base.go} | 9 +- dtmcli/{adapter.go => dtmimp/types.go} | 6 +- dtmcli/dtmimp/types_test.go | 19 + dtmcli/{ => dtmimp}/utils.go | 34 +- dtmcli/{ => dtmimp}/utils_test.go | 2 +- dtmcli/dtmimp/vars.go | 38 + dtmcli/message.go | 39 - dtmcli/msg.go | 31 + dtmcli/saga.go | 28 +- dtmcli/tcc.go | 40 +- dtmcli/trans_test.go | 2 +- dtmcli/types.go | 104 +-- dtmcli/types_test.go | 12 +- dtmcli/xa.go | 61 +- dtmgrpc/barrier.go | 18 +- dtmgrpc/dtmgimp/dtmgimp.pb.go | 674 ++++++++++++++++ dtmgrpc/dtmgimp/dtmgimp.proto | 58 ++ .../dtmgimp_grpc.pb.go} | 30 +- dtmgrpc/dtmgimp/grpc_clients.go | 67 ++ dtmgrpc/dtmgimp/types.go | 61 ++ dtmgrpc/dtmgimp/utils.go | 73 ++ dtmgrpc/dtmgrpc.pb.go | 717 ------------------ dtmgrpc/dtmgrpc.proto | 66 -- dtmgrpc/message.go | 50 -- dtmgrpc/msg.go | 36 + dtmgrpc/saga.go | 41 +- dtmgrpc/tcc.go | 55 +- dtmgrpc/type.go | 92 +-- dtmgrpc/type_test.go | 5 +- dtmgrpc/xa.go | 86 +-- dtmsvr/api.go | 12 +- dtmsvr/api_grpc.go | 26 +- dtmsvr/api_http.go | 13 +- dtmsvr/cron.go | 10 +- dtmsvr/dtmsvr.go | 24 +- dtmsvr/dtmsvr.mysql.sql | 1 + dtmsvr/dtmsvr.postgres.sql | 1 + dtmsvr/trans.go | 113 ++- dtmsvr/trans_msg.go | 19 +- dtmsvr/trans_saga.go | 23 +- dtmsvr/trans_tcc.go | 5 +- dtmsvr/trans_xa.go | 5 +- dtmsvr/utils.go | 23 +- dtmsvr/utils_test.go | 8 +- examples/base_grpc.go | 133 ++-- examples/base_http.go | 42 +- examples/base_types.go | 34 +- examples/busi.pb.go | 318 +++++--- examples/busi.proto | 43 +- examples/busi_grpc.pb.go | 240 +++--- examples/data.go | 40 +- examples/grpc_msg.go | 6 +- examples/grpc_saga.go | 14 +- examples/grpc_saga_barrier.go | 52 +- examples/grpc_tcc.go | 14 +- examples/grpc_xa.go | 24 +- examples/http_gorm_xa.go | 3 +- examples/http_msg.go | 9 +- examples/http_saga.go | 25 +- examples/http_saga_barrier.go | 9 +- examples/http_saga_gorm_barrier.go | 7 +- examples/http_tcc.go | 11 +- examples/http_tcc_barrier.go | 9 +- examples/http_xa.go | 5 +- examples/quick_start.go | 7 +- go.mod | 3 - go.sum | 12 +- test/api_test.go | 44 ++ test/base_test.go | 22 +- test/dtmsvr_test.go | 50 +- test/examples_test.go | 1 - test/grpc_msg_test.go | 36 +- ...saga_test.go => grpc_saga_barrier_test.go} | 19 +- test/grpc_saga_test.go | 26 +- test/grpc_tcc_test.go | 49 +- test/grpc_xa_test.go | 44 +- test/main_test.go | 17 - test/msg_test.go | 48 +- ...rier_saga_test.go => saga_barrier_test.go} | 19 +- test/saga_compatible_test.go | 21 + test/saga_concurrent_test.go | 76 +- test/saga_options_test.go | 82 ++ test/saga_test.go | 59 +- ...arrier_tcc_test.go => tcc_barrier_test.go} | 44 +- test/tcc_test.go | 15 +- test/types.go | 22 +- test/wait_saga_test.go | 50 -- test/xa_test.go | 33 +- 100 files changed, 2621 insertions(+), 2367 deletions(-) create mode 100644 dtmcli/dtmimp/consts.go rename dtmcli/{ => dtmimp}/db_special.go (99%) rename dtmcli/{ => dtmimp}/db_special_test.go (97%) create mode 100644 dtmcli/dtmimp/trans_base.go rename dtmcli/{xa_base.go => dtmimp/trans_xa_base.go} (92%) rename dtmcli/{adapter.go => dtmimp/types.go} (85%) create mode 100644 dtmcli/dtmimp/types_test.go rename dtmcli/{ => dtmimp}/utils.go (89%) rename dtmcli/{ => dtmimp}/utils_test.go (99%) create mode 100644 dtmcli/dtmimp/vars.go delete mode 100644 dtmcli/message.go create mode 100644 dtmcli/msg.go create mode 100644 dtmgrpc/dtmgimp/dtmgimp.pb.go create mode 100644 dtmgrpc/dtmgimp/dtmgimp.proto rename dtmgrpc/{dtmgrpc_grpc.pb.go => dtmgimp/dtmgimp_grpc.pb.go} (92%) create mode 100644 dtmgrpc/dtmgimp/grpc_clients.go create mode 100644 dtmgrpc/dtmgimp/types.go create mode 100644 dtmgrpc/dtmgimp/utils.go delete mode 100644 dtmgrpc/dtmgrpc.pb.go delete mode 100644 dtmgrpc/dtmgrpc.proto delete mode 100644 dtmgrpc/message.go create mode 100644 dtmgrpc/msg.go create mode 100644 test/api_test.go rename test/{grpc_barrier_saga_test.go => grpc_saga_barrier_test.go} (69%) rename test/{barrier_saga_test.go => saga_barrier_test.go} (71%) create mode 100644 test/saga_compatible_test.go create mode 100644 test/saga_options_test.go rename test/{barrier_tcc_test.go => tcc_barrier_test.go} (82%) delete mode 100644 test/wait_saga_test.go diff --git a/README-cn.md b/README-cn.md index ea51ca5..78aac58 100644 --- a/README-cn.md +++ b/README-cn.md @@ -66,15 +66,19 @@ DTM是一款golang开发的分布式事务管理器,解决了跨数据库、 ## 快速开始 -### 安装 +### 获取代码 `git clone https://github.com/yedf/dtm` ### dtm依赖于mysql -配置mysql: +安装[docker 20.04+](https://docs.docker.com/get-docker/)之后 -`cp conf.sample.yml conf.yml # 修改conf.yml` +`docker-compose helper/compose.mysql.yml` + +> 您也可以配置使用现有的mysql,需要高级权限,允许dtm创建数据库 +> +> `cp conf.sample.yml conf.yml # 修改conf.yml` ### 启动并运行saga示例 `go run app/main.go saga` diff --git a/app/main.go b/app/main.go index c85b943..d628c97 100644 --- a/app/main.go +++ b/app/main.go @@ -8,6 +8,7 @@ import ( "github.com/yedf/dtm/bench" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmsvr" "github.com/yedf/dtm/examples" ) @@ -56,7 +57,7 @@ func main() { examples.BaseAppStartup() sample := examples.Samples[os.Args[1]] - dtmcli.LogIfFatalf(sample == nil, "no sample name for %s", os.Args[1]) + dtmimp.LogIfFatalf(sample == nil, "no sample name for %s", os.Args[1]) sample.Action() } select {} diff --git a/bench/http.go b/bench/http.go index 7a93b22..010977f 100644 --- a/bench/http.go +++ b/bench/http.go @@ -10,6 +10,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmsvr" "github.com/yedf/dtm/examples" ) @@ -24,15 +25,15 @@ const total = 200000 var benchBusi = fmt.Sprintf("http://localhost:%d%s", benchPort, benchAPI) func sdbGet() *sql.DB { - db, err := dtmcli.PooledDB(common.DtmConfig.DB) - dtmcli.FatalIfError(err) + db, err := dtmimp.PooledDB(common.DtmConfig.DB) + dtmimp.FatalIfError(err) return db } func txGet() *sql.Tx { db := sdbGet() tx, err := db.Begin() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return tx } @@ -42,17 +43,17 @@ func reloadData() { db := sdbGet() tables := []string{"dtm_busi.user_account", "dtm_busi.user_account_log", "dtm.trans_global", "dtm.trans_branch", "dtm_barrier.barrier"} for _, t := range tables { - _, err := dtmcli.DBExec(db, fmt.Sprintf("truncate %s", t)) - dtmcli.FatalIfError(err) + _, err := dtmimp.DBExec(db, fmt.Sprintf("truncate %s", t)) + dtmimp.FatalIfError(err) } s := "insert ignore into dtm_busi.user_account(user_id, balance) values " ss := []string{} for i := 1; i <= total; i++ { ss = append(ss, fmt.Sprintf("(%d, 1000000)", i)) } - _, err := dtmcli.DBExec(db, s+strings.Join(ss, ",")) - dtmcli.FatalIfError(err) - dtmcli.Logf("%d users inserted. used: %dms", total, time.Since(began).Milliseconds()) + _, err := dtmimp.DBExec(db, s+strings.Join(ss, ",")) + dtmimp.FatalIfError(err) + dtmimp.Logf("%d users inserted. used: %dms", total, time.Since(began).Milliseconds()) } var uidCounter int32 = 0 @@ -63,12 +64,12 @@ var sqls int = 1 func StartSvr() { app := common.GetGinApp() benchAddRoute(app) - dtmcli.Logf("bench listening at %d", benchPort) + dtmimp.Logf("bench listening at %d", benchPort) go app.Run(fmt.Sprintf(":%d", benchPort)) db := sdbGet() - _, err := dtmcli.DBExec(db, "drop table if exists dtm_busi.user_account_log") - dtmcli.FatalIfError(err) - _, err = dtmcli.DBExec(db, `create table if not exists dtm_busi.user_account_log ( + _, err := dtmimp.DBExec(db, "drop table if exists dtm_busi.user_account_log") + dtmimp.FatalIfError(err) + _, err = dtmimp.DBExec(db, `create table if not exists dtm_busi.user_account_log ( id INT(11) AUTO_INCREMENT PRIMARY KEY, user_id INT(11) NOT NULL, delta DECIMAL(11, 2) not null, @@ -82,33 +83,33 @@ func StartSvr() { key(create_time) ) `) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) } func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { if strings.Contains(mode, "empty") { return dtmcli.MapSuccess, nil } - tb := dtmcli.TransBaseFromQuery(c.Request.URL.Query()) + tb := dtmimp.TransBaseFromQuery(c.Request.URL.Query()) f := func(tx dtmcli.DB) error { for i := 0; i < sqls; i++ { - _, err := dtmcli.DBExec(tx, "insert into dtm_busi.user_account_log(user_id, delta, gid, branch_id, branch_type, reason) values(?,?,?,?,?,?)", + _, err := dtmimp.DBExec(tx, "insert into dtm_busi.user_account_log(user_id, delta, gid, branch_id, branch_type, reason) values(?,?,?,?,?,?)", uid, amount, tb.Gid, c.Query("branch_id"), tb.TransType, fmt.Sprintf("inserted by dtm transaction %s %s", tb.Gid, c.Query("branch_id"))) - dtmcli.FatalIfError(err) - _, err = dtmcli.DBExec(tx, "update dtm_busi.user_account set balance = balance + ?, update_time = now() where user_id = ?", amount, uid) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) + _, err = dtmimp.DBExec(tx, "update dtm_busi.user_account set balance = balance + ?, update_time = now() where user_id = ?", amount, uid) + dtmimp.FatalIfError(err) } return nil } if strings.Contains(mode, "barrier") { barrier, err := dtmcli.BarrierFromQuery(c.Request.URL.Query()) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) barrier.Call(txGet(), f) } else { tx := txGet() f(tx) err := tx.Commit() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) } return dtmcli.MapSuccess, nil @@ -116,23 +117,23 @@ func qsAdjustBalance(uid int, amount int, c *gin.Context) (interface{}, error) { func benchAddRoute(app *gin.Engine) { app.POST(benchAPI+"/TransIn", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(dtmcli.MustAtoi(c.Query("uid")), 1, c) + return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), 1, c) })) app.POST(benchAPI+"/TransInCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(dtmcli.MustAtoi(c.Query("uid")), -1, c) + return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), -1, c) })) app.POST(benchAPI+"/TransOut", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(dtmcli.MustAtoi(c.Query("uid")), -1, c) + return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), -1, c) })) app.POST(benchAPI+"/TransOutCompensate", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return qsAdjustBalance(dtmcli.MustAtoi(c.Query("uid")), 30, c) + return qsAdjustBalance(dtmimp.MustAtoi(c.Query("uid")), 30, c) })) app.Any(benchAPI+"/reloadData", common.WrapHandler(func(c *gin.Context) (interface{}, error) { reloadData() mode = c.Query("m") s := c.Query("sqls") if s != "" { - sqls = dtmcli.MustAtoi(s) + sqls = dtmimp.MustAtoi(s) } return nil, nil })) @@ -143,19 +144,19 @@ func benchAddRoute(app *gin.Engine) { req := gin.H{} params := fmt.Sprintf("?uid=%s", suid) params2 := fmt.Sprintf("?uid=%s", suid2) - dtmcli.Logf("mode: %s contains dtm: %t", mode, strings.Contains(mode, "dtm")) + dtmimp.Logf("mode: %s contains dtm: %t", mode, strings.Contains(mode, "dtm")) if strings.Contains(mode, "dtm") { saga := dtmcli.NewSaga(examples.DtmServer, fmt.Sprintf("bench-%d", uid)). Add(benchBusi+"/TransOut"+params, benchBusi+"/TransOutCompensate"+params, req). Add(benchBusi+"/TransIn"+params2, benchBusi+"/TransInCompensate"+params2, req) saga.WaitResult = true err := saga.Submit() - dtmcli.E2P(err) + dtmimp.E2P(err) } else { - _, err := dtmcli.RestyClient.R().SetBody(gin.H{}).SetQueryParam("uid", suid2).Post(benchBusi + "/TransOut") - dtmcli.E2P(err) - _, err = dtmcli.RestyClient.R().SetBody(gin.H{}).SetQueryParam("uid", suid).Post(benchBusi + "/TransIn") - dtmcli.E2P(err) + _, err := dtmimp.RestyClient.R().SetBody(gin.H{}).SetQueryParam("uid", suid2).Post(benchBusi + "/TransOut") + dtmimp.E2P(err) + _, err = dtmimp.RestyClient.R().SetBody(gin.H{}).SetQueryParam("uid", suid).Post(benchBusi + "/TransIn") + dtmimp.E2P(err) } return nil, nil })) diff --git a/common/types.go b/common/types.go index e080313..9852e65 100644 --- a/common/types.go +++ b/common/types.go @@ -18,6 +18,7 @@ import ( "gorm.io/gorm" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) // ModelBase model base for gorm to provide base fields @@ -31,7 +32,7 @@ func getGormDialetor(driver string, dsn string) gorm.Dialector { if driver == dtmcli.DBTypePostgres { return postgres.Open(dsn) } - dtmcli.PanicIf(driver != dtmcli.DBTypeMysql, fmt.Errorf("unkown driver: %s", driver)) + dtmimp.PanicIf(driver != dtmcli.DBTypeMysql, fmt.Errorf("unkown driver: %s", driver)) return mysql.Open(dsn) } @@ -57,7 +58,7 @@ func (m *DB) NoMust() *DB { // ToSQLDB get the sql.DB func (m *DB) ToSQLDB() *sql.DB { d, err := m.DB.DB() - dtmcli.E2P(err) + dtmimp.E2P(err) return d } @@ -75,7 +76,7 @@ func (op *tracePlugin) Initialize(db *gorm.DB) (err error) { after := func(db *gorm.DB) { _ts, _ := db.InstanceGet("ivy.startTime") sql := db.Dialector.Explain(db.Statement.SQL.String(), db.Statement.Vars...) - dtmcli.Logf("used: %d ms affected: %d sql is: %s", time.Since(_ts.(time.Time)).Milliseconds(), db.RowsAffected, sql) + dtmimp.Logf("used: %d ms affected: %d sql is: %s", time.Since(_ts.(time.Time)).Milliseconds(), db.RowsAffected, sql) if v, ok := db.InstanceGet("ivy.must"); ok && v.(bool) { if db.Error != nil && db.Error != gorm.ErrRecordNotFound { panic(db.Error) @@ -86,7 +87,7 @@ func (op *tracePlugin) Initialize(db *gorm.DB) (err error) { beforeName := "cb_before" afterName := "cb_after" - dtmcli.Logf("installing db plugin: %s", op.Name()) + dtmimp.Logf("installing db plugin: %s", op.Name()) // 开始前 _ = db.Callback().Create().Before("gorm:before_create").Register(beforeName, before) _ = db.Callback().Query().Before("gorm:query").Register(beforeName, before) @@ -107,14 +108,14 @@ func (op *tracePlugin) Initialize(db *gorm.DB) (err error) { // DbGet get db connection for specified conf func DbGet(conf map[string]string) *DB { - dsn := dtmcli.GetDsn(conf) + dsn := dtmimp.GetDsn(conf) db, ok := dbs.Load(dsn) if !ok { - dtmcli.Logf("connecting %s", strings.Replace(dsn, conf["password"], "****", 1)) + dtmimp.Logf("connecting %s", strings.Replace(dsn, conf["password"], "****", 1)) db1, err := gorm.Open(getGormDialetor(conf["driver"], dsn), &gorm.Config{ SkipDefaultTransaction: true, }) - dtmcli.E2P(err) + dtmimp.E2P(err) db1.Use(&tracePlugin{}) db = &DB{DB: db1} dbs.Store(dsn, db) @@ -135,7 +136,7 @@ type dtmConfigType struct { var DtmConfig = dtmConfigType{} func getIntEnv(key string, defaultV string) int64 { - return int64(dtmcli.MustAtoi(dtmcli.OrString(os.Getenv(key), defaultV))) + return int64(dtmimp.MustAtoi(dtmimp.OrString(os.Getenv(key), defaultV))) } func init() { @@ -146,9 +147,9 @@ func init() { DtmConfig.TimeoutToFail = getIntEnv("TIMEOUT_TO_FAIL", "35") DtmConfig.RetryInterval = getIntEnv("RETRY_INTERVAL", "10") DtmConfig.DB = map[string]string{ - "driver": dtmcli.OrString(os.Getenv("DB_DRIVER"), "mysql"), + "driver": dtmimp.OrString(os.Getenv("DB_DRIVER"), "mysql"), "host": os.Getenv("DB_HOST"), - "port": dtmcli.OrString(os.Getenv("DB_PORT"), "3306"), + "port": dtmimp.OrString(os.Getenv("DB_PORT"), "3306"), "user": os.Getenv("DB_USER"), "password": os.Getenv("DB_PASSWORD"), } @@ -166,12 +167,12 @@ func init() { } } if cont != nil && len(cont) != 0 { - dtmcli.Logf("cont is: \n%s", string(cont)) + dtmimp.Logf("cont is: \n%s", string(cont)) err := yaml.Unmarshal(cont, &DtmConfig) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) } errStr := checkConfig() - dtmcli.LogIfFatalf(errStr != "", + dtmimp.LogIfFatalf(errStr != "", `config error: '%s'. 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. diff --git a/common/types_test.go b/common/types_test.go index 4dd9c0b..84d4c32 100644 --- a/common/types_test.go +++ b/common/types_test.go @@ -4,13 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func TestDb(t *testing.T) { db := DbGet(DtmConfig.DB) err := func() (rerr error) { - defer dtmcli.P2E(&rerr) + defer dtmimp.P2E(&rerr) dbr := db.NoMust().Exec("select a") assert.NotEqual(t, nil, dbr.Error) db.Must().Exec("select a") @@ -20,14 +20,14 @@ func TestDb(t *testing.T) { } func TestDbAlone(t *testing.T) { - db, err := dtmcli.StandaloneDB(DtmConfig.DB) + db, err := dtmimp.StandaloneDB(DtmConfig.DB) assert.Nil(t, err) - _, err = dtmcli.DBExec(db, "select 1") + _, err = dtmimp.DBExec(db, "select 1") assert.Equal(t, nil, err) - _, err = dtmcli.DBExec(db, "") + _, err = dtmimp.DBExec(db, "") assert.Equal(t, nil, err) db.Close() - _, err = dtmcli.DBExec(db, "select 1") + _, err = dtmimp.DBExec(db, "select 1") assert.NotEqual(t, nil, err) } diff --git a/common/utils.go b/common/utils.go index 5c9b174..73b70e8 100644 --- a/common/utils.go +++ b/common/utils.go @@ -14,6 +14,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) // GetGinApp init and return gin @@ -24,19 +25,19 @@ func GetGinApp() *gin.Engine { body := "" if c.Request.Body != nil { rb, err := c.GetRawData() - dtmcli.E2P(err) + dtmimp.E2P(err) if len(rb) > 0 { body = string(rb) c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(rb)) } } began := time.Now() - dtmcli.Logf("begin %s %s query: %s body: %s", c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) + dtmimp.Logf("begin %s %s query: %s body: %s", c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) c.Next() - dtmcli.Logf("used %d ms %s %s query: %s body: %s", time.Since(began).Milliseconds(), c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) + dtmimp.Logf("used %d ms %s %s query: %s body: %s", time.Since(began).Milliseconds(), c.Request.Method, c.FullPath(), c.Request.URL.RawQuery, body) }) - app.Any("/api/ping", func(c *gin.Context) { c.JSON(200, dtmcli.M{"msg": "pong"}) }) + app.Any("/api/ping", func(c *gin.Context) { c.JSON(200, map[string]interface{}{"msg": "pong"}) }) return app } @@ -44,24 +45,27 @@ func GetGinApp() *gin.Engine { func WrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc { return func(c *gin.Context) { r, err := func() (r interface{}, rerr error) { - defer dtmcli.P2E(&rerr) + defer dtmimp.P2E(&rerr) return fn(c) }() var b = []byte{} if resp, ok := r.(*resty.Response); ok { // 如果是response,则取出body直接处理 b = resp.Body() + } else if err != nil && (strings.Contains(err.Error(), dtmcli.ResultFailure) || strings.Contains(err.Error(), dtmcli.ResultOngoing)) { + b = []byte(err.Error()) + err = nil } else if err == nil { b, err = json.Marshal(r) } if err != nil { - dtmcli.Logf("status: 500, code: 500 message: %s", err.Error()) - c.JSON(500, dtmcli.M{"code": 500, "message": err.Error()}) + dtmimp.Logf("status: 500, code: 500 message: %s", err.Error()) + c.JSON(500, map[string]interface{}{"code": 500, "message": err.Error()}) } else { - dtmcli.Logf("status: 200, content: %s", string(b)) + dtmimp.Logf("status: 200, content: %s", string(b)) c.Status(200) c.Writer.Header().Add("Content-Type", "application/json") _, err = c.Writer.Write(b) - dtmcli.E2P(err) + dtmimp.E2P(err) } } } @@ -69,7 +73,7 @@ func WrapHandler(fn func(*gin.Context) (interface{}, error)) gin.HandlerFunc { // MustGetwd must version of os.Getwd func MustGetwd() string { wd, err := os.Getwd() - dtmcli.E2P(err) + dtmimp.E2P(err) return wd } diff --git a/dtmcli/barrier.go b/dtmcli/barrier.go index b0c7343..024b975 100644 --- a/dtmcli/barrier.go +++ b/dtmcli/barrier.go @@ -3,10 +3,12 @@ package dtmcli import ( "fmt" "net/url" + + "github.com/yedf/dtm/dtmcli/dtmimp" ) -// BusiFunc type for busi func -type BusiFunc func(db DB) error +// BarrierBusiFunc type for busi func +type BarrierBusiFunc func(db DB) error // BranchBarrier every branch info type BranchBarrier struct { @@ -44,14 +46,14 @@ func insertBarrier(tx Tx, transType string, gid string, branchID string, branchT if branchType == "" { return 0, nil } - sql := GetDBSpecial().GetInsertIgnoreTemplate("dtm_barrier.barrier(trans_type, gid, branch_id, branch_type, barrier_id, reason) values(?,?,?,?,?,?)", "uniq_barrier") - return DBExec(tx, sql, transType, gid, branchID, branchType, barrierID, reason) + sql := dtmimp.GetDBSpecial().GetInsertIgnoreTemplate("dtm_barrier.barrier(trans_type, gid, branch_id, branch_type, barrier_id, reason) values(?,?,?,?,?,?)", "uniq_barrier") + return dtmimp.DBExec(tx, sql, transType, gid, branchID, branchType, barrierID, reason) } // Call 子事务屏障,详细介绍见 https://zhuanlan.zhihu.com/p/388444465 // tx: 本地数据库的事务对象,允许子事务屏障进行事务操作 // busiCall: 业务函数,仅在必要时被调用 -func (bb *BranchBarrier) Call(tx Tx, busiCall BusiFunc) (rerr error) { +func (bb *BranchBarrier) Call(tx Tx, busiCall BarrierBusiFunc) (rerr error) { bb.BarrierID = bb.BarrierID + 1 bid := fmt.Sprintf("%02d", bb.BarrierID) defer func() { @@ -73,7 +75,7 @@ func (bb *BranchBarrier) Call(tx Tx, busiCall BusiFunc) (rerr error) { originAffected, _ := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, originType, bid, ti.BranchType) currentAffected, rerr := insertBarrier(tx, ti.TransType, ti.Gid, ti.BranchID, ti.BranchType, bid, ti.BranchType) - Logf("originAffected: %d currentAffected: %d", originAffected, currentAffected) + dtmimp.Logf("originAffected: %d currentAffected: %d", originAffected, currentAffected) if (ti.BranchType == BranchCancel || ti.BranchType == BranchCompensate) && originAffected > 0 || // 这个是空补偿 currentAffected == 0 { // 这个是重复请求或者悬挂 return diff --git a/dtmcli/consts.go b/dtmcli/consts.go index 438deed..36bf2de 100644 --- a/dtmcli/consts.go +++ b/dtmcli/consts.go @@ -1,5 +1,9 @@ package dtmcli +import ( + "github.com/yedf/dtm/dtmcli/dtmimp" +) + const ( // StatusPrepared status for global/branch trans status. StatusPrepared = "prepared" @@ -28,14 +32,26 @@ const ( BranchRollback = "rollback" // ResultSuccess for result of a trans/trans branch - ResultSuccess = "SUCCESS" + ResultSuccess = dtmimp.ResultSuccess // ResultFailure for result of a trans/trans branch - ResultFailure = "FAILURE" + ResultFailure = dtmimp.ResultFailure // ResultOngoing for result of a trans/trans branch - ResultOngoing = "ONGOING" + ResultOngoing = dtmimp.ResultOngoing // DBTypeMysql const for driver mysql - DBTypeMysql = "mysql" + DBTypeMysql = dtmimp.DBTypeMysql // DBTypePostgres const for driver postgres - DBTypePostgres = "postgres" + DBTypePostgres = dtmimp.DBTypePostgres ) + +// MapSuccess HTTP result of SUCCESS +var MapSuccess = dtmimp.MapSuccess + +// MapFailure HTTP result of FAILURE +var MapFailure = dtmimp.MapSuccess + +// ErrFailure error for returned failure +var ErrFailure = dtmimp.ErrFailure + +// ErrOngoing error for returned ongoing +var ErrOngoing = dtmimp.ErrOngoing diff --git a/dtmcli/dtmimp/consts.go b/dtmcli/dtmimp/consts.go new file mode 100644 index 0000000..c32d558 --- /dev/null +++ b/dtmcli/dtmimp/consts.go @@ -0,0 +1,14 @@ +package dtmimp + +const ( + // ResultFailure for result of a trans/trans branch + ResultFailure = "FAILURE" + // ResultSuccess for result of a trans/trans branch + ResultSuccess = "SUCCESS" + // ResultOngoing for result of a trans/trans branch + ResultOngoing = "ONGOING" + // DBTypeMysql const for driver mysql + DBTypeMysql = "mysql" + // DBTypePostgres const for driver postgres + DBTypePostgres = "postgres" +) diff --git a/dtmcli/db_special.go b/dtmcli/dtmimp/db_special.go similarity index 99% rename from dtmcli/db_special.go rename to dtmcli/dtmimp/db_special.go index cb61e90..26c6b61 100644 --- a/dtmcli/db_special.go +++ b/dtmcli/dtmimp/db_special.go @@ -1,4 +1,4 @@ -package dtmcli +package dtmimp import ( "fmt" diff --git a/dtmcli/db_special_test.go b/dtmcli/dtmimp/db_special_test.go similarity index 97% rename from dtmcli/db_special_test.go rename to dtmcli/dtmimp/db_special_test.go index 586f64c..16ddae3 100644 --- a/dtmcli/db_special_test.go +++ b/dtmcli/dtmimp/db_special_test.go @@ -1,4 +1,4 @@ -package dtmcli +package dtmimp import ( "testing" diff --git a/dtmcli/dtmimp/trans_base.go b/dtmcli/dtmimp/trans_base.go new file mode 100644 index 0000000..f515c11 --- /dev/null +++ b/dtmcli/dtmimp/trans_base.go @@ -0,0 +1,117 @@ +package dtmimp + +import ( + "errors" + "fmt" + "net/url" + "strings" + + "github.com/go-resty/resty/v2" +) + +// BranchIDGen used to generate a sub branch id +type BranchIDGen struct { + BranchID string + subBranchID int +} + +// NewSubBranchID generate a sub branch id +func (g *BranchIDGen) NewSubBranchID() string { + if g.subBranchID >= 99 { + panic(fmt.Errorf("branch id is larger than 99")) + } + if len(g.BranchID) >= 20 { + panic(fmt.Errorf("total branch id is longer than 20")) + } + g.subBranchID = g.subBranchID + 1 + return g.CurrentSubBranchID() +} + +// CurrentSubBranchID return current branchID +func (g *BranchIDGen) CurrentSubBranchID() string { + return g.BranchID + fmt.Sprintf("%02d", g.subBranchID) +} + +// TransOptions transaction options +type TransOptions struct { + WaitResult bool `json:"wait_result,omitempty" gorm:"-"` + TimeoutToFail int64 `json:"timeout_to_fail,omitempty" gorm:"-"` // for trans type: xa, tcc + RetryInterval int64 `json:"retry_interval,omitempty" gorm:"-"` // for trans type: msg saga xa tcc +} + +// TransBase base for all trans +type TransBase struct { + Gid string `json:"gid"` + TransType string `json:"trans_type"` + Dtm string `json:"-"` + CustomData string `json:"custom_data,omitempty"` + TransOptions + + Steps []map[string]string `json:"steps,omitempty"` // use in MSG/SAGA + Payloads []string `json:"payloads,omitempty"` // used in MSG/SAGA + BinPayloads [][]byte `json:"-"` + BranchIDGen `json:"-"` // used in XA/TCC + BranchType string `json:"-"` // used in XA/TCC + + QueryPrepared string `json:"query_prepared"` // used in MSG +} + +// SetOptions set options +func (tb *TransBase) SetOptions(options *TransOptions) { + tb.TransOptions = *options +} + +// NewTransBase new a TransBase +func NewTransBase(gid string, transType string, dtm string, branchID string) *TransBase { + return &TransBase{ + Gid: gid, + TransType: transType, + BranchIDGen: BranchIDGen{BranchID: branchID}, + Dtm: dtm, + } +} + +// TransBaseFromQuery construct transaction info from request +func TransBaseFromQuery(qs url.Values) *TransBase { + return NewTransBase(qs.Get("gid"), qs.Get("trans_type"), qs.Get("dtm"), qs.Get("branch_id")) +} + +// TransCallDtm TransBase call dtm +func TransCallDtm(tb *TransBase, body interface{}, operation string) error { + resp, err := RestyClient.R(). + SetBody(body).Post(fmt.Sprintf("%s/%s", tb.Dtm, operation)) + if err != nil { + return err + } + if !strings.Contains(resp.String(), ResultSuccess) { + return errors.New(resp.String()) + } + return nil +} + +// TransRegisterBranch TransBase register a branch to dtm +func TransRegisterBranch(tb *TransBase, added map[string]string, operation string) error { + m := map[string]string{ + "gid": tb.Gid, + "trans_type": tb.TransType, + } + for k, v := range added { + m[k] = v + } + return TransCallDtm(tb, m, operation) +} + +// TransRequestBranch TransBAse request branch result +func TransRequestBranch(t *TransBase, body interface{}, branchID string, branchType string, url string) (*resty.Response, error) { + resp, err := RestyClient.R(). + SetBody(body). + SetQueryParams(map[string]string{ + "dtm": t.Dtm, + "gid": t.Gid, + "branch_id": branchID, + "trans_type": t.TransType, + "branch_type": branchType, + }). + Post(url) + return resp, CheckResponse(resp, err) +} diff --git a/dtmcli/xa_base.go b/dtmcli/dtmimp/trans_xa_base.go similarity index 92% rename from dtmcli/xa_base.go rename to dtmcli/dtmimp/trans_xa_base.go index a8c3ceb..014235b 100644 --- a/dtmcli/xa_base.go +++ b/dtmcli/dtmimp/trans_xa_base.go @@ -1,4 +1,4 @@ -package dtmcli +package dtmimp import ( "database/sql" @@ -29,9 +29,8 @@ func (xc *XaClientBase) HandleCallback(gid string, branchID string, action strin } // HandleLocalTrans http/grpc 处理LocalTransaction的公共方法 -func (xc *XaClientBase) HandleLocalTrans(xa *TransBase, cb func(*sql.DB) (interface{}, error)) (ret interface{}, rerr error) { - branchID := xa.NewBranchID() - xaBranch := xa.Gid + "-" + branchID +func (xc *XaClientBase) HandleLocalTrans(xa *TransBase, cb func(*sql.DB) error) (rerr error) { + xaBranch := xa.Gid + "-" + xa.BranchID db, rerr := StandaloneDB(xc.Conf) if rerr != nil { return @@ -54,7 +53,7 @@ func (xc *XaClientBase) HandleLocalTrans(xa *TransBase, cb func(*sql.DB) (interf if rerr != nil { return } - ret, rerr = cb(db) + rerr = cb(db) return } diff --git a/dtmcli/adapter.go b/dtmcli/dtmimp/types.go similarity index 85% rename from dtmcli/adapter.go rename to dtmcli/dtmimp/types.go index d549caa..c962dad 100644 --- a/dtmcli/adapter.go +++ b/dtmcli/dtmimp/types.go @@ -1,8 +1,6 @@ -package dtmcli +package dtmimp -import ( - "database/sql" -) +import "database/sql" // DB inteface of dtmcli db type DB interface { diff --git a/dtmcli/dtmimp/types_test.go b/dtmcli/dtmimp/types_test.go new file mode 100644 index 0000000..803744a --- /dev/null +++ b/dtmcli/dtmimp/types_test.go @@ -0,0 +1,19 @@ +package dtmimp + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestTypes(t *testing.T) { + err := CatchP(func() { + idGen := BranchIDGen{BranchID: "12345678901234567890123"} + idGen.NewSubBranchID() + }) + assert.Error(t, err) + err = CatchP(func() { + idGen := BranchIDGen{subBranchID: 99} + idGen.NewSubBranchID() + }) +} diff --git a/dtmcli/utils.go b/dtmcli/dtmimp/utils.go similarity index 89% rename from dtmcli/utils.go rename to dtmcli/dtmimp/utils.go index e9d511a..531b792 100644 --- a/dtmcli/utils.go +++ b/dtmcli/dtmimp/utils.go @@ -1,4 +1,4 @@ -package dtmcli +package dtmimp import ( "database/sql" @@ -19,6 +19,7 @@ import ( // AsError wrap a panic value as an error func AsError(x interface{}) error { + LogRedf("panic to error: '%v', stack: \n%s", x, debug.Stack()) if e, ok := x.(error); ok { return e } @@ -111,7 +112,7 @@ func MustRemarshal(from interface{}, to interface{}) { E2P(err) } -var layout = "2006-01-02 15:04:05.999" +var layout = "2006/01/02 15:04:05.999" // Logf 输出日志 func Logf(format string, args ...interface{}) { @@ -157,29 +158,11 @@ func FatalIfError(err error) { LogIfFatalf(err != nil, "Fatal error: %v", err) } -// RestyClient the resty object -var RestyClient = resty.New() - -func init() { - // RestyClient.SetTimeout(3 * time.Second) - // RestyClient.SetRetryCount(2) - // RestyClient.SetRetryWaitTime(1 * time.Second) - RestyClient.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error { - r.URL = MayReplaceLocalhost(r.URL) - Logf("requesting: %s %s %v %v", r.Method, r.URL, r.Body, r.QueryParam) - return nil - }) - RestyClient.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { - r := resp.Request - Logf("requested: %s %s %s", r.Method, r.URL, resp.String()) - return nil - }) -} - // GetFuncName get current call func name func GetFuncName() string { pc, _, _, _ := runtime.Caller(1) - return runtime.FuncForPC(pc).Name() + nm := runtime.FuncForPC(pc).Name() + return nm[strings.LastIndex(nm, ".")+1:] } // MayReplaceLocalhost when run in docker compose, change localhost to host.docker.internal for accessing host network @@ -234,7 +217,7 @@ func DBExec(db DB, sql string, values ...interface{}) (affected int64, rerr erro func GetDsn(conf map[string]string) string { host := MayReplaceLocalhost(conf["host"]) driver := conf["driver"] - dsn := MS{ + dsn := map[string]string{ "mysql": fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=true&loc=Local", conf["user"], conf["password"], host, conf["port"], conf["database"]), "postgres": fmt.Sprintf("host=%s user=%s password=%s dbname='%s' port=%s sslmode=disable TimeZone=Asia/Shanghai", @@ -251,6 +234,8 @@ func CheckResponse(resp *resty.Response, err error) error { return errors.New(resp.String()) } else if strings.Contains(resp.String(), ResultFailure) { return ErrFailure + } else if strings.Contains(resp.String(), ResultOngoing) { + return ErrOngoing } } return err @@ -258,6 +243,9 @@ func CheckResponse(resp *resty.Response, err error) error { // CheckResult 检查Result,返回错误 func CheckResult(res interface{}, err error) error { + if err != nil { + return err + } resp, ok := res.(*resty.Response) if ok { return CheckResponse(resp, err) diff --git a/dtmcli/utils_test.go b/dtmcli/dtmimp/utils_test.go similarity index 99% rename from dtmcli/utils_test.go rename to dtmcli/dtmimp/utils_test.go index c0954c3..90c1552 100644 --- a/dtmcli/utils_test.go +++ b/dtmcli/dtmimp/utils_test.go @@ -1,4 +1,4 @@ -package dtmcli +package dtmimp import ( "errors" diff --git a/dtmcli/dtmimp/vars.go b/dtmcli/dtmimp/vars.go new file mode 100644 index 0000000..7f4e824 --- /dev/null +++ b/dtmcli/dtmimp/vars.go @@ -0,0 +1,38 @@ +package dtmimp + +import ( + "errors" + + "github.com/go-resty/resty/v2" +) + +// ErrFailure error of FAILURE +var ErrFailure = errors.New("FAILURE") + +// ErrOngoing error of ONGOING +var ErrOngoing = errors.New("ONGOING") + +// MapSuccess HTTP result of SUCCESS +var MapSuccess = map[string]interface{}{"dtm_result": ResultSuccess} + +// MapFailure HTTP result of FAILURE +var MapFailure = map[string]interface{}{"dtm_result": ResultFailure} + +// RestyClient the resty object +var RestyClient = resty.New() + +func init() { + // RestyClient.SetTimeout(3 * time.Second) + // RestyClient.SetRetryCount(2) + // RestyClient.SetRetryWaitTime(1 * time.Second) + RestyClient.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error { + r.URL = MayReplaceLocalhost(r.URL) + Logf("requesting: %s %s %v %v", r.Method, r.URL, r.Body, r.QueryParam) + return nil + }) + RestyClient.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error { + r := resp.Request + Logf("requested: %s %s %s", r.Method, r.URL, resp.String()) + return nil + }) +} diff --git a/dtmcli/message.go b/dtmcli/message.go deleted file mode 100644 index 5f7b25f..0000000 --- a/dtmcli/message.go +++ /dev/null @@ -1,39 +0,0 @@ -package dtmcli - -// Msg reliable msg type -type Msg struct { - TransBase - Steps []MsgStep `json:"steps"` - QueryPrepared string `json:"query_prepared"` -} - -// MsgStep struct of one step msg -type MsgStep struct { - Action string `json:"action"` - Data string `json:"data"` -} - -// NewMsg create new msg -func NewMsg(server string, gid string) *Msg { - return &Msg{TransBase: *NewTransBase(gid, "msg", server, "")} -} - -// Add add a new step -func (s *Msg) Add(action string, postData interface{}) *Msg { - s.Steps = append(s.Steps, MsgStep{ - Action: action, - Data: MustMarshalString(postData), - }) - return s -} - -// Prepare prepare the msg -func (s *Msg) Prepare(queryPrepared string) error { - s.QueryPrepared = OrString(queryPrepared, s.QueryPrepared) - return s.callDtm(s, "prepare") -} - -// Submit submit the msg -func (s *Msg) Submit() error { - return s.callDtm(s, "submit") -} diff --git a/dtmcli/msg.go b/dtmcli/msg.go new file mode 100644 index 0000000..a2fd73f --- /dev/null +++ b/dtmcli/msg.go @@ -0,0 +1,31 @@ +package dtmcli + +import "github.com/yedf/dtm/dtmcli/dtmimp" + +// Msg reliable msg type +type Msg struct { + dtmimp.TransBase +} + +// NewMsg create new msg +func NewMsg(server string, gid string) *Msg { + return &Msg{TransBase: *dtmimp.NewTransBase(gid, "msg", server, "")} +} + +// Add add a new step +func (s *Msg) Add(action string, postData interface{}) *Msg { + s.Steps = append(s.Steps, map[string]string{"action": action}) + s.Payloads = append(s.Payloads, dtmimp.MustMarshalString(postData)) + return s +} + +// Prepare prepare the msg, msg will later be submitted +func (s *Msg) Prepare(queryPrepared string) error { + s.QueryPrepared = dtmimp.OrString(queryPrepared, s.QueryPrepared) + return dtmimp.TransCallDtm(&s.TransBase, s, "prepare") +} + +// Submit submit the msg +func (s *Msg) Submit() error { + return dtmimp.TransCallDtm(&s.TransBase, s, "submit") +} diff --git a/dtmcli/saga.go b/dtmcli/saga.go index 80a3faa..7f9ce7e 100644 --- a/dtmcli/saga.go +++ b/dtmcli/saga.go @@ -1,40 +1,30 @@ package dtmcli -import "fmt" +import ( + "github.com/yedf/dtm/dtmcli/dtmimp" +) // Saga struct of saga type Saga struct { - TransBase - Steps []SagaStep `json:"steps"` + dtmimp.TransBase orders map[int][]int concurrent bool } -// SagaStep one step of saga -type SagaStep struct { - Action string `json:"action"` - Compensate string `json:"compensate"` - Data string `json:"data"` -} - // NewSaga create a saga func NewSaga(server string, gid string) *Saga { - return &Saga{TransBase: *NewTransBase(gid, "saga", server, ""), orders: map[int][]int{}} + return &Saga{TransBase: *dtmimp.NewTransBase(gid, "saga", server, ""), orders: map[int][]int{}} } // Add add a saga step func (s *Saga) Add(action string, compensate string, postData interface{}) *Saga { - s.Steps = append(s.Steps, SagaStep{ - Action: action, - Compensate: compensate, - Data: MustMarshalString(postData), - }) + s.Steps = append(s.Steps, map[string]string{"action": action, "compensate": compensate}) + s.Payloads = append(s.Payloads, dtmimp.MustMarshalString(postData)) return s } // AddBranchOrder specify that branch should be after preBranches. branch should is larger than all the element in preBranches func (s *Saga) AddBranchOrder(branch int, preBranches []int) *Saga { - PanicIf(branch > len(s.Steps), fmt.Errorf("step value: %d is invalid. which cannot be larger than total steps: %d", branch, len(s.Steps))) s.orders[branch] = preBranches return s } @@ -48,7 +38,7 @@ func (s *Saga) EnableConcurrent() *Saga { // Submit submit the saga trans func (s *Saga) Submit() error { if s.concurrent { - s.CustomData = MustMarshalString(M{"orders": s.orders, "concurrent": s.concurrent}) + s.CustomData = dtmimp.MustMarshalString(map[string]interface{}{"orders": s.orders, "concurrent": s.concurrent}) } - return s.callDtm(s, "submit") + return dtmimp.TransCallDtm(&s.TransBase, s, "submit") } diff --git a/dtmcli/tcc.go b/dtmcli/tcc.go index 013d3c0..c8618a2 100644 --- a/dtmcli/tcc.go +++ b/dtmcli/tcc.go @@ -5,11 +5,12 @@ import ( "net/url" "github.com/go-resty/resty/v2" + "github.com/yedf/dtm/dtmcli/dtmimp" ) // Tcc struct of tcc type Tcc struct { - TransBase + dtmimp.TransBase } // TccGlobalFunc type of global tcc call @@ -20,16 +21,16 @@ type TccGlobalFunc func(tcc *Tcc) (*resty.Response, error) // gid 全局事务id // tccFunc tcc事务函数,里面会定义全局事务的分支 func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr error) { - tcc := &Tcc{TransBase: *NewTransBase(gid, "tcc", dtm, "")} - rerr = tcc.callDtm(tcc, "prepare") + tcc := &Tcc{TransBase: *dtmimp.NewTransBase(gid, "tcc", dtm, "")} + rerr = dtmimp.TransCallDtm(&tcc.TransBase, tcc, "prepare") if rerr != nil { return rerr } // 小概率情况下,prepare成功了,但是由于网络状况导致上面Failure,那么不执行下面defer的内容,等待超时后再回滚标记事务失败,也没有问题 defer func() { x := recover() - operation := If(x == nil && rerr == nil, "submit", "abort").(string) - err := tcc.callDtm(tcc, operation) + operation := dtmimp.If(x == nil && rerr == nil, "submit", "abort").(string) + err := dtmimp.TransCallDtm(&tcc.TransBase, tcc, operation) if rerr == nil { rerr = err } @@ -37,16 +38,15 @@ func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr e panic(x) } }() - resp, rerr := tccFunc(tcc) - rerr = CheckResponse(resp, rerr) + _, rerr = tccFunc(tcc) return } // TccFromQuery tcc from request info func TccFromQuery(qs url.Values) (*Tcc, error) { - tcc := &Tcc{TransBase: *TransBaseFromQuery(qs)} + tcc := &Tcc{TransBase: *dtmimp.TransBaseFromQuery(qs)} if tcc.Dtm == "" || tcc.Gid == "" { - return nil, fmt.Errorf("bad tcc info. dtm: %s, gid: %s parentID: %s", tcc.Dtm, tcc.Gid, tcc.parentID) + return nil, fmt.Errorf("bad tcc info. dtm: %s, gid: %s parentID: %s", tcc.Dtm, tcc.Gid, tcc.BranchID) } return tcc, nil } @@ -54,28 +54,16 @@ func TccFromQuery(qs url.Values) (*Tcc, error) { // CallBranch call a tcc branch // 函数首先注册子事务的所有分支,成功后调用try分支,返回try分支的调用结果 func (t *Tcc) CallBranch(body interface{}, tryURL string, confirmURL string, cancelURL string) (*resty.Response, error) { - branchID := t.NewBranchID() - err := t.callDtm(&M{ - "gid": t.Gid, + branchID := t.NewSubBranchID() + err := dtmimp.TransRegisterBranch(&t.TransBase, map[string]string{ + "data": dtmimp.MustMarshalString(body), "branch_id": branchID, - "trans_type": "tcc", - "data": string(MustMarshal(body)), BranchTry: tryURL, BranchConfirm: confirmURL, - "cancel": cancelURL, + BranchCancel: cancelURL, }, "registerTccBranch") if err != nil { return nil, err } - resp, err := RestyClient.R(). - SetBody(body). - SetQueryParams(MS{ - "dtm": t.Dtm, - "gid": t.Gid, - "branch_id": branchID, - "trans_type": "tcc", - "branch_type": BranchTry, - }). - Post(tryURL) - return resp, CheckResponse(resp, err) + return dtmimp.TransRequestBranch(&t.TransBase, body, branchID, BranchTry, tryURL) } diff --git a/dtmcli/trans_test.go b/dtmcli/trans_test.go index 05ab78e..7b4b98b 100644 --- a/dtmcli/trans_test.go +++ b/dtmcli/trans_test.go @@ -19,6 +19,6 @@ func TestQuery(t *testing.T) { } func TestXa(t *testing.T) { - _, err := NewXaClient("http://localhost:8080", MS{}, ":::::", nil) + _, err := NewXaClient("http://localhost:8080", map[string]string{}, ":::::", nil) assert.Error(t, err) } diff --git a/dtmcli/types.go b/dtmcli/types.go index 1db9227..5e0098a 100644 --- a/dtmcli/types.go +++ b/dtmcli/types.go @@ -1,109 +1,33 @@ package dtmcli import ( - "errors" "fmt" - "net/url" - "strings" -) - -// M a short name -type M = map[string]interface{} -// MS a short name -type MS = map[string]string + "github.com/yedf/dtm/dtmcli/dtmimp" +) // MustGenGid generate a new gid func MustGenGid(server string) string { - res := MS{} - resp, err := RestyClient.R().SetResult(&res).Get(server + "/newGid") + res := map[string]string{} + resp, err := dtmimp.RestyClient.R().SetResult(&res).Get(server + "/newGid") if err != nil || res["gid"] == "" { panic(fmt.Errorf("newGid error: %v, resp: %s", err, resp)) } return res["gid"] } -// IDGenerator used to generate a branch id -type IDGenerator struct { - parentID string - branchID int -} - -// NewBranchID generate a branch id -func (g *IDGenerator) NewBranchID() string { - if g.branchID >= 99 { - panic(fmt.Errorf("branch id is larger than 99")) - } - if len(g.parentID) >= 20 { - panic(fmt.Errorf("total branch id is longer than 20")) - } - g.branchID = g.branchID + 1 - return g.CurrentBranchID() -} - -// CurrentBranchID return current branchID -func (g *IDGenerator) CurrentBranchID() string { - return g.parentID + fmt.Sprintf("%02d", g.branchID) -} - -// TransOptions transaction options -type TransOptions struct { - WaitResult bool `json:"wait_result,omitempty" gorm:"-"` - TimeoutToFail int64 `json:"timeout_to_fail,omitempty" gorm:"-"` // for trans type: xa, tcc - RetryInterval int64 `json:"retry_interval,omitempty" gorm:"-"` // for trans type: msg saga xa tcc -} - -// TransBase 事务的基础类 -type TransBase struct { - Gid string `json:"gid"` - TransType string `json:"trans_type"` - Dtm string `json:"-"` - CustomData string `json:"custom_data,omitempty"` - IDGenerator - TransOptions -} - -// SetOptions set options -func (tb *TransBase) SetOptions(options *TransOptions) { - tb.TransOptions = *options -} +// DB interface +type DB = dtmimp.DB -// NewTransBase 1 -func NewTransBase(gid string, transType string, dtm string, parentID string) *TransBase { - return &TransBase{ - Gid: gid, - TransType: transType, - IDGenerator: IDGenerator{parentID: parentID}, - Dtm: dtm, - } -} +// Tx interface +type Tx = dtmimp.Tx -// TransBaseFromQuery construct transaction info from request -func TransBaseFromQuery(qs url.Values) *TransBase { - return NewTransBase(qs.Get("gid"), qs.Get("trans_type"), qs.Get("dtm"), qs.Get("branch_id")) +// SetCurrentDBType set currentDBType +func SetCurrentDBType(dbType string) { + dtmimp.SetCurrentDBType(dbType) } -// callDtm 调用dtm服务器,返回事务的状态 -func (tb *TransBase) callDtm(body interface{}, operation string) error { - resp, err := RestyClient.R(). - SetBody(body).Post(fmt.Sprintf("%s/%s", tb.Dtm, operation)) - if err != nil { - return err - } - if strings.Contains(resp.String(), ResultFailure) { - return errors.New(resp.String()) - } - return nil +// GetCurrentDBType get currentDBType +func GetCurrentDBType() string { + return dtmimp.GetCurrentDBType() } - -// ErrFailure 表示返回失败,要求回滚 -var ErrFailure = errors.New("FAILURE") - -// ErrOngoing 表示暂时失败,要求重试 -var ErrOngoing = errors.New("ONGOING") - -// MapSuccess 表示返回成功,可以进行下一步 -var MapSuccess = M{"dtm_result": ResultSuccess} - -// MapFailure 表示返回失败,要求回滚 -var MapFailure = M{"dtm_result": ResultFailure} diff --git a/dtmcli/types_test.go b/dtmcli/types_test.go index f8c647e..48525bd 100644 --- a/dtmcli/types_test.go +++ b/dtmcli/types_test.go @@ -5,19 +5,11 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func TestTypes(t *testing.T) { - err := CatchP(func() { - idGen := IDGenerator{parentID: "12345678901234567890123"} - idGen.NewBranchID() - }) - assert.Error(t, err) - err = CatchP(func() { - idGen := IDGenerator{branchID: 99} - idGen.NewBranchID() - }) - err = CatchP(func() { + err := dtmimp.CatchP(func() { MustGenGid("http://localhost:8080/api/no") }) assert.Error(t, err) diff --git a/dtmcli/xa.go b/dtmcli/xa.go index ebdbabd..5999d67 100644 --- a/dtmcli/xa.go +++ b/dtmcli/xa.go @@ -6,39 +6,40 @@ import ( "net/url" "github.com/go-resty/resty/v2" + "github.com/yedf/dtm/dtmcli/dtmimp" ) // XaGlobalFunc type of xa global function type XaGlobalFunc func(xa *Xa) (*resty.Response, error) // XaLocalFunc type of xa local function -type XaLocalFunc func(db *sql.DB, xa *Xa) (interface{}, error) +type XaLocalFunc func(db *sql.DB, xa *Xa) error // XaRegisterCallback type of xa register callback handler type XaRegisterCallback func(path string, xa *XaClient) // XaClient xa client type XaClient struct { - XaClientBase + dtmimp.XaClientBase } // Xa xa transaction type Xa struct { - TransBase + dtmimp.TransBase } // XaFromQuery construct xa info from request func XaFromQuery(qs url.Values) (*Xa, error) { - xa := &Xa{TransBase: *TransBaseFromQuery(qs)} - if xa.Gid == "" || xa.parentID == "" { - return nil, fmt.Errorf("bad xa info: gid: %s parentid: %s", xa.Gid, xa.parentID) + xa := &Xa{TransBase: *dtmimp.TransBaseFromQuery(qs)} + if xa.Gid == "" || xa.BranchID == "" { + return nil, fmt.Errorf("bad xa info: gid: %s branchid: %s", xa.Gid, xa.BranchID) } return xa, nil } // NewXaClient construct a xa client func NewXaClient(server string, mysqlConf map[string]string, notifyURL string, register XaRegisterCallback) (*XaClient, error) { - xa := &XaClient{XaClientBase: XaClientBase{ + xa := &XaClient{XaClientBase: dtmimp.XaClientBase{ Server: server, Conf: mysqlConf, NotifyURL: notifyURL, @@ -57,46 +58,36 @@ func (xc *XaClient) HandleCallback(gid string, branchID string, action string) ( } // XaLocalTransaction start a xa local transaction -func (xc *XaClient) XaLocalTransaction(qs url.Values, xaFunc XaLocalFunc) (ret interface{}, rerr error) { - xa, rerr := XaFromQuery(qs) - if rerr != nil { - return +func (xc *XaClient) XaLocalTransaction(qs url.Values, xaFunc XaLocalFunc) error { + xa, err := XaFromQuery(qs) + if err != nil { + return err } - ret, rerr = xc.HandleLocalTrans(&xa.TransBase, func(db *sql.DB) (ret interface{}, rerr error) { - ret, rerr = xaFunc(db, xa) - rerr = CheckResult(ret, rerr) - if rerr != nil { - return + return xc.HandleLocalTrans(&xa.TransBase, func(db *sql.DB) error { + err := xaFunc(db, xa) + if err != nil { + return err } - rerr = xa.callDtm(&M{"gid": xa.Gid, "branch_id": xa.CurrentBranchID(), "trans_type": "xa", "url": xc.XaClientBase.NotifyURL}, "registerXaBranch") - return + return dtmimp.TransRegisterBranch(&xa.TransBase, map[string]string{ + "url": xc.XaClientBase.NotifyURL, + "branch_id": xa.BranchID, + }, "registerXaBranch") }) - return } // XaGlobalTransaction start a xa global transaction func (xc *XaClient) XaGlobalTransaction(gid string, xaFunc XaGlobalFunc) (rerr error) { - xa := Xa{TransBase: *NewTransBase(gid, "xa", xc.XaClientBase.Server, "")} + xa := Xa{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.XaClientBase.Server, "")} return xc.HandleGlobalTrans(&xa.TransBase, func(action string) error { - return xa.callDtm(xa, action) + return dtmimp.TransCallDtm(&xa.TransBase, &xa, action) }, func() error { - resp, rerr := xaFunc(&xa) - return CheckResponse(resp, rerr) + _, rerr := xaFunc(&xa) + return rerr }) } // CallBranch call a xa branch func (x *Xa) CallBranch(body interface{}, url string) (*resty.Response, error) { - branchID := x.NewBranchID() - resp, err := RestyClient.R(). - SetBody(body). - SetQueryParams(MS{ - "dtm": x.Dtm, - "gid": x.Gid, - "branch_id": branchID, - "trans_type": "xa", - "branch_type": BranchAction, - }). - Post(url) - return resp, CheckResponse(resp, err) + branchID := x.NewSubBranchID() + return dtmimp.TransRequestBranch(&x.TransBase, body, branchID, BranchAction, url) } diff --git a/dtmgrpc/barrier.go b/dtmgrpc/barrier.go index f24fc46..5c96246 100644 --- a/dtmgrpc/barrier.go +++ b/dtmgrpc/barrier.go @@ -1,18 +1,14 @@ package dtmgrpc import ( + "context" + "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" ) -// BranchBarrier 子事务屏障 -type BranchBarrier struct { - *dtmcli.BranchBarrier -} - -// BarrierFromGrpc 从BusiRequest生成一个Barrier -func BarrierFromGrpc(in *BusiRequest) (*BranchBarrier, error) { - b, err := dtmcli.BarrierFrom(in.Info.TransType, in.Info.Gid, in.Info.BranchID, in.Info.BranchType) - return &BranchBarrier{ - BranchBarrier: b, - }, err +// BarrierFromGrpc generate a Barrier from grpc context +func BarrierFromGrpc(ctx context.Context) (*dtmcli.BranchBarrier, error) { + tb := dtmgimp.TransBaseFromGrpc(ctx) + return dtmcli.BarrierFrom(tb.TransType, tb.Gid, tb.BranchID, tb.BranchType) } diff --git a/dtmgrpc/dtmgimp/dtmgimp.pb.go b/dtmgrpc/dtmgimp/dtmgimp.pb.go new file mode 100644 index 0000000..9ef264c --- /dev/null +++ b/dtmgrpc/dtmgimp/dtmgimp.pb.go @@ -0,0 +1,674 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.27.1 +// protoc v3.17.3 +// source: dtmgrpc/dtmgimp/dtmgimp.proto + +package dtmgimp + +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) +) + +type DtmTransOptions struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + WaitResult bool `protobuf:"varint,1,opt,name=WaitResult,proto3" json:"WaitResult,omitempty"` + TimeoutToFail int64 `protobuf:"varint,2,opt,name=TimeoutToFail,proto3" json:"TimeoutToFail,omitempty"` + RetryInterval int64 `protobuf:"varint,3,opt,name=RetryInterval,proto3" json:"RetryInterval,omitempty"` +} + +func (x *DtmTransOptions) Reset() { + *x = DtmTransOptions{} + if protoimpl.UnsafeEnabled { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DtmTransOptions) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DtmTransOptions) ProtoMessage() {} + +func (x *DtmTransOptions) ProtoReflect() protoreflect.Message { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_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 DtmTransOptions.ProtoReflect.Descriptor instead. +func (*DtmTransOptions) Descriptor() ([]byte, []int) { + return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{0} +} + +func (x *DtmTransOptions) GetWaitResult() bool { + if x != nil { + return x.WaitResult + } + return false +} + +func (x *DtmTransOptions) GetTimeoutToFail() int64 { + if x != nil { + return x.TimeoutToFail + } + return 0 +} + +func (x *DtmTransOptions) GetRetryInterval() int64 { + if x != nil { + return x.RetryInterval + } + return 0 +} + +// DtmRequest request sent to dtm server +type DtmRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Gid string `protobuf:"bytes,1,opt,name=Gid,proto3" json:"Gid,omitempty"` + TransType string `protobuf:"bytes,2,opt,name=TransType,proto3" json:"TransType,omitempty"` + TransOptions *DtmTransOptions `protobuf:"bytes,3,opt,name=TransOptions,proto3" json:"TransOptions,omitempty"` + CustomedData string `protobuf:"bytes,4,opt,name=CustomedData,proto3" json:"CustomedData,omitempty"` + BinPayloads [][]byte `protobuf:"bytes,5,rep,name=BinPayloads,proto3" json:"BinPayloads,omitempty"` // for MSG/SAGA branch payloads + QueryPrepared string `protobuf:"bytes,6,opt,name=QueryPrepared,proto3" json:"QueryPrepared,omitempty"` // for MSG + Steps string `protobuf:"bytes,7,opt,name=Steps,proto3" json:"Steps,omitempty"` +} + +func (x *DtmRequest) Reset() { + *x = DtmRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DtmRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DtmRequest) ProtoMessage() {} + +func (x *DtmRequest) ProtoReflect() protoreflect.Message { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_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 DtmRequest.ProtoReflect.Descriptor instead. +func (*DtmRequest) Descriptor() ([]byte, []int) { + return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{1} +} + +func (x *DtmRequest) GetGid() string { + if x != nil { + return x.Gid + } + return "" +} + +func (x *DtmRequest) GetTransType() string { + if x != nil { + return x.TransType + } + return "" +} + +func (x *DtmRequest) GetTransOptions() *DtmTransOptions { + if x != nil { + return x.TransOptions + } + return nil +} + +func (x *DtmRequest) GetCustomedData() string { + if x != nil { + return x.CustomedData + } + return "" +} + +func (x *DtmRequest) GetBinPayloads() [][]byte { + if x != nil { + return x.BinPayloads + } + return nil +} + +func (x *DtmRequest) GetQueryPrepared() string { + if x != nil { + return x.QueryPrepared + } + return "" +} + +func (x *DtmRequest) GetSteps() string { + if x != nil { + return x.Steps + } + return "" +} + +type DtmGidReply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Gid string `protobuf:"bytes,1,opt,name=Gid,proto3" json:"Gid,omitempty"` +} + +func (x *DtmGidReply) Reset() { + *x = DtmGidReply{} + if protoimpl.UnsafeEnabled { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DtmGidReply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DtmGidReply) ProtoMessage() {} + +func (x *DtmGidReply) ProtoReflect() protoreflect.Message { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[2] + 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 DtmGidReply.ProtoReflect.Descriptor instead. +func (*DtmGidReply) Descriptor() ([]byte, []int) { + return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{2} +} + +func (x *DtmGidReply) GetGid() string { + if x != nil { + return x.Gid + } + return "" +} + +type DtmBranchInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Gid string `protobuf:"bytes,1,opt,name=Gid,proto3" json:"Gid,omitempty"` + TransType string `protobuf:"bytes,2,opt,name=TransType,proto3" json:"TransType,omitempty"` + BranchID string `protobuf:"bytes,3,opt,name=BranchID,proto3" json:"BranchID,omitempty"` + BranchType string `protobuf:"bytes,4,opt,name=BranchType,proto3" json:"BranchType,omitempty"` +} + +func (x *DtmBranchInfo) Reset() { + *x = DtmBranchInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DtmBranchInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DtmBranchInfo) ProtoMessage() {} + +func (x *DtmBranchInfo) ProtoReflect() protoreflect.Message { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[3] + 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 DtmBranchInfo.ProtoReflect.Descriptor instead. +func (*DtmBranchInfo) Descriptor() ([]byte, []int) { + return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{3} +} + +func (x *DtmBranchInfo) GetGid() string { + if x != nil { + return x.Gid + } + return "" +} + +func (x *DtmBranchInfo) GetTransType() string { + if x != nil { + return x.TransType + } + return "" +} + +func (x *DtmBranchInfo) GetBranchID() string { + if x != nil { + return x.BranchID + } + return "" +} + +func (x *DtmBranchInfo) GetBranchType() string { + if x != nil { + return x.BranchType + } + return "" +} + +type DtmTccBranchRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info *DtmBranchInfo `protobuf:"bytes,1,opt,name=Info,proto3" json:"Info,omitempty"` + BusiPayload []byte `protobuf:"bytes,2,opt,name=BusiPayload,proto3" json:"BusiPayload,omitempty"` + Try string `protobuf:"bytes,3,opt,name=Try,proto3" json:"Try,omitempty"` + Confirm string `protobuf:"bytes,4,opt,name=Confirm,proto3" json:"Confirm,omitempty"` + Cancel string `protobuf:"bytes,5,opt,name=Cancel,proto3" json:"Cancel,omitempty"` +} + +func (x *DtmTccBranchRequest) Reset() { + *x = DtmTccBranchRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DtmTccBranchRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DtmTccBranchRequest) ProtoMessage() {} + +func (x *DtmTccBranchRequest) ProtoReflect() protoreflect.Message { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[4] + 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 DtmTccBranchRequest.ProtoReflect.Descriptor instead. +func (*DtmTccBranchRequest) Descriptor() ([]byte, []int) { + return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{4} +} + +func (x *DtmTccBranchRequest) GetInfo() *DtmBranchInfo { + if x != nil { + return x.Info + } + return nil +} + +func (x *DtmTccBranchRequest) GetBusiPayload() []byte { + if x != nil { + return x.BusiPayload + } + return nil +} + +func (x *DtmTccBranchRequest) GetTry() string { + if x != nil { + return x.Try + } + return "" +} + +func (x *DtmTccBranchRequest) GetConfirm() string { + if x != nil { + return x.Confirm + } + return "" +} + +func (x *DtmTccBranchRequest) GetCancel() string { + if x != nil { + return x.Cancel + } + return "" +} + +type DtmXaBranchRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info *DtmBranchInfo `protobuf:"bytes,1,opt,name=Info,proto3" json:"Info,omitempty"` + BusiPayload []byte `protobuf:"bytes,2,opt,name=BusiPayload,proto3" json:"BusiPayload,omitempty"` + Notify string `protobuf:"bytes,3,opt,name=Notify,proto3" json:"Notify,omitempty"` // dtm will call this url to commit/rollback +} + +func (x *DtmXaBranchRequest) Reset() { + *x = DtmXaBranchRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DtmXaBranchRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DtmXaBranchRequest) ProtoMessage() {} + +func (x *DtmXaBranchRequest) ProtoReflect() protoreflect.Message { + mi := &file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[5] + 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 DtmXaBranchRequest.ProtoReflect.Descriptor instead. +func (*DtmXaBranchRequest) Descriptor() ([]byte, []int) { + return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP(), []int{5} +} + +func (x *DtmXaBranchRequest) GetInfo() *DtmBranchInfo { + if x != nil { + return x.Info + } + return nil +} + +func (x *DtmXaBranchRequest) GetBusiPayload() []byte { + if x != nil { + return x.BusiPayload + } + return nil +} + +func (x *DtmXaBranchRequest) GetNotify() string { + if x != nil { + return x.Notify + } + return "" +} + +var File_dtmgrpc_dtmgimp_dtmgimp_proto protoreflect.FileDescriptor + +var file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc = []byte{ + 0x0a, 0x1d, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, + 0x70, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, + 0x07, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7d, 0x0a, 0x0f, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x57, 0x61, 0x69, 0x74, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x57, 0x61, + 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x54, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0d, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x54, 0x6f, 0x46, 0x61, 0x69, 0x6c, 0x12, 0x24, + 0x0a, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0d, 0x52, 0x65, 0x74, 0x72, 0x79, 0x49, 0x6e, 0x74, 0x65, + 0x72, 0x76, 0x61, 0x6c, 0x22, 0xfc, 0x01, 0x0a, 0x0a, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, + 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, + 0x79, 0x70, 0x65, 0x12, 0x3c, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x64, 0x74, 0x6d, 0x67, + 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, + 0x6f, 0x6e, 0x73, 0x52, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x22, 0x0a, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, 0x64, 0x44, 0x61, 0x74, + 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x65, + 0x64, 0x44, 0x61, 0x74, 0x61, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x69, 0x6e, 0x50, 0x61, 0x79, 0x6c, + 0x6f, 0x61, 0x64, 0x73, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x69, 0x6e, 0x50, + 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x73, 0x12, 0x24, 0x0a, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, + 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x53, 0x74, 0x65, 0x70, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x53, 0x74, + 0x65, 0x70, 0x73, 0x22, 0x1f, 0x0a, 0x0b, 0x44, 0x74, 0x6d, 0x47, 0x69, 0x64, 0x52, 0x65, 0x70, + 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x47, 0x69, 0x64, 0x22, 0x7b, 0x0a, 0x0d, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, + 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, + 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, + 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x54, 0x79, 0x70, + 0x65, 0x22, 0xa7, 0x01, 0x0a, 0x13, 0x44, 0x74, 0x6d, 0x54, 0x63, 0x63, 0x42, 0x72, 0x61, 0x6e, + 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x49, 0x6e, 0x66, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, + 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, + 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x75, 0x73, 0x69, + 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x54, 0x72, 0x79, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x54, 0x72, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x72, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x66, + 0x69, 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x43, 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x22, 0x7a, 0x0a, 0x12, 0x44, + 0x74, 0x6d, 0x58, 0x61, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x2a, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x42, 0x72, 0x61, + 0x6e, 0x63, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, + 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x50, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x12, + 0x16, 0x0a, 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x32, 0x82, 0x03, 0x0a, 0x03, 0x44, 0x74, 0x6d, 0x12, + 0x38, 0x0a, 0x06, 0x4e, 0x65, 0x77, 0x47, 0x69, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x47, + 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x53, 0x75, 0x62, + 0x6d, 0x69, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, + 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x22, 0x00, 0x12, 0x38, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x13, 0x2e, + 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x05, + 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, + 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x22, 0x00, 0x12, 0x4b, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, + 0x54, 0x63, 0x63, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1c, 0x2e, 0x64, 0x74, 0x6d, 0x67, + 0x69, 0x6d, 0x70, 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x63, 0x63, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, + 0x00, 0x12, 0x49, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x58, 0x61, 0x42, + 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x69, 0x6d, 0x70, 0x2e, + 0x44, 0x74, 0x6d, 0x58, 0x61, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x25, 0x5a, 0x23, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x65, 0x64, 0x66, 0x2f, + 0x64, 0x74, 0x6d, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x74, 0x6d, 0x67, + 0x69, 0x6d, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescOnce sync.Once + file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData = file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc +) + +func file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescGZIP() []byte { + file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescOnce.Do(func() { + file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData = protoimpl.X.CompressGZIP(file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData) + }) + return file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDescData +} + +var file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_dtmgrpc_dtmgimp_dtmgimp_proto_goTypes = []interface{}{ + (*DtmTransOptions)(nil), // 0: dtmgimp.DtmTransOptions + (*DtmRequest)(nil), // 1: dtmgimp.DtmRequest + (*DtmGidReply)(nil), // 2: dtmgimp.DtmGidReply + (*DtmBranchInfo)(nil), // 3: dtmgimp.DtmBranchInfo + (*DtmTccBranchRequest)(nil), // 4: dtmgimp.DtmTccBranchRequest + (*DtmXaBranchRequest)(nil), // 5: dtmgimp.DtmXaBranchRequest + (*emptypb.Empty)(nil), // 6: google.protobuf.Empty +} +var file_dtmgrpc_dtmgimp_dtmgimp_proto_depIdxs = []int32{ + 0, // 0: dtmgimp.DtmRequest.TransOptions:type_name -> dtmgimp.DtmTransOptions + 3, // 1: dtmgimp.DtmTccBranchRequest.Info:type_name -> dtmgimp.DtmBranchInfo + 3, // 2: dtmgimp.DtmXaBranchRequest.Info:type_name -> dtmgimp.DtmBranchInfo + 6, // 3: dtmgimp.Dtm.NewGid:input_type -> google.protobuf.Empty + 1, // 4: dtmgimp.Dtm.Submit:input_type -> dtmgimp.DtmRequest + 1, // 5: dtmgimp.Dtm.Prepare:input_type -> dtmgimp.DtmRequest + 1, // 6: dtmgimp.Dtm.Abort:input_type -> dtmgimp.DtmRequest + 4, // 7: dtmgimp.Dtm.RegisterTccBranch:input_type -> dtmgimp.DtmTccBranchRequest + 5, // 8: dtmgimp.Dtm.RegisterXaBranch:input_type -> dtmgimp.DtmXaBranchRequest + 2, // 9: dtmgimp.Dtm.NewGid:output_type -> dtmgimp.DtmGidReply + 6, // 10: dtmgimp.Dtm.Submit:output_type -> google.protobuf.Empty + 6, // 11: dtmgimp.Dtm.Prepare:output_type -> google.protobuf.Empty + 6, // 12: dtmgimp.Dtm.Abort:output_type -> google.protobuf.Empty + 6, // 13: dtmgimp.Dtm.RegisterTccBranch:output_type -> google.protobuf.Empty + 6, // 14: dtmgimp.Dtm.RegisterXaBranch:output_type -> google.protobuf.Empty + 9, // [9:15] is the sub-list for method output_type + 3, // [3:9] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name +} + +func init() { file_dtmgrpc_dtmgimp_dtmgimp_proto_init() } +func file_dtmgrpc_dtmgimp_dtmgimp_proto_init() { + if File_dtmgrpc_dtmgimp_dtmgimp_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DtmTransOptions); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DtmRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DtmGidReply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DtmBranchInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DtmTccBranchRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DtmXaBranchRequest); 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_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_dtmgrpc_dtmgimp_dtmgimp_proto_goTypes, + DependencyIndexes: file_dtmgrpc_dtmgimp_dtmgimp_proto_depIdxs, + MessageInfos: file_dtmgrpc_dtmgimp_dtmgimp_proto_msgTypes, + }.Build() + File_dtmgrpc_dtmgimp_dtmgimp_proto = out.File + file_dtmgrpc_dtmgimp_dtmgimp_proto_rawDesc = nil + file_dtmgrpc_dtmgimp_dtmgimp_proto_goTypes = nil + file_dtmgrpc_dtmgimp_dtmgimp_proto_depIdxs = nil +} diff --git a/dtmgrpc/dtmgimp/dtmgimp.proto b/dtmgrpc/dtmgimp/dtmgimp.proto new file mode 100644 index 0000000..ed32f18 --- /dev/null +++ b/dtmgrpc/dtmgimp/dtmgimp.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +option go_package = "github.com/yedf/dtm/dtmgrpc/dtmgimp"; +import "google/protobuf/empty.proto"; + +package dtmgimp; + +// The dtm service definition. +service Dtm { + rpc NewGid(google.protobuf.Empty) returns (DtmGidReply) {} + rpc Submit(DtmRequest) returns (google.protobuf.Empty) {} + rpc Prepare(DtmRequest) returns (google.protobuf.Empty) {} + rpc Abort(DtmRequest) returns (google.protobuf.Empty) {} + rpc RegisterTccBranch(DtmTccBranchRequest) returns (google.protobuf.Empty) {} + rpc RegisterXaBranch(DtmXaBranchRequest) returns (google.protobuf.Empty) {} +} + +message DtmTransOptions { + bool WaitResult = 1; + int64 TimeoutToFail = 2; + int64 RetryInterval = 3; +} + +// DtmRequest request sent to dtm server +message DtmRequest { + string Gid = 1; + string TransType = 2; + DtmTransOptions TransOptions = 3; + string CustomedData = 4; + repeated bytes BinPayloads = 5; // for MSG/SAGA branch payloads + string QueryPrepared = 6; // for MSG + string Steps = 7; +} + +message DtmGidReply { + string Gid = 1; +} + +message DtmBranchInfo { + string Gid = 1; + string TransType = 2; + string BranchID = 3; + string BranchType = 4; +} + +message DtmTccBranchRequest { + DtmBranchInfo Info = 1; + bytes BusiPayload = 2; + string Try = 3; + string Confirm = 4; + string Cancel = 5; +} + +message DtmXaBranchRequest { + DtmBranchInfo Info = 1; + bytes BusiPayload = 2; + string Notify = 3; // dtm will call this url to commit/rollback +} diff --git a/dtmgrpc/dtmgrpc_grpc.pb.go b/dtmgrpc/dtmgimp/dtmgimp_grpc.pb.go similarity index 92% rename from dtmgrpc/dtmgrpc_grpc.pb.go rename to dtmgrpc/dtmgimp/dtmgimp_grpc.pb.go index 99ae4e0..e480194 100644 --- a/dtmgrpc/dtmgrpc_grpc.pb.go +++ b/dtmgrpc/dtmgimp/dtmgimp_grpc.pb.go @@ -1,6 +1,6 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. -package dtmgrpc +package dtmgimp import ( context "context" @@ -37,7 +37,7 @@ func NewDtmClient(cc grpc.ClientConnInterface) DtmClient { func (c *dtmClient) NewGid(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*DtmGidReply, error) { out := new(DtmGidReply) - err := c.cc.Invoke(ctx, "/dtmgrpc.Dtm/NewGid", in, out, opts...) + err := c.cc.Invoke(ctx, "/dtmgimp.Dtm/NewGid", in, out, opts...) if err != nil { return nil, err } @@ -46,7 +46,7 @@ func (c *dtmClient) NewGid(ctx context.Context, in *emptypb.Empty, opts ...grpc. func (c *dtmClient) Submit(ctx context.Context, in *DtmRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/dtmgrpc.Dtm/Submit", in, out, opts...) + err := c.cc.Invoke(ctx, "/dtmgimp.Dtm/Submit", in, out, opts...) if err != nil { return nil, err } @@ -55,7 +55,7 @@ func (c *dtmClient) Submit(ctx context.Context, in *DtmRequest, opts ...grpc.Cal func (c *dtmClient) Prepare(ctx context.Context, in *DtmRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/dtmgrpc.Dtm/Prepare", in, out, opts...) + err := c.cc.Invoke(ctx, "/dtmgimp.Dtm/Prepare", in, out, opts...) if err != nil { return nil, err } @@ -64,7 +64,7 @@ func (c *dtmClient) Prepare(ctx context.Context, in *DtmRequest, opts ...grpc.Ca func (c *dtmClient) Abort(ctx context.Context, in *DtmRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/dtmgrpc.Dtm/Abort", in, out, opts...) + err := c.cc.Invoke(ctx, "/dtmgimp.Dtm/Abort", in, out, opts...) if err != nil { return nil, err } @@ -73,7 +73,7 @@ func (c *dtmClient) Abort(ctx context.Context, in *DtmRequest, opts ...grpc.Call func (c *dtmClient) RegisterTccBranch(ctx context.Context, in *DtmTccBranchRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/dtmgrpc.Dtm/RegisterTccBranch", in, out, opts...) + err := c.cc.Invoke(ctx, "/dtmgimp.Dtm/RegisterTccBranch", in, out, opts...) if err != nil { return nil, err } @@ -82,7 +82,7 @@ func (c *dtmClient) RegisterTccBranch(ctx context.Context, in *DtmTccBranchReque func (c *dtmClient) RegisterXaBranch(ctx context.Context, in *DtmXaBranchRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, "/dtmgrpc.Dtm/RegisterXaBranch", in, out, opts...) + err := c.cc.Invoke(ctx, "/dtmgimp.Dtm/RegisterXaBranch", in, out, opts...) if err != nil { return nil, err } @@ -147,7 +147,7 @@ func _Dtm_NewGid_Handler(srv interface{}, ctx context.Context, dec func(interfac } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/dtmgrpc.Dtm/NewGid", + FullMethod: "/dtmgimp.Dtm/NewGid", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DtmServer).NewGid(ctx, req.(*emptypb.Empty)) @@ -165,7 +165,7 @@ func _Dtm_Submit_Handler(srv interface{}, ctx context.Context, dec func(interfac } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/dtmgrpc.Dtm/Submit", + FullMethod: "/dtmgimp.Dtm/Submit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DtmServer).Submit(ctx, req.(*DtmRequest)) @@ -183,7 +183,7 @@ func _Dtm_Prepare_Handler(srv interface{}, ctx context.Context, dec func(interfa } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/dtmgrpc.Dtm/Prepare", + FullMethod: "/dtmgimp.Dtm/Prepare", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DtmServer).Prepare(ctx, req.(*DtmRequest)) @@ -201,7 +201,7 @@ func _Dtm_Abort_Handler(srv interface{}, ctx context.Context, dec func(interface } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/dtmgrpc.Dtm/Abort", + FullMethod: "/dtmgimp.Dtm/Abort", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DtmServer).Abort(ctx, req.(*DtmRequest)) @@ -219,7 +219,7 @@ func _Dtm_RegisterTccBranch_Handler(srv interface{}, ctx context.Context, dec fu } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/dtmgrpc.Dtm/RegisterTccBranch", + FullMethod: "/dtmgimp.Dtm/RegisterTccBranch", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DtmServer).RegisterTccBranch(ctx, req.(*DtmTccBranchRequest)) @@ -237,7 +237,7 @@ func _Dtm_RegisterXaBranch_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/dtmgrpc.Dtm/RegisterXaBranch", + FullMethod: "/dtmgimp.Dtm/RegisterXaBranch", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(DtmServer).RegisterXaBranch(ctx, req.(*DtmXaBranchRequest)) @@ -249,7 +249,7 @@ func _Dtm_RegisterXaBranch_Handler(srv interface{}, ctx context.Context, dec fun // It's only intended for direct use with grpc.RegisterService, // and not to be introspected or modified (even as a copy) var Dtm_ServiceDesc = grpc.ServiceDesc{ - ServiceName: "dtmgrpc.Dtm", + ServiceName: "dtmgimp.Dtm", HandlerType: (*DtmServer)(nil), Methods: []grpc.MethodDesc{ { @@ -278,5 +278,5 @@ var Dtm_ServiceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "dtmgrpc/dtmgrpc.proto", + Metadata: "dtmgrpc/dtmgimp/dtmgimp.proto", } diff --git a/dtmgrpc/dtmgimp/grpc_clients.go b/dtmgrpc/dtmgimp/grpc_clients.go new file mode 100644 index 0000000..e32647e --- /dev/null +++ b/dtmgrpc/dtmgimp/grpc_clients.go @@ -0,0 +1,67 @@ +package dtmgimp + +import ( + sync "sync" + + "github.com/yedf/dtm/dtmcli/dtmimp" + grpc "google.golang.org/grpc" +) + +type rawCodec struct{} + +func (cb rawCodec) Marshal(v interface{}) ([]byte, error) { + return v.([]byte), nil +} + +func (cb rawCodec) Unmarshal(data []byte, v interface{}) error { + ba, _ := v.([]byte) + for index, byte := range data { + ba[index] = byte + } + return nil +} + +func (cb rawCodec) Name() string { return "dtm_raw" } + +var normalClients, rawClients sync.Map + +// MustGetDtmClient 1 +func MustGetDtmClient(grpcServer string) DtmClient { + return NewDtmClient(MustGetGrpcConn(grpcServer, false)) +} + +// MustGetRawDtmClient must get raw codec grpc conn +func MustGetRawDtmClient(grpcServer string) DtmClient { + return NewDtmClient(MustGetGrpcConn(grpcServer, true)) +} + +// GetGrpcConn 1 +func GetGrpcConn(grpcServer string, isRaw bool) (conn *grpc.ClientConn, rerr error) { + clients := &normalClients + if isRaw { + clients = &rawClients + } + grpcServer = dtmimp.MayReplaceLocalhost(grpcServer) + v, ok := clients.Load(grpcServer) + if !ok { + opts := grpc.WithDefaultCallOptions() + if isRaw { + opts = grpc.WithDefaultCallOptions(grpc.ForceCodec(rawCodec{})) + } + dtmimp.Logf("grpc client connecting %s", grpcServer) + conn, rerr := grpc.Dial(grpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(GrpcClientLog), opts) + if rerr == nil { + clients.Store(grpcServer, conn) + v = conn + dtmimp.Logf("grpc client inited for %s", grpcServer) + } + } + return v.(*grpc.ClientConn), rerr +} + +// MustGetGrpcConn 1 +func MustGetGrpcConn(grpcServer string, isRaw bool) *grpc.ClientConn { + conn, err := GetGrpcConn(grpcServer, isRaw) + dtmimp.E2P(err) + return conn +} diff --git a/dtmgrpc/dtmgimp/types.go b/dtmgrpc/dtmgimp/types.go new file mode 100644 index 0000000..e17fa7f --- /dev/null +++ b/dtmgrpc/dtmgimp/types.go @@ -0,0 +1,61 @@ +package dtmgimp + +import ( + "context" + "fmt" + "strings" + + "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// GetServerAndMethod 将grpc的url分解为server和method +func GetServerAndMethod(grpcURL string) (string, string) { + fs := strings.Split(grpcURL, "/") + server := fs[0] + method := "/" + strings.Join(fs[1:], "/") + return server, method +} + +// GrpcServerLog 打印grpc服务端的日志 +func GrpcServerLog(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { + dtmimp.Logf("grpc server handling: %s %v", info.FullMethod, req) + LogDtmCtx(ctx) + m, err := handler(ctx, req) + res := fmt.Sprintf("grpc server handled: %s %v result: %v err: %v", info.FullMethod, req, m, err) + if err != nil { + dtmimp.LogRedf("%s", res) + } else { + dtmimp.Logf("%s", res) + } + return m, err +} + +// GrpcClientLog 打印grpc服务端的日志 +func GrpcClientLog(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + dtmimp.Logf("grpc client calling: %s%s %v", cc.Target(), method, req) + LogDtmCtx(ctx) + err := invoker(ctx, method, req, reply, cc, opts...) + res := fmt.Sprintf("grpc client called: %s%s %v result: %v err: %v", cc.Target(), method, req, reply, err) + if err != nil { + dtmimp.LogRedf("%s", res) + } else { + dtmimp.Logf("%s", res) + } + return err +} + +// Result2Error 将通用的result转成grpc的error +func Result2Error(res interface{}, err error) error { + e := dtmimp.CheckResult(res, err) + if e == dtmimp.ErrFailure { + dtmimp.LogRedf("failure: res: %v, err: %v", res, e) + return status.New(codes.Aborted, dtmcli.ResultFailure).Err() + } else if e == dtmimp.ErrOngoing { + return status.New(codes.Aborted, dtmcli.ResultOngoing).Err() + } + return e +} diff --git a/dtmgrpc/dtmgimp/utils.go b/dtmgrpc/dtmgimp/utils.go new file mode 100644 index 0000000..badcf14 --- /dev/null +++ b/dtmgrpc/dtmgimp/utils.go @@ -0,0 +1,73 @@ +package dtmgimp + +import ( + context "context" + + "github.com/yedf/dtm/dtmcli/dtmimp" + "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/proto" + emptypb "google.golang.org/protobuf/types/known/emptypb" +) + +// MustProtoMarshal must version of proto.Marshal +func MustProtoMarshal(msg proto.Message) []byte { + b, err := proto.Marshal(msg) + dtmimp.PanicIf(err != nil, err) + return b +} + +// DtmGrpcCall make a convenient call to dtm +func DtmGrpcCall(s *dtmimp.TransBase, operation string) error { + reply := emptypb.Empty{} + return MustGetGrpcConn(s.Dtm, false).Invoke(context.Background(), "/dtmgimp.Dtm/"+operation, &DtmRequest{ + Gid: s.Gid, + TransType: s.TransType, + TransOptions: &DtmTransOptions{ + WaitResult: s.WaitResult, + TimeoutToFail: s.TimeoutToFail, + RetryInterval: s.RetryInterval, + }, + QueryPrepared: s.QueryPrepared, + CustomedData: s.CustomData, + BinPayloads: s.BinPayloads, + Steps: dtmimp.MustMarshalString(s.Steps), + }, &reply) +} + +const mdpre string = "dtm-" + +// TransInfo2Ctx add trans info to grpc context +func TransInfo2Ctx(gid, transType, branchID, branchType, dtm string) context.Context { + md := metadata.Pairs( + mdpre+"gid", gid, + mdpre+"trans_type", transType, + mdpre+"branch_id", branchID, + mdpre+"branch_type", branchType, + mdpre+"dtm", dtm, + ) + return metadata.NewOutgoingContext(context.Background(), md) +} + +// LogDtmCtx logout dtm info in context metadata +func LogDtmCtx(ctx context.Context) { + tb := TransBaseFromGrpc(ctx) + if tb.Gid != "" { + dtmimp.Logf("gid: %s trans_type: %s branch_id: %s branch_type: %s dtm: %s", tb.Gid, tb.TransType, tb.BranchID, tb.BranchType, tb.Dtm) + } +} + +func mdGet(md metadata.MD, key string) string { + v := md.Get(mdpre + key) + if len(v) == 0 { + return "" + } + return v[0] +} + +// TransBaseFromGrpc get trans base info from a context metadata +func TransBaseFromGrpc(ctx context.Context) *dtmimp.TransBase { + md, _ := metadata.FromIncomingContext(ctx) + tb := dtmimp.NewTransBase(mdGet(md, "gid"), mdGet(md, "trans_type"), mdGet(md, "dtm"), mdGet(md, "branch_id")) + tb.BranchType = mdGet(md, "branch_type") + return tb +} diff --git a/dtmgrpc/dtmgrpc.pb.go b/dtmgrpc/dtmgrpc.pb.go deleted file mode 100644 index 6c4f1ae..0000000 --- a/dtmgrpc/dtmgrpc.pb.go +++ /dev/null @@ -1,717 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// versions: -// protoc-gen-go v1.26.0 -// protoc v3.17.3 -// source: dtmgrpc/dtmgrpc.proto - -package dtmgrpc - -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 发给dtm服务器的消息,响应为Emtpy,error == nil为成功,== Aborted 为失败 == 其他 可以重试 -type DtmRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Gid string `protobuf:"bytes,1,opt,name=Gid,proto3" json:"Gid,omitempty"` - TransType string `protobuf:"bytes,2,opt,name=TransType,proto3" json:"TransType,omitempty"` - // QueryPrepared 对于事务消息处于prepared状态过期,责护查询QueryPrepared - QueryPrepared string `protobuf:"bytes,3,opt,name=QueryPrepared,proto3" json:"QueryPrepared,omitempty"` - // WaitResult 设定这个值,Submit操作会等待dtm处理一次请求,可能在返回时,就可以把分布式事务完成 - WaitResult bool `protobuf:"varint,4,opt,name=WaitResult,proto3" json:"WaitResult,omitempty"` - // Data 包含saga、msg的子事务信息 - Data string `protobuf:"bytes,5,opt,name=Data,proto3" json:"Data,omitempty"` -} - -func (x *DtmRequest) Reset() { - *x = DtmRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DtmRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DtmRequest) ProtoMessage() {} - -func (x *DtmRequest) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgrpc_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 DtmRequest.ProtoReflect.Descriptor instead. -func (*DtmRequest) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgrpc_proto_rawDescGZIP(), []int{0} -} - -func (x *DtmRequest) GetGid() string { - if x != nil { - return x.Gid - } - return "" -} - -func (x *DtmRequest) GetTransType() string { - if x != nil { - return x.TransType - } - return "" -} - -func (x *DtmRequest) GetQueryPrepared() string { - if x != nil { - return x.QueryPrepared - } - return "" -} - -func (x *DtmRequest) GetWaitResult() bool { - if x != nil { - return x.WaitResult - } - return false -} - -func (x *DtmRequest) GetData() string { - if x != nil { - return x.Data - } - return "" -} - -type DtmGidReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Gid string `protobuf:"bytes,1,opt,name=Gid,proto3" json:"Gid,omitempty"` -} - -func (x *DtmGidReply) Reset() { - *x = DtmGidReply{} - if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DtmGidReply) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DtmGidReply) ProtoMessage() {} - -func (x *DtmGidReply) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgrpc_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 DtmGidReply.ProtoReflect.Descriptor instead. -func (*DtmGidReply) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgrpc_proto_rawDescGZIP(), []int{1} -} - -func (x *DtmGidReply) GetGid() string { - if x != nil { - return x.Gid - } - return "" -} - -// BranchInfo 事务分支信息 -type BranchInfo struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Gid string `protobuf:"bytes,1,opt,name=Gid,proto3" json:"Gid,omitempty"` - TransType string `protobuf:"bytes,2,opt,name=TransType,proto3" json:"TransType,omitempty"` - BranchID string `protobuf:"bytes,3,opt,name=BranchID,proto3" json:"BranchID,omitempty"` - BranchType string `protobuf:"bytes,4,opt,name=BranchType,proto3" json:"BranchType,omitempty"` -} - -func (x *BranchInfo) Reset() { - *x = BranchInfo{} - if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BranchInfo) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BranchInfo) ProtoMessage() {} - -func (x *BranchInfo) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[2] - 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 BranchInfo.ProtoReflect.Descriptor instead. -func (*BranchInfo) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgrpc_proto_rawDescGZIP(), []int{2} -} - -func (x *BranchInfo) GetGid() string { - if x != nil { - return x.Gid - } - return "" -} - -func (x *BranchInfo) GetTransType() string { - if x != nil { - return x.TransType - } - return "" -} - -func (x *BranchInfo) GetBranchID() string { - if x != nil { - return x.BranchID - } - return "" -} - -func (x *BranchInfo) GetBranchType() string { - if x != nil { - return x.BranchType - } - return "" -} - -type DtmTccBranchRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Info *BranchInfo `protobuf:"bytes,1,opt,name=Info,proto3" json:"Info,omitempty"` - BusiData string `protobuf:"bytes,2,opt,name=BusiData,proto3" json:"BusiData,omitempty"` - Try string `protobuf:"bytes,3,opt,name=Try,proto3" json:"Try,omitempty"` - Confirm string `protobuf:"bytes,4,opt,name=Confirm,proto3" json:"Confirm,omitempty"` - Cancel string `protobuf:"bytes,5,opt,name=Cancel,proto3" json:"Cancel,omitempty"` -} - -func (x *DtmTccBranchRequest) Reset() { - *x = DtmTccBranchRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DtmTccBranchRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DtmTccBranchRequest) ProtoMessage() {} - -func (x *DtmTccBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[3] - 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 DtmTccBranchRequest.ProtoReflect.Descriptor instead. -func (*DtmTccBranchRequest) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgrpc_proto_rawDescGZIP(), []int{3} -} - -func (x *DtmTccBranchRequest) GetInfo() *BranchInfo { - if x != nil { - return x.Info - } - return nil -} - -func (x *DtmTccBranchRequest) GetBusiData() string { - if x != nil { - return x.BusiData - } - return "" -} - -func (x *DtmTccBranchRequest) GetTry() string { - if x != nil { - return x.Try - } - return "" -} - -func (x *DtmTccBranchRequest) GetConfirm() string { - if x != nil { - return x.Confirm - } - return "" -} - -func (x *DtmTccBranchRequest) GetCancel() string { - if x != nil { - return x.Cancel - } - return "" -} - -type DtmXaBranchRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Info *BranchInfo `protobuf:"bytes,1,opt,name=Info,proto3" json:"Info,omitempty"` - BusiData string `protobuf:"bytes,2,opt,name=BusiData,proto3" json:"BusiData,omitempty"` - // dtm通知业务提交和回滚的地址 - Notify string `protobuf:"bytes,3,opt,name=Notify,proto3" json:"Notify,omitempty"` -} - -func (x *DtmXaBranchRequest) Reset() { - *x = DtmXaBranchRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *DtmXaBranchRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*DtmXaBranchRequest) ProtoMessage() {} - -func (x *DtmXaBranchRequest) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[4] - 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 DtmXaBranchRequest.ProtoReflect.Descriptor instead. -func (*DtmXaBranchRequest) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgrpc_proto_rawDescGZIP(), []int{4} -} - -func (x *DtmXaBranchRequest) GetInfo() *BranchInfo { - if x != nil { - return x.Info - } - return nil -} - -func (x *DtmXaBranchRequest) GetBusiData() string { - if x != nil { - return x.BusiData - } - return "" -} - -func (x *DtmXaBranchRequest) GetNotify() string { - if x != nil { - return x.Notify - } - return "" -} - -// BusiRequest 请求业务的数据,需要携带事务信息,便于业务进行幂等处理 -type BusiRequest struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - Info *BranchInfo `protobuf:"bytes,1,opt,name=Info,proto3" json:"Info,omitempty"` - Dtm string `protobuf:"bytes,2,opt,name=Dtm,proto3" json:"Dtm,omitempty"` - BusiData []byte `protobuf:"bytes,3,opt,name=BusiData,proto3" json:"BusiData,omitempty"` -} - -func (x *BusiRequest) Reset() { - *x = BusiRequest{} - if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } -} - -func (x *BusiRequest) String() string { - return protoimpl.X.MessageStringOf(x) -} - -func (*BusiRequest) ProtoMessage() {} - -func (x *BusiRequest) ProtoReflect() protoreflect.Message { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[5] - 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 BusiRequest.ProtoReflect.Descriptor instead. -func (*BusiRequest) Descriptor() ([]byte, []int) { - return file_dtmgrpc_dtmgrpc_proto_rawDescGZIP(), []int{5} -} - -func (x *BusiRequest) GetInfo() *BranchInfo { - if x != nil { - return x.Info - } - return nil -} - -func (x *BusiRequest) GetDtm() string { - if x != nil { - return x.Dtm - } - return "" -} - -func (x *BusiRequest) GetBusiData() []byte { - if x != nil { - return x.BusiData - } - return nil -} - -// BusiReply 业务响应数据 -type BusiReply struct { - state protoimpl.MessageState - sizeCache protoimpl.SizeCache - unknownFields protoimpl.UnknownFields - - BusiData []byte `protobuf:"bytes,1,opt,name=BusiData,proto3" json:"BusiData,omitempty"` -} - -func (x *BusiReply) Reset() { - *x = BusiReply{} - if protoimpl.UnsafeEnabled { - mi := &file_dtmgrpc_dtmgrpc_proto_msgTypes[6] - 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_dtmgrpc_dtmgrpc_proto_msgTypes[6] - 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_dtmgrpc_dtmgrpc_proto_rawDescGZIP(), []int{6} -} - -func (x *BusiReply) GetBusiData() []byte { - if x != nil { - return x.BusiData - } - return nil -} - -var File_dtmgrpc_dtmgrpc_proto protoreflect.FileDescriptor - -var file_dtmgrpc_dtmgrpc_proto_rawDesc = []byte{ - 0x0a, 0x15, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, - 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, - 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, 0x96, 0x01, - 0x0a, 0x0a, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, - 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x24, 0x0a, 0x0d, - 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x64, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x51, 0x75, 0x65, 0x72, 0x79, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, - 0x65, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x57, 0x61, 0x69, 0x74, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x44, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x44, 0x61, 0x74, 0x61, 0x22, 0x1f, 0x0a, 0x0b, 0x44, 0x74, 0x6d, 0x47, 0x69, 0x64, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x22, 0x78, 0x0a, 0x0a, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, 0x03, 0x47, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x47, 0x69, 0x64, 0x12, 0x1c, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x54, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, - 0x44, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, - 0x44, 0x12, 0x1e, 0x0a, 0x0a, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x54, 0x79, 0x70, 0x65, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x54, 0x79, 0x70, - 0x65, 0x22, 0x9e, 0x01, 0x0a, 0x13, 0x44, 0x74, 0x6d, 0x54, 0x63, 0x63, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x49, 0x6e, 0x66, - 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, - 0x63, 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x49, 0x6e, - 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x75, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x75, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x12, 0x10, - 0x0a, 0x03, 0x54, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x54, 0x72, 0x79, - 0x12, 0x18, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12, 0x16, 0x0a, 0x06, 0x43, 0x61, - 0x6e, 0x63, 0x65, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x43, 0x61, 0x6e, 0x63, - 0x65, 0x6c, 0x22, 0x71, 0x0a, 0x12, 0x44, 0x74, 0x6d, 0x58, 0x61, 0x42, 0x72, 0x61, 0x6e, 0x63, - 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x49, 0x6e, 0x66, - 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x75, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x42, 0x75, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, - 0x06, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x4e, - 0x6f, 0x74, 0x69, 0x66, 0x79, 0x22, 0x64, 0x0a, 0x0b, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x72, 0x61, - 0x6e, 0x63, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x10, 0x0a, - 0x03, 0x44, 0x74, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x44, 0x74, 0x6d, 0x12, - 0x1a, 0x0a, 0x08, 0x42, 0x75, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x08, 0x42, 0x75, 0x73, 0x69, 0x44, 0x61, 0x74, 0x61, 0x22, 0x27, 0x0a, 0x09, 0x42, - 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x42, 0x75, 0x73, 0x69, - 0x44, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x42, 0x75, 0x73, 0x69, - 0x44, 0x61, 0x74, 0x61, 0x32, 0x82, 0x03, 0x0a, 0x03, 0x44, 0x74, 0x6d, 0x12, 0x38, 0x0a, 0x06, - 0x4e, 0x65, 0x77, 0x47, 0x69, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x14, - 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x74, 0x6d, 0x47, 0x69, 0x64, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x06, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, - 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, - 0x38, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x70, 0x61, 0x72, 0x65, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, - 0x67, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x74, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x05, 0x41, 0x62, 0x6f, - 0x72, 0x74, 0x12, 0x13, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x74, 0x6d, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, - 0x00, 0x12, 0x4b, 0x0a, 0x11, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x54, 0x63, 0x63, - 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x12, 0x1c, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x44, 0x74, 0x6d, 0x54, 0x63, 0x63, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x12, 0x49, - 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x58, 0x61, 0x42, 0x72, 0x61, 0x6e, - 0x63, 0x68, 0x12, 0x1b, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x74, 0x6d, - 0x58, 0x61, 0x42, 0x72, 0x61, 0x6e, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x22, 0x00, 0x42, 0x1d, 0x5a, 0x1b, 0x67, 0x69, 0x74, - 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x65, 0x64, 0x66, 0x2f, 0x64, 0x74, 0x6d, - 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, -} - -var ( - file_dtmgrpc_dtmgrpc_proto_rawDescOnce sync.Once - file_dtmgrpc_dtmgrpc_proto_rawDescData = file_dtmgrpc_dtmgrpc_proto_rawDesc -) - -func file_dtmgrpc_dtmgrpc_proto_rawDescGZIP() []byte { - file_dtmgrpc_dtmgrpc_proto_rawDescOnce.Do(func() { - file_dtmgrpc_dtmgrpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_dtmgrpc_dtmgrpc_proto_rawDescData) - }) - return file_dtmgrpc_dtmgrpc_proto_rawDescData -} - -var file_dtmgrpc_dtmgrpc_proto_msgTypes = make([]protoimpl.MessageInfo, 7) -var file_dtmgrpc_dtmgrpc_proto_goTypes = []interface{}{ - (*DtmRequest)(nil), // 0: dtmgrpc.DtmRequest - (*DtmGidReply)(nil), // 1: dtmgrpc.DtmGidReply - (*BranchInfo)(nil), // 2: dtmgrpc.BranchInfo - (*DtmTccBranchRequest)(nil), // 3: dtmgrpc.DtmTccBranchRequest - (*DtmXaBranchRequest)(nil), // 4: dtmgrpc.DtmXaBranchRequest - (*BusiRequest)(nil), // 5: dtmgrpc.BusiRequest - (*BusiReply)(nil), // 6: dtmgrpc.BusiReply - (*emptypb.Empty)(nil), // 7: google.protobuf.Empty -} -var file_dtmgrpc_dtmgrpc_proto_depIdxs = []int32{ - 2, // 0: dtmgrpc.DtmTccBranchRequest.Info:type_name -> dtmgrpc.BranchInfo - 2, // 1: dtmgrpc.DtmXaBranchRequest.Info:type_name -> dtmgrpc.BranchInfo - 2, // 2: dtmgrpc.BusiRequest.Info:type_name -> dtmgrpc.BranchInfo - 7, // 3: dtmgrpc.Dtm.NewGid:input_type -> google.protobuf.Empty - 0, // 4: dtmgrpc.Dtm.Submit:input_type -> dtmgrpc.DtmRequest - 0, // 5: dtmgrpc.Dtm.Prepare:input_type -> dtmgrpc.DtmRequest - 0, // 6: dtmgrpc.Dtm.Abort:input_type -> dtmgrpc.DtmRequest - 3, // 7: dtmgrpc.Dtm.RegisterTccBranch:input_type -> dtmgrpc.DtmTccBranchRequest - 4, // 8: dtmgrpc.Dtm.RegisterXaBranch:input_type -> dtmgrpc.DtmXaBranchRequest - 1, // 9: dtmgrpc.Dtm.NewGid:output_type -> dtmgrpc.DtmGidReply - 7, // 10: dtmgrpc.Dtm.Submit:output_type -> google.protobuf.Empty - 7, // 11: dtmgrpc.Dtm.Prepare:output_type -> google.protobuf.Empty - 7, // 12: dtmgrpc.Dtm.Abort:output_type -> google.protobuf.Empty - 7, // 13: dtmgrpc.Dtm.RegisterTccBranch:output_type -> google.protobuf.Empty - 7, // 14: dtmgrpc.Dtm.RegisterXaBranch:output_type -> google.protobuf.Empty - 9, // [9:15] is the sub-list for method output_type - 3, // [3:9] is the sub-list for method input_type - 3, // [3:3] is the sub-list for extension type_name - 3, // [3:3] is the sub-list for extension extendee - 0, // [0:3] is the sub-list for field type_name -} - -func init() { file_dtmgrpc_dtmgrpc_proto_init() } -func file_dtmgrpc_dtmgrpc_proto_init() { - if File_dtmgrpc_dtmgrpc_proto != nil { - return - } - if !protoimpl.UnsafeEnabled { - file_dtmgrpc_dtmgrpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DtmRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_dtmgrpc_dtmgrpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DtmGidReply); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_dtmgrpc_dtmgrpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BranchInfo); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_dtmgrpc_dtmgrpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DtmTccBranchRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_dtmgrpc_dtmgrpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*DtmXaBranchRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_dtmgrpc_dtmgrpc_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BusiRequest); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_dtmgrpc_dtmgrpc_proto_msgTypes[6].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_dtmgrpc_dtmgrpc_proto_rawDesc, - NumEnums: 0, - NumMessages: 7, - NumExtensions: 0, - NumServices: 1, - }, - GoTypes: file_dtmgrpc_dtmgrpc_proto_goTypes, - DependencyIndexes: file_dtmgrpc_dtmgrpc_proto_depIdxs, - MessageInfos: file_dtmgrpc_dtmgrpc_proto_msgTypes, - }.Build() - File_dtmgrpc_dtmgrpc_proto = out.File - file_dtmgrpc_dtmgrpc_proto_rawDesc = nil - file_dtmgrpc_dtmgrpc_proto_goTypes = nil - file_dtmgrpc_dtmgrpc_proto_depIdxs = nil -} diff --git a/dtmgrpc/dtmgrpc.proto b/dtmgrpc/dtmgrpc.proto deleted file mode 100644 index e6fe971..0000000 --- a/dtmgrpc/dtmgrpc.proto +++ /dev/null @@ -1,66 +0,0 @@ -syntax = "proto3"; - -option go_package = "github.com/yedf/dtm/dtmgrpc"; -import "google/protobuf/empty.proto"; - -package dtmgrpc; - -// The dtm service definition. -service Dtm { - rpc NewGid(google.protobuf.Empty) returns (DtmGidReply) {} - rpc Submit(DtmRequest) returns (google.protobuf.Empty) {} - rpc Prepare(DtmRequest) returns (google.protobuf.Empty) {} - rpc Abort(DtmRequest) returns (google.protobuf.Empty) {} - rpc RegisterTccBranch(DtmTccBranchRequest) returns (google.protobuf.Empty) {} - rpc RegisterXaBranch(DtmXaBranchRequest) returns (google.protobuf.Empty) {} -} - -// DtmRequest 发给dtm服务器的消息,响应为Emtpy,error == nil为成功,== Aborted 为失败 == 其他 可以重试 -message DtmRequest { - string Gid = 1; - string TransType = 2; - // QueryPrepared 对于事务消息处于prepared状态过期,责护查询QueryPrepared - string QueryPrepared = 3; - // WaitResult 设定这个值,Submit操作会等待dtm处理一次请求,可能在返回时,就可以把分布式事务完成 - bool WaitResult = 4; - // Data 包含saga、msg的子事务信息 - string Data = 5; -} - -message DtmGidReply { - string Gid = 1; -} -// BranchInfo 事务分支信息 -message BranchInfo { - string Gid = 1; - string TransType = 2; - string BranchID = 3; - string BranchType = 4; -} - -message DtmTccBranchRequest { - BranchInfo Info = 1; - string BusiData = 2; - string Try = 3; - string Confirm = 4; - string Cancel = 5; -} - -message DtmXaBranchRequest { - BranchInfo Info = 1; - string BusiData = 2; - // dtm通知业务提交和回滚的地址 - string Notify = 3; -} - -// BusiRequest 请求业务的数据,需要携带事务信息,便于业务进行幂等处理 -message BusiRequest { - BranchInfo Info = 1; - string Dtm = 2; - bytes BusiData = 3; -} - -// BusiReply 业务响应数据 -message BusiReply { - bytes BusiData = 1; -} \ No newline at end of file diff --git a/dtmgrpc/message.go b/dtmgrpc/message.go deleted file mode 100644 index 9f8a223..0000000 --- a/dtmgrpc/message.go +++ /dev/null @@ -1,50 +0,0 @@ -package dtmgrpc - -import ( - "context" - - "github.com/yedf/dtm/dtmcli" -) - -// MsgGrpc reliable msg type -type MsgGrpc struct { - dtmcli.TransBase - Steps []dtmcli.MsgStep `json:"steps"` - QueryPrepared string `json:"query_prepared"` -} - -// NewMsgGrpc create new msg -func NewMsgGrpc(server string, gid string) *MsgGrpc { - return &MsgGrpc{TransBase: *dtmcli.NewTransBase(gid, "msg", server, "")} -} - -// Add add a new step -func (s *MsgGrpc) Add(action string, data []byte) *MsgGrpc { - s.Steps = append(s.Steps, dtmcli.MsgStep{ - Action: action, - Data: string(data), - }) - return s -} - -// Submit submit the msg -func (s *MsgGrpc) Submit() error { - _, err := MustGetDtmClient(s.Dtm).Submit(context.Background(), &DtmRequest{ - Gid: s.Gid, - TransType: s.TransType, - Data: dtmcli.MustMarshalString(&s.Steps), - }) - return err -} - -// Prepare prepare the msg -func (s *MsgGrpc) Prepare(queryPrepared string) error { - s.QueryPrepared = dtmcli.OrString(queryPrepared, s.QueryPrepared) - _, err := MustGetDtmClient(s.Dtm).Prepare(context.Background(), &DtmRequest{ - Gid: s.Gid, - TransType: s.TransType, - QueryPrepared: s.QueryPrepared, - Data: dtmcli.MustMarshalString(&s.Steps), - }) - return err -} diff --git a/dtmgrpc/msg.go b/dtmgrpc/msg.go new file mode 100644 index 0000000..7297794 --- /dev/null +++ b/dtmgrpc/msg.go @@ -0,0 +1,36 @@ +package dtmgrpc + +import ( + "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "google.golang.org/protobuf/proto" +) + +// MsgGrpc reliable msg type +type MsgGrpc struct { + dtmcli.Msg +} + +// NewMsgGrpc create new msg +func NewMsgGrpc(server string, gid string) *MsgGrpc { + return &MsgGrpc{Msg: *dtmcli.NewMsg(server, gid)} +} + +// Add add a new step +func (s *MsgGrpc) Add(action string, msg proto.Message) *MsgGrpc { + s.Steps = append(s.Steps, map[string]string{"action": action}) + s.BinPayloads = append(s.BinPayloads, dtmgimp.MustProtoMarshal(msg)) + return s +} + +// Prepare prepare the msg, msg will later be submitted +func (s *MsgGrpc) Prepare(queryPrepared string) error { + s.QueryPrepared = dtmimp.OrString(queryPrepared, s.QueryPrepared) + return dtmgimp.DtmGrpcCall(&s.TransBase, "Prepare") +} + +// Submit submit the msg +func (s *MsgGrpc) Submit() error { + return dtmgimp.DtmGrpcCall(&s.TransBase, "Submit") +} diff --git a/dtmgrpc/saga.go b/dtmgrpc/saga.go index 4d37353..2fa6c84 100644 --- a/dtmgrpc/saga.go +++ b/dtmgrpc/saga.go @@ -1,38 +1,41 @@ package dtmgrpc import ( - context "context" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "google.golang.org/protobuf/proto" ) // SagaGrpc struct of saga type SagaGrpc struct { - dtmcli.TransBase - Steps []dtmcli.SagaStep `json:"steps"` + dtmcli.Saga } -// NewSaga create a saga -func NewSaga(server string, gid string) *SagaGrpc { - return &SagaGrpc{TransBase: *dtmcli.NewTransBase(gid, "saga", server, "")} +// NewSagaGrpc create a saga +func NewSagaGrpc(server string, gid string) *SagaGrpc { + return &SagaGrpc{Saga: *dtmcli.NewSaga(server, gid)} } // Add add a saga step -func (s *SagaGrpc) Add(action string, compensate string, busiData []byte) *SagaGrpc { - s.Steps = append(s.Steps, dtmcli.SagaStep{ - Action: action, - Compensate: compensate, - Data: string(busiData), - }) +func (s *SagaGrpc) Add(action string, compensate string, payload proto.Message) *SagaGrpc { + s.Steps = append(s.Steps, map[string]string{"action": action, "compensate": compensate}) + s.BinPayloads = append(s.BinPayloads, dtmgimp.MustProtoMarshal(payload)) + return s +} + +// AddBranchOrder specify that branch should be after preBranches. branch should is larger than all the element in preBranches +func (s *SagaGrpc) AddBranchOrder(branch int, preBranches []int) *SagaGrpc { + s.Saga.AddBranchOrder(branch, preBranches) + return s +} + +// EnableConcurrent enable the concurrent exec of sub trans +func (s *SagaGrpc) EnableConcurrent() *SagaGrpc { + s.Saga.EnableConcurrent() return s } // Submit submit the saga trans func (s *SagaGrpc) Submit() error { - _, err := MustGetDtmClient(s.Dtm).Submit(context.Background(), &DtmRequest{ - Gid: s.Gid, - TransType: s.TransType, - Data: dtmcli.MustMarshalString(&s.Steps), - }) - return err + return dtmgimp.DtmGrpcCall(&s.Saga.TransBase, "Submit") } diff --git a/dtmgrpc/tcc.go b/dtmgrpc/tcc.go index a8d4623..cec9338 100644 --- a/dtmgrpc/tcc.go +++ b/dtmgrpc/tcc.go @@ -4,12 +4,14 @@ import ( context "context" "fmt" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" + "google.golang.org/protobuf/proto" ) // TccGrpc struct of tcc type TccGrpc struct { - dtmcli.TransBase + dtmimp.TransBase } // TccGlobalFunc type of global tcc call @@ -20,9 +22,9 @@ type TccGlobalFunc func(tcc *TccGrpc) error // gid 全局事务id // tccFunc tcc事务函数,里面会定义全局事务的分支 func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr error) { - tcc := &TccGrpc{TransBase: *dtmcli.NewTransBase(gid, "tcc", dtm, "")} - dc := MustGetDtmClient(tcc.Dtm) - dr := &DtmRequest{ + tcc := &TccGrpc{TransBase: *dtmimp.NewTransBase(gid, "tcc", dtm, "")} + dc := dtmgimp.MustGetDtmClient(tcc.Dtm) + dr := &dtmgimp.DtmRequest{ Gid: tcc.Gid, TransType: tcc.TransType, } @@ -48,46 +50,37 @@ func TccGlobalTransaction(dtm string, gid string, tccFunc TccGlobalFunc) (rerr e return tccFunc(tcc) } -// TccFromRequest tcc from request info -func TccFromRequest(br *BusiRequest) (*TccGrpc, error) { +// TccFromGrpc tcc from request info +func TccFromGrpc(ctx context.Context) (*TccGrpc, error) { tcc := &TccGrpc{ - TransBase: *dtmcli.NewTransBase(br.Info.Gid, br.Info.TransType, br.Dtm, br.Info.BranchID), + TransBase: *dtmgimp.TransBaseFromGrpc(ctx), } if tcc.Dtm == "" || tcc.Gid == "" { - return nil, fmt.Errorf("bad tcc info. dtm: %s, gid: %s parentID: %s", tcc.Dtm, tcc.Gid, br.Info.BranchID) + return nil, fmt.Errorf("bad tcc info. dtm: %s, gid: %s branchid: %s", tcc.Dtm, tcc.Gid, tcc.BranchID) } return tcc, nil } // CallBranch call a tcc branch // 函数首先注册子事务的所有分支,成功后调用try分支,返回try分支的调用结果 -func (t *TccGrpc) CallBranch(busiData []byte, tryURL string, confirmURL string, cancelURL string) (*BusiReply, error) { - branchID := t.NewBranchID() - _, err := MustGetDtmClient(t.Dtm).RegisterTccBranch(context.Background(), &DtmTccBranchRequest{ - Info: &BranchInfo{ +func (t *TccGrpc) CallBranch(busiMsg proto.Message, tryURL string, confirmURL string, cancelURL string, reply interface{}) error { + branchID := t.NewSubBranchID() + bd, err := proto.Marshal(busiMsg) + _, err = dtmgimp.MustGetDtmClient(t.Dtm).RegisterTccBranch(context.Background(), &dtmgimp.DtmTccBranchRequest{ + Info: &dtmgimp.DtmBranchInfo{ Gid: t.Gid, TransType: t.TransType, BranchID: branchID, }, - BusiData: string(busiData), - Try: tryURL, - Confirm: confirmURL, - Cancel: cancelURL, + BusiPayload: bd, + Try: tryURL, + Confirm: confirmURL, + Cancel: cancelURL, }) if err != nil { - return nil, err + return err } - server, method := GetServerAndMethod(tryURL) - reply := &BusiReply{} - err = MustGetGrpcConn(server).Invoke(context.Background(), method, &BusiRequest{ - Info: &BranchInfo{ - Gid: t.Gid, - TransType: t.TransType, - BranchID: branchID, - BranchType: t.TransType, - }, - BusiData: busiData, - Dtm: t.Dtm, - }, reply) - return reply, err + server, method := dtmgimp.GetServerAndMethod(tryURL) + return dtmgimp.MustGetGrpcConn(server, false).Invoke( + dtmgimp.TransInfo2Ctx(t.Gid, t.TransType, branchID, "try", t.Dtm), method, busiMsg, reply) } diff --git a/dtmgrpc/type.go b/dtmgrpc/type.go index fdc21db..1f5f741 100644 --- a/dtmgrpc/type.go +++ b/dtmgrpc/type.go @@ -2,101 +2,21 @@ package dtmgrpc import ( context "context" - "fmt" - "strings" - sync "sync" "github.com/yedf/dtm/dtmcli" - grpc "google.golang.org/grpc" - codes "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/emptypb" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" + emptypb "google.golang.org/protobuf/types/known/emptypb" ) -var clients sync.Map - -// GetGrpcConn 1 -func GetGrpcConn(grpcServer string) (conn *grpc.ClientConn, rerr error) { - grpcServer = dtmcli.MayReplaceLocalhost(grpcServer) - v, ok := clients.Load(grpcServer) - if !ok { - dtmcli.Logf("grpc client connecting %s", grpcServer) - conn, rerr := grpc.Dial(grpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(GrpcClientLog)) - if rerr == nil { - clients.Store(grpcServer, conn) - v = conn - dtmcli.Logf("grpc client inited for %s", grpcServer) - } - } - return v.(*grpc.ClientConn), rerr -} - -// MustGetGrpcConn 1 -func MustGetGrpcConn(grpcServer string) *grpc.ClientConn { - conn, err := GetGrpcConn(grpcServer) - dtmcli.E2P(err) - return conn -} - -// MustGetDtmClient 1 -func MustGetDtmClient(grpcServer string) DtmClient { - return NewDtmClient(MustGetGrpcConn(grpcServer)) -} - -// MustGenGid 1 +// MustGenGid must gen a gid from grpcServer func MustGenGid(grpcServer string) string { - dc := MustGetDtmClient(grpcServer) + dc := dtmgimp.MustGetDtmClient(grpcServer) r, err := dc.NewGid(context.Background(), &emptypb.Empty{}) - dtmcli.E2P(err) + dtmimp.E2P(err) return r.Gid } -// GetServerAndMethod 将grpc的url分解为server和method -func GetServerAndMethod(grpcURL string) (string, string) { - fs := strings.Split(grpcURL, "/") - server := fs[0] - method := "/" + strings.Join(fs[1:], "/") - return server, method -} - -// GrpcServerLog 打印grpc服务端的日志 -func GrpcServerLog(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - dtmcli.Logf("grpc server handling: %s %v", info.FullMethod, req) - m, err := handler(ctx, req) - res := fmt.Sprintf("grpc server handled: %s %v result: %v err: %v", info.FullMethod, req, m, err) - if err != nil { - dtmcli.LogRedf("%s", res) - } else { - dtmcli.Logf("%s", res) - } - return m, err -} - -// GrpcClientLog 打印grpc服务端的日志 -func GrpcClientLog(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { - dtmcli.Logf("grpc client calling: %s%s %v", cc.Target(), method, req) - err := invoker(ctx, method, req, reply, cc, opts...) - res := fmt.Sprintf("grpc client called: %s%s %v result: %v err: %v", cc.Target(), method, req, reply, err) - if err != nil { - dtmcli.LogRedf("%s", res) - } else { - dtmcli.Logf("%s", res) - } - return err -} - -// Result2Error 将通用的result转成grpc的error -func Result2Error(res interface{}, err error) error { - e := dtmcli.CheckResult(res, err) - if e == dtmcli.ErrFailure { - dtmcli.LogRedf("failure: res: %v, err: %v", res, e) - return status.New(codes.Aborted, dtmcli.ResultFailure).Err() - } else if e == dtmcli.ErrOngoing { - return status.New(codes.Aborted, dtmcli.ResultOngoing).Err() - } - return e -} - // SetCurrentDBType set the current db type func SetCurrentDBType(dbType string) { dtmcli.SetCurrentDBType(dbType) diff --git a/dtmgrpc/type_test.go b/dtmgrpc/type_test.go index 0c3fb98..831357e 100644 --- a/dtmgrpc/type_test.go +++ b/dtmgrpc/type_test.go @@ -1,15 +1,16 @@ package dtmgrpc import ( + "context" "testing" "github.com/stretchr/testify/assert" ) func TestType(t *testing.T) { - _, err := BarrierFromGrpc(&BusiRequest{Info: &BranchInfo{}}) + _, err := BarrierFromGrpc(context.Background()) assert.Error(t, err) - _, err = TccFromRequest(&BusiRequest{Info: &BranchInfo{}}) + _, err = TccFromGrpc(context.Background()) assert.Error(t, err) } diff --git a/dtmgrpc/xa.go b/dtmgrpc/xa.go index 7417628..dea9f31 100644 --- a/dtmgrpc/xa.go +++ b/dtmgrpc/xa.go @@ -5,8 +5,10 @@ import ( "database/sql" "fmt" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" grpc "google.golang.org/grpc" + "google.golang.org/protobuf/proto" emptypb "google.golang.org/protobuf/types/known/emptypb" ) @@ -18,28 +20,28 @@ type XaGrpcLocalFunc func(db *sql.DB, xa *XaGrpc) error // XaGrpcClient xa client type XaGrpcClient struct { - dtmcli.XaClientBase + dtmimp.XaClientBase } // XaGrpc xa transaction type XaGrpc struct { - dtmcli.TransBase + dtmimp.TransBase } // XaGrpcFromRequest construct xa info from request -func XaGrpcFromRequest(br *BusiRequest) (*XaGrpc, error) { +func XaGrpcFromRequest(ctx context.Context) (*XaGrpc, error) { xa := &XaGrpc{ - TransBase: *dtmcli.NewTransBase(br.Info.Gid, br.Info.TransType, br.Dtm, br.Info.BranchID), + TransBase: *dtmgimp.TransBaseFromGrpc(ctx), } - if xa.Gid == "" || br.Info.BranchID == "" { - return nil, fmt.Errorf("bad xa info: gid: %s parentid: %s", xa.Gid, br.Info.BranchID) + if xa.Gid == "" || xa.BranchID == "" { + return nil, fmt.Errorf("bad xa info: gid: %s branchid: %s", xa.Gid, xa.BranchID) } return xa, nil } // NewXaGrpcClient construct a xa client func NewXaGrpcClient(server string, mysqlConf map[string]string, notifyURL string) *XaGrpcClient { - xa := &XaGrpcClient{XaClientBase: dtmcli.XaClientBase{ + xa := &XaGrpcClient{XaClientBase: dtmimp.XaClientBase{ Server: server, Conf: mysqlConf, NotifyURL: notifyURL, @@ -48,45 +50,49 @@ func NewXaGrpcClient(server string, mysqlConf map[string]string, notifyURL strin } // HandleCallback 处理commit/rollback的回调 -func (xc *XaGrpcClient) HandleCallback(gid string, branchID string, action string) error { - return xc.XaClientBase.HandleCallback(gid, branchID, action) +func (xc *XaGrpcClient) HandleCallback(ctx context.Context) (*emptypb.Empty, error) { + tb := dtmgimp.TransBaseFromGrpc(ctx) + return &emptypb.Empty{}, xc.XaClientBase.HandleCallback(tb.Gid, tb.BranchID, tb.BranchType) } // XaLocalTransaction start a xa local transaction -func (xc *XaGrpcClient) XaLocalTransaction(br *BusiRequest, xaFunc XaGrpcLocalFunc) (rerr error) { - xa, rerr := XaGrpcFromRequest(br) - if rerr != nil { - return +func (xc *XaGrpcClient) XaLocalTransaction(ctx context.Context, msg proto.Message, xaFunc XaGrpcLocalFunc) error { + xa, err := XaGrpcFromRequest(ctx) + if err != nil { + return err + } + data, err := proto.Marshal(msg) + if err != nil { + return err } - _, rerr = xc.HandleLocalTrans(&xa.TransBase, func(db *sql.DB) (interface{}, error) { - rerr := xaFunc(db, xa) - if rerr != nil { - return nil, rerr + return xc.HandleLocalTrans(&xa.TransBase, func(db *sql.DB) error { + err := xaFunc(db, xa) + if err != nil { + return err } - _, rerr = MustGetDtmClient(xa.Dtm).RegisterXaBranch(context.Background(), &DtmXaBranchRequest{ - Info: &BranchInfo{ + _, err = dtmgimp.MustGetDtmClient(xa.Dtm).RegisterXaBranch(context.Background(), &dtmgimp.DtmXaBranchRequest{ + Info: &dtmgimp.DtmBranchInfo{ Gid: xa.Gid, - BranchID: xa.CurrentBranchID(), + BranchID: xa.BranchID, TransType: xa.TransType, }, - BusiData: "", - Notify: xc.NotifyURL, + BusiPayload: data, + Notify: xc.NotifyURL, }) - return nil, rerr + return err }) - return } // XaGlobalTransaction start a xa global transaction -func (xc *XaGrpcClient) XaGlobalTransaction(gid string, xaFunc XaGrpcGlobalFunc) (rerr error) { - xa := XaGrpc{TransBase: *dtmcli.NewTransBase(gid, "xa", xc.Server, "")} - dc := MustGetDtmClient(xa.Dtm) - req := &DtmRequest{ +func (xc *XaGrpcClient) XaGlobalTransaction(gid string, xaFunc XaGrpcGlobalFunc) error { + xa := XaGrpc{TransBase: *dtmimp.NewTransBase(gid, "xa", xc.Server, "")} + dc := dtmgimp.MustGetDtmClient(xa.Dtm) + req := &dtmgimp.DtmRequest{ Gid: gid, TransType: xa.TransType, } return xc.HandleGlobalTrans(&xa.TransBase, func(action string) error { - f := map[string]func(context.Context, *DtmRequest, ...grpc.CallOption) (*emptypb.Empty, error){ + f := map[string]func(context.Context, *dtmgimp.DtmRequest, ...grpc.CallOption) (*emptypb.Empty, error){ "prepare": dc.Prepare, "submit": dc.Submit, "abort": dc.Abort, @@ -99,20 +105,10 @@ func (xc *XaGrpcClient) XaGlobalTransaction(gid string, xaFunc XaGrpcGlobalFunc) } // CallBranch call a xa branch -func (x *XaGrpc) CallBranch(busiData []byte, url string) (*BusiReply, error) { - branchID := x.NewBranchID() - server, method := GetServerAndMethod(url) - reply := &BusiReply{} - err := MustGetGrpcConn(server).Invoke(context.Background(), method, &BusiRequest{ - Info: &BranchInfo{ - Gid: x.Gid, - TransType: x.TransType, - BranchID: branchID, - BranchType: "", - }, - Dtm: x.Dtm, - BusiData: busiData, - }, reply) - return reply, err +func (x *XaGrpc) CallBranch(msg proto.Message, url string, reply interface{}) error { + server, method := dtmgimp.GetServerAndMethod(url) + err := dtmgimp.MustGetGrpcConn(server, false).Invoke( + dtmgimp.TransInfo2Ctx(x.Gid, x.TransType, x.NewSubBranchID(), "action", x.Dtm), method, msg, reply) + return err } diff --git a/dtmsvr/api.go b/dtmsvr/api.go index f2923f0..756d34a 100644 --- a/dtmsvr/api.go +++ b/dtmsvr/api.go @@ -18,7 +18,7 @@ func svcSubmit(t *TransGlobal) (interface{}, error) { updates := t.setNextCron(cronReset) db.Must().Model(t).Where("gid=? and status=?", t.Gid, dtmcli.StatusPrepared).Select(append(updates, "status")).Updates(t) } else if dbt.Status != dtmcli.StatusSubmitted { - return M{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status '%s', cannot sumbmit", dbt.Status)}, nil + return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status '%s', cannot sumbmit", dbt.Status)}, nil } } return t.Process(db), nil @@ -30,7 +30,7 @@ func svcPrepare(t *TransGlobal) (interface{}, error) { if err == errUniqueConflict { dbt := transFromDb(dbGet(), t.Gid) if dbt.Status != dtmcli.StatusPrepared { - return M{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status '%s', cannot prepare", dbt.Status)}, nil + return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status '%s', cannot prepare", dbt.Status)}, nil } } return dtmcli.MapSuccess, nil @@ -40,17 +40,17 @@ func svcAbort(t *TransGlobal) (interface{}, error) { db := dbGet() dbt := transFromDb(db, t.Gid) if t.TransType != "xa" && t.TransType != "tcc" || dbt.Status != dtmcli.StatusPrepared && dbt.Status != dtmcli.StatusAborting { - return M{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("trans type: '%s' current status '%s', cannot abort", dbt.TransType, dbt.Status)}, nil + return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("trans type: '%s' current status '%s', cannot abort", dbt.TransType, dbt.Status)}, nil } dbt.changeStatus(db, dtmcli.StatusAborting) return dbt.Process(db), nil } -func svcRegisterTccBranch(branch *TransBranch, data dtmcli.MS) (interface{}, error) { +func svcRegisterTccBranch(branch *TransBranch, data map[string]string) (interface{}, error) { db := dbGet() dbt := transFromDb(db, branch.Gid) if dbt.Status != dtmcli.StatusPrepared { - return M{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status: %s cannot register branch", dbt.Status)}, nil + return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status: %s cannot register branch", dbt.Status)}, nil } branches := []TransBranch{*branch, *branch, *branch} @@ -72,7 +72,7 @@ func svcRegisterXaBranch(branch *TransBranch) (interface{}, error) { db := dbGet() dbt := transFromDb(db, branch.Gid) if dbt.Status != dtmcli.StatusPrepared { - return M{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status: %s cannot register branch", dbt.Status)}, nil + return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": fmt.Sprintf("current status: %s cannot register branch", dbt.Status)}, nil } branches := []TransBranch{*branch, *branch} branches[0].BranchType = dtmcli.BranchRollback diff --git a/dtmsvr/api_grpc.go b/dtmsvr/api_grpc.go index 4b44cdf..8429267 100644 --- a/dtmsvr/api_grpc.go +++ b/dtmsvr/api_grpc.go @@ -4,33 +4,33 @@ import ( "context" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmgrpc" - pb "github.com/yedf/dtm/dtmgrpc" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" + pb "github.com/yedf/dtm/dtmgrpc/dtmgimp" "google.golang.org/protobuf/types/known/emptypb" ) -// dtmServer is used to implement dtmgrpc.DtmServer. +// dtmServer is used to implement dtmgimp.DtmServer. type dtmServer struct { pb.UnimplementedDtmServer } -func (s *dtmServer) NewGid(ctx context.Context, in *emptypb.Empty) (*dtmgrpc.DtmGidReply, error) { - return &dtmgrpc.DtmGidReply{Gid: GenGid()}, nil +func (s *dtmServer) NewGid(ctx context.Context, in *emptypb.Empty) (*dtmgimp.DtmGidReply, error) { + return &dtmgimp.DtmGidReply{Gid: GenGid()}, nil } func (s *dtmServer) Submit(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { r, err := svcSubmit(TransFromDtmRequest(in)) - return &emptypb.Empty{}, dtmgrpc.Result2Error(r, err) + return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } func (s *dtmServer) Prepare(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { r, err := svcPrepare(TransFromDtmRequest(in)) - return &emptypb.Empty{}, dtmgrpc.Result2Error(r, err) + return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } func (s *dtmServer) Abort(ctx context.Context, in *pb.DtmRequest) (*emptypb.Empty, error) { r, err := svcAbort(TransFromDtmRequest(in)) - return &emptypb.Empty{}, dtmgrpc.Result2Error(r, err) + return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } func (s *dtmServer) RegisterTccBranch(ctx context.Context, in *pb.DtmTccBranchRequest) (*emptypb.Empty, error) { @@ -38,13 +38,13 @@ func (s *dtmServer) RegisterTccBranch(ctx context.Context, in *pb.DtmTccBranchRe Gid: in.Info.Gid, BranchID: in.Info.BranchID, Status: dtmcli.StatusPrepared, - Data: in.BusiData, - }, dtmcli.MS{ + BinData: in.BusiPayload, + }, map[string]string{ dtmcli.BranchCancel: in.Cancel, dtmcli.BranchConfirm: in.Confirm, dtmcli.BranchTry: in.Try, }) - return &emptypb.Empty{}, dtmgrpc.Result2Error(r, err) + return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } func (s *dtmServer) RegisterXaBranch(ctx context.Context, in *pb.DtmXaBranchRequest) (*emptypb.Empty, error) { @@ -52,8 +52,8 @@ func (s *dtmServer) RegisterXaBranch(ctx context.Context, in *pb.DtmXaBranchRequ Gid: in.Info.Gid, BranchID: in.Info.BranchID, Status: dtmcli.StatusPrepared, - Data: in.BusiData, + BinData: in.BusiPayload, URL: in.Notify, }) - return &emptypb.Empty{}, dtmgrpc.Result2Error(r, err) + return &emptypb.Empty{}, dtmgimp.Result2Error(r, err) } diff --git a/dtmsvr/api_http.go b/dtmsvr/api_http.go index 07aec3a..27ee901 100644 --- a/dtmsvr/api_http.go +++ b/dtmsvr/api_http.go @@ -7,6 +7,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func addRoute(engine *gin.Engine) { @@ -21,7 +22,7 @@ func addRoute(engine *gin.Engine) { } func newGid(c *gin.Context) (interface{}, error) { - return M{"gid": GenGid(), "dtm_result": dtmcli.ResultSuccess}, nil + return map[string]interface{}{"gid": GenGid(), "dtm_result": dtmcli.ResultSuccess}, nil } func prepare(c *gin.Context) (interface{}, error) { @@ -44,14 +45,14 @@ func registerXaBranch(c *gin.Context) (interface{}, error) { } func registerTccBranch(c *gin.Context) (interface{}, error) { - data := dtmcli.MS{} + data := map[string]string{} err := c.BindJSON(&data) e2p(err) branch := TransBranch{ Gid: data["gid"], BranchID: data["branch_id"], Status: dtmcli.StatusPrepared, - Data: data["data"], + BinData: []byte(data["data"]), } return svcRegisterTccBranch(&branch, data) } @@ -65,16 +66,16 @@ func query(c *gin.Context) (interface{}, error) { trans := transFromDb(db, gid) branches := []TransBranch{} db.Must().Where("gid", gid).Find(&branches) - return M{"transaction": trans, "branches": branches}, nil + return map[string]interface{}{"transaction": trans, "branches": branches}, nil } func all(c *gin.Context) (interface{}, error) { lastID := c.Query("last_id") lid := math.MaxInt64 if lastID != "" { - lid = dtmcli.MustAtoi(lastID) + lid = dtmimp.MustAtoi(lastID) } trans := []TransGlobal{} dbGet().Must().Where("id < ?", lid).Order("id desc").Limit(100).Find(&trans) - return M{"transactions": trans}, nil + return map[string]interface{}{"transactions": trans}, nil } diff --git a/dtmsvr/cron.go b/dtmsvr/cron.go index 9cb1e64..0bf7e12 100644 --- a/dtmsvr/cron.go +++ b/dtmsvr/cron.go @@ -6,7 +6,7 @@ import ( "runtime/debug" "time" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) // NowForwardDuration will be set in test, trans may be timeout @@ -42,7 +42,7 @@ func lockOneTrans(expireIn time.Duration) *TransGlobal { trans := TransGlobal{} owner := GenGid() db := dbGet() - getTime := dtmcli.GetDBSpecial().TimestampAdd + getTime := dtmimp.GetDBSpecial().TimestampAdd expire := int(expireIn / time.Second) whereTime := fmt.Sprintf("next_cron_time < %s and update_time < %s", getTime(expire), getTime(expire-3)) // 这里next_cron_time需要限定范围,否则数据量累计之后,会导致查询变慢 @@ -60,7 +60,7 @@ func lockOneTrans(expireIn time.Duration) *TransGlobal { func handlePanic(perr *error) { if err := recover(); err != nil { - dtmcli.LogRedf("----recovered panic %v\n%s", err, string(debug.Stack())) + dtmimp.LogRedf("----recovered panic %v\n%s", err, string(debug.Stack())) if perr != nil { *perr = fmt.Errorf("dtm panic: %v", err) } @@ -69,7 +69,7 @@ func handlePanic(perr *error) { func sleepCronTime() { normal := time.Duration((float64(config.TransCronInterval) - rand.Float64()) * float64(time.Second)) - interval := dtmcli.If(CronForwardDuration > 0, 1*time.Millisecond, normal).(time.Duration) - dtmcli.Logf("sleeping for %v milli", interval/time.Microsecond) + interval := dtmimp.If(CronForwardDuration > 0, 1*time.Millisecond, normal).(time.Duration) + dtmimp.Logf("sleeping for %v milli", interval/time.Microsecond) time.Sleep(interval) } diff --git a/dtmsvr/dtmsvr.go b/dtmsvr/dtmsvr.go index ee0b35d..6f391c1 100644 --- a/dtmsvr/dtmsvr.go +++ b/dtmsvr/dtmsvr.go @@ -6,8 +6,8 @@ import ( "time" "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmgrpc" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" "gorm.io/gorm/clause" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" @@ -22,29 +22,29 @@ var metricsPort = 8889 // StartSvr StartSvr func StartSvr() { - dtmcli.Logf("start dtmsvr") + dtmimp.Logf("start dtmsvr") app := common.GetGinApp() app = httpMetrics(app) addRoute(app) - dtmcli.Logf("dtmsvr listen at: %d", dtmsvrPort) + dtmimp.Logf("dtmsvr listen at: %d", dtmsvrPort) go app.Run(fmt.Sprintf(":%d", dtmsvrPort)) lis, err := net.Listen("tcp", fmt.Sprintf(":%d", dtmsvrGrpcPort)) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) s := grpc.NewServer( grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( - grpc.UnaryServerInterceptor(grpcMetrics), grpc.UnaryServerInterceptor(dtmgrpc.GrpcServerLog)), + grpc.UnaryServerInterceptor(grpcMetrics), grpc.UnaryServerInterceptor(dtmgimp.GrpcServerLog)), )) - dtmgrpc.RegisterDtmServer(s, &dtmServer{}) - dtmcli.Logf("grpc listening at %v", lis.Addr()) + dtmgimp.RegisterDtmServer(s, &dtmServer{}) + dtmimp.Logf("grpc listening at %v", lis.Addr()) go func() { err := s.Serve(lis) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) }() go updateBranchAsync() // prometheus exporter - dtmcli.Logf("prometheus exporter listen at: %d", metricsPort) + dtmimp.Logf("prometheus exporter listen at: %d", metricsPort) prometheusHTTPRun(fmt.Sprintf("%d", metricsPort)) time.Sleep(100 * time.Millisecond) } @@ -80,9 +80,9 @@ func updateBranchAsync() { OnConstraint: "trans_branch_pkey", DoUpdates: clause.AssignmentColumns([]string{"status", "finish_time"}), }).Create(updates) - dtmcli.Logf("flushed %d branch status to db. affected: %d", len(updates), dbr.RowsAffected) + dtmimp.Logf("flushed %d branch status to db. affected: %d", len(updates), dbr.RowsAffected) if dbr.Error != nil { - dtmcli.LogRedf("async update branch status error: %v", dbr.Error) + dtmimp.LogRedf("async update branch status error: %v", dbr.Error) time.Sleep(1 * time.Second) } else { updates = []TransBranch{} diff --git a/dtmsvr/dtmsvr.mysql.sql b/dtmsvr/dtmsvr.mysql.sql index 20ce7b9..76dbcc7 100644 --- a/dtmsvr/dtmsvr.mysql.sql +++ b/dtmsvr/dtmsvr.mysql.sql @@ -33,6 +33,7 @@ CREATE TABLE IF NOT EXISTS dtm.trans_branch ( `gid` varchar(128) NOT NULL COMMENT '事务全局id', `url` varchar(128) NOT NULL COMMENT '动作关联的url', `data` TEXT COMMENT '请求所携带的数据', + `bin_data` BLOB COMMENT 'grpc的二进制数据', `branch_id` VARCHAR(128) NOT NULL COMMENT '事务分支名称', `branch_type` varchar(45) NOT NULL COMMENT '事务分支类型 saga_action | saga_compensate | xa', `status` varchar(45) NOT NULL COMMENT '步骤的状态 submitted | finished | rollbacked', diff --git a/dtmsvr/dtmsvr.postgres.sql b/dtmsvr/dtmsvr.postgres.sql index ed8b273..1d21a26 100644 --- a/dtmsvr/dtmsvr.postgres.sql +++ b/dtmsvr/dtmsvr.postgres.sql @@ -36,6 +36,7 @@ CREATE TABLE IF NOT EXISTS dtm.trans_branch ( gid varchar(128) NOT NULL, url varchar(128) NOT NULL, data TEXT, + bin_data BLOB, branch_id VARCHAR(128) NOT NULL, branch_type varchar(45) NOT NULL, status varchar(45) NOT NULL, diff --git a/dtmsvr/trans.go b/dtmsvr/trans.go index 534751b..709b998 100644 --- a/dtmsvr/trans.go +++ b/dtmsvr/trans.go @@ -1,7 +1,6 @@ package dtmsvr import ( - "context" "errors" "fmt" "strings" @@ -10,10 +9,10 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/dtmgrpc" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc/dtmgimp" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - "google.golang.org/protobuf/types/known/emptypb" "gorm.io/gorm" "gorm.io/gorm/clause" ) @@ -23,12 +22,14 @@ var errUniqueConflict = errors.New("unique key conflict error") // TransGlobal global transaction type TransGlobal struct { common.ModelBase - Gid string `json:"gid"` - TransType string `json:"trans_type"` - Data string `json:"data" gorm:"-"` - Status string `json:"status"` - QueryPrepared string `json:"query_prepared"` - Protocol string `json:"protocol"` + Gid string `json:"gid"` + TransType string `json:"trans_type"` + Steps []map[string]string `json:"steps" gorm:"-"` + Payloads []string `json:"payloads" gorm:"-"` + BinPayloads [][]byte `json:"-" gorm:"-"` + Status string `json:"status"` + QueryPrepared string `json:"query_prepared"` + Protocol string `json:"protocol"` CommitTime *time.Time FinishTime *time.Time RollbackTime *time.Time @@ -36,7 +37,7 @@ type TransGlobal struct { CustomData string `json:"custom_data"` NextCronInterval int64 NextCronTime *time.Time - dtmcli.TransOptions + dtmimp.TransOptions lastTouched time.Time // record the start time of process } @@ -51,14 +52,12 @@ type transProcessor interface { } func (t *TransGlobal) touch(db *common.DB, ctype cronType) *gorm.DB { - writeTransLog(t.Gid, "touch trans", "", "", "") t.lastTouched = time.Now() updates := t.setNextCron(ctype) return db.Model(&TransGlobal{}).Where("gid=?", t.Gid).Select(updates).Updates(t) } func (t *TransGlobal) changeStatus(db *common.DB, status string) *gorm.DB { - writeTransLog(t.Gid, "change status", status, "", "") old := t.Status t.Status = status updates := t.setNextCron(cronReset) @@ -96,7 +95,7 @@ type TransBranch struct { common.ModelBase Gid string URL string `json:"url"` - Data string + BinData []byte BranchID string `json:"branch_id"` BranchType string Status string @@ -110,9 +109,8 @@ func (*TransBranch) TableName() string { } func (t *TransBranch) changeStatus(db *common.DB, status string) *gorm.DB { - writeTransLog(t.Gid, "branch change", status, t.BranchID, "") if common.DtmConfig.UpdateBranchSync > 0 { - dbr := db.Must().Model(t).Updates(M{ + dbr := db.Must().Model(t).Updates(map[string]interface{}{ "status": status, "finish_time": time.Now(), }) @@ -126,7 +124,7 @@ func (t *TransBranch) changeStatus(db *common.DB, status string) *gorm.DB { func checkAffected(db1 *gorm.DB) { if db1.RowsAffected == 0 { - panic(fmt.Errorf("duplicate updating")) + panic(fmt.Errorf("rows affected 0, please check for abnormal trans")) } } @@ -143,15 +141,15 @@ func (t *TransGlobal) getProcessor() transProcessor { } // Process process global transaction once -func (t *TransGlobal) Process(db *common.DB) dtmcli.M { +func (t *TransGlobal) Process(db *common.DB) map[string]interface{} { r := t.process(db) transactionMetrics(t, r["dtm_result"] == dtmcli.ResultSuccess) return r } -func (t *TransGlobal) process(db *common.DB) dtmcli.M { +func (t *TransGlobal) process(db *common.DB) map[string]interface{} { if t.Options != "" { - dtmcli.MustUnmarshalString(t.Options, &t.TransOptions) + dtmimp.MustUnmarshalString(t.Options, &t.TransOptions) } if !t.WaitResult { @@ -161,10 +159,10 @@ func (t *TransGlobal) process(db *common.DB) dtmcli.M { submitting := t.Status == dtmcli.StatusSubmitted err := t.processInner(db) if err != nil { - return dtmcli.M{"dtm_result": dtmcli.ResultFailure, "message": err.Error()} + return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": err.Error()} } if submitting && t.Status != dtmcli.StatusSucceed { - return dtmcli.M{"dtm_result": dtmcli.ResultFailure, "message": "trans failed by user"} + return map[string]interface{}{"dtm_result": dtmcli.ResultFailure, "message": "trans failed by user"} } return dtmcli.MapSuccess } @@ -173,15 +171,15 @@ func (t *TransGlobal) processInner(db *common.DB) (rerr error) { defer handlePanic(&rerr) defer func() { if rerr != nil { - dtmcli.LogRedf("processInner got error: %s", rerr.Error()) + dtmimp.LogRedf("processInner got error: %s", rerr.Error()) } if TransProcessedTestChan != nil { - dtmcli.Logf("processed: %s", t.Gid) + dtmimp.Logf("processed: %s", t.Gid) TransProcessedTestChan <- t.Gid - dtmcli.Logf("notified: %s", t.Gid) + dtmimp.Logf("notified: %s", t.Gid) } }() - dtmcli.Logf("processing: %s status: %s", t.Gid, t.Status) + dtmimp.Logf("processing: %s status: %s", t.Gid, t.Status) branches := []TransBranch{} db.Must().Where("gid=?", t.Gid).Order("id asc").Find(&branches) t.lastTouched = time.Now() @@ -213,20 +211,13 @@ func (t *TransGlobal) setNextCron(ctype cronType) []string { return []string{"next_cron_interval", "next_cron_time"} } -func (t *TransGlobal) getURLResult(url string, branchID, branchType string, branchData []byte) (string, error) { +func (t *TransGlobal) getURLResult(url string, branchID, branchType string, branchPayload []byte) (string, error) { if t.Protocol == "grpc" { - dtmcli.PanicIf(strings.HasPrefix(url, "http"), fmt.Errorf("bad url for grpc: %s", url)) - server, method := dtmgrpc.GetServerAndMethod(url) - conn := dtmgrpc.MustGetGrpcConn(server) - err := conn.Invoke(context.Background(), method, &dtmgrpc.BusiRequest{ - Info: &dtmgrpc.BranchInfo{ - Gid: t.Gid, - TransType: t.TransType, - BranchID: branchID, - BranchType: branchType, - }, - BusiData: branchData, - }, &emptypb.Empty{}) + dtmimp.PanicIf(strings.HasPrefix(url, "http"), fmt.Errorf("bad url for grpc: %s", url)) + server, method := dtmgimp.GetServerAndMethod(url) + conn := dtmgimp.MustGetGrpcConn(server, true) + ctx := dtmgimp.TransInfo2Ctx(t.Gid, t.TransType, branchID, branchType, "") + err := conn.Invoke(ctx, method, branchPayload, []byte{}) if err == nil { return dtmcli.ResultSuccess, nil } @@ -240,16 +231,16 @@ func (t *TransGlobal) getURLResult(url string, branchID, branchType string, bran } return "", err } - dtmcli.PanicIf(!strings.HasPrefix(url, "http"), fmt.Errorf("bad url for http: %s", url)) - resp, err := dtmcli.RestyClient.R().SetBody(string(branchData)). - SetQueryParams(dtmcli.MS{ + dtmimp.PanicIf(!strings.HasPrefix(url, "http"), fmt.Errorf("bad url for http: %s", url)) + resp, err := dtmimp.RestyClient.R().SetBody(string(branchPayload)). + SetQueryParams(map[string]string{ "gid": t.Gid, "trans_type": t.TransType, "branch_id": branchID, "branch_type": branchType, }). SetHeader("Content-type", "application/json"). - Execute(dtmcli.If(branchData == nil, "GET", "POST").(string), url) + Execute(dtmimp.If(branchPayload != nil || t.TransType == "xa", "POST", "GET").(string), url) if err != nil { return "", err } @@ -257,7 +248,7 @@ func (t *TransGlobal) getURLResult(url string, branchID, branchType string, bran } func (t *TransGlobal) getBranchResult(branch *TransBranch) (string, error) { - body, err := t.getURLResult(branch.URL, branch.BranchID, branch.BranchType, []byte(branch.Data)) + body, err := t.getURLResult(branch.URL, branch.BranchID, branch.BranchType, branch.BinData) if err != nil { return "", err } @@ -266,7 +257,7 @@ func (t *TransGlobal) getBranchResult(branch *TransBranch) (string, error) { } else if strings.HasSuffix(t.TransType, "saga") && branch.BranchType == dtmcli.BranchAction && strings.Contains(body, dtmcli.ResultFailure) { return dtmcli.StatusFailed, nil } else if strings.Contains(body, dtmcli.ResultOngoing) { - return "", dtmcli.ErrOngoing + return "", dtmimp.ErrOngoing } return "", fmt.Errorf("http result should contains SUCCESS|FAILURE|ONGOING. grpc error should return nil|Aborted with message(FAILURE|ONGOING). \nrefer to: https://dtm.pub/summary/arch.html#http\nunkown result will be retried: %s", body) } @@ -281,7 +272,7 @@ func (t *TransGlobal) execBranch(db *common.DB, branch *TransBranch) error { if err == nil && time.Since(t.lastTouched)+NowForwardDuration >= 1500*time.Millisecond || t.NextCronInterval > config.RetryInterval && t.NextCronInterval > t.RetryInterval { t.touch(db, cronReset) - } else if err == dtmcli.ErrOngoing { + } else if err == dtmimp.ErrOngoing { t.touch(db, cronKeep) } else { t.touch(db, cronBackoff) @@ -293,11 +284,10 @@ func (t *TransGlobal) saveNew(db *common.DB) error { return db.Transaction(func(db1 *gorm.DB) error { db := &common.DB{DB: db1} t.setNextCron(cronReset) - t.Options = dtmcli.MustMarshalString(t.TransOptions) + t.Options = dtmimp.MustMarshalString(t.TransOptions) if t.Options == "{}" { t.Options = "" } - writeTransLog(t.Gid, "create trans", t.Status, "", t.Data) dbr := db.Must().Clauses(clause.OnConflict{ DoNothing: true, }).Create(t) @@ -306,7 +296,6 @@ func (t *TransGlobal) saveNew(db *common.DB) error { } branches := t.getProcessor().GenBranches() if len(branches) > 0 { - writeTransLog(t.Gid, "save branches", t.Status, "", dtmcli.MustMarshalString(branches)) checkLocalhost(branches) db.Must().Clauses(clause.OnConflict{ DoNothing: true, @@ -318,27 +307,35 @@ func (t *TransGlobal) saveNew(db *common.DB) error { // TransFromContext TransFromContext func TransFromContext(c *gin.Context) *TransGlobal { - data := M{} b, err := c.GetRawData() e2p(err) - dtmcli.MustUnmarshal(b, &data) - dtmcli.Logf("creating trans in prepare") - if data["steps"] != nil { - data["data"] = dtmcli.MustMarshalString(data["steps"]) - } m := TransGlobal{} - dtmcli.MustRemarshal(data, &m) + dtmimp.MustUnmarshal(b, &m) + dtmimp.Logf("creating trans in prepare") + // Payloads will be store in BinPayloads, Payloads is only used to Unmarshal + for _, p := range m.Payloads { + m.BinPayloads = append(m.BinPayloads, []byte(p)) + } + for _, d := range m.Steps { + if d["data"] != "" { + m.BinPayloads = append(m.BinPayloads, []byte(d["data"])) + } + } m.Protocol = "http" return &m } // TransFromDtmRequest TransFromContext -func TransFromDtmRequest(c *dtmgrpc.DtmRequest) *TransGlobal { - return &TransGlobal{ +func TransFromDtmRequest(c *dtmgimp.DtmRequest) *TransGlobal { + r := TransGlobal{ Gid: c.Gid, TransType: c.TransType, QueryPrepared: c.QueryPrepared, - Data: c.Data, Protocol: "grpc", + BinPayloads: c.BinPayloads, + } + if c.Steps != "" { + dtmimp.MustUnmarshalString(c.Steps, &r.Steps) } + return &r } diff --git a/dtmsvr/trans_msg.go b/dtmsvr/trans_msg.go index 1c4e0d0..ace7edf 100644 --- a/dtmsvr/trans_msg.go +++ b/dtmsvr/trans_msg.go @@ -1,10 +1,12 @@ package dtmsvr import ( + "fmt" "strings" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) type transMsgProcessor struct { @@ -17,17 +19,16 @@ func init() { func (t *transMsgProcessor) GenBranches() []TransBranch { branches := []TransBranch{} - steps := []M{} - dtmcli.MustUnmarshalString(t.Data, &steps) - for _, step := range steps { - branches = append(branches, TransBranch{ + for i, step := range t.Steps { + b := &TransBranch{ Gid: t.Gid, - BranchID: GenGid(), - Data: step["data"].(string), - URL: step[dtmcli.BranchAction].(string), + BranchID: fmt.Sprintf("%02d", i+1), + BinData: t.BinPayloads[i], + URL: step[dtmcli.BranchAction], BranchType: dtmcli.BranchAction, Status: dtmcli.StatusPrepared, - }) + } + branches = append(branches, *b) } return branches } @@ -44,7 +45,7 @@ func (t *TransGlobal) mayQueryPrepared(db *common.DB) { } else if strings.Contains(body, dtmcli.ResultOngoing) { t.touch(db, cronReset) } else { - dtmcli.LogRedf("getting result failed for %s. error: %s", t.QueryPrepared, err.Error()) + dtmimp.LogRedf("getting result failed for %s. error: %s", t.QueryPrepared, err.Error()) t.touch(db, cronBackoff) } } diff --git a/dtmsvr/trans_saga.go b/dtmsvr/trans_saga.go index dc74237..0da5ae1 100644 --- a/dtmsvr/trans_saga.go +++ b/dtmsvr/trans_saga.go @@ -6,6 +6,7 @@ import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) type transSagaProcessor struct { @@ -18,16 +19,14 @@ func init() { func (t *transSagaProcessor) GenBranches() []TransBranch { branches := []TransBranch{} - steps := []M{} - dtmcli.MustUnmarshalString(t.Data, &steps) - for i, step := range steps { + for i, step := range t.Steps { branch := fmt.Sprintf("%02d", i+1) for _, branchType := range []string{dtmcli.BranchCompensate, dtmcli.BranchAction} { branches = append(branches, TransBranch{ Gid: t.Gid, BranchID: branch, - Data: step["data"].(string), - URL: step[branchType].(string), + BinData: t.BinPayloads[i], + URL: step[branchType], BranchType: branchType, Status: dtmcli.StatusPrepared, }) @@ -50,7 +49,7 @@ type branchResult struct { func (t *transSagaProcessor) ProcessOnce(db *common.DB, branches []TransBranch) error { // when saga tasks is fetched, it always need to process - dtmcli.Logf("status: %s timeout: %t", t.Status, t.isTimeout()) + dtmimp.Logf("status: %s timeout: %t", t.Status, t.isTimeout()) if t.Status == dtmcli.StatusSubmitted && t.isTimeout() { t.changeStatus(db, dtmcli.StatusAborting) } @@ -58,7 +57,7 @@ func (t *transSagaProcessor) ProcessOnce(db *common.DB, branches []TransBranch) csc := cSagaCustom{Orders: map[int][]int{}} if t.CustomData != "" { - dtmcli.MustUnmarshalString(t.CustomData, &csc) + dtmimp.MustUnmarshalString(t.CustomData, &csc) } // resultStats var rsAToStart, rsAStarted, rsADone, rsAFailed, rsASucceed, rsCToStart, rsCDone, rsCSucceed int @@ -93,11 +92,11 @@ func (t *transSagaProcessor) ProcessOnce(db *common.DB, branches []TransBranch) var err error defer func() { if x := recover(); x != nil { - err = dtmcli.AsError(x) + err = dtmimp.AsError(x) } resultChan <- branchResult{index: i, status: branches[i].Status, branchType: branches[i].BranchType} if err != nil { - dtmcli.LogRedf("exec branch error: %v", err) + dtmimp.LogRedf("exec branch error: %v", err) } }() err = t.execBranch(db, &branches[i]) @@ -110,7 +109,7 @@ func (t *transSagaProcessor) ProcessOnce(db *common.DB, branches []TransBranch) toRun = append(toRun, current) } } - dtmcli.Logf("toRun picked for action is: %v", toRun) + dtmimp.Logf("toRun picked for action is: %v", toRun) return toRun } runBranches := func(toRun []int) { @@ -152,9 +151,9 @@ func (t *transSagaProcessor) ProcessOnce(db *common.DB, branches []TransBranch) rsCSucceed++ } } - dtmcli.Logf("branch done: %v", r) + dtmimp.Logf("branch done: %v", r) case <-time.After(time.Duration(time.Second * 3)): - dtmcli.Logf("wait once for done") + dtmimp.Logf("wait once for done") } } diff --git a/dtmsvr/trans_tcc.go b/dtmsvr/trans_tcc.go index 80be0ee..8870fa3 100644 --- a/dtmsvr/trans_tcc.go +++ b/dtmsvr/trans_tcc.go @@ -3,6 +3,7 @@ package dtmsvr import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) type transTccProcessor struct { @@ -24,7 +25,7 @@ func (t *transTccProcessor) ProcessOnce(db *common.DB, branches []TransBranch) e if t.Status == dtmcli.StatusPrepared && t.isTimeout() { t.changeStatus(db, dtmcli.StatusAborting) } - branchType := dtmcli.If(t.Status == dtmcli.StatusSubmitted, dtmcli.BranchConfirm, dtmcli.BranchCancel).(string) + branchType := dtmimp.If(t.Status == dtmcli.StatusSubmitted, dtmcli.BranchConfirm, dtmcli.BranchCancel).(string) for current := len(branches) - 1; current >= 0; current-- { if branches[current].BranchType == branchType && branches[current].Status == dtmcli.StatusPrepared { err := t.execBranch(db, &branches[current]) @@ -33,6 +34,6 @@ func (t *transTccProcessor) ProcessOnce(db *common.DB, branches []TransBranch) e } } } - t.changeStatus(db, dtmcli.If(t.Status == dtmcli.StatusSubmitted, dtmcli.StatusSucceed, dtmcli.StatusFailed).(string)) + t.changeStatus(db, dtmimp.If(t.Status == dtmcli.StatusSubmitted, dtmcli.StatusSucceed, dtmcli.StatusFailed).(string)) return nil } diff --git a/dtmsvr/trans_xa.go b/dtmsvr/trans_xa.go index 007aa76..e8106bc 100644 --- a/dtmsvr/trans_xa.go +++ b/dtmsvr/trans_xa.go @@ -3,6 +3,7 @@ package dtmsvr import ( "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) type transXaProcessor struct { @@ -24,7 +25,7 @@ func (t *transXaProcessor) ProcessOnce(db *common.DB, branches []TransBranch) er if t.Status == dtmcli.StatusPrepared && t.isTimeout() { t.changeStatus(db, dtmcli.StatusAborting) } - currentType := dtmcli.If(t.Status == dtmcli.StatusSubmitted, dtmcli.BranchCommit, dtmcli.BranchRollback).(string) + currentType := dtmimp.If(t.Status == dtmcli.StatusSubmitted, dtmcli.BranchCommit, dtmcli.BranchRollback).(string) for _, branch := range branches { if branch.BranchType == currentType && branch.Status != dtmcli.StatusSucceed { err := t.execBranch(db, &branch) @@ -33,6 +34,6 @@ func (t *transXaProcessor) ProcessOnce(db *common.DB, branches []TransBranch) er } } } - t.changeStatus(db, dtmcli.If(t.Status == dtmcli.StatusSubmitted, dtmcli.StatusSucceed, dtmcli.StatusFailed).(string)) + t.changeStatus(db, dtmimp.If(t.Status == dtmcli.StatusSubmitted, dtmcli.StatusSucceed, dtmcli.StatusFailed).(string)) return nil } diff --git a/dtmsvr/utils.go b/dtmsvr/utils.go index 3dc08e3..1aeb587 100644 --- a/dtmsvr/utils.go +++ b/dtmsvr/utils.go @@ -10,39 +10,24 @@ import ( "github.com/bwmarrin/snowflake" "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "gorm.io/gorm" ) -// M a short name -type M = map[string]interface{} - type branchStatus struct { id uint64 status string finishTime *time.Time } -var p2e = dtmcli.P2E -var e2p = dtmcli.E2P +var p2e = dtmimp.P2E +var e2p = dtmimp.E2P var config = common.DtmConfig func dbGet() *common.DB { return common.DbGet(config.DB) } -func writeTransLog(gid string, action string, status string, branch string, detail string) { - // if detail == "" { - // detail = "{}" - // } - // dbGet().Must().Table("trans_log").Create(M{ - // "gid": gid, - // dtmcli.BranchAction: action, - // "new_status": status, - // "branch": branch, - // "detail": detail, - // }) -} // TransProcessedTestChan only for test usage. when transaction processed once, write gid to this chan var TransProcessedTestChan chan string = nil @@ -69,7 +54,7 @@ func getOneHexIP() string { ns := strings.Split(ip, ".") r := []byte{} for _, n := range ns { - r = append(r, byte(dtmcli.MustAtoi(n))) + r = append(r, byte(dtmimp.MustAtoi(n))) } return hex.EncodeToString(r) } diff --git a/dtmsvr/utils_test.go b/dtmsvr/utils_test.go index ede2ec6..9abf132 100644 --- a/dtmsvr/utils_test.go +++ b/dtmsvr/utils_test.go @@ -4,13 +4,13 @@ import ( "testing" "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func TestUtils(t *testing.T) { db := dbGet() db.NoMust() - err := dtmcli.CatchP(func() { + err := dtmimp.CatchP(func() { checkAffected(db.DB) }) assert.Error(t, err) @@ -21,12 +21,12 @@ func TestUtils(t *testing.T) { func TestCheckLocalHost(t *testing.T) { config.DisableLocalhost = 1 - err := dtmcli.CatchP(func() { + err := dtmimp.CatchP(func() { checkLocalhost([]TransBranch{{URL: "http://localhost"}}) }) assert.Error(t, err) config.DisableLocalhost = 0 - err = dtmcli.CatchP(func() { + err = dtmimp.CatchP(func() { checkLocalhost([]TransBranch{{URL: "http://localhost"}}) }) assert.Nil(t, err) diff --git a/examples/base_grpc.go b/examples/base_grpc.go index d449015..0be9307 100644 --- a/examples/base_grpc.go +++ b/examples/base_grpc.go @@ -7,45 +7,61 @@ import ( "net" "time" + "github.com/gin-gonic/gin" "github.com/yedf/dtm/dtmcli" - dtmgrpc "github.com/yedf/dtm/dtmgrpc" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/dtmgrpc" + + "github.com/yedf/dtm/dtmgrpc/dtmgimp" grpc "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + emptypb "google.golang.org/protobuf/types/known/emptypb" ) // BusiGrpc busi service grpc address var BusiGrpc string = fmt.Sprintf("localhost:%d", BusiGrpcPort) // DtmClient grpc client for dtm -var DtmClient dtmgrpc.DtmClient = nil +var DtmClient dtmgimp.DtmClient = nil + +// XaGrpcClient XA client connection +var XaGrpcClient *dtmgrpc.XaGrpcClient = nil + +func init() { + setupFuncs["XaGrpcSetup"] = func(app *gin.Engine) { + XaGrpcClient = dtmgrpc.NewXaGrpcClient(DtmGrpcServer, config.DB, BusiGrpc+"/examples.Busi/XaNotify") + } +} // GrpcStartup for grpc func GrpcStartup() { - conn, err := grpc.Dial(DtmGrpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(dtmgrpc.GrpcClientLog)) - dtmcli.FatalIfError(err) - DtmClient = dtmgrpc.NewDtmClient(conn) - dtmcli.Logf("dtm client inited") + conn, err := grpc.Dial(DtmGrpcServer, grpc.WithInsecure(), grpc.WithUnaryInterceptor(dtmgimp.GrpcClientLog)) + dtmimp.FatalIfError(err) + DtmClient = dtmgimp.NewDtmClient(conn) + dtmimp.Logf("dtm client inited") lis, err := net.Listen("tcp", fmt.Sprintf(":%d", BusiGrpcPort)) - dtmcli.FatalIfError(err) - s := grpc.NewServer(grpc.UnaryInterceptor(dtmgrpc.GrpcServerLog)) + dtmimp.FatalIfError(err) + s := grpc.NewServer(grpc.UnaryInterceptor(dtmgimp.GrpcServerLog)) RegisterBusiServer(s, &busiServer{}) go func() { - dtmcli.Logf("busi grpc listening at %v", lis.Addr()) + dtmimp.Logf("busi grpc listening at %v", lis.Addr()) err := s.Serve(lis) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) }() time.Sleep(100 * time.Millisecond) } -func handleGrpcBusiness(in *dtmgrpc.BusiRequest, result1 string, result2 string, busi string) error { - res := dtmcli.OrString(result1, result2, dtmcli.ResultSuccess) - dtmcli.Logf("grpc busi %s %s result: %s", busi, in.Info, res) +func handleGrpcBusiness(in *BusiReq, result1 string, result2 string, busi string) error { + res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) + dtmimp.Logf("grpc busi %s %v %s %s result: %s", busi, in, result1, result2, res) 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() } @@ -55,89 +71,68 @@ type busiServer struct { UnimplementedBusiServer } -func (s *busiServer) CanSubmit(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (s *busiServer) CanSubmit(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { res := MainSwitch.CanSubmitResult.Fetch() - return &dtmgrpc.BusiReply{}, dtmgrpc.Result2Error(res, nil) + return &emptypb.Empty{}, dtmgimp.Result2Error(res, nil) } -func (s *busiServer) TransIn(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{}, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), req.TransInResult, dtmcli.GetFuncName()) +func (s *busiServer) TransIn(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), in.TransInResult, dtmimp.GetFuncName()) } -func (s *busiServer) TransOut(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{}, handleGrpcBusiness(in, MainSwitch.TransOutResult.Fetch(), req.TransOutResult, dtmcli.GetFuncName()) +func (s *busiServer) TransOut(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransOutResult.Fetch(), in.TransOutResult, dtmimp.GetFuncName()) } -func (s *busiServer) TransInRevert(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{}, handleGrpcBusiness(in, MainSwitch.TransInRevertResult.Fetch(), "", dtmcli.GetFuncName()) +func (s *busiServer) TransInRevert(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransInRevertResult.Fetch(), "", dtmimp.GetFuncName()) } -func (s *busiServer) TransOutRevert(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{}, handleGrpcBusiness(in, MainSwitch.TransOutRevertResult.Fetch(), "", dtmcli.GetFuncName()) +func (s *busiServer) TransOutRevert(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransOutRevertResult.Fetch(), "", dtmimp.GetFuncName()) } -func (s *busiServer) TransInConfirm(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{}, handleGrpcBusiness(in, MainSwitch.TransInConfirmResult.Fetch(), "", dtmcli.GetFuncName()) +func (s *busiServer) TransInConfirm(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransInConfirmResult.Fetch(), "", dtmimp.GetFuncName()) } -func (s *busiServer) TransOutConfirm(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{}, handleGrpcBusiness(in, MainSwitch.TransOutConfirmResult.Fetch(), "", dtmcli.GetFuncName()) +func (s *busiServer) TransOutConfirm(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransOutConfirmResult.Fetch(), "", dtmimp.GetFuncName()) } -func (s *busiServer) TransInTcc(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{BusiData: []byte("reply")}, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), req.TransInResult, dtmcli.GetFuncName()) +func (s *busiServer) TransInTcc(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), in.TransInResult, dtmimp.GetFuncName()) } -func (s *busiServer) TransOutTcc(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{BusiData: []byte("reply")}, handleGrpcBusiness(in, MainSwitch.TransOutResult.Fetch(), req.TransOutResult, dtmcli.GetFuncName()) +func (s *busiServer) TransOutTcc(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + return &emptypb.Empty{}, handleGrpcBusiness(in, MainSwitch.TransOutResult.Fetch(), in.TransOutResult, dtmimp.GetFuncName()) } -func (s *busiServer) TransInXa(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{BusiData: []byte("reply")}, XaGrpcClient.XaLocalTransaction(in, func(db *sql.DB, xa *dtmgrpc.XaGrpc) error { - if req.TransInResult == dtmcli.ResultFailure { +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 := dtmcli.DBExec(db, "update dtm_busi.user_account set balance=balance+? where user_id=?", req.Amount, 2) + _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance+? where user_id=?", in.Amount, 2) return err }) } -func (s *busiServer) TransOutXa(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - return &dtmgrpc.BusiReply{BusiData: []byte("reply")}, XaGrpcClient.XaLocalTransaction(in, func(db *sql.DB, xa *dtmgrpc.XaGrpc) error { - if req.TransOutResult == dtmcli.ResultFailure { +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 := dtmcli.DBExec(db, "update dtm_busi.user_account set balance=balance-? where user_id=?", req.Amount, 1) + _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance-? where user_id=?", in.Amount, 1) return err }) } -func (s *busiServer) TransInTccNested(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - tcc, err := dtmgrpc.TccFromRequest(in) - dtmcli.FatalIfError(err) - _, err = tcc.CallBranch(dtmcli.MustMarshal(req), BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInConfirm", BusiGrpc+"/examples.Busi/TransInRevert") - dtmcli.FatalIfError(err) - return &dtmgrpc.BusiReply{BusiData: []byte("reply")}, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), req.TransInResult, dtmcli.GetFuncName()) +func (s *busiServer) TransInTccNested(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + tcc, err := dtmgrpc.TccFromGrpc(ctx) + dtmimp.FatalIfError(err) + r := &emptypb.Empty{} + err = tcc.CallBranch(in, BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransInConfirm", BusiGrpc+"/examples.Busi/TransInRevert", r) + dtmimp.FatalIfError(err) + return r, handleGrpcBusiness(in, MainSwitch.TransInResult.Fetch(), in.TransInResult, dtmimp.GetFuncName()) } diff --git a/examples/base_http.go b/examples/base_http.go index 8dcebc7..9728dd7 100644 --- a/examples/base_http.go +++ b/examples/base_http.go @@ -9,6 +9,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "gorm.io/driver/mysql" "gorm.io/driver/postgres" "gorm.io/gorm" @@ -32,14 +33,14 @@ var Busi string = fmt.Sprintf("http://localhost:%d%s", BusiPort, BusiAPI) // BaseAppStartup base app startup func BaseAppStartup() *gin.Engine { - dtmcli.Logf("examples starting") + dtmimp.Logf("examples starting") app := common.GetGinApp() BaseAddRoute(app) for k, v := range setupFuncs { - dtmcli.Logf("initing %s", k) + dtmimp.Logf("initing %s", k) v(app) } - dtmcli.Logf("Starting busi at: %d", BusiPort) + dtmimp.Logf("Starting busi at: %d", BusiPort) go app.Run(fmt.Sprintf(":%d", BusiPort)) time.Sleep(100 * time.Millisecond) @@ -58,6 +59,7 @@ func (s *AutoEmptyString) SetOnce(v string) { // Fetch fetch the stored value, then reset the value to empty func (s *AutoEmptyString) Fetch() string { + dtmimp.Logf("fetch result is: %s", s.value) v := s.value s.value = "" return v @@ -78,12 +80,12 @@ var MainSwitch mainSwitchType func handleGeneralBusiness(c *gin.Context, result1 string, result2 string, busi string) (interface{}, error) { info := infoFromContext(c) - res := dtmcli.OrString(result1, result2, dtmcli.ResultSuccess) - dtmcli.Logf("%s %s result: %s", busi, info.String(), res) + res := dtmimp.OrString(result1, result2, dtmcli.ResultSuccess) + dtmimp.Logf("%s %s result: %s", busi, info.String(), res) if res == "ERROR" { return nil, errors.New("ERROR from user") } - return M{"dtm_result": res}, nil + return map[string]interface{}{"dtm_result": res}, nil } // BaseAddRoute add base route handler @@ -107,32 +109,32 @@ func BaseAddRoute(app *gin.Engine) { return handleGeneralBusiness(c, MainSwitch.TransOutRevertResult.Fetch(), "", "TransOutRevert") })) app.GET(BusiAPI+"/CanSubmit", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - dtmcli.Logf("%s CanSubmit", c.Query("gid")) - return dtmcli.OrString(MainSwitch.CanSubmitResult.Fetch(), dtmcli.ResultSuccess), nil + dtmimp.Logf("%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) { - return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) (interface{}, error) { + return dtmcli.MapSuccess, XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { if reqFrom(c).TransInResult == dtmcli.ResultFailure { - return dtmcli.MapFailure, nil + return dtmcli.ErrFailure } - _, err := dtmcli.DBExec(db, "update dtm_busi.user_account set balance=balance+? where user_id=?", reqFrom(c).Amount, 2) - return dtmcli.MapSuccess, err + _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance+? where user_id=?", reqFrom(c).Amount, 2) + return err }) })) app.POST(BusiAPI+"/TransOutXa", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) (interface{}, error) { + return dtmcli.MapSuccess, XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { if reqFrom(c).TransOutResult == dtmcli.ResultFailure { - return dtmcli.MapFailure, nil + return dtmcli.ErrFailure } - _, err := dtmcli.DBExec(db, "update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, 1) - return dtmcli.MapSuccess, err + _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, 1) + return err }) })) app.POST(BusiAPI+"/TransOutXaGorm", common.WrapHandler(func(c *gin.Context) (interface{}, error) { - return XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) (interface{}, error) { + return dtmcli.MapSuccess, XaClient.XaLocalTransaction(c.Request.URL.Query(), func(db *sql.DB, xa *dtmcli.Xa) error { if reqFrom(c).TransOutResult == dtmcli.ResultFailure { - return dtmcli.MapFailure, nil + return dtmcli.ErrFailure } var dia gorm.Dialector = nil if dtmcli.GetCurrentDBType() == dtmcli.DBTypeMysql { @@ -142,10 +144,10 @@ func BaseAddRoute(app *gin.Engine) { } gdb, err := gorm.Open(dia, &gorm.Config{}) if err != nil { - return nil, err + return err } dbr := gdb.Exec("update dtm_busi.user_account set balance=balance-? where user_id=?", reqFrom(c).Amount, 1) - return dtmcli.MapSuccess, dbr.Error + return dbr.Error }) })) diff --git a/examples/base_types.go b/examples/base_types.go index 0e2381c..394962a 100644 --- a/examples/base_types.go +++ b/examples/base_types.go @@ -1,18 +1,17 @@ package examples import ( + "context" "database/sql" "fmt" "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc" ) -// M alias -type M = map[string]interface{} - // DtmServer dtm service address const DtmServer = "http://localhost:8080/api/dtmsvr" @@ -34,8 +33,17 @@ func (t *TransReq) String() string { func GenTransReq(amount int, outFailed bool, inFailed bool) *TransReq { return &TransReq{ Amount: amount, - TransOutResult: dtmcli.If(outFailed, dtmcli.ResultFailure, dtmcli.ResultSuccess).(string), - TransInResult: dtmcli.If(inFailed, dtmcli.ResultFailure, dtmcli.ResultSuccess).(string), + TransOutResult: dtmimp.If(outFailed, dtmcli.ResultFailure, dtmcli.ResultSuccess).(string), + TransInResult: dtmimp.If(inFailed, dtmcli.ResultFailure, dtmcli.ResultSuccess).(string), + } +} + +// GenBusiReq 1 +func GenBusiReq(amount int, outFailed bool, inFailed bool) *BusiReq { + return &BusiReq{ + Amount: int64(amount), + TransOutResult: dtmimp.If(outFailed, dtmcli.ResultFailure, dtmcli.ResultSuccess).(string), + TransInResult: dtmimp.If(inFailed, dtmcli.ResultFailure, dtmcli.ResultSuccess).(string), } } @@ -44,7 +52,7 @@ func reqFrom(c *gin.Context) *TransReq { if !ok { req := TransReq{} err := c.BindJSON(&req) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) c.Set("trans_req", &req) v = &req } @@ -66,28 +74,28 @@ func dbGet() *common.DB { } func sdbGet() *sql.DB { - db, err := dtmcli.PooledDB(config.DB) - dtmcli.FatalIfError(err) + db, err := dtmimp.PooledDB(config.DB) + dtmimp.FatalIfError(err) return db } func txGet() *sql.Tx { db := sdbGet() tx, err := db.Begin() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return tx } // MustBarrierFromGin 1 func MustBarrierFromGin(c *gin.Context) *dtmcli.BranchBarrier { ti, err := dtmcli.BarrierFromQuery(c.Request.URL.Query()) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return ti } // MustBarrierFromGrpc 1 -func MustBarrierFromGrpc(in *dtmgrpc.BusiRequest) *dtmgrpc.BranchBarrier { - ti, err := dtmgrpc.BarrierFromGrpc(in) - dtmcli.FatalIfError(err) +func MustBarrierFromGrpc(ctx context.Context) *dtmcli.BranchBarrier { + ti, err := dtmgrpc.BarrierFromGrpc(ctx) + dtmimp.FatalIfError(err) return ti } diff --git a/examples/busi.pb.go b/examples/busi.pb.go index 614c3fb..cbf37b7 100644 --- a/examples/busi.pb.go +++ b/examples/busi.pb.go @@ -1,16 +1,17 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 +// protoc-gen-go v1.27.1 // protoc v3.17.3 // source: examples/busi.proto package examples import ( - dtmgrpc "github.com/yedf/dtm/dtmgrpc" 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 ( @@ -20,121 +21,207 @@ const ( _ = 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 "" +} + 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, - 0x15, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x32, 0x84, 0x08, 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, - 0x37, 0x0a, 0x09, 0x43, 0x61, 0x6e, 0x53, 0x75, 0x62, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x2e, 0x64, - 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, - 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x07, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x49, 0x6e, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, - 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, - 0x36, 0x0a, 0x08, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x12, 0x14, 0x2e, 0x64, 0x74, - 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x49, 0x6e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, - 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, - 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, - 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, - 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, - 0x22, 0x00, 0x12, 0x3c, 0x0a, 0x0e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x43, 0x6f, 0x6e, - 0x66, 0x69, 0x72, 0x6d, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, - 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, - 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, - 0x12, 0x3d, 0x0a, 0x0f, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x72, 0x6d, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, - 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, - 0x36, 0x0a, 0x08, 0x58, 0x61, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x79, 0x12, 0x14, 0x2e, 0x64, 0x74, - 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, - 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x37, 0x0a, 0x09, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x49, 0x6e, 0x58, 0x61, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, - 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, - 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, - 0x12, 0x38, 0x0a, 0x0a, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x58, 0x61, 0x12, 0x14, - 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, - 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x0a, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, - 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, - 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, - 0x6c, 0x79, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0b, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, - 0x54, 0x63, 0x63, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, - 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, - 0x3e, 0x0a, 0x10, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x54, 0x63, 0x63, 0x4e, 0x65, 0x73, - 0x74, 0x65, 0x64, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, - 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, - 0x3a, 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x49, 0x6e, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, - 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, - 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x0d, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x14, 0x2e, 0x64, - 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, - 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x40, 0x0a, 0x12, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x49, 0x6e, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, 0x61, 0x12, 0x14, - 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, - 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x13, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x4f, 0x75, 0x74, 0x52, 0x65, 0x76, 0x65, 0x72, 0x74, 0x42, 0x53, 0x61, 0x67, - 0x61, 0x12, 0x14, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x64, 0x74, 0x6d, 0x67, 0x72, 0x70, - 0x63, 0x2e, 0x42, 0x75, 0x73, 0x69, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x1e, 0x5a, - 0x1c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x65, 0x64, 0x66, - 0x2f, 0x64, 0x74, 0x6d, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 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, 0x32, 0x9a, 0x08, + 0x0a, 0x04, 0x42, 0x75, 0x73, 0x69, 0x12, 0x38, 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, 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, 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, 0x1e, 0x5a, 0x1c, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x79, 0x65, 0x64, 0x66, 0x2f, 0x64, 0x74, + 0x6d, 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, 1) var file_examples_busi_proto_goTypes = []interface{}{ - (*dtmgrpc.BusiRequest)(nil), // 0: dtmgrpc.BusiRequest - (*dtmgrpc.BusiReply)(nil), // 1: dtmgrpc.BusiReply + (*BusiReq)(nil), // 0: examples.BusiReq + (*emptypb.Empty)(nil), // 1: google.protobuf.Empty } var file_examples_busi_proto_depIdxs = []int32{ - 0, // 0: examples.Busi.CanSubmit:input_type -> dtmgrpc.BusiRequest - 0, // 1: examples.Busi.TransIn:input_type -> dtmgrpc.BusiRequest - 0, // 2: examples.Busi.TransOut:input_type -> dtmgrpc.BusiRequest - 0, // 3: examples.Busi.TransInRevert:input_type -> dtmgrpc.BusiRequest - 0, // 4: examples.Busi.TransOutRevert:input_type -> dtmgrpc.BusiRequest - 0, // 5: examples.Busi.TransInConfirm:input_type -> dtmgrpc.BusiRequest - 0, // 6: examples.Busi.TransOutConfirm:input_type -> dtmgrpc.BusiRequest - 0, // 7: examples.Busi.XaNotify:input_type -> dtmgrpc.BusiRequest - 0, // 8: examples.Busi.TransInXa:input_type -> dtmgrpc.BusiRequest - 0, // 9: examples.Busi.TransOutXa:input_type -> dtmgrpc.BusiRequest - 0, // 10: examples.Busi.TransInTcc:input_type -> dtmgrpc.BusiRequest - 0, // 11: examples.Busi.TransOutTcc:input_type -> dtmgrpc.BusiRequest - 0, // 12: examples.Busi.TransInTccNested:input_type -> dtmgrpc.BusiRequest - 0, // 13: examples.Busi.TransInBSaga:input_type -> dtmgrpc.BusiRequest - 0, // 14: examples.Busi.TransOutBSaga:input_type -> dtmgrpc.BusiRequest - 0, // 15: examples.Busi.TransInRevertBSaga:input_type -> dtmgrpc.BusiRequest - 0, // 16: examples.Busi.TransOutRevertBSaga:input_type -> dtmgrpc.BusiRequest - 1, // 17: examples.Busi.CanSubmit:output_type -> dtmgrpc.BusiReply - 1, // 18: examples.Busi.TransIn:output_type -> dtmgrpc.BusiReply - 1, // 19: examples.Busi.TransOut:output_type -> dtmgrpc.BusiReply - 1, // 20: examples.Busi.TransInRevert:output_type -> dtmgrpc.BusiReply - 1, // 21: examples.Busi.TransOutRevert:output_type -> dtmgrpc.BusiReply - 1, // 22: examples.Busi.TransInConfirm:output_type -> dtmgrpc.BusiReply - 1, // 23: examples.Busi.TransOutConfirm:output_type -> dtmgrpc.BusiReply - 1, // 24: examples.Busi.XaNotify:output_type -> dtmgrpc.BusiReply - 1, // 25: examples.Busi.TransInXa:output_type -> dtmgrpc.BusiReply - 1, // 26: examples.Busi.TransOutXa:output_type -> dtmgrpc.BusiReply - 1, // 27: examples.Busi.TransInTcc:output_type -> dtmgrpc.BusiReply - 1, // 28: examples.Busi.TransOutTcc:output_type -> dtmgrpc.BusiReply - 1, // 29: examples.Busi.TransInTccNested:output_type -> dtmgrpc.BusiReply - 1, // 30: examples.Busi.TransInBSaga:output_type -> dtmgrpc.BusiReply - 1, // 31: examples.Busi.TransOutBSaga:output_type -> dtmgrpc.BusiReply - 1, // 32: examples.Busi.TransInRevertBSaga:output_type -> dtmgrpc.BusiReply - 1, // 33: examples.Busi.TransOutRevertBSaga:output_type -> dtmgrpc.BusiReply + 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 + 1, // 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 -> google.protobuf.Empty + 1, // 18: examples.Busi.TransIn:output_type -> google.protobuf.Empty + 1, // 19: examples.Busi.TransOut:output_type -> google.protobuf.Empty + 1, // 20: examples.Busi.TransInRevert:output_type -> google.protobuf.Empty + 1, // 21: examples.Busi.TransOutRevert:output_type -> google.protobuf.Empty + 1, // 22: examples.Busi.TransInConfirm:output_type -> google.protobuf.Empty + 1, // 23: examples.Busi.TransOutConfirm:output_type -> google.protobuf.Empty + 1, // 24: examples.Busi.XaNotify:output_type -> google.protobuf.Empty + 1, // 25: examples.Busi.TransInXa:output_type -> google.protobuf.Empty + 1, // 26: examples.Busi.TransOutXa:output_type -> google.protobuf.Empty + 1, // 27: examples.Busi.TransInTcc:output_type -> google.protobuf.Empty + 1, // 28: examples.Busi.TransOutTcc:output_type -> google.protobuf.Empty + 1, // 29: examples.Busi.TransInTccNested:output_type -> google.protobuf.Empty + 1, // 30: examples.Busi.TransInBSaga:output_type -> google.protobuf.Empty + 1, // 31: examples.Busi.TransOutBSaga:output_type -> google.protobuf.Empty + 1, // 32: examples.Busi.TransInRevertBSaga:output_type -> google.protobuf.Empty + 1, // 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 @@ -147,18 +234,33 @@ 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 + } + } + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_examples_busi_proto_rawDesc, NumEnums: 0, - NumMessages: 0, + NumMessages: 1, 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 diff --git a/examples/busi.proto b/examples/busi.proto index b4bcfdb..afed6b4 100644 --- a/examples/busi.proto +++ b/examples/busi.proto @@ -1,30 +1,37 @@ syntax = "proto3"; package examples; +import "google/protobuf/empty.proto"; option go_package = "github.com/yedf/dtm/examples"; -import "dtmgrpc/dtmgrpc.proto"; + +// DtmRequest request sent to dtm server +message BusiReq { + int64 Amount = 1; + string TransOutResult = 2; + string TransInResult = 3; +} // The dtm service definition. service Busi { - rpc CanSubmit(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransIn(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransOut(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransInRevert(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransOutRevert(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransInConfirm(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransOutConfirm(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc XaNotify(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} + rpc CanSubmit(BusiReq) returns (google.protobuf.Empty) {} + rpc TransIn(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOut(BusiReq) returns (google.protobuf.Empty) {} + rpc TransInRevert(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutRevert(BusiReq) returns (google.protobuf.Empty) {} + rpc TransInConfirm(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutConfirm(BusiReq) returns (google.protobuf.Empty) {} + rpc XaNotify(google.protobuf.Empty) returns (google.protobuf.Empty) {} - rpc TransInXa(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransOutXa(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransInTcc(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransOutTcc(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransInTccNested(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} + rpc TransInXa(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutXa(BusiReq) returns (google.protobuf.Empty) {} + rpc TransInTcc(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutTcc(BusiReq) returns (google.protobuf.Empty) {} + rpc TransInTccNested(BusiReq) returns (google.protobuf.Empty) {} - rpc TransInBSaga(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransOutBSaga(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransInRevertBSaga(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} - rpc TransOutRevertBSaga(dtmgrpc.BusiRequest) returns (dtmgrpc.BusiReply) {} + rpc TransInBSaga(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutBSaga(BusiReq) returns (google.protobuf.Empty) {} + rpc TransInRevertBSaga(BusiReq) returns (google.protobuf.Empty) {} + rpc TransOutRevertBSaga(BusiReq) returns (google.protobuf.Empty) {} } diff --git a/examples/busi_grpc.pb.go b/examples/busi_grpc.pb.go index af9e600..f779fc6 100644 --- a/examples/busi_grpc.pb.go +++ b/examples/busi_grpc.pb.go @@ -4,10 +4,10 @@ package examples import ( context "context" - dtmgrpc "github.com/yedf/dtm/dtmgrpc" 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" ) // This is a compile-time assertion to ensure that this generated file @@ -19,23 +19,23 @@ const _ = grpc.SupportPackageIsVersion7 // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. type BusiClient interface { - CanSubmit(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransIn(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransOut(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransInRevert(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransOutRevert(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransInConfirm(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransOutConfirm(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - XaNotify(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransInXa(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransOutXa(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransInTcc(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransOutTcc(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransInTccNested(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransInBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransOutBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransInRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) - TransOutRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) + CanSubmit(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransIn(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOut(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransInRevert(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutRevert(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransInConfirm(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutConfirm(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + XaNotify(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransInXa(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutXa(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransInTcc(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutTcc(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransInTccNested(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransInBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransInRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) + TransOutRevertBSaga(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) } type busiClient struct { @@ -46,8 +46,8 @@ func NewBusiClient(cc grpc.ClientConnInterface) BusiClient { return &busiClient{cc} } -func (c *busiClient) CanSubmit(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +func (c *busiClient) CanSubmit(ctx context.Context, in *BusiReq, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) err := c.cc.Invoke(ctx, "/examples.Busi/CanSubmit", in, out, opts...) if err != nil { return nil, err @@ -55,8 +55,8 @@ func (c *busiClient) CanSubmit(ctx context.Context, in *dtmgrpc.BusiRequest, opt return out, nil } -func (c *busiClient) TransIn(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -64,8 +64,8 @@ func (c *busiClient) TransIn(ctx context.Context, in *dtmgrpc.BusiRequest, opts return out, nil } -func (c *busiClient) TransOut(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -73,8 +73,8 @@ func (c *busiClient) TransOut(ctx context.Context, in *dtmgrpc.BusiRequest, opts return out, nil } -func (c *busiClient) TransInRevert(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -82,8 +82,8 @@ func (c *busiClient) TransInRevert(ctx context.Context, in *dtmgrpc.BusiRequest, return out, nil } -func (c *busiClient) TransOutRevert(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -91,8 +91,8 @@ func (c *busiClient) TransOutRevert(ctx context.Context, in *dtmgrpc.BusiRequest return out, nil } -func (c *busiClient) TransInConfirm(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -100,8 +100,8 @@ func (c *busiClient) TransInConfirm(ctx context.Context, in *dtmgrpc.BusiRequest return out, nil } -func (c *busiClient) TransOutConfirm(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -109,8 +109,8 @@ func (c *busiClient) TransOutConfirm(ctx context.Context, in *dtmgrpc.BusiReques return out, nil } -func (c *busiClient) XaNotify(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -118,8 +118,8 @@ func (c *busiClient) XaNotify(ctx context.Context, in *dtmgrpc.BusiRequest, opts return out, nil } -func (c *busiClient) TransInXa(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -127,8 +127,8 @@ func (c *busiClient) TransInXa(ctx context.Context, in *dtmgrpc.BusiRequest, opt return out, nil } -func (c *busiClient) TransOutXa(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -136,8 +136,8 @@ func (c *busiClient) TransOutXa(ctx context.Context, in *dtmgrpc.BusiRequest, op return out, nil } -func (c *busiClient) TransInTcc(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -145,8 +145,8 @@ func (c *busiClient) TransInTcc(ctx context.Context, in *dtmgrpc.BusiRequest, op return out, nil } -func (c *busiClient) TransOutTcc(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -154,8 +154,8 @@ func (c *busiClient) TransOutTcc(ctx context.Context, in *dtmgrpc.BusiRequest, o return out, nil } -func (c *busiClient) TransInTccNested(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -163,8 +163,8 @@ func (c *busiClient) TransInTccNested(ctx context.Context, in *dtmgrpc.BusiReque return out, nil } -func (c *busiClient) TransInBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -172,8 +172,8 @@ func (c *busiClient) TransInBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, return out, nil } -func (c *busiClient) TransOutBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -181,8 +181,8 @@ func (c *busiClient) TransOutBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, return out, nil } -func (c *busiClient) TransInRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -190,8 +190,8 @@ func (c *busiClient) TransInRevertBSaga(ctx context.Context, in *dtmgrpc.BusiReq return out, nil } -func (c *busiClient) TransOutRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest, opts ...grpc.CallOption) (*dtmgrpc.BusiReply, error) { - out := new(dtmgrpc.BusiReply) +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...) if err != nil { return nil, err @@ -203,23 +203,23 @@ func (c *busiClient) TransOutRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRe // All implementations must embed UnimplementedBusiServer // for forward compatibility type BusiServer interface { - CanSubmit(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransIn(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransOut(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransInRevert(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransOutRevert(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransInConfirm(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransOutConfirm(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - XaNotify(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransInXa(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransOutXa(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransInTcc(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransOutTcc(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransInTccNested(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransInBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransOutBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransInRevertBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) - TransOutRevertBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) + CanSubmit(context.Context, *BusiReq) (*emptypb.Empty, error) + TransIn(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOut(context.Context, *BusiReq) (*emptypb.Empty, error) + TransInRevert(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutRevert(context.Context, *BusiReq) (*emptypb.Empty, error) + TransInConfirm(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutConfirm(context.Context, *BusiReq) (*emptypb.Empty, error) + XaNotify(context.Context, *emptypb.Empty) (*emptypb.Empty, error) + TransInXa(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutXa(context.Context, *BusiReq) (*emptypb.Empty, error) + TransInTcc(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutTcc(context.Context, *BusiReq) (*emptypb.Empty, error) + TransInTccNested(context.Context, *BusiReq) (*emptypb.Empty, error) + TransInBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) + TransInRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) + TransOutRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) mustEmbedUnimplementedBusiServer() } @@ -227,55 +227,55 @@ type BusiServer interface { type UnimplementedBusiServer struct { } -func (UnimplementedBusiServer) CanSubmit(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) CanSubmit(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method CanSubmit not implemented") } -func (UnimplementedBusiServer) TransIn(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransIn(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransIn not implemented") } -func (UnimplementedBusiServer) TransOut(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransOut(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOut not implemented") } -func (UnimplementedBusiServer) TransInRevert(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransInRevert(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransInRevert not implemented") } -func (UnimplementedBusiServer) TransOutRevert(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransOutRevert(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutRevert not implemented") } -func (UnimplementedBusiServer) TransInConfirm(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransInConfirm(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransInConfirm not implemented") } -func (UnimplementedBusiServer) TransOutConfirm(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransOutConfirm(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutConfirm not implemented") } -func (UnimplementedBusiServer) XaNotify(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) XaNotify(context.Context, *emptypb.Empty) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method XaNotify not implemented") } -func (UnimplementedBusiServer) TransInXa(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransInXa(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransInXa not implemented") } -func (UnimplementedBusiServer) TransOutXa(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransOutXa(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutXa not implemented") } -func (UnimplementedBusiServer) TransInTcc(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransInTcc(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransInTcc not implemented") } -func (UnimplementedBusiServer) TransOutTcc(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransOutTcc(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutTcc not implemented") } -func (UnimplementedBusiServer) TransInTccNested(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransInTccNested(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransInTccNested not implemented") } -func (UnimplementedBusiServer) TransInBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransInBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransInBSaga not implemented") } -func (UnimplementedBusiServer) TransOutBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransOutBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutBSaga not implemented") } -func (UnimplementedBusiServer) TransInRevertBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransInRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransInRevertBSaga not implemented") } -func (UnimplementedBusiServer) TransOutRevertBSaga(context.Context, *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { +func (UnimplementedBusiServer) TransOutRevertBSaga(context.Context, *BusiReq) (*emptypb.Empty, error) { return nil, status.Errorf(codes.Unimplemented, "method TransOutRevertBSaga not implemented") } func (UnimplementedBusiServer) mustEmbedUnimplementedBusiServer() {} @@ -292,7 +292,7 @@ func RegisterBusiServer(s grpc.ServiceRegistrar, srv BusiServer) { } func _Busi_CanSubmit_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -304,13 +304,13 @@ func _Busi_CanSubmit_Handler(srv interface{}, ctx context.Context, dec func(inte FullMethod: "/examples.Busi/CanSubmit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).CanSubmit(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).CanSubmit(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransIn_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -322,13 +322,13 @@ func _Busi_TransIn_Handler(srv interface{}, ctx context.Context, dec func(interf FullMethod: "/examples.Busi/TransIn", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransIn(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransIn(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransOut_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -340,13 +340,13 @@ func _Busi_TransOut_Handler(srv interface{}, ctx context.Context, dec func(inter FullMethod: "/examples.Busi/TransOut", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransOut(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransOut(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransInRevert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -358,13 +358,13 @@ func _Busi_TransInRevert_Handler(srv interface{}, ctx context.Context, dec func( FullMethod: "/examples.Busi/TransInRevert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransInRevert(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransInRevert(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransOutRevert_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -376,13 +376,13 @@ func _Busi_TransOutRevert_Handler(srv interface{}, ctx context.Context, dec func FullMethod: "/examples.Busi/TransOutRevert", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransOutRevert(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransOutRevert(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransInConfirm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -394,13 +394,13 @@ func _Busi_TransInConfirm_Handler(srv interface{}, ctx context.Context, dec func FullMethod: "/examples.Busi/TransInConfirm", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransInConfirm(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransInConfirm(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransOutConfirm_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -412,13 +412,13 @@ func _Busi_TransOutConfirm_Handler(srv interface{}, ctx context.Context, dec fun FullMethod: "/examples.Busi/TransOutConfirm", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransOutConfirm(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransOutConfirm(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_XaNotify_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(emptypb.Empty) if err := dec(in); err != nil { return nil, err } @@ -430,13 +430,13 @@ func _Busi_XaNotify_Handler(srv interface{}, ctx context.Context, dec func(inter FullMethod: "/examples.Busi/XaNotify", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).XaNotify(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).XaNotify(ctx, req.(*emptypb.Empty)) } return interceptor(ctx, in, info, handler) } func _Busi_TransInXa_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -448,13 +448,13 @@ func _Busi_TransInXa_Handler(srv interface{}, ctx context.Context, dec func(inte FullMethod: "/examples.Busi/TransInXa", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransInXa(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransInXa(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransOutXa_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -466,13 +466,13 @@ func _Busi_TransOutXa_Handler(srv interface{}, ctx context.Context, dec func(int FullMethod: "/examples.Busi/TransOutXa", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransOutXa(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransOutXa(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransInTcc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -484,13 +484,13 @@ func _Busi_TransInTcc_Handler(srv interface{}, ctx context.Context, dec func(int FullMethod: "/examples.Busi/TransInTcc", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransInTcc(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransInTcc(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransOutTcc_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -502,13 +502,13 @@ func _Busi_TransOutTcc_Handler(srv interface{}, ctx context.Context, dec func(in FullMethod: "/examples.Busi/TransOutTcc", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransOutTcc(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransOutTcc(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransInTccNested_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -520,13 +520,13 @@ func _Busi_TransInTccNested_Handler(srv interface{}, ctx context.Context, dec fu FullMethod: "/examples.Busi/TransInTccNested", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransInTccNested(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransInTccNested(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransInBSaga_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -538,13 +538,13 @@ func _Busi_TransInBSaga_Handler(srv interface{}, ctx context.Context, dec func(i FullMethod: "/examples.Busi/TransInBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransInBSaga(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransInBSaga(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransOutBSaga_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -556,13 +556,13 @@ func _Busi_TransOutBSaga_Handler(srv interface{}, ctx context.Context, dec func( FullMethod: "/examples.Busi/TransOutBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransOutBSaga(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransOutBSaga(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransInRevertBSaga_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -574,13 +574,13 @@ func _Busi_TransInRevertBSaga_Handler(srv interface{}, ctx context.Context, dec FullMethod: "/examples.Busi/TransInRevertBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransInRevertBSaga(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransInRevertBSaga(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } func _Busi_TransOutRevertBSaga_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(dtmgrpc.BusiRequest) + in := new(BusiReq) if err := dec(in); err != nil { return nil, err } @@ -592,7 +592,7 @@ func _Busi_TransOutRevertBSaga_Handler(srv interface{}, ctx context.Context, dec FullMethod: "/examples.Busi/TransOutRevertBSaga", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(BusiServer).TransOutRevertBSaga(ctx, req.(*dtmgrpc.BusiRequest)) + return srv.(BusiServer).TransOutRevertBSaga(ctx, req.(*BusiReq)) } return interceptor(ctx, in, info, handler) } diff --git a/examples/data.go b/examples/data.go index 490bcd7..c32362e 100644 --- a/examples/data.go +++ b/examples/data.go @@ -7,34 +7,54 @@ import ( "time" "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) var config = common.DtmConfig // RunSQLScript 1 func RunSQLScript(conf map[string]string, script string, skipDrop bool) { - con, err := dtmcli.StandaloneDB(conf) - dtmcli.FatalIfError(err) + con, err := dtmimp.StandaloneDB(conf) + dtmimp.FatalIfError(err) defer func() { con.Close() }() content, err := ioutil.ReadFile(script) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) sqls := strings.Split(string(content), ";") for _, sql := range sqls { s := strings.TrimSpace(sql) if s == "" || (skipDrop && strings.Contains(s, "drop")) { continue } - for _, err = dtmcli.DBExec(con, s); err != nil; { // wait for mysql to start - time.Sleep(3 * time.Second) - _, err = dtmcli.DBExec(con, s) - } - dtmcli.FatalIfError(err) + _, err = dtmimp.DBExec(con, s) + dtmimp.FatalIfError(err) + } +} + +func resetXaData() { + if config.DB["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) { + sdb := sdbGet() + for _, err := dtmimp.DBExec(sdb, "select 1"); err != nil; { // wait for mysql to start + time.Sleep(3 * time.Second) + _, err = dtmimp.DBExec(sdb, "select 1") + } + + resetXaData() file := fmt.Sprintf("%s/examples.%s.sql", common.GetCallerCodeDir(), config.DB["driver"]) RunSQLScript(config.DB, file, skipDrop) file = fmt.Sprintf("%s/../dtmcli/barrier.%s.sql", common.GetCallerCodeDir(), config.DB["driver"]) @@ -51,6 +71,6 @@ type sampleInfo struct { var Samples = map[string]*sampleInfo{} func addSample(name string, fn func() string) { - dtmcli.LogIfFatalf(Samples[name] != nil, "%s already exists", name) + dtmimp.LogIfFatalf(Samples[name] != nil, "%s already exists", name) Samples[name] = &sampleInfo{Arg: name, Action: fn} } diff --git a/examples/grpc_msg.go b/examples/grpc_msg.go index 8a14efc..5ce369c 100644 --- a/examples/grpc_msg.go +++ b/examples/grpc_msg.go @@ -1,19 +1,19 @@ package examples import ( - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" dtmgrpc "github.com/yedf/dtm/dtmgrpc" ) func init() { addSample("grpc_msg", func() string { - req := dtmcli.MustMarshal(&TransReq{Amount: 30}) + 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() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return msg.Gid }) } diff --git a/examples/grpc_saga.go b/examples/grpc_saga.go index 8d90d6e..178169a 100644 --- a/examples/grpc_saga.go +++ b/examples/grpc_saga.go @@ -1,30 +1,30 @@ package examples import ( - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" dtmgrpc "github.com/yedf/dtm/dtmgrpc" ) func init() { addSample("grpc_saga", func() string { - req := dtmcli.MustMarshal(&TransReq{Amount: 30}) + req := &BusiReq{Amount: 30} gid := dtmgrpc.MustGenGid(DtmGrpcServer) - saga := dtmgrpc.NewSaga(DtmGrpcServer, gid). + saga := dtmgrpc.NewSagaGrpc(DtmGrpcServer, gid). Add(BusiGrpc+"/examples.Busi/TransOut", BusiGrpc+"/examples.Busi/TransOutRevert", req). Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransOutRevert", req) err := saga.Submit() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return saga.Gid }) addSample("grpc_saga_wait", func() string { - req := dtmcli.MustMarshal(&TransReq{Amount: 30}) + req := &BusiReq{Amount: 30} gid := dtmgrpc.MustGenGid(DtmGrpcServer) - saga := dtmgrpc.NewSaga(DtmGrpcServer, gid). + saga := dtmgrpc.NewSagaGrpc(DtmGrpcServer, gid). Add(BusiGrpc+"/examples.Busi/TransOut", BusiGrpc+"/examples.Busi/TransOutRevert", req). Add(BusiGrpc+"/examples.Busi/TransIn", BusiGrpc+"/examples.Busi/TransOutRevert", req) saga.WaitResult = true err := saga.Submit() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return saga.Gid }) } diff --git a/examples/grpc_saga_barrier.go b/examples/grpc_saga_barrier.go index a1ee504..b8bd517 100644 --- a/examples/grpc_saga_barrier.go +++ b/examples/grpc_saga_barrier.go @@ -4,65 +4,59 @@ import ( "context" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/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 := dtmcli.MustMarshal(&TransReq{Amount: 30}) + req := &BusiReq{Amount: 30} gid := dtmgrpc.MustGenGid(DtmGrpcServer) - saga := dtmgrpc.NewSaga(DtmGrpcServer, gid). + 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() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return saga.Gid }) } -func sagaGrpcBarrierAdjustBalance(db dtmcli.DB, uid int, amount int, result string) error { +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 := dtmcli.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) + _, 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 *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - barrier := MustBarrierFromGrpc(in) - return &dtmgrpc.BusiReply{}, barrier.Call(txGet(), func(tx dtmcli.DB) error { - return sagaGrpcBarrierAdjustBalance(tx, 2, req.Amount, req.TransInResult) +func (s *busiServer) TransInBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(tx dtmcli.DB) error { + return sagaGrpcBarrierAdjustBalance(tx, 2, in.Amount, in.TransInResult) }) } -func (s *busiServer) TransOutBSaga(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - barrier := MustBarrierFromGrpc(in) - return &dtmgrpc.BusiReply{}, barrier.Call(txGet(), func(db dtmcli.DB) error { - return sagaGrpcBarrierAdjustBalance(db, 1, -req.Amount, req.TransOutResult) +func (s *busiServer) TransOutBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(db dtmcli.DB) error { + return sagaGrpcBarrierAdjustBalance(db, 1, -in.Amount, in.TransOutResult) }) } -func (s *busiServer) TransInRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - barrier := MustBarrierFromGrpc(in) - return &dtmgrpc.BusiReply{}, barrier.Call(txGet(), func(db dtmcli.DB) error { - return sagaGrpcBarrierAdjustBalance(db, 2, -req.Amount, "") +func (s *busiServer) TransInRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(db dtmcli.DB) error { + return sagaGrpcBarrierAdjustBalance(db, 2, -in.Amount, "") }) } -func (s *busiServer) TransOutRevertBSaga(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - req := TransReq{} - dtmcli.MustUnmarshal(in.BusiData, &req) - barrier := MustBarrierFromGrpc(in) - return &dtmgrpc.BusiReply{}, barrier.Call(txGet(), func(db dtmcli.DB) error { - return sagaGrpcBarrierAdjustBalance(db, 1, req.Amount, "") +func (s *busiServer) TransOutRevertBSaga(ctx context.Context, in *BusiReq) (*emptypb.Empty, error) { + barrier := MustBarrierFromGrpc(ctx) + return &emptypb.Empty{}, barrier.Call(txGet(), func(db dtmcli.DB) error { + return sagaGrpcBarrierAdjustBalance(db, 1, in.Amount, "") }) } diff --git a/examples/grpc_tcc.go b/examples/grpc_tcc.go index f8b61d6..94e91b9 100644 --- a/examples/grpc_tcc.go +++ b/examples/grpc_tcc.go @@ -1,24 +1,26 @@ package examples import ( - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" dtmgrpc "github.com/yedf/dtm/dtmgrpc" + emptypb "google.golang.org/protobuf/types/known/emptypb" ) func init() { addSample("grpc_tcc", func() string { - dtmcli.Logf("tcc simple transaction begin") + dtmimp.Logf("tcc simple transaction begin") gid := dtmgrpc.MustGenGid(DtmGrpcServer) err := dtmgrpc.TccGlobalTransaction(DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { - data := dtmcli.MustMarshal(&TransReq{Amount: 30}) - _, err := tcc.CallBranch(data, BusiGrpc+"/examples.Busi/TransOutTcc", BusiGrpc+"/examples.Busi/TransOutConfirm", BusiGrpc+"/examples.Busi/TransOutRevert") + 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") + err = tcc.CallBranch(data, BusiGrpc+"/examples.Busi/TransInTcc", BusiGrpc+"/examples.Busi/TransInConfirm", BusiGrpc+"/examples.Busi/TransInRevert", r) return err }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return gid }) } diff --git a/examples/grpc_xa.go b/examples/grpc_xa.go index 27c9f05..c9b3dd7 100644 --- a/examples/grpc_xa.go +++ b/examples/grpc_xa.go @@ -3,35 +3,29 @@ package examples import ( context "context" - "github.com/gin-gonic/gin" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc" + "google.golang.org/protobuf/types/known/emptypb" ) -// XaGrpcClient XA client connection -var XaGrpcClient *dtmgrpc.XaGrpcClient = nil - func init() { - setupFuncs["XaGrpcSetup"] = func(app *gin.Engine) { - XaGrpcClient = dtmgrpc.NewXaGrpcClient(DtmGrpcServer, config.DB, BusiGrpc+"/examples.Busi/XaNotify") - } addSample("grpc_xa", func() string { gid := dtmgrpc.MustGenGid(DtmGrpcServer) - busiData := dtmcli.MustMarshal(&TransReq{Amount: 30}) + req := &BusiReq{Amount: 30} err := XaGrpcClient.XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { - _, err := xa.CallBranch(busiData, BusiGrpc+"/examples.Busi/TransOutXa") + r := &emptypb.Empty{} + err := xa.CallBranch(req, BusiGrpc+"/examples.Busi/TransOutXa", r) if err != nil { return err } - _, err = xa.CallBranch(busiData, BusiGrpc+"/examples.Busi/TransInXa") + err = xa.CallBranch(req, BusiGrpc+"/examples.Busi/TransInXa", r) return err }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return gid }) } -func (s *busiServer) XaNotify(ctx context.Context, in *dtmgrpc.BusiRequest) (*dtmgrpc.BusiReply, error) { - err := XaGrpcClient.HandleCallback(in.Info.Gid, in.Info.BranchID, in.Info.BranchType) - return &dtmgrpc.BusiReply{}, dtmgrpc.Result2Error(nil, err) +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 index a6d817e..5ab1c5b 100644 --- a/examples/http_gorm_xa.go +++ b/examples/http_gorm_xa.go @@ -3,6 +3,7 @@ package examples import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func init() { @@ -15,7 +16,7 @@ func init() { } return xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInXa") }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return gid }) diff --git a/examples/http_msg.go b/examples/http_msg.go index 044f541..79151e2 100644 --- a/examples/http_msg.go +++ b/examples/http_msg.go @@ -2,20 +2,21 @@ package examples import ( "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func init() { addSample("msg", func() string { - dtmcli.Logf("a busi transaction begin") + dtmimp.Logf("a busi transaction begin") req := &TransReq{Amount: 30} msg := dtmcli.NewMsg(DtmServer, dtmcli.MustGenGid(DtmServer)). Add(Busi+"/TransOut", req). Add(Busi+"/TransIn", req) err := msg.Prepare(Busi + "/query") - dtmcli.FatalIfError(err) - dtmcli.Logf("busi trans submit") + dtmimp.FatalIfError(err) + dtmimp.Logf("busi trans submit") err = msg.Submit() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return msg.Gid }) } diff --git a/examples/http_saga.go b/examples/http_saga.go index 3e7598d..c326db6 100644 --- a/examples/http_saga.go +++ b/examples/http_saga.go @@ -2,35 +2,36 @@ package examples import ( "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func init() { addSample("saga", func() string { - dtmcli.Logf("a saga busi transaction begin") + dtmimp.Logf("a saga busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). Add(Busi+"/TransIn", Busi+"/TransInRevert", req) - dtmcli.Logf("saga busi trans submit") + dtmimp.Logf("saga busi trans submit") err := saga.Submit() - dtmcli.Logf("result gid is: %s", saga.Gid) - dtmcli.FatalIfError(err) + dtmimp.Logf("result gid is: %s", saga.Gid) + dtmimp.FatalIfError(err) return saga.Gid }) addSample("saga_wait", func() string { - dtmcli.Logf("a saga busi transaction begin") + dtmimp.Logf("a saga busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). Add(Busi+"/TransIn", Busi+"/TransInRevert", req) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) + saga.SetOptions(&dtmimp.TransOptions{WaitResult: true}) err := saga.Submit() - dtmcli.Logf("result gid is: %s", saga.Gid) - dtmcli.FatalIfError(err) + dtmimp.Logf("result gid is: %s", saga.Gid) + dtmimp.FatalIfError(err) return saga.Gid }) addSample("concurrent_saga", func() string { - dtmcli.Logf("a concurrent saga busi transaction begin") + dtmimp.Logf("a concurrent saga busi transaction begin") req := &TransReq{Amount: 30} csaga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). Add(Busi+"/TransOut", Busi+"/TransOutRevert", req). @@ -40,10 +41,10 @@ func init() { EnableConcurrent(). AddBranchOrder(2, []int{0, 1}). AddBranchOrder(3, []int{0, 1}) - dtmcli.Logf("concurrent saga busi trans submit") + dtmimp.Logf("concurrent saga busi trans submit") err := csaga.Submit() - dtmcli.Logf("result gid is: %s", csaga.Gid) - dtmcli.FatalIfError(err) + dtmimp.Logf("result gid is: %s", csaga.Gid) + dtmimp.FatalIfError(err) return csaga.Gid }) } diff --git a/examples/http_saga_barrier.go b/examples/http_saga_barrier.go index 0b0291b..7c8a125 100644 --- a/examples/http_saga_barrier.go +++ b/examples/http_saga_barrier.go @@ -4,6 +4,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func init() { @@ -14,20 +15,20 @@ func init() { app.POST(BusiAPI+"/SagaBTransOutCompensate", common.WrapHandler(sagaBarrierTransOutCompensate)) } addSample("saga_barrier", func() string { - dtmcli.Logf("a busi transaction begin") + dtmimp.Logf("a busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). Add(Busi+"/SagaBTransOut", Busi+"/SagaBTransOutCompensate", req). Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) - dtmcli.Logf("busi trans submit") + dtmimp.Logf("busi trans submit") err := saga.Submit() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return saga.Gid }) } func sagaBarrierAdjustBalance(db dtmcli.DB, uid int, amount int) error { - _, err := dtmcli.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) + _, err := dtmimp.DBExec(db, "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) return err } diff --git a/examples/http_saga_gorm_barrier.go b/examples/http_saga_gorm_barrier.go index ae3605e..0028259 100644 --- a/examples/http_saga_gorm_barrier.go +++ b/examples/http_saga_gorm_barrier.go @@ -6,6 +6,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func init() { @@ -13,14 +14,14 @@ func init() { app.POST(BusiAPI+"/SagaBTransOutGorm", common.WrapHandler(sagaGormBarrierTransOut)) } addSample("saga_gorm_barrier", func() string { - dtmcli.Logf("a busi transaction begin") + dtmimp.Logf("a busi transaction begin") req := &TransReq{Amount: 30} saga := dtmcli.NewSaga(DtmServer, dtmcli.MustGenGid(DtmServer)). Add(Busi+"/SagaBTransOutGorm", Busi+"/SagaBTransOutCompensate", req). Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) - dtmcli.Logf("busi trans submit") + dtmimp.Logf("busi trans submit") err := saga.Submit() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return saga.Gid }) diff --git a/examples/http_tcc.go b/examples/http_tcc.go index 1747fdb..968f0b0 100644 --- a/examples/http_tcc.go +++ b/examples/http_tcc.go @@ -5,14 +5,15 @@ import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) 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()) - dtmcli.FatalIfError(err) - dtmcli.Logf("TransInTccParent ") + dtmimp.FatalIfError(err) + dtmimp.Logf("TransInTccParent ") return tcc.CallBranch(&TransReq{Amount: reqFrom(c).Amount}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") })) } @@ -25,11 +26,11 @@ func init() { } return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInTccParent", Busi+"/TransInConfirm", Busi+"/TransInRevert") }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return gid }) addSample("tcc", func() string { - dtmcli.Logf("tcc simple transaction begin") + dtmimp.Logf("tcc simple transaction begin") gid := dtmcli.MustGenGid(DtmServer) err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") @@ -38,7 +39,7 @@ func init() { } return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TransIn", Busi+"/TransInConfirm", Busi+"/TransInRevert") }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return gid }) } diff --git a/examples/http_tcc_barrier.go b/examples/http_tcc_barrier.go index 5eec99d..a241e23 100644 --- a/examples/http_tcc_barrier.go +++ b/examples/http_tcc_barrier.go @@ -7,6 +7,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) func init() { @@ -19,7 +20,7 @@ func init() { app.POST(BusiAPI+"/TccBTransOutCancel", common.WrapHandler(TccBarrierTransOutCancel)) } addSample("tcc_barrier", func() string { - dtmcli.Logf("tcc transaction begin") + dtmimp.Logf("tcc transaction begin") gid := dtmcli.MustGenGid(DtmServer) err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { resp, err := tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransOutTry", @@ -29,7 +30,7 @@ func init() { } return tcc.CallBranch(&TransReq{Amount: 30}, Busi+"/TccBTransInTry", Busi+"/TccBTransInConfirm", Busi+"/TccBTransInCancel") }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return gid }) } @@ -38,7 +39,7 @@ const transInUID = 1 const transOutUID = 2 func adjustTrading(db dtmcli.DB, uid int, amount int) error { - affected, err := dtmcli.DBExec(db, `update dtm_busi.user_account set trading_balance=trading_balance+? + 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") @@ -47,7 +48,7 @@ func adjustTrading(db dtmcli.DB, uid int, amount int) error { } func adjustBalance(db dtmcli.DB, uid int, amount int) error { - affected, err := dtmcli.DBExec(db, `update dtm_busi.user_account set trading_balance=trading_balance-?, + 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") diff --git a/examples/http_xa.go b/examples/http_xa.go index f2e3c22..c968ca2 100644 --- a/examples/http_xa.go +++ b/examples/http_xa.go @@ -5,6 +5,7 @@ import ( "github.com/go-resty/resty/v2" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) // XaClient XA client connection @@ -18,7 +19,7 @@ func init() { return xa.HandleCallback(c.Query("gid"), c.Query("branch_id"), c.Query("branch_type")) })) }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) } addSample("xa", func() string { gid := dtmcli.MustGenGid(DtmServer) @@ -29,7 +30,7 @@ func init() { } return xa.CallBranch(&TransReq{Amount: 30}, Busi+"/TransInXa") }) - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return gid }) } diff --git a/examples/quick_start.go b/examples/quick_start.go index 5610e2d..5dee011 100644 --- a/examples/quick_start.go +++ b/examples/quick_start.go @@ -7,6 +7,7 @@ import ( "github.com/gin-gonic/gin" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" ) // 启动命令:go run app/main.go qs @@ -21,7 +22,7 @@ var qsBusi = fmt.Sprintf("http://localhost:%d%s", qsBusiPort, qsBusiAPI) func QsStartSvr() { app := common.GetGinApp() qsAddRoute(app) - dtmcli.Logf("quick qs examples listening at %d", qsBusiPort) + dtmimp.Logf("quick qs examples listening at %d", qsBusiPort) go app.Run(fmt.Sprintf(":%d", qsBusiPort)) time.Sleep(100 * time.Millisecond) } @@ -37,12 +38,12 @@ func QsFireRequest() string { Add(qsBusi+"/TransIn", qsBusi+"/TransInCompensate", req) // 提交saga事务,dtm会完成所有的子事务/回滚所有的子事务 err := saga.Submit() - dtmcli.FatalIfError(err) + dtmimp.FatalIfError(err) return saga.Gid } func qsAdjustBalance(uid int, amount int) (interface{}, error) { - _, err := dtmcli.DBExec(sdbGet(), "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) + _, err := dtmimp.DBExec(sdbGet(), "update dtm_busi.user_account set balance = balance + ? where user_id = ?", amount, uid) return dtmcli.MapSuccess, err } diff --git a/go.mod b/go.mod index c7370fa..1316cb2 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,7 @@ require ( github.com/go-resty/resty/v2 v2.6.0 github.com/go-sql-driver/mysql v1.5.0 github.com/grpc-ecosystem/go-grpc-middleware v1.3.0 - github.com/kr/pretty v0.1.0 // indirect github.com/lib/pq v1.10.3 - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.1 // indirect github.com/prometheus/client_golang v1.11.0 github.com/stretchr/testify v1.7.0 golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d // indirect diff --git a/go.sum b/go.sum index dbe25ce..a58d8ce 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -21,6 +22,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -58,6 +60,7 @@ github.com/go-resty/resty/v2 v2.6.0/go.mod h1:PwvJS6hvaPkjtjNg9ph+VrSD92bi5Zq73w github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -109,6 +112,7 @@ github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= @@ -146,7 +150,6 @@ github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -191,6 +194,7 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -220,6 +224,7 @@ github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OK github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -339,7 +344,6 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= @@ -400,7 +404,6 @@ google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+Rur google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -421,11 +424,8 @@ gorm.io/driver/mysql v1.0.3/go.mod h1:twGxftLBlFgNVNakL7F+P/x9oYqoymG3YYT8cAfI9o gorm.io/driver/postgres v1.1.2 h1:Amy3hCvLqM+/ICzjCnQr8wKFLVJTeOTdlMT7kCP+J1Q= gorm.io/driver/postgres v1.1.2/go.mod h1:/AGV0zvqF3mt9ZtzLzQmXWQ/5vr+1V1TyHZGZVjzmwI= gorm.io/gorm v1.20.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= -gorm.io/gorm v1.21.12 h1:3fQM0Eiz7jcJEhPggHEpoYnsGZqynMzverL77DV40RM= -gorm.io/gorm v1.21.12/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= gorm.io/gorm v1.21.15 h1:gAyaDoPw0lCyrSFWhBlahbUA1U4P5RViC1uIqoB+1Rk= gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/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= - diff --git a/test/api_test.go b/test/api_test.go new file mode 100644 index 0000000..aa464cc --- /dev/null +++ b/test/api_test.go @@ -0,0 +1,44 @@ +package test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/examples" +) + +const gidTestAPI = "TestAPI" + +func TestAPIQuery(t *testing.T) { + err := genMsg(gidTestAPI).Submit() + assert.Nil(t, err) + waitTransProcessed(gidTestAPI) + resp, err := dtmimp.RestyClient.R().SetQueryParam("gid", gidTestAPI).Get(examples.DtmServer + "/query") + e2p(err) + m := map[string]interface{}{} + assert.Equal(t, resp.StatusCode(), 200) + dtmimp.MustUnmarshalString(resp.String(), &m) + assert.NotEqual(t, nil, m["transaction"]) + assert.Equal(t, 2, len(m["branches"].([]interface{}))) + + resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "").Get(examples.DtmServer + "/query") + e2p(err) + assert.Equal(t, resp.StatusCode(), 500) + + resp, err = dtmimp.RestyClient.R().SetQueryParam("gid", "1").Get(examples.DtmServer + "/query") + e2p(err) + assert.Equal(t, resp.StatusCode(), 200) + dtmimp.MustUnmarshalString(resp.String(), &m) + assert.Equal(t, nil, m["transaction"]) + assert.Equal(t, 0, len(m["branches"].([]interface{}))) +} + +func TestAPIAll(t *testing.T) { + _, err := dtmimp.RestyClient.R().Get(examples.DtmServer + "/all") + assert.Nil(t, err) + _, err = dtmimp.RestyClient.R().SetQueryParam("last_id", "10").Get(examples.DtmServer + "/all") + assert.Nil(t, err) + resp, err := dtmimp.RestyClient.R().SetQueryParam("last_id", "abc").Get(examples.DtmServer + "/all") + assert.Equal(t, resp.StatusCode(), 500) +} diff --git a/test/base_test.go b/test/base_test.go index ba50e94..51ed610 100644 --- a/test/base_test.go +++ b/test/base_test.go @@ -7,10 +7,20 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestSqlDB(t *testing.T) { +// BarrierModel barrier model for gorm +type BarrierModel struct { + common.ModelBase + dtmcli.BranchBarrier +} + +// TableName gorm table name +func (BarrierModel) TableName() string { return "dtm_barrier.barrier" } + +func TestBaseSqlDB(t *testing.T) { asserts := assert.New(t) db := common.DbGet(config.DB) barrier := &dtmcli.BranchBarrier{ @@ -23,7 +33,7 @@ func TestSqlDB(t *testing.T) { tx, err := db.ToSQLDB().Begin() asserts.Nil(err) err = barrier.Call(tx, func(db dtmcli.DB) error { - dtmcli.Logf("rollback gid2") + dtmimp.Logf("rollback gid2") return fmt.Errorf("gid2 error") }) asserts.Error(err, fmt.Errorf("gid2 error")) @@ -35,7 +45,7 @@ func TestSqlDB(t *testing.T) { tx2, err := db.ToSQLDB().Begin() asserts.Nil(err) err = barrier.Call(tx2, func(db dtmcli.DB) error { - dtmcli.Logf("submit gid2") + dtmimp.Logf("submit gid2") return nil }) asserts.Nil(err) @@ -43,11 +53,11 @@ func TestSqlDB(t *testing.T) { asserts.Equal(dbr.RowsAffected, int64(1)) } -func TestHttp(t *testing.T) { - resp, err := dtmcli.RestyClient.R().SetQueryParam("panic_string", "1").Post(examples.Busi + "/TestPanic") +func TestBaseHttp(t *testing.T) { + resp, err := dtmimp.RestyClient.R().SetQueryParam("panic_string", "1").Post(examples.Busi + "/TestPanic") assert.Nil(t, err) assert.Contains(t, resp.String(), "panic_string") - resp, err = dtmcli.RestyClient.R().SetQueryParam("panic_error", "1").Post(examples.Busi + "/TestPanic") + resp, err = dtmimp.RestyClient.R().SetQueryParam("panic_error", "1").Post(examples.Busi + "/TestPanic") assert.Nil(t, err) assert.Contains(t, resp.String(), "panic_error") } diff --git a/test/dtmsvr_test.go b/test/dtmsvr_test.go index 4701ca6..b0dc6e3 100644 --- a/test/dtmsvr_test.go +++ b/test/dtmsvr_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmsvr" "github.com/yedf/dtm/examples" ) @@ -16,15 +17,6 @@ var DtmServer = examples.DtmServer var Busi = examples.Busi var app *gin.Engine -// BarrierModel barrier model for gorm -type BarrierModel struct { - common.ModelBase - dtmcli.BranchBarrier -} - -// TableName gorm table name -func (BarrierModel) TableName() string { return "dtm_barrier.barrier" } - func getTransStatus(gid string) string { sm := TransGlobal{} dbr := dbGet().Model(&sm).Where("gid=?", gid).First(&sm) @@ -48,49 +40,15 @@ func assertSucceed(t *testing.T, gid string) { assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(gid)) } -func genMsg(gid string) *dtmcli.Msg { - dtmcli.Logf("beginning a msg test ---------------- %s", gid) - msg := dtmcli.NewMsg(examples.DtmServer, gid) - msg.QueryPrepared = examples.Busi + "/CanSubmit" - req := examples.GenTransReq(30, false, false) - msg.Add(examples.Busi+"/TransOut", &req) - msg.Add(examples.Busi+"/TransIn", &req) - return msg -} - -func transQuery(t *testing.T, gid string) { - resp, err := dtmcli.RestyClient.R().SetQueryParam("gid", gid).Get(examples.DtmServer + "/query") - e2p(err) - m := M{} - assert.Equal(t, resp.StatusCode(), 200) - dtmcli.MustUnmarshalString(resp.String(), &m) - assert.NotEqual(t, nil, m["transaction"]) - assert.Equal(t, 4, len(m["branches"].([]interface{}))) - - resp, err = dtmcli.RestyClient.R().SetQueryParam("gid", "").Get(examples.DtmServer + "/query") - e2p(err) - assert.Equal(t, resp.StatusCode(), 500) - - resp, err = dtmcli.RestyClient.R().SetQueryParam("gid", "1").Get(examples.DtmServer + "/query") - e2p(err) - assert.Equal(t, resp.StatusCode(), 200) - dtmcli.MustUnmarshalString(resp.String(), &m) - assert.Equal(t, nil, m["transaction"]) - assert.Equal(t, 0, len(m["branches"].([]interface{}))) - - resp, err = dtmcli.RestyClient.R().Get(examples.DtmServer + "/all") - assert.Nil(t, err) -} - func TestUpdateBranchAsync(t *testing.T) { common.DtmConfig.UpdateBranchSync = 0 - saga := genSaga("gid-update-branch-async", false, false) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) + saga := genSaga1(dtmimp.GetFuncName(), false, false) + saga.SetOptions(&dtmimp.TransOptions{WaitResult: true}) err := saga.Submit() assert.Nil(t, err) waitTransProcessed(saga.Gid) time.Sleep(dtmsvr.UpdateBranchAsyncInterval) - assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) common.DtmConfig.UpdateBranchSync = 1 } diff --git a/test/examples_test.go b/test/examples_test.go index 059f803..c5d172f 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -7,7 +7,6 @@ import ( ) func TestExamples(t *testing.T) { - // for coverage examples.QsStartSvr() for _, s := range examples.Samples { assertSucceed(t, s.Action()) diff --git a/test/grpc_msg_test.go b/test/grpc_msg_test.go index 25d3dda..2366d87 100644 --- a/test/grpc_msg_test.go +++ b/test/grpc_msg_test.go @@ -6,26 +6,22 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/examples" ) -func TestGrpcMsg(t *testing.T) { - grpcMsgNormal(t) - grpcMsgOngoing(t) -} - -func grpcMsgNormal(t *testing.T) { - msg := genGrpcMsg("grpc-msg-normal") +func TestGrpcMsgNormal(t *testing.T) { + msg := genGrpcMsg(dtmimp.GetFuncName()) err := msg.Submit() assert.Nil(t, err) waitTransProcessed(msg.Gid) assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(msg.Gid)) } -func grpcMsgOngoing(t *testing.T) { - msg := genGrpcMsg("grpc-msg-pending") - err := msg.Prepare(fmt.Sprintf("%s/examples.Busi/CanSubmit", examples.BusiGrpc)) +func TestGrpcMsgOngoingSuccess(t *testing.T) { + msg := genGrpcMsg(dtmimp.GetFuncName()) + err := msg.Prepare("") assert.Nil(t, err) examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) @@ -37,10 +33,24 @@ func grpcMsgOngoing(t *testing.T) { assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(msg.Gid)) } +func TestGrpcMsgOngoingFailed(t *testing.T) { + msg := genGrpcMsg(dtmimp.GetFuncName()) + msg.Prepare("") + assert.Equal(t, dtmcli.StatusPrepared, getTransStatus(msg.Gid)) + examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) + cronTransOnceForwardNow(180) + assert.Equal(t, dtmcli.StatusPrepared, getTransStatus(msg.Gid)) + examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultFailure) + cronTransOnceForwardNow(180) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(msg.Gid)) + assert.Equal(t, dtmcli.StatusFailed, getTransStatus(msg.Gid)) +} + func genGrpcMsg(gid string) *dtmgrpc.MsgGrpc { - req := dtmcli.MustMarshal(&examples.TransReq{Amount: 30}) - return dtmgrpc.NewMsgGrpc(examples.DtmGrpcServer, gid). + 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) + return msg } diff --git a/test/grpc_barrier_saga_test.go b/test/grpc_saga_barrier_test.go similarity index 69% rename from test/grpc_barrier_saga_test.go rename to test/grpc_saga_barrier_test.go index a88eb62..e744075 100644 --- a/test/grpc_barrier_saga_test.go +++ b/test/grpc_saga_barrier_test.go @@ -5,19 +5,14 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/examples" ) -func TestGrpcBarrierSaga(t *testing.T) { - - grpcSagaBarrierNormal(t) - grpcSagaBarrierRollback(t) -} - -func grpcSagaBarrierNormal(t *testing.T) { - req := dtmcli.MustMarshal(&examples.TransReq{Amount: 30}) - saga := dtmgrpc.NewSaga(examples.DtmGrpcServer, "grpcSagaBarrierNormal"). +func TestGrpcSagaBarrierNormal(t *testing.T) { + req := examples.GenBusiReq(30, false, false) + saga := dtmgrpc.NewSagaGrpc(examples.DtmGrpcServer, dtmimp.GetFuncName()). Add(examples.BusiGrpc+"/examples.Busi/TransOutBSaga", examples.BusiGrpc+"/examples.Busi/TransOutRevertBSaga", req). Add(examples.BusiGrpc+"/examples.Busi/TransInBSaga", examples.BusiGrpc+"/examples.Busi/TransInRevertBSaga", req) err := saga.Submit() @@ -26,9 +21,9 @@ func grpcSagaBarrierNormal(t *testing.T) { assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) } -func grpcSagaBarrierRollback(t *testing.T) { - req := dtmcli.MustMarshal(&examples.TransReq{Amount: 30, TransInResult: dtmcli.ResultFailure}) - saga := dtmgrpc.NewSaga(examples.DtmGrpcServer, "grpcSagaBarrierRollback"). +func TestGrpcSagaBarrierRollback(t *testing.T) { + req := examples.GenBusiReq(30, false, true) + saga := dtmgrpc.NewSagaGrpc(examples.DtmGrpcServer, dtmimp.GetFuncName()). Add(examples.BusiGrpc+"/examples.Busi/TransOutBSaga", examples.BusiGrpc+"/examples.Busi/TransOutRevertBSaga", req). Add(examples.BusiGrpc+"/examples.Busi/TransInBSaga", examples.BusiGrpc+"/examples.Busi/TransInRevertBSaga", req) err := saga.Submit() diff --git a/test/grpc_saga_test.go b/test/grpc_saga_test.go index bb29bf1..513de55 100644 --- a/test/grpc_saga_test.go +++ b/test/grpc_saga_test.go @@ -5,27 +5,21 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/examples" ) -func TestGrpcSaga(t *testing.T) { - sagaGrpcNormal(t) - sagaGrpcCommittedOngoing(t) - sagaGrpcRollback(t) -} - -func sagaGrpcNormal(t *testing.T) { - saga := genSagaGrpc("gid-sagaGrpcNormal", false, false) +func TestGrpcSagaNormal(t *testing.T) { + saga := genSagaGrpc(dtmimp.GetFuncName(), false, false) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) - transQuery(t, saga.Gid) } -func sagaGrpcCommittedOngoing(t *testing.T) { - saga := genSagaGrpc("gid-committedOngoingGrpc", false, false) +func TestGrpcSagaCommittedOngoing(t *testing.T) { + saga := genSagaGrpc(dtmimp.GetFuncName(), false, false) examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) saga.Submit() waitTransProcessed(saga.Gid) @@ -35,8 +29,8 @@ func sagaGrpcCommittedOngoing(t *testing.T) { assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) } -func sagaGrpcRollback(t *testing.T) { - saga := genSagaGrpc("gid-rollbackSaga2Grpc", false, true) +func TestGrpcSagaRollback(t *testing.T) { + saga := genSagaGrpc(dtmimp.GetFuncName(), false, true) examples.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) saga.Submit() waitTransProcessed(saga.Gid) @@ -47,9 +41,9 @@ func sagaGrpcRollback(t *testing.T) { } func genSagaGrpc(gid string, outFailed bool, inFailed bool) *dtmgrpc.SagaGrpc { - dtmcli.Logf("beginning a grpc saga test ---------------- %s", gid) - saga := dtmgrpc.NewSaga(examples.DtmGrpcServer, gid) - req := dtmcli.MustMarshal(examples.GenTransReq(30, outFailed, inFailed)) + dtmimp.Logf("beginning a grpc saga test ---------------- %s", gid) + 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) return saga diff --git a/test/grpc_tcc_test.go b/test/grpc_tcc_test.go index f06fae8..afee7f7 100644 --- a/test/grpc_tcc_test.go +++ b/test/grpc_tcc_test.go @@ -1,60 +1,59 @@ package test import ( + "context" "testing" "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/examples" + "google.golang.org/protobuf/types/known/emptypb" ) -func TestGrpcTcc(t *testing.T) { - tccGrpcType(t) - tccGrpcNormal(t) - tccGrpcNested(t) - tccGrpcRollback(t) -} - -func tccGrpcType(t *testing.T) { - _, err := dtmgrpc.TccFromRequest(&dtmgrpc.BusiRequest{Info: &dtmgrpc.BranchInfo{}}) +func TestGrpcTccType(t *testing.T) { + _, err := dtmgrpc.TccFromGrpc(context.Background()) assert.Error(t, err) - dtmcli.Logf("expecting dtmgrpcserver error") + dtmimp.Logf("expecting dtmgrpcserver error") err = dtmgrpc.TccGlobalTransaction("-", "", func(tcc *dtmgrpc.TccGrpc) error { return nil }) assert.Error(t, err) } -func tccGrpcNormal(t *testing.T) { - data := dtmcli.MustMarshal(&examples.TransReq{Amount: 30}) - gid := "tccGrpcNormal" +func TestGrpcTccNormal(t *testing.T) { + data := &examples.BusiReq{Amount: 30} + gid := dtmimp.GetFuncName() err := dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { - _, err := tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransOut", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert") + r := &emptypb.Empty{} + err := tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransOut", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) assert.Nil(t, err) - _, err = tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransIn", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert") + err = tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransIn", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert", r) return err }) assert.Nil(t, err) } -func tccGrpcNested(t *testing.T) { - data := dtmcli.MustMarshal(&examples.TransReq{Amount: 30}) - gid := "tccGrpcNested" +func TestGrpcTestNested(t *testing.T) { + data := &examples.BusiReq{Amount: 30} + gid := dtmimp.GetFuncName() err := dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { - _, err := tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransOutTcc", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert") + r := &emptypb.Empty{} + err := tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransOutTcc", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) assert.Nil(t, err) - _, err = tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransInTccNested", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert") + err = tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransInTccNested", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert", r) return err }) assert.Nil(t, err) } -func tccGrpcRollback(t *testing.T) { - gid := "tccGrpcRollback" - data := dtmcli.MustMarshal(&examples.TransReq{Amount: 30, TransInResult: dtmcli.ResultFailure}) +func TestGrpcTccRollback(t *testing.T) { + gid := dtmimp.GetFuncName() + data := &examples.BusiReq{Amount: 30, TransInResult: dtmcli.ResultFailure} err := dtmgrpc.TccGlobalTransaction(examples.DtmGrpcServer, gid, func(tcc *dtmgrpc.TccGrpc) error { - _, err := tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransOutTcc", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert") + r := &emptypb.Empty{} + err := tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransOutTcc", examples.BusiGrpc+"/examples.Busi/TransOutConfirm", examples.BusiGrpc+"/examples.Busi/TransOutRevert", r) assert.Nil(t, err) examples.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) - _, err = tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransInTcc", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert") + err = tcc.CallBranch(data, examples.BusiGrpc+"/examples.Busi/TransInTcc", examples.BusiGrpc+"/examples.Busi/TransInConfirm", examples.BusiGrpc+"/examples.Busi/TransInRevert", r) return err }) assert.Error(t, err) diff --git a/test/grpc_xa_test.go b/test/grpc_xa_test.go index ad57fbd..1421645 100644 --- a/test/grpc_xa_test.go +++ b/test/grpc_xa_test.go @@ -1,53 +1,50 @@ package test import ( + "context" "fmt" "testing" "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmgrpc" "github.com/yedf/dtm/examples" + "google.golang.org/protobuf/types/known/emptypb" ) -func TestGrpcXa(t *testing.T) { - xaGrpcType(t) - xaGrpcLocalError(t) - xaGrpcNormal(t) - xaGrpcRollback(t) -} - -func xaGrpcType(t *testing.T) { - _, err := dtmgrpc.XaGrpcFromRequest(&dtmgrpc.BusiRequest{Info: &dtmgrpc.BranchInfo{}}) +func TestGrpcXaType(t *testing.T) { + _, err := dtmgrpc.XaGrpcFromRequest(context.Background()) assert.Error(t, err) - err = examples.XaGrpcClient.XaLocalTransaction(&dtmgrpc.BusiRequest{Info: &dtmgrpc.BranchInfo{}}, nil) + err = examples.XaGrpcClient.XaLocalTransaction(context.Background(), nil, nil) assert.Error(t, err) - err = dtmcli.CatchP(func() { + err = dtmimp.CatchP(func() { examples.XaGrpcClient.XaGlobalTransaction("id1", func(xa *dtmgrpc.XaGrpc) error { panic(fmt.Errorf("hello")) }) }) assert.Error(t, err) } -func xaGrpcLocalError(t *testing.T) { +func TestGrpcXaLocalError(t *testing.T) { xc := examples.XaGrpcClient - err := xc.XaGlobalTransaction("xaGrpcLocalError", func(xa *dtmgrpc.XaGrpc) error { + err := xc.XaGlobalTransaction(dtmimp.GetFuncName(), func(xa *dtmgrpc.XaGrpc) error { return fmt.Errorf("an error") }) assert.Error(t, err, fmt.Errorf("an error")) } -func xaGrpcNormal(t *testing.T) { +func TestGrpcXaNormal(t *testing.T) { xc := examples.XaGrpcClient - gid := "xaGrpcNormal" + gid := dtmimp.GetFuncName() err := xc.XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { - req := dtmcli.MustMarshal(examples.GenTransReq(30, false, false)) - _, err := xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutXa") + req := &examples.BusiReq{Amount: 30} + r := &emptypb.Empty{} + err := xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutXa", r) if err != nil { return err } - _, err = xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInXa") + err = xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInXa", r) return err }) assert.Equal(t, nil, err) @@ -55,16 +52,17 @@ func xaGrpcNormal(t *testing.T) { assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(gid)) } -func xaGrpcRollback(t *testing.T) { +func TestGrpcXaRollback(t *testing.T) { xc := examples.XaGrpcClient - gid := "xaGrpcRollback" + gid := dtmimp.GetFuncName() err := xc.XaGlobalTransaction(gid, func(xa *dtmgrpc.XaGrpc) error { - req := dtmcli.MustMarshal(&examples.TransReq{Amount: 30, TransInResult: dtmcli.ResultFailure}) - _, err := xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutXa") + req := &examples.BusiReq{Amount: 30, TransInResult: dtmcli.ResultFailure} + r := &emptypb.Empty{} + err := xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransOutXa", r) if err != nil { return err } - _, err = xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInXa") + err = xa.CallBranch(req, examples.BusiGrpc+"/examples.Busi/TransInXa", r) return err }) assert.Error(t, err) diff --git a/test/main_test.go b/test/main_test.go index 328cb4c..c3d8c9f 100644 --- a/test/main_test.go +++ b/test/main_test.go @@ -1,7 +1,6 @@ package test import ( - "fmt" "testing" "time" @@ -24,21 +23,5 @@ func TestMain(m *testing.M) { examples.GrpcStartup() app = examples.BaseAppStartup() - resetXaData() m.Run() } - -func resetXaData() { - if config.DB["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)) - } -} diff --git a/test/msg_test.go b/test/msg_test.go index f5c8161..c788525 100644 --- a/test/msg_test.go +++ b/test/msg_test.go @@ -5,31 +5,22 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestMsg(t *testing.T) { - - msgNormal(t) - msgOngoing(t) - msgOngoingFailed(t) -} - -func msgNormal(t *testing.T) { - msg := genMsg("gid-msg-normal") +func TestMsgNormal(t *testing.T) { + msg := genMsg(dtmimp.GetFuncName()) msg.Submit() assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(msg.Gid)) waitTransProcessed(msg.Gid) assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusSucceed}, getBranchesStatus(msg.Gid)) assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(msg.Gid)) - cronTransOnce() } -func msgOngoing(t *testing.T) { - msg := genMsg("gid-msg-normal-pending") +func TestMsgOngoingSuccess(t *testing.T) { + msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") - err := msg.Prepare("") // additional prepare to go conflict key path - assert.Nil(t, err) assert.Equal(t, dtmcli.StatusPrepared, getTransStatus(msg.Gid)) examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) cronTransOnceForwardNow(180) @@ -40,12 +31,10 @@ func msgOngoing(t *testing.T) { cronTransOnce() assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusSucceed}, getBranchesStatus(msg.Gid)) assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(msg.Gid)) - err = msg.Prepare("") - assert.Error(t, err) } -func msgOngoingFailed(t *testing.T) { - msg := genMsg("gid-msg-pending-failed") +func TestMsgOngoingFailed(t *testing.T) { + msg := genMsg(dtmimp.GetFuncName()) msg.Prepare("") assert.Equal(t, dtmcli.StatusPrepared, getTransStatus(msg.Gid)) examples.MainSwitch.CanSubmitResult.SetOnce(dtmcli.ResultOngoing) @@ -56,3 +45,26 @@ func msgOngoingFailed(t *testing.T) { assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(msg.Gid)) assert.Equal(t, dtmcli.StatusFailed, getTransStatus(msg.Gid)) } + +func TestMsgAbnormal(t *testing.T) { + msg := genMsg(dtmimp.GetFuncName()) + msg.Prepare("") + err := msg.Prepare("") + assert.Nil(t, err) + err = msg.Submit() + assert.Nil(t, err) + err = msg.Submit() + assert.Nil(t, err) + + err = msg.Prepare("") + assert.Error(t, err) +} + +func genMsg(gid string) *dtmcli.Msg { + req := examples.GenTransReq(30, false, false) + msg := dtmcli.NewMsg(examples.DtmServer, gid). + Add(examples.Busi+"/TransOut", &req). + Add(examples.Busi+"/TransIn", &req) + msg.QueryPrepared = examples.Busi + "/CanSubmit" + return msg +} diff --git a/test/barrier_saga_test.go b/test/saga_barrier_test.go similarity index 71% rename from test/barrier_saga_test.go rename to test/saga_barrier_test.go index 4f7ccf6..ab8b1e1 100644 --- a/test/barrier_saga_test.go +++ b/test/saga_barrier_test.go @@ -5,32 +5,27 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestBarrierSaga(t *testing.T) { - - sagaBarrierNormal(t) - sagaBarrierRollback(t) -} - -func sagaBarrierNormal(t *testing.T) { +func TestSagaBarrierNormal(t *testing.T) { req := &examples.TransReq{Amount: 30} - saga := dtmcli.NewSaga(DtmServer, "sagaBarrierNormal"). + saga := dtmcli.NewSaga(DtmServer, dtmimp.GetFuncName()). Add(Busi+"/SagaBTransOut", Busi+"/SagaBTransOutCompensate", req). Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", req) - dtmcli.Logf("busi trans submit") + dtmimp.Logf("busi trans submit") err := saga.Submit() e2p(err) waitTransProcessed(saga.Gid) assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) } -func sagaBarrierRollback(t *testing.T) { - saga := dtmcli.NewSaga(DtmServer, "sagaBarrierRollback"). +func TestSagaBarrierRollback(t *testing.T) { + saga := dtmcli.NewSaga(DtmServer, dtmimp.GetFuncName()). Add(Busi+"/SagaBTransOut", Busi+"/SagaBTransOutCompensate", &examples.TransReq{Amount: 30}). Add(Busi+"/SagaBTransIn", Busi+"/SagaBTransInCompensate", &examples.TransReq{Amount: 30, TransInResult: dtmcli.ResultFailure}) - dtmcli.Logf("busi trans submit") + dtmimp.Logf("busi trans submit") err := saga.Submit() e2p(err) waitTransProcessed(saga.Gid) diff --git a/test/saga_compatible_test.go b/test/saga_compatible_test.go new file mode 100644 index 0000000..aa338ca --- /dev/null +++ b/test/saga_compatible_test.go @@ -0,0 +1,21 @@ +package test + +import ( + "fmt" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/examples" +) + +func TestSagaCompatibleNormal(t *testing.T) { // compatible with old http, which put payload in steps.data + 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.DtmServer)) + waitTransProcessed(gid) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(gid)) + assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(gid)) +} diff --git a/test/saga_concurrent_test.go b/test/saga_concurrent_test.go index 6983442..450b4b9 100644 --- a/test/saga_concurrent_test.go +++ b/test/saga_concurrent_test.go @@ -5,69 +5,63 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestCSaga(t *testing.T) { - csagaNormal(t) - csagaRollback(t) - csagaRollback2(t) - csagaCommittedOngoing(t) -} - -func genCSaga(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { - dtmcli.Logf("beginning a concurrent saga test ---------------- %s", gid) +func genSagaCon(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { + dtmimp.Logf("beginning a concurrent saga test ---------------- %s", gid) req := examples.GenTransReq(30, outFailed, inFailed) - csaga := dtmcli.NewSaga(examples.DtmServer, gid). + sagaCon := dtmcli.NewSaga(examples.DtmServer, gid). Add(examples.Busi+"/TransOut", examples.Busi+"/TransOutRevert", &req). Add(examples.Busi+"/TransIn", examples.Busi+"/TransInRevert", &req). EnableConcurrent() - return csaga + return sagaCon } -func csagaNormal(t *testing.T) { - csaga := genCSaga("gid-noraml-csaga", false, false) - csaga.Submit() - waitTransProcessed(csaga.Gid) - assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(csaga.Gid)) - assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(csaga.Gid)) +func TestSagaConNormal(t *testing.T) { + sagaCon := genSagaCon(dtmimp.GetFuncName(), false, false) + sagaCon.Submit() + waitTransProcessed(sagaCon.Gid) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(sagaCon.Gid)) + assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(sagaCon.Gid)) } -func csagaRollback(t *testing.T) { - csaga := genCSaga("gid-rollback-csaga", true, false) +func TestSagaConRollback(t *testing.T) { + sagaCon := genSagaCon(dtmimp.GetFuncName(), true, false) examples.MainSwitch.TransOutRevertResult.SetOnce(dtmcli.ResultOngoing) - err := csaga.Submit() + err := sagaCon.Submit() assert.Nil(t, err) - waitTransProcessed(csaga.Gid) - assert.Equal(t, dtmcli.StatusAborting, getTransStatus(csaga.Gid)) + waitTransProcessed(sagaCon.Gid) + assert.Equal(t, dtmcli.StatusAborting, getTransStatus(sagaCon.Gid)) cronTransOnce() - assert.Equal(t, dtmcli.StatusFailed, getTransStatus(csaga.Gid)) - assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusFailed, dtmcli.StatusSucceed, dtmcli.StatusSucceed}, getBranchesStatus(csaga.Gid)) - err = csaga.Submit() + assert.Equal(t, dtmcli.StatusFailed, getTransStatus(sagaCon.Gid)) + assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusFailed, dtmcli.StatusSucceed, dtmcli.StatusSucceed}, getBranchesStatus(sagaCon.Gid)) + err = sagaCon.Submit() assert.Error(t, err) } -func csagaRollback2(t *testing.T) { - csaga := genCSaga("gid-rollback-csaga2", true, false) - csaga.AddBranchOrder(1, []int{0}) - err := csaga.Submit() +func TestSagaConRollback2(t *testing.T) { + sagaCon := genSagaCon(dtmimp.GetFuncName(), true, false) + sagaCon.AddBranchOrder(1, []int{0}) + err := sagaCon.Submit() assert.Nil(t, err) - waitTransProcessed(csaga.Gid) - assert.Equal(t, dtmcli.StatusFailed, getTransStatus(csaga.Gid)) - assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusFailed, dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(csaga.Gid)) - err = csaga.Submit() + waitTransProcessed(sagaCon.Gid) + assert.Equal(t, dtmcli.StatusFailed, getTransStatus(sagaCon.Gid)) + assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusFailed, dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(sagaCon.Gid)) + err = sagaCon.Submit() assert.Error(t, err) } -func csagaCommittedOngoing(t *testing.T) { - csaga := genCSaga("gid-committed-ongoing-csaga", false, false) +func TestSagaConCommittedOngoing(t *testing.T) { + sagaCon := genSagaCon(dtmimp.GetFuncName(), false, false) examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) - csaga.Submit() - waitTransProcessed(csaga.Gid) - assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(csaga.Gid)) - assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(csaga.Gid)) + sagaCon.Submit() + waitTransProcessed(sagaCon.Gid) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(sagaCon.Gid)) + assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(sagaCon.Gid)) cronTransOnce() - assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(csaga.Gid)) - assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(csaga.Gid)) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(sagaCon.Gid)) + assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(sagaCon.Gid)) } diff --git a/test/saga_options_test.go b/test/saga_options_test.go new file mode 100644 index 0000000..ea56eff --- /dev/null +++ b/test/saga_options_test.go @@ -0,0 +1,82 @@ +package test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" + "github.com/yedf/dtm/examples" +) + +func TestSagaOptionsRetryOngoing(t *testing.T) { + saga := genSaga1(dtmimp.GetFuncName(), false, false) + saga.RetryInterval = 150 // CronForwardDuration is larger than RetryInterval + examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + err := saga.Submit() + assert.Nil(t, err) + waitTransProcessed(saga.Gid) + cronTransOnce() + assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) +} + +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") + err := saga.Submit() + assert.Nil(t, err) + waitTransProcessed(saga.Gid) + cronTransOnce() + assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(saga.Gid)) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(saga.Gid)) + cronTransOnceForwardCron(360) + assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) +} + +func TestSagaOptionsTimeout(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, false) + saga.TimeoutToFail = 1800 + examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + saga.Submit() + waitTransProcessed(saga.Gid) + assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(saga.Gid)) + cronTransOnceForwardNow(3600) + assert.Equal(t, dtmcli.StatusFailed, getTransStatus(saga.Gid)) +} + +func TestSagaOptionsNormalWait(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, false) + saga.SetOptions(&dtmimp.TransOptions{WaitResult: true}) + err := saga.Submit() + assert.Nil(t, err) + waitTransProcessed(saga.Gid) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) + assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) +} + +func TestSagaOptionsCommittedOngoingWait(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, false) + examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) + saga.SetOptions(&dtmimp.TransOptions{WaitResult: true}) + err := saga.Submit() + assert.Error(t, err) + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(saga.Gid)) + assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(saga.Gid)) + waitTransProcessed(saga.Gid) + cronTransOnce() + assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) + assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) +} + +func TestSagaOptionsRollbackWait(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, true) + saga.SetOptions(&dtmimp.TransOptions{WaitResult: true}) + err := saga.Submit() + assert.Error(t, err) + waitTransProcessed(saga.Gid) + assert.Equal(t, dtmcli.StatusFailed, getTransStatus(saga.Gid)) + assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusFailed}, getBranchesStatus(saga.Gid)) +} diff --git a/test/saga_test.go b/test/saga_test.go index 1e20648..a005a7b 100644 --- a/test/saga_test.go +++ b/test/saga_test.go @@ -5,41 +5,32 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestSaga(t *testing.T) { - sagaNormal(t) - sagaCommittedOngoing(t) - sagaRollback(t) - sagaRollback2(t) - sagaTimeout(t) -} - -func sagaNormal(t *testing.T) { - saga := genSaga("gid-noramlSaga", false, false) +func TestSagaNormal(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, false) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) - transQuery(t, saga.Gid) - err := saga.Submit() // 第二次提交 - assert.Error(t, err) } -func sagaCommittedOngoing(t *testing.T) { - saga := genSaga("gid-committedOngoing", false, false) +func TestSagaOngoingSucceed(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, false) examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) saga.Submit() waitTransProcessed(saga.Gid) assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(saga.Gid)) + assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(saga.Gid)) cronTransOnce() assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) } -func sagaRollback(t *testing.T) { - saga := genSaga("gid-rollback-saga", false, true) +func TestSagaFailed(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, true) examples.MainSwitch.TransOutRevertResult.SetOnce("ERROR") err := saga.Submit() assert.Nil(t, err) @@ -48,38 +39,30 @@ func sagaRollback(t *testing.T) { cronTransOnce() assert.Equal(t, dtmcli.StatusFailed, getTransStatus(saga.Gid)) assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusFailed}, getBranchesStatus(saga.Gid)) - err = saga.Submit() - assert.Error(t, err) } -func sagaRollback2(t *testing.T) { - saga := genSaga("gid-rollback-saga2", false, false) - saga.TimeoutToFail = 1800 - examples.MainSwitch.TransInResult.SetOnce(dtmcli.ResultOngoing) +func TestSagaAbnormal(t *testing.T) { + saga := genSaga(dtmimp.GetFuncName(), false, false) err := saga.Submit() assert.Nil(t, err) + err = saga.Submit() // submit twice, ignored + assert.Nil(t, err) waitTransProcessed(saga.Gid) - cronTransOnceForwardNow(3600) - assert.Equal(t, dtmcli.StatusFailed, getTransStatus(saga.Gid)) - assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusPrepared}, getBranchesStatus(saga.Gid)) -} - -func sagaTimeout(t *testing.T) { - saga := genSaga("gid-timeout-saga", false, false) - saga.TimeoutToFail = 1800 - examples.MainSwitch.TransOutResult.SetOnce("UNKOWN") - saga.Submit() - waitTransProcessed(saga.Gid) - assert.Equal(t, dtmcli.StatusSubmitted, getTransStatus(saga.Gid)) - cronTransOnceForwardNow(3600) - assert.Equal(t, dtmcli.StatusFailed, getTransStatus(saga.Gid)) + err = saga.Submit() + assert.Error(t, err) // a succeed trans can't accept submit } func genSaga(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { - dtmcli.Logf("beginning a saga test ---------------- %s", gid) saga := dtmcli.NewSaga(examples.DtmServer, 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) return saga } + +func genSaga1(gid string, outFailed bool, inFailed bool) *dtmcli.Saga { + saga := dtmcli.NewSaga(examples.DtmServer, gid) + req := examples.GenTransReq(30, outFailed, inFailed) + saga.Add(examples.Busi+"/TransOut", examples.Busi+"/TransOutRevert", &req) + return saga +} diff --git a/test/barrier_tcc_test.go b/test/tcc_barrier_test.go similarity index 82% rename from test/barrier_tcc_test.go rename to test/tcc_barrier_test.go index 78ffc66..f3a53e2 100644 --- a/test/barrier_tcc_test.go +++ b/test/tcc_barrier_test.go @@ -13,18 +13,12 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestBarrierTcc(t *testing.T) { - tccBarrierDisorder(t) - tccBarrierNormal(t) - tccBarrierRollback(t) - barrierPanic(t) -} - -func tccBarrierRollback(t *testing.T) { - gid := "tccBarrierRollback" +func TestTccBarrierRollback(t *testing.T) { + gid := dtmimp.GetFuncName() err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel") assert.Nil(t, err) @@ -35,8 +29,8 @@ func tccBarrierRollback(t *testing.T) { assert.Equal(t, dtmcli.StatusFailed, getTransStatus(gid)) } -func tccBarrierNormal(t *testing.T) { - gid := "tccBarrierNormal" +func TestTccBarrierNormal(t *testing.T) { + gid := dtmimp.GetFuncName() err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(&examples.TransReq{Amount: 30}, Busi+"/TccBTransOutTry", Busi+"/TccBTransOutConfirm", Busi+"/TccBTransOutCancel") assert.Nil(t, err) @@ -47,36 +41,36 @@ func tccBarrierNormal(t *testing.T) { assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(gid)) } -func tccBarrierDisorder(t *testing.T) { +func TestTccBarrierDisorder(t *testing.T) { timeoutChan := make(chan string, 2) finishedChan := make(chan string, 2) - gid := "tccBarrierDisorder" + gid := dtmimp.GetFuncName() err := dtmcli.TccGlobalTransaction(DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { body := &examples.TransReq{Amount: 30} tryURL := Busi + "/TccBTransOutTry" confirmURL := Busi + "/TccBTransOutConfirm" cancelURL := Busi + "/TccBSleepCancel" // 请参见子事务屏障里的时序图,这里为了模拟该时序图,手动拆解了callbranch - branchID := tcc.NewBranchID() + branchID := tcc.NewSubBranchID() sleeped := false app.POST(examples.BusiAPI+"/TccBSleepCancel", common.WrapHandler(func(c *gin.Context) (interface{}, error) { res, err := examples.TccBarrierTransOutCancel(c) if !sleeped { sleeped = true - dtmcli.Logf("sleep before cancel return") + dtmimp.Logf("sleep before cancel return") <-timeoutChan finishedChan <- "1" } return res, err })) // 注册子事务 - resp, err := dtmcli.RestyClient.R(). - SetBody(M{ + resp, err := dtmimp.RestyClient.R(). + SetBody(map[string]interface{}{ "gid": tcc.Gid, "branch_id": branchID, "trans_type": "tcc", "status": dtmcli.StatusPrepared, - "data": string(dtmcli.MustMarshal(body)), + "data": string(dtmimp.MustMarshal(body)), dtmcli.BranchTry: tryURL, dtmcli.BranchConfirm: confirmURL, dtmcli.BranchCancel: cancelURL, @@ -85,11 +79,11 @@ func tccBarrierDisorder(t *testing.T) { assert.Contains(t, resp.String(), dtmcli.ResultSuccess) go func() { - dtmcli.Logf("sleeping to wait for tcc try timeout") + dtmimp.Logf("sleeping to wait for tcc try timeout") <-timeoutChan - r, _ := dtmcli.RestyClient.R(). + r, _ := dtmimp.RestyClient.R(). SetBody(body). - SetQueryParams(dtmcli.MS{ + SetQueryParams(map[string]string{ "dtm": tcc.Dtm, "gid": tcc.Gid, "branch_id": branchID, @@ -100,10 +94,10 @@ func tccBarrierDisorder(t *testing.T) { assert.True(t, strings.Contains(r.String(), dtmcli.ResultSuccess)) // 这个是悬挂操作,为了简单起见,依旧让他返回成功 finishedChan <- "1" }() - dtmcli.Logf("cron to timeout and then call cancel") + dtmimp.Logf("cron to timeout and then call cancel") go cronTransOnceForwardNow(300) time.Sleep(100 * time.Millisecond) - dtmcli.Logf("cron to timeout and then call cancelled twice") + dtmimp.Logf("cron to timeout and then call cancelled twice") cronTransOnceForwardNow(300) timeoutChan <- "wake" timeoutChan <- "wake" @@ -117,11 +111,11 @@ func tccBarrierDisorder(t *testing.T) { assert.Equal(t, dtmcli.StatusFailed, getTransStatus(gid)) } -func barrierPanic(t *testing.T) { +func TestTccBarrierPanic(t *testing.T) { bb := &dtmcli.BranchBarrier{TransType: "saga", Gid: "gid1", BranchID: "bid1", BranchType: "action", BarrierID: 1} var err error func() { - defer dtmcli.P2E(&err) + defer dtmimp.P2E(&err) tx, _ := dbGet().ToSQLDB().BeginTx(context.Background(), &sql.TxOptions{}) bb.Call(tx, func(db dtmcli.DB) error { panic(fmt.Errorf("an error")) diff --git a/test/tcc_test.go b/test/tcc_test.go index fc0195a..9a8d119 100644 --- a/test/tcc_test.go +++ b/test/tcc_test.go @@ -6,18 +6,13 @@ import ( "github.com/go-resty/resty/v2" "github.com/stretchr/testify/assert" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestTcc(t *testing.T) { - tccNormal(t) - tccRollback(t) - -} - -func tccNormal(t *testing.T) { +func TestTccNormal(t *testing.T) { data := &examples.TransReq{Amount: 30} - gid := "tccNormal" + gid := dtmimp.GetFuncName() err := dtmcli.TccGlobalTransaction(examples.DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, err := tcc.CallBranch(data, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") assert.Nil(t, err) @@ -26,8 +21,8 @@ func tccNormal(t *testing.T) { assert.Nil(t, err) } -func tccRollback(t *testing.T) { - gid := "tccRollback" +func TestTccRollback(t *testing.T) { + gid := dtmimp.GetFuncName() data := &examples.TransReq{Amount: 30, TransInResult: dtmcli.ResultFailure} err := dtmcli.TccGlobalTransaction(examples.DtmServer, gid, func(tcc *dtmcli.Tcc) (*resty.Response, error) { _, rerr := tcc.CallBranch(data, Busi+"/TransOut", Busi+"/TransOutConfirm", Busi+"/TransOutRevert") diff --git a/test/types.go b/test/types.go index 6fbfa40..663f0f0 100644 --- a/test/types.go +++ b/test/types.go @@ -4,7 +4,7 @@ import ( "time" "github.com/yedf/dtm/common" - "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/dtmsvr" ) @@ -16,16 +16,16 @@ func dbGet() *common.DB { // waitTransProcessed only for test usage. wait for transaction processed once func waitTransProcessed(gid string) { - dtmcli.Logf("waiting for gid %s", gid) + dtmimp.Logf("waiting for gid %s", gid) select { case id := <-dtmsvr.TransProcessedTestChan: for id != gid { - dtmcli.LogRedf("-------id %s not match gid %s", id, gid) + dtmimp.LogRedf("-------id %s not match gid %s", id, gid) id = <-dtmsvr.TransProcessedTestChan } - dtmcli.Logf("finish for gid %s", gid) + dtmimp.Logf("finish for gid %s", gid) case <-time.After(time.Duration(time.Second * 3)): - dtmcli.LogFatalf("Wait Trans timeout") + dtmimp.LogFatalf("Wait Trans timeout") } } @@ -36,7 +36,7 @@ func cronTransOnce() { } } -var e2p = dtmcli.E2P +var e2p = dtmimp.E2P // TransGlobal alias type TransGlobal = dtmsvr.TransGlobal @@ -44,12 +44,16 @@ type TransGlobal = dtmsvr.TransGlobal // TransBranch alias type TransBranch = dtmsvr.TransBranch -// M alias -type M = dtmcli.M - func cronTransOnceForwardNow(seconds int) { old := dtmsvr.NowForwardDuration dtmsvr.NowForwardDuration = time.Duration(seconds) * time.Second cronTransOnce() dtmsvr.NowForwardDuration = old } + +func cronTransOnceForwardCron(seconds int) { + old := dtmsvr.CronForwardDuration + dtmsvr.CronForwardDuration = time.Duration(seconds) * time.Second + cronTransOnce() + dtmsvr.CronForwardDuration = old +} diff --git a/test/wait_saga_test.go b/test/wait_saga_test.go deleted file mode 100644 index 7efdeec..0000000 --- a/test/wait_saga_test.go +++ /dev/null @@ -1,50 +0,0 @@ -package test - -import ( - "testing" - - "github.com/stretchr/testify/assert" - "github.com/yedf/dtm/dtmcli" - "github.com/yedf/dtm/examples" -) - -func TestWaitSaga(t *testing.T) { - - sagaNormalWait(t) - sagaCommittedOngoingWait(t) - sagaRollbackWait(t) -} - -func sagaNormalWait(t *testing.T) { - saga := genSaga("gid-noramlSagaWait", false, false) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) - err := saga.Submit() - assert.Nil(t, err) - waitTransProcessed(saga.Gid) - assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) - assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) - transQuery(t, saga.Gid) -} - -func sagaCommittedOngoingWait(t *testing.T) { - saga := genSaga("gid-committedOngoingWait", false, false) - examples.MainSwitch.TransOutResult.SetOnce(dtmcli.ResultOngoing) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) - err := saga.Submit() - assert.Error(t, err) - waitTransProcessed(saga.Gid) - assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared, dtmcli.StatusPrepared}, getBranchesStatus(saga.Gid)) - cronTransOnce() - assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(saga.Gid)) - assert.Equal(t, dtmcli.StatusSucceed, getTransStatus(saga.Gid)) -} - -func sagaRollbackWait(t *testing.T) { - saga := genSaga("gid-rollbackSaga2Wait", false, true) - saga.SetOptions(&dtmcli.TransOptions{WaitResult: true}) - err := saga.Submit() - assert.Error(t, err) - waitTransProcessed(saga.Gid) - assert.Equal(t, dtmcli.StatusFailed, getTransStatus(saga.Gid)) - assert.Equal(t, []string{dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusSucceed, dtmcli.StatusFailed}, getBranchesStatus(saga.Gid)) -} diff --git a/test/xa_test.go b/test/xa_test.go index 782962d..6223d03 100644 --- a/test/xa_test.go +++ b/test/xa_test.go @@ -8,18 +8,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/yedf/dtm/common" "github.com/yedf/dtm/dtmcli" + "github.com/yedf/dtm/dtmcli/dtmimp" "github.com/yedf/dtm/examples" ) -func TestXa(t *testing.T) { - xaLocalError(t) - xaNormal(t) - xaDuplicate(t) - xaRollback(t) - xaTimeout(t) -} - -func xaLocalError(t *testing.T) { +func TestXaLocalError(t *testing.T) { xc := examples.XaClient err := xc.XaGlobalTransaction("xaLocalError", func(xa *dtmcli.Xa) (*resty.Response, error) { return nil, fmt.Errorf("an error") @@ -27,9 +20,9 @@ func xaLocalError(t *testing.T) { assert.Error(t, err, fmt.Errorf("an error")) } -func xaNormal(t *testing.T) { +func TestXaNormal(t *testing.T) { xc := examples.XaClient - gid := "xaNormal" + gid := dtmimp.GetFuncName() err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { req := examples.GenTransReq(30, false, false) resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") @@ -43,26 +36,26 @@ func xaNormal(t *testing.T) { assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(gid)) } -func xaDuplicate(t *testing.T) { +func TestXaDuplicate(t *testing.T) { xc := examples.XaClient - gid := "xaDuplicate" + gid := dtmimp.GetFuncName() err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { req := examples.GenTransReq(30, false, false) _, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") assert.Nil(t, err) - sdb, err := dtmcli.StandaloneDB(common.DtmConfig.DB) + sdb, err := dtmimp.StandaloneDB(common.DtmConfig.DB) assert.Nil(t, err) - dtmcli.DBExec(sdb, "xa recover") - dtmcli.DBExec(sdb, "xa commit 'xaDuplicate-0101'") // 先把某一个事务提交,模拟重复请求 + dtmimp.DBExec(sdb, "xa recover") + dtmimp.DBExec(sdb, "xa commit 'xaDuplicate-0101'") // 先把某一个事务提交,模拟重复请求 return xa.CallBranch(req, examples.Busi+"/TransInXa") }) assert.Equal(t, nil, err) waitTransProcessed(gid) assert.Equal(t, []string{dtmcli.StatusPrepared, dtmcli.StatusSucceed, dtmcli.StatusPrepared, dtmcli.StatusSucceed}, getBranchesStatus(gid)) } -func xaRollback(t *testing.T) { +func TestXaRollback(t *testing.T) { xc := examples.XaClient - gid := "xaRollback" + gid := dtmimp.GetFuncName() err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { req := &examples.TransReq{Amount: 30, TransInResult: dtmcli.ResultFailure} resp, err := xa.CallBranch(req, examples.Busi+"/TransOutXa") @@ -77,9 +70,9 @@ func xaRollback(t *testing.T) { assert.Equal(t, dtmcli.StatusFailed, getTransStatus(gid)) } -func xaTimeout(t *testing.T) { +func TestXaTimeout(t *testing.T) { xc := examples.XaClient - gid := "xaTimeout" + gid := dtmimp.GetFuncName() timeoutChan := make(chan int, 1) err := xc.XaGlobalTransaction(gid, func(xa *dtmcli.Xa) (*resty.Response, error) { go func() {