Browse Source

feat: add sync worker and fmt (#303)

* feat: add sync worker and fmt

* feat: update

* feat: update

* feat: update

* feat: update

* feat: update

* feat: update

* feat: update

* feat: fix spell

* feat: fix conflict

Co-authored-by: Xin.Zh <dragoncharlie@foxmail.com>
Co-authored-by: haohongfan1 <haohongfan1@jd.com>
tags/1.0.2-RC1
georgehao GitHub 3 years ago
parent
commit
29c7f38440
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
100 changed files with 1170 additions and 433 deletions
  1. +4
    -4
      go.mod
  2. +1
    -1
      pkg/config/getty_config.go
  3. +1
    -1
      pkg/constant/context.go
  4. +191
    -0
      pkg/datasource/sql/async_worker.go
  5. +18
    -141
      pkg/datasource/sql/at.go
  6. +0
    -3
      pkg/datasource/sql/conn.go
  7. +0
    -1
      pkg/datasource/sql/conn_xa_test.go
  8. +1
    -1
      pkg/datasource/sql/connector_test.go
  9. +2
    -2
      pkg/datasource/sql/driver.go
  10. +1
    -1
      pkg/datasource/sql/driver_test.go
  11. +1
    -1
      pkg/datasource/sql/exec/executor.go
  12. +3
    -4
      pkg/datasource/sql/hook/basic_undo_builder.go
  13. +1
    -1
      pkg/datasource/sql/hook/logger_hook.go
  14. +1
    -2
      pkg/datasource/sql/hook/undo_log_hook.go
  15. +1
    -1
      pkg/datasource/sql/hook/update_undo_hook.go
  16. +1
    -1
      pkg/datasource/sql/sql_test.go
  17. +1
    -1
      pkg/datasource/sql/tx.go
  18. +22
    -22
      pkg/datasource/sql/types/const.go
  19. +20
    -3
      pkg/datasource/sql/undo/base/undo.go
  20. +1
    -2
      pkg/datasource/sql/undo/builder/basic_undo_log_builder.go
  21. +2
    -2
      pkg/datasource/sql/undo/builder/mysql_delete_undo_log_builder.go
  22. +2
    -2
      pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder.go
  23. +2
    -4
      pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder_test.go
  24. +4
    -2
      pkg/datasource/sql/undo/undo.go
  25. +11
    -13
      pkg/integration/dubbo/dubbo_transaction_filter.go
  26. +0
    -3
      pkg/integration/dubbo/dubbo_transaction_filter_test.go
  27. +5
    -5
      pkg/integration/gin/gin_transaction_middleware.go
  28. +6
    -6
      pkg/integration/grpc/grpc_transaction_interceptor.go
  29. +4
    -2
      pkg/protocol/branch/branch.go
  30. +2
    -3
      pkg/protocol/codec/branch_commit_req_codec.go
  31. +3
    -4
      pkg/protocol/codec/branch_commit_response_codec.go
  32. +1
    -1
      pkg/protocol/codec/branch_commit_response_codec_test.go
  33. +2
    -3
      pkg/protocol/codec/branch_register_req_codec.go
  34. +3
    -4
      pkg/protocol/codec/branch_register_response_codec.go
  35. +1
    -1
      pkg/protocol/codec/branch_register_response_codec_test.go
  36. +2
    -3
      pkg/protocol/codec/branch_rollback_req_codec.go
  37. +3
    -4
      pkg/protocol/codec/branch_rollback_response_codec.go
  38. +1
    -1
      pkg/protocol/codec/branch_rollback_response_codec_test.go
  39. +2
    -2
      pkg/protocol/codec/codec.go
  40. +2
    -3
      pkg/protocol/codec/common_global_end_request_codec.go
  41. +3
    -4
      pkg/protocol/codec/common_global_end_response_codec.go
  42. +2
    -3
      pkg/protocol/codec/common_identify_request_codec.go
  43. +2
    -3
      pkg/protocol/codec/common_identify_response_codec.go
  44. +2
    -3
      pkg/protocol/codec/global_begin_request_codec.go
  45. +3
    -4
      pkg/protocol/codec/global_begin_response_codec.go
  46. +1
    -1
      pkg/protocol/codec/global_begin_response_codec_test.go
  47. +1
    -1
      pkg/protocol/codec/global_report_request_codec.go
  48. +2
    -3
      pkg/protocol/codec/register_rm_request_codec.go
  49. +1
    -1
      pkg/protocol/codec/register_rm_response_codec_test.go
  50. +1
    -1
      pkg/protocol/message/response_message.go
  51. +1
    -1
      pkg/remoting/getty/getty_client.go
  52. +3
    -3
      pkg/remoting/getty/getty_client_test.go
  53. +3
    -3
      pkg/remoting/getty/getty_remoting.go
  54. +4
    -4
      pkg/remoting/getty/getty_remoting_test.go
  55. +1
    -1
      pkg/remoting/getty/listener.go
  56. +2
    -2
      pkg/remoting/getty/readwriter.go
  57. +1
    -1
      pkg/remoting/getty/rpc_client.go
  58. +1
    -3
      pkg/remoting/getty/session_manager.go
  59. +1
    -1
      pkg/remoting/processor/client/client_heart_beat_processon.go
  60. +2
    -3
      pkg/remoting/processor/client/client_heart_beat_processor_test.go
  61. +2
    -3
      pkg/remoting/processor/client/client_on_response_processor.go
  62. +2
    -3
      pkg/remoting/processor/client/client_on_response_processor_test.go
  63. +2
    -3
      pkg/remoting/processor/client/rm_branch_commit_processor.go
  64. +2
    -4
      pkg/remoting/processor/client/rm_branch_commit_processor_test.go
  65. +2
    -3
      pkg/remoting/processor/client/rm_branch_rollback_processor.go
  66. +2
    -4
      pkg/remoting/processor/client/rm_branch_rollback_processor_test.go
  67. +0
    -2
      pkg/rm/rm_cache_test.go
  68. +5
    -8
      pkg/rm/rm_remoting.go
  69. +2
    -2
      pkg/rm/tcc/fence/fence_api.go
  70. +1
    -1
      pkg/rm/tcc/fence/fence_api_test.go
  71. +2
    -3
      pkg/rm/tcc/fence/handler/tcc_fence_wrapper_handler.go
  72. +1
    -2
      pkg/rm/tcc/fence/store/db/dao/tcc_fence_db.go
  73. +0
    -1
      pkg/rm/tcc/fence/store/db/dao/tcc_fence_db_test.go
  74. +0
    -2
      pkg/rm/tcc/fence/store/db/sql/tcc_fence_store_sql.go
  75. +6
    -6
      pkg/rm/tcc/tcc_resource.go
  76. +16
    -16
      pkg/rm/tcc/tcc_service.go
  77. +35
    -26
      pkg/rm/tcc/tcc_service_test.go
  78. +0
    -1
      pkg/rm/two_phase.go
  79. +1
    -6
      pkg/rm/two_phase_test.go
  80. +4
    -5
      pkg/tm/global_transaction.go
  81. +1
    -1
      pkg/tm/global_transaction_test.go
  82. +1
    -1
      pkg/tm/transaction_executor.go
  83. +0
    -0
      pkg/util/bytes/buf.go
  84. +0
    -0
      pkg/util/bytes/buf_helper.go
  85. +0
    -0
      pkg/util/bytes/buf_helper_test.go
  86. +0
    -0
      pkg/util/bytes/buf_test.go
  87. +0
    -0
      pkg/util/errors/error.go
  88. +0
    -0
      pkg/util/errors/error_code.go
  89. +119
    -0
      pkg/util/fanout/fanout.go
  90. +30
    -0
      pkg/util/fanout/fanout_test.go
  91. +99
    -0
      pkg/util/flagext/cidr.go
  92. +68
    -0
      pkg/util/flagext/cidr_test.go
  93. +76
    -0
      pkg/util/flagext/day.go
  94. +71
    -0
      pkg/util/flagext/day_test.go
  95. +54
    -0
      pkg/util/flagext/deprecated.go
  96. +22
    -1
      pkg/util/flagext/ignored.go
  97. +18
    -18
      pkg/util/flagext/register.go
  98. +51
    -0
      pkg/util/flagext/secret.go
  99. +94
    -0
      pkg/util/flagext/secret_test.go
  100. +15
    -4
      pkg/util/flagext/stringslice.go

+ 4
- 4
go.mod View File

@@ -16,11 +16,14 @@ require (
github.com/natefinch/lumberjack v2.0.0+incompatible
github.com/parnurzeal/gorequest v0.2.16
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.12.2
github.com/prometheus/common v0.32.1
github.com/stretchr/testify v1.8.0
go.uber.org/atomic v1.9.0
go.uber.org/zap v1.21.0
google.golang.org/grpc v1.49.0
google.golang.org/protobuf v1.28.1
gopkg.in/yaml.v2 v2.4.0
vimagination.zapto.org/byteio v0.0.0-20200222190125-d27cba0f0b10
)

@@ -105,9 +108,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/polarismesh/polaris-go v1.1.0 // indirect
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/prometheus/client_golang v1.12.2 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/prometheus/statsd_exporter v0.21.0 // indirect
github.com/robfig/cron/v3 v3.0.1 // indirect
@@ -134,11 +135,10 @@ require (
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect
golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/tools v0.1.12 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220630174209-ad1d48641aa7 // indirect
gopkg.in/ini.v1 v1.62.0 // indirect
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
moul.io/http2curl v1.0.0 // indirect
vimagination.zapto.org/memio v0.0.0-20200222190306-588ebc67b97d // indirect


+ 1
- 1
pkg/config/getty_config.go View File

@@ -22,7 +22,7 @@ import (
)

// GettyConfig
//Config holds supported types by the multiconfig package
// Config holds supported types by the multiconfig package
type GettyConfig struct {
ReconnectInterval int `default:"0" yaml:"reconnect_interval" json:"reconnect_interval,omitempty"`
// getty_session pool


pkg/common/constants.go → pkg/constant/context.go View File

@@ -15,7 +15,7 @@
* limitations under the License.
*/

package common
package constant

const (
ActionStartTime = "action-start-time"

+ 191
- 0
pkg/datasource/sql/async_worker.go View File

@@ -0,0 +1,191 @@
package sql

import (
"context"
"flag"
"time"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

"github.com/seata/seata-go/pkg/datasource/sql/datasource"
"github.com/seata/seata-go/pkg/datasource/sql/undo"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/fanout"
"github.com/seata/seata-go/pkg/util/log"
)

type phaseTwoContext struct {
Xid string
BranchID int64
ResourceID string
}

type AsyncWorkerConfig struct {
BufferLimit int `yaml:"buffer_limit" json:"buffer_limit"`
BufferCleanInterval time.Duration `yaml:"buffer_clean_interval" json:"buffer_clean_interval"`
ReceiveChanSize int `yaml:"receive_chan_size" json:"receive_chan_size"`
CommitWorkerCount int `yaml:"commit_worker_count" json:"commit_worker_count"`
CommitWorkerBufferSize int `yaml:"commit_worker_buffer_size" json:"commit_worker_buffer_size"`
}

func (cfg *AsyncWorkerConfig) RegisterFlags(f *flag.FlagSet) {
f.IntVar(&cfg.BufferLimit, "async-worker.commit.buffer_size", 10000, "async worker commit buffer limit.")
f.DurationVar(&cfg.BufferCleanInterval, "async-worker.commit.buffer.clean_interval", time.Second, "async worker commit buffer interval")
f.IntVar(&cfg.ReceiveChanSize, "async-worker.commit.channel_size", 10000, "async worker commit channel size")
f.IntVar(&cfg.CommitWorkerCount, "async-worker.commit.worker_count", 10, "async worker commit worker count")
f.IntVar(&cfg.CommitWorkerBufferSize, "async-worker.commit.worker_buffer_size", 1000, "async worker commit worker buffer size")
}

// AsyncWorker executor for branch transaction commit and undo log
type AsyncWorker struct {
conf AsyncWorkerConfig

commitQueue chan phaseTwoContext
resourceMgr datasource.DataSourceManager
commitWorker *fanout.Fanout

branchCommitTotal prometheus.Counter
doBranchCommitFailureTotal prometheus.Counter
receiveChanLength prometheus.Gauge
rePutBackToQueue prometheus.Counter
}

func NewAsyncWorker(prom prometheus.Registerer, conf AsyncWorkerConfig, sourceManager datasource.DataSourceManager) *AsyncWorker {
var asyncWorker AsyncWorker
asyncWorker.conf = conf
asyncWorker.commitQueue = make(chan phaseTwoContext, asyncWorker.conf.ReceiveChanSize)
asyncWorker.resourceMgr = sourceManager
asyncWorker.commitWorker = fanout.New("asyncWorker",
fanout.WithWorker(asyncWorker.conf.CommitWorkerCount),
fanout.WithBuffer(asyncWorker.conf.CommitWorkerBufferSize),
)

asyncWorker.branchCommitTotal = promauto.With(prom).NewCounter(prometheus.CounterOpts{
Name: "async_worker_branch_commit_total",
Help: "the total count of branch commit total count",
})
asyncWorker.doBranchCommitFailureTotal = promauto.With(prom).NewCounter(prometheus.CounterOpts{
Name: "async_worker_branch_commit_failure_total",
Help: "the total count of branch commit failure count",
})
asyncWorker.receiveChanLength = promauto.With(prom).NewGauge(prometheus.GaugeOpts{
Name: "async_worker_receive_channel_length",
Help: "the current length of the receive channel size",
})
asyncWorker.rePutBackToQueue = promauto.With(prom).NewCounter(prometheus.CounterOpts{
Name: "async_worker_commit_failure_retry_counter",
Help: "the counter of commit failure retry counter",
})

go asyncWorker.run()

return &asyncWorker
}

// BranchCommit commit branch transaction
func (aw *AsyncWorker) BranchCommit(ctx context.Context, req message.BranchCommitRequest) (branch.BranchStatus, error) {
phaseCtx := phaseTwoContext{
Xid: req.Xid,
BranchID: req.BranchId,
ResourceID: req.ResourceId,
}

aw.branchCommitTotal.Add(1)

select {
case aw.commitQueue <- phaseCtx:
case <-ctx.Done():
}

aw.receiveChanLength.Add(float64(len(aw.commitQueue)))

return branch.BranchStatusPhasetwoCommitted, nil
}

func (aw *AsyncWorker) run() {
ticker := time.NewTicker(aw.conf.BufferCleanInterval)
phaseCtxs := make([]phaseTwoContext, 0, aw.conf.BufferLimit)
for {
select {
case phaseCtx := <-aw.commitQueue:
phaseCtxs = append(phaseCtxs, phaseCtx)
if len(phaseCtxs) >= aw.conf.BufferLimit*2/3 {
aw.doBranchCommit(&phaseCtxs)
}
case <-ticker.C:
aw.doBranchCommit(&phaseCtxs)
}
}
}

func (aw *AsyncWorker) doBranchCommit(phaseCtxs *[]phaseTwoContext) {
copyPhaseCtxs := make([]phaseTwoContext, len(*phaseCtxs))
copy(copyPhaseCtxs, *phaseCtxs)
*phaseCtxs = (*phaseCtxs)[:0]

doBranchCommit := func(ctx context.Context) {
groupCtxs := make(map[string][]phaseTwoContext, 16)
for i := range copyPhaseCtxs {
if copyPhaseCtxs[i].ResourceID == "" {
continue
}

if _, ok := groupCtxs[copyPhaseCtxs[i].ResourceID]; !ok {
groupCtxs[copyPhaseCtxs[i].ResourceID] = make([]phaseTwoContext, 0, 4)
}

ctxs := groupCtxs[copyPhaseCtxs[i].ResourceID]
ctxs = append(ctxs, copyPhaseCtxs[i])
groupCtxs[copyPhaseCtxs[i].ResourceID] = ctxs
}

for k := range groupCtxs {
aw.dealWithGroupedContexts(k, groupCtxs[k])
}
}

if err := aw.commitWorker.Do(context.Background(), doBranchCommit); err != nil {
aw.doBranchCommitFailureTotal.Add(1)
log.Errorf("do branch commit err:%v", err)
}
}

func (aw *AsyncWorker) dealWithGroupedContexts(resID string, phaseCtxs []phaseTwoContext) {
val, ok := aw.resourceMgr.GetManagedResources()[resID]
if !ok {
for i := range phaseCtxs {
aw.rePutBackToQueue.Add(1)
aw.commitQueue <- phaseCtxs[i]
}
return
}

res := val.(*DBResource)
conn, err := res.target.Conn(context.Background())
if err != nil {
for i := range phaseCtxs {
aw.commitQueue <- phaseCtxs[i]
}
}

defer conn.Close()

undoMgr, err := undo.GetUndoLogManager(res.dbType)
if err != nil {
for i := range phaseCtxs {
aw.rePutBackToQueue.Add(1)
aw.commitQueue <- phaseCtxs[i]
}
return
}

for i := range phaseCtxs {
phaseCtx := phaseCtxs[i]
if err := undoMgr.BatchDeleteUndoLog([]string{phaseCtx.Xid}, []int64{phaseCtx.BranchID}, conn); err != nil {
aw.rePutBackToQueue.Add(1)
aw.commitQueue <- phaseCtx
}
}
}

+ 18
- 141
pkg/datasource/sql/at.go View File

@@ -20,16 +20,15 @@ package sql
import (
"context"
"database/sql"
"flag"
"fmt"
"os"
"strconv"
"sync"
"time"

"github.com/seata/seata-go/pkg/datasource/sql/undo"
"github.com/prometheus/client_golang/prometheus"

"github.com/seata/seata-go/pkg/datasource/sql/datasource"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/datasource/sql/undo"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/rm"
@@ -41,16 +40,23 @@ const (
)

func init() {
datasource.RegisterResourceManager(branch.BranchTypeAT,
&ATSourceManager{
resourceCache: sync.Map{},
basic: datasource.NewBasicSourceManager(),
})
atSourceManager := &ATSourceManager{
resourceCache: sync.Map{},
basic: datasource.NewBasicSourceManager(),
}

fs := flag.NewFlagSet("", flag.PanicOnError)
asyncWorkerConf := AsyncWorkerConfig{}
asyncWorkerConf.RegisterFlags(fs)
_ = fs.Parse([]string{})

atSourceManager.worker = NewAsyncWorker(prometheus.DefaultRegisterer, asyncWorkerConf, atSourceManager)
datasource.RegisterResourceManager(branch.BranchTypeAT, atSourceManager)
}

type ATSourceManager struct {
resourceCache sync.Map
worker *asyncATWorker
worker *AsyncWorker
basic *datasource.BasicSourceManager
}

@@ -61,7 +67,7 @@ func (mgr *ATSourceManager) RegisterResource(res rm.Resource) error {
return mgr.basic.RegisterResource(res)
}

// Unregister a Resource from the Resource Manager
// Unregister a Resource from the Resource Manager
func (mgr *ATSourceManager) UnregisterResource(res rm.Resource) error {
return mgr.basic.UnregisterResource(res)
}
@@ -116,7 +122,7 @@ func (mgr *ATSourceManager) BranchRollback(ctx context.Context, req message.Bran

// BranchCommit
func (mgr *ATSourceManager) BranchCommit(ctx context.Context, req message.BranchCommitRequest) (branch.BranchStatus, error) {
mgr.worker.branchCommit(ctx, req)
mgr.worker.BranchCommit(ctx, req)
return branch.BranchStatusPhaseoneDone, nil
}

@@ -140,132 +146,3 @@ func (mgr *ATSourceManager) CreateTableMetaCache(ctx context.Context, resID stri
db *sql.DB) (datasource.TableMetaCache, error) {
return mgr.basic.CreateTableMetaCache(ctx, resID, dbType, db)
}

type asyncATWorker struct {
asyncCommitBufferLimit int64
commitQueue chan phaseTwoContext
resourceMgr datasource.DataSourceManager
}

func newAsyncATWorker() *asyncATWorker {
asyncCommitBufferLimit := int64(10000)

val := os.Getenv("CLIENT_RM_ASYNC_COMMIT_BUFFER_LIMIT")
if val != "" {
limit, _ := strconv.ParseInt(val, 10, 64)
if limit != 0 {
asyncCommitBufferLimit = limit
}
}

worker := &asyncATWorker{
commitQueue: make(chan phaseTwoContext, asyncCommitBufferLimit),
}

return worker
}

func (w *asyncATWorker) doBranchCommitSafely() {
batchSize := 64

ticker := time.NewTicker(1 * time.Second)
phaseCtxs := make([]phaseTwoContext, 0, batchSize)

for {
select {
case phaseCtx := <-w.commitQueue:
phaseCtxs = append(phaseCtxs, phaseCtx)
if len(phaseCtxs) == batchSize {
tmp := phaseCtxs
w.doBranchCommit(tmp)
phaseCtxs = make([]phaseTwoContext, 0, batchSize)
}
case <-ticker.C:
tmp := phaseCtxs
w.doBranchCommit(tmp)

phaseCtxs = make([]phaseTwoContext, 0, batchSize)
}
}
}

func (w *asyncATWorker) doBranchCommit(phaseCtxs []phaseTwoContext) {
groupCtxs := make(map[string][]phaseTwoContext, _defaultResourceSize)

for i := range phaseCtxs {
if phaseCtxs[i].ResourceID == "" {
continue
}

if _, ok := groupCtxs[phaseCtxs[i].ResourceID]; !ok {
groupCtxs[phaseCtxs[i].ResourceID] = make([]phaseTwoContext, 0, 4)
}

ctxs := groupCtxs[phaseCtxs[i].ResourceID]
ctxs = append(ctxs, phaseCtxs[i])

groupCtxs[phaseCtxs[i].ResourceID] = ctxs
}

for k := range groupCtxs {
w.dealWithGroupedContexts(k, groupCtxs[k])
}
}

func (w *asyncATWorker) dealWithGroupedContexts(resID string, phaseCtxs []phaseTwoContext) {
val, ok := w.resourceMgr.GetManagedResources()[resID]
if !ok {
for i := range phaseCtxs {
w.commitQueue <- phaseCtxs[i]
}
return
}

res := val.(*DBResource)

conn, err := res.target.Conn(context.Background())
if err != nil {
for i := range phaseCtxs {
w.commitQueue <- phaseCtxs[i]
}
}

defer conn.Close()

undoMgr, err := undo.GetUndoLogManager(res.dbType)
if err != nil {
for i := range phaseCtxs {
w.commitQueue <- phaseCtxs[i]
}

return
}

for i := range phaseCtxs {
phaseCtx := phaseCtxs[i]
if err := undoMgr.BatchDeleteUndoLog([]string{phaseCtx.Xid}, []int64{phaseCtx.BranchID}, conn); err != nil {
w.commitQueue <- phaseCtx
}
}
}

func (w *asyncATWorker) branchCommit(ctx context.Context, req message.BranchCommitRequest) {
phaseCtx := phaseTwoContext{
Xid: req.Xid,
BranchID: req.BranchId,
ResourceID: req.ResourceId,
}

select {
case w.commitQueue <- phaseCtx:
case <-ctx.Done():
}

return
}

type phaseTwoContext struct {
Xid string
BranchID int64
ResourceID string
}

+ 0
- 3
pkg/datasource/sql/conn.go View File

@@ -124,7 +124,6 @@ func (c *Conn) Exec(query string, args []driver.Value) (driver.Result, error) {
return types.NewResult(types.WithResult(ret)), nil
})
})

if err != nil {
return nil, err
}
@@ -169,7 +168,6 @@ func (c *Conn) ExecContext(ctx context.Context, query string, args []driver.Name

return ret, err
})

if err != nil {
return nil, err
}
@@ -335,7 +333,6 @@ func (c *Conn) createNewTxOnExecIfNeed(f func() (types.ExecResult, error)) (type
}()

ret, err := f()

if err != nil {
return nil, err
}


+ 0
- 1
pkg/datasource/sql/conn_xa_test.go View File

@@ -85,7 +85,6 @@ func baseMoclConn(mockConn *mock.MockTestDriverConn) {
}

func TestXAConn_ExecContext(t *testing.T) {

ctrl := gomock.NewController(t)
defer ctrl.Finish()



+ 1
- 1
pkg/datasource/sql/connector_test.go View File

@@ -25,9 +25,9 @@ import (
"testing"

"github.com/golang/mock/gomock"
"github.com/seata/seata-go/pkg/common/reflectx"
"github.com/seata/seata-go/pkg/datasource/sql/mock"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/util/reflectx"
"github.com/stretchr/testify/assert"
)



+ 2
- 2
pkg/datasource/sql/driver.go View File

@@ -26,11 +26,11 @@ import (
"strings"

"github.com/go-sql-driver/mysql"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/common/reflectx"
"github.com/seata/seata-go/pkg/datasource/sql/datasource"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/util/log"
"github.com/seata/seata-go/pkg/util/reflectx"
)

const (


+ 1
- 1
pkg/datasource/sql/driver_test.go View File

@@ -23,10 +23,10 @@ import (
"testing"

"github.com/golang/mock/gomock"
"github.com/seata/seata-go/pkg/common/reflectx"
"github.com/seata/seata-go/pkg/datasource/sql/datasource"
"github.com/seata/seata-go/pkg/datasource/sql/mock"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/util/reflectx"
"github.com/stretchr/testify/assert"
)



+ 1
- 1
pkg/datasource/sql/exec/executor.go View File

@@ -21,9 +21,9 @@ import (
"context"
"database/sql/driver"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/datasource/sql/parser"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/util/log"
)

// executorSolts


+ 3
- 4
pkg/datasource/sql/hook/basic_undo_builder.go View File

@@ -23,17 +23,16 @@ import (

"github.com/arana-db/parser/ast"
"github.com/arana-db/parser/format"
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/datasource/sql/exec"
"github.com/seata/seata-go/pkg/datasource/sql/parser"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/util/bytes"
"github.com/seata/seata-go/pkg/util/log"

_ "github.com/arana-db/parser/test_driver"
)

type BasicUndoBuilder struct {
}
type BasicUndoBuilder struct{}

// buildRowImages build row iamge by exec condition
func (u *BasicUndoBuilder) buildRowImages(ctx context.Context, execCtx *exec.ExecContext) ([]*types.RowImage, error) {


+ 1
- 1
pkg/datasource/sql/hook/logger_hook.go View File

@@ -20,9 +20,9 @@ package hook
import (
"context"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/datasource/sql/exec"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/util/log"
"go.uber.org/zap"
)



+ 1
- 2
pkg/datasource/sql/hook/undo_log_hook.go View File

@@ -33,8 +33,7 @@ func init() {
exec.RegisCommonHook(&undoLogSQLHook{})
}

type undoLogSQLHook struct {
}
type undoLogSQLHook struct{}

func (h *undoLogSQLHook) Type() types.SQLType {
return types.SQLTypeUnknown


+ 1
- 1
pkg/datasource/sql/hook/update_undo_hook.go View File

@@ -20,9 +20,9 @@ package hook
import (
"context"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/datasource/sql/exec"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/util/log"
)

// UpdateUndoHook build image when update executed


+ 1
- 1
pkg/datasource/sql/sql_test.go View File

@@ -26,7 +26,7 @@ import (

_ "github.com/go-sql-driver/mysql"
"github.com/seata/seata-go/pkg/client"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/util/log"
)

var db *sql.DB


+ 1
- 1
pkg/datasource/sql/tx.go View File

@@ -24,10 +24,10 @@ import (

"github.com/seata/seata-go/pkg/datasource/sql/undo"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/datasource/sql/datasource"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"

"github.com/pkg/errors"
"github.com/seata/seata-go/pkg/datasource/sql/types"


+ 22
- 22
pkg/datasource/sql/types/const.go View File

@@ -145,67 +145,67 @@ func GetJDBCTypeByTypeName(typeName string) JDBCType {
case "ENUM":
return JDBCTypeTinyInt
// todo 待完善
//case fieldTypeEnum:
// case fieldTypeEnum:
// return "ENUM"
//case fieldTypeFloat:
// case fieldTypeFloat:
// return "FLOAT"
//case fieldTypeGeometry:
// case fieldTypeGeometry:
// return "GEOMETRY"
//case fieldTypeInt24:
// case fieldTypeInt24:
// return "MEDIUMINT"
//case fieldTypeJSON:
// case fieldTypeJSON:
// return "JSON"
//case fieldTypeLong:
// case fieldTypeLong:
// return "INT"
//case fieldTypeLongBLOB:
// case fieldTypeLongBLOB:
// if mf.charSet != collations[binaryCollation] {
// return "LONGTEXT"
// }
// return "LONGBLOB"
//case fieldTypeLongLong:
// case fieldTypeLongLong:
// return "BIGINT"
//case fieldTypeMediumBLOB:
// case fieldTypeMediumBLOB:
// if mf.charSet != collations[binaryCollation] {
// return "MEDIUMTEXT"
// }
// return "MEDIUMBLOB"
//case fieldTypeNewDate:
// case fieldTypeNewDate:
// return "DATE"
//case fieldTypeNewDecimal:
// case fieldTypeNewDecimal:
// return "DECIMAL"
//case fieldTypeNULL:
// case fieldTypeNULL:
// return "NULL"
//case fieldTypeSet:
// case fieldTypeSet:
// return "SET"
//case fieldTypeShort:
// case fieldTypeShort:
// return "SMALLINT"
//case fieldTypeString:
// case fieldTypeString:
// if mf.charSet == collations[binaryCollation] {
// return "BINARY"
// }
// return "CHAR"
//case fieldTypeTime:
// case fieldTypeTime:
// return "TIME"
//case fieldTypeTimestamp:
// case fieldTypeTimestamp:
// return "TIMESTAMP"
//case fieldTypeTiny:
// case fieldTypeTiny:
// return "TINYINT"
//case fieldTypeTinyBLOB:
// case fieldTypeTinyBLOB:
// if mf.charSet != collations[binaryCollation] {
// return "TINYTEXT"
// }
// return "TINYBLOB"
//case fieldTypeVarChar:
// case fieldTypeVarChar:
// if mf.charSet == collations[binaryCollation] {
// return "VARBINARY"
// }
// return "VARCHAR"
//case fieldTypeVarString:
// case fieldTypeVarString:
// if mf.charSet == collations[binaryCollation] {
// return "VARBINARY"
// }
// return "VARCHAR"
//case fieldTypeYear:
// case fieldTypeYear:
// return "YEAR"
default:
return -1


+ 20
- 3
pkg/datasource/sql/undo/base/undo.go View File

@@ -21,15 +21,15 @@ import (
"context"
"database/sql"
"database/sql/driver"
"strconv"
"strings"

"github.com/arana-db/parser/mysql"

"github.com/pkg/errors"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/common/util"
"github.com/seata/seata-go/pkg/constant"
"github.com/seata/seata-go/pkg/datasource/sql/undo"
"github.com/seata/seata-go/pkg/util/log"

"github.com/seata/seata-go/pkg/datasource/sql/types"
)
@@ -87,7 +87,7 @@ func (m *BaseUndoLogManager) BatchDeleteUndoLog(xid []string, branchID []int64,
return err
}

branchIDStr, err := util.Int64Slice2Str(branchID, ",")
branchIDStr, err := Int64Slice2Str(branchID, ",")
if err != nil {
log.Errorf("slice to string transfer fail, err: %v", err)
return err
@@ -168,3 +168,20 @@ func (m *BaseUndoLogManager) appendInParam(size int, str *strings.Builder) {

str.WriteString(") ")
}

// Int64Slice2Str
func Int64Slice2Str(values interface{}, sep string) (string, error) {
v, ok := values.([]int64)
if !ok {
return "", errors.New("param type is fault")
}

var valuesText []string

for i := range v {
text := strconv.FormatInt(v[i], 10)
valuesText = append(valuesText, text)
}

return strings.Join(valuesText, sep), nil
}

+ 1
- 2
pkg/datasource/sql/undo/builder/basic_undo_log_builder.go View File

@@ -28,8 +28,7 @@ import (
"github.com/seata/seata-go/pkg/datasource/sql/types"
)

type BasicUndoLogBuilder struct {
}
type BasicUndoLogBuilder struct{}

// getScanSlice get the column type for scann
func (*BasicUndoLogBuilder) getScanSlice(columnNames []string, tableMeta types.TableMeta) []driver.Value {


+ 2
- 2
pkg/datasource/sql/undo/builder/mysql_delete_undo_log_builder.go View File

@@ -7,11 +7,11 @@ import (

"github.com/arana-db/parser/ast"
"github.com/arana-db/parser/format"
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/datasource/sql/exec"
"github.com/seata/seata-go/pkg/datasource/sql/parser"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/util/bytes"
"github.com/seata/seata-go/pkg/util/log"
)

type MySQLDeleteUndoLogBuilder struct {


+ 2
- 2
pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder.go View File

@@ -26,10 +26,10 @@ import (

"github.com/arana-db/parser/ast"
"github.com/arana-db/parser/format"
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/datasource/sql/parser"
"github.com/seata/seata-go/pkg/datasource/sql/types"
"github.com/seata/seata-go/pkg/util/bytes"
"github.com/seata/seata-go/pkg/util/log"
)

type MySQLUpdateUndoLogBuilder struct {


+ 2
- 4
pkg/datasource/sql/undo/builder/mysql_update_undo_log_builder_test.go View File

@@ -22,14 +22,12 @@ import (
"testing"

_ "github.com/arana-db/parser/test_driver"
_ "github.com/seata/seata-go/pkg/common/log"
_ "github.com/seata/seata-go/pkg/util/log"
"github.com/stretchr/testify/assert"
)

func TestBuildBeforeImageSQL(t *testing.T) {
var (
builder = MySQLUpdateUndoLogBuilder{}
)
builder := MySQLUpdateUndoLogBuilder{}

tests := []struct {
name string


+ 4
- 2
pkg/datasource/sql/undo/undo.go View File

@@ -33,8 +33,10 @@ func init() {
RegistrUndoLogBuilder(&builder.MySQLUpdateUndoLogBuilder{})
}

var solts = map[types.DBType]*undoLogMgrHolder{}
var builders = map[types.SQLType]UndoLogBuilder{}
var (
solts = map[types.DBType]*undoLogMgrHolder{}
builders = map[types.SQLType]UndoLogBuilder{}
)

type undoLogMgrHolder struct {
once sync.Once


+ 11
- 13
pkg/integration/dubbo/dubbo_transaction_filter.go View File

@@ -25,9 +25,9 @@ import (
"dubbo.apache.org/dubbo-go/v3/common/extension"
"dubbo.apache.org/dubbo-go/v3/filter"
"dubbo.apache.org/dubbo-go/v3/protocol"
"github.com/seata/seata-go/pkg/common"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/constant"
"github.com/seata/seata-go/pkg/tm"
"github.com/seata/seata-go/pkg/util/log"
)

var (
@@ -36,14 +36,12 @@ var (
)

func InitSeataDubbo() {
extension.SetFilter(common.SeataFilterKey, GetDubboTransactionFilter)
extension.SetFilter(constant.SeataFilterKey, GetDubboTransactionFilter)
}

type Filter interface {
}
type Filter interface{}

type dubboTransactionFilter struct {
}
type dubboTransactionFilter struct{}

func GetDubboTransactionFilter() filter.Filter {
if seataFilter == nil {
@@ -61,9 +59,9 @@ func (d *dubboTransactionFilter) Invoke(ctx context.Context, invoker protocol.In

if xid != "" {
// dubbo go
invocation.SetAttachment(common.SeataXidKey, xid)
invocation.SetAttachment(constant.SeataXidKey, xid)
// dubbo java
invocation.SetAttachment(common.XidKey, xid)
invocation.SetAttachment(constant.XidKey, xid)
} else if rpcXid != xid {
ctx = tm.InitSeataContext(ctx)
tm.SetXID(ctx, rpcXid)
@@ -85,17 +83,17 @@ func (d *dubboTransactionFilter) getRpcXid(invocation protocol.Invocation) strin
}

func (*dubboTransactionFilter) getDubboGoRpcXid(invocation protocol.Invocation) string {
rpcXid := invocation.GetAttachmentWithDefaultValue(common.SeataXidKey, "")
rpcXid := invocation.GetAttachmentWithDefaultValue(constant.SeataXidKey, "")
if rpcXid == "" {
rpcXid = invocation.GetAttachmentWithDefaultValue(strings.ToLower(common.SeataXidKey), "")
rpcXid = invocation.GetAttachmentWithDefaultValue(strings.ToLower(constant.SeataXidKey), "")
}
return rpcXid
}

func (*dubboTransactionFilter) getDubboJavaRpcXid(invocation protocol.Invocation) string {
rpcXid := invocation.GetAttachmentWithDefaultValue(common.XidKey, "")
rpcXid := invocation.GetAttachmentWithDefaultValue(constant.XidKey, "")
if rpcXid == "" {
rpcXid = invocation.GetAttachmentWithDefaultValue(strings.ToLower(common.XidKey), "")
rpcXid = invocation.GetAttachmentWithDefaultValue(strings.ToLower(constant.XidKey), "")
}
return rpcXid
}

+ 0
- 3
pkg/integration/dubbo/dubbo_transaction_filter_test.go View File

@@ -19,7 +19,6 @@ package dubbo

import (
"context"

"testing"

"dubbo.apache.org/dubbo-go/v3/filter"
@@ -45,7 +44,6 @@ func TestGetDubboTransactionFilter(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, GetDubboTransactionFilter(), tt.want)

})
}
}
@@ -89,7 +87,6 @@ func TestDubboTransactionFilterOnResponse(t *testing.T) {
du := &dubboTransactionFilter{}
got := du.OnResponse(tt.args.ctx, tt.args.result, tt.args.invoker, tt.args.invocation)
assert.Equal(t, got, tt.want)

})
}
}

+ 5
- 5
pkg/integration/gin/gin_transaction_middleware.go View File

@@ -22,22 +22,22 @@ import (

"github.com/gin-gonic/gin"

"github.com/seata/seata-go/pkg/common"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/constant"
"github.com/seata/seata-go/pkg/tm"
"github.com/seata/seata-go/pkg/util/log"
)

// TransactionMiddleware filter gin invocation
// NOTE: when use gin,must set gin.ContextWithFallback true when gin version >= 1.8.1
func TransactionMiddleware() gin.HandlerFunc {
return func(ctx *gin.Context) {
xid := ctx.GetHeader(common.XidKey)
xid := ctx.GetHeader(constant.XidKey)
if xid == "" {
xid = ctx.GetHeader(common.XidKeyLowercase)
xid = ctx.GetHeader(constant.XidKeyLowercase)
}

if len(xid) == 0 {
log.Errorf("Gin: header not contain header: %s, global transaction xid", common.XidKey)
log.Errorf("Gin: header not contain header: %s, global transaction xid", constant.XidKey)
ctx.AbortWithStatus(http.StatusBadRequest)
return
}


+ 6
- 6
pkg/integration/grpc/grpc_transaction_interceptor.go View File

@@ -24,9 +24,9 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"

"github.com/seata/seata-go/pkg/common"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/constant"
"github.com/seata/seata-go/pkg/tm"
"github.com/seata/seata-go/pkg/util/log"
)

// ClientTransactionInterceptor is client interceptor of grpc,
@@ -34,11 +34,11 @@ import (
// and put it in the http header.
func ClientTransactionInterceptor(ctx context.Context, method string, req, reply interface{},
cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
//set the XID when intercepting a client request and release it directly when intercepting a response
// set the XID when intercepting a client request and release it directly when intercepting a response
if tm.IsSeataContext(ctx) {
xid := tm.GetXID(ctx)
header := make(map[string]string)
header[common.XidKey] = xid
header[constant.XidKey] = xid
ctx = metadata.NewOutgoingContext(ctx, metadata.New(header))
}

@@ -60,11 +60,11 @@ func ServerTransactionInterceptor(ctx context.Context, req interface{},
log.Errorf("missing grpc metadata")
}
var xid string
if slice := md.Get(common.XidKey); slice != nil && len(slice) > 0 {
if slice := md.Get(constant.XidKey); slice != nil && len(slice) > 0 {
xid = slice[0]
}
if xid == "" {
if slice := md.Get(common.XidKeyLowercase); slice != nil && len(slice) > 0 {
if slice := md.Get(constant.XidKeyLowercase); slice != nil && len(slice) > 0 {
xid = slice[0]
}
}


+ 4
- 2
pkg/protocol/branch/branch.go View File

@@ -21,8 +21,10 @@ import (
"fmt"
)

type BranchType int8
type BranchStatus int8
type (
BranchType int8
BranchStatus int8
)

const (
BranchTypeAT BranchType = 0


+ 2
- 3
pkg/protocol/codec/branch_commit_req_codec.go View File

@@ -18,17 +18,16 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &BranchCommitRequestCodec{})
}

type BranchCommitRequestCodec struct {
}
type BranchCommitRequestCodec struct{}

func (g *BranchCommitRequestCodec) Decode(in []byte) interface{} {
data := message.BranchCommitRequest{}


+ 3
- 4
pkg/protocol/codec/branch_commit_response_codec.go View File

@@ -20,19 +20,18 @@ package codec
import (
"math"

serror "github.com/seata/seata-go/pkg/common/errors"
serror "github.com/seata/seata-go/pkg/util/errors"

"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &BranchCommitResponseCodec{})
}

type BranchCommitResponseCodec struct {
}
type BranchCommitResponseCodec struct{}

func (g *BranchCommitResponseCodec) Decode(in []byte) interface{} {
data := message.BranchCommitResponse{}


+ 1
- 1
pkg/protocol/codec/branch_commit_response_codec_test.go View File

@@ -22,9 +22,9 @@ import (

"github.com/stretchr/testify/assert"

serror "github.com/seata/seata-go/pkg/common/errors"
model2 "github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
serror "github.com/seata/seata-go/pkg/util/errors"
)

func TestBranchCommitResponseCodec(t *testing.T) {


+ 2
- 3
pkg/protocol/codec/branch_register_req_codec.go View File

@@ -18,7 +18,7 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/util/bytes"

model2 "github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
@@ -28,8 +28,7 @@ func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &BranchRegisterRequestCodec{})
}

type BranchRegisterRequestCodec struct {
}
type BranchRegisterRequestCodec struct{}

func (g *BranchRegisterRequestCodec) Decode(in []byte) interface{} {
data := message.BranchRegisterRequest{}


+ 3
- 4
pkg/protocol/codec/branch_register_response_codec.go View File

@@ -20,17 +20,16 @@ package codec
import (
"math"

"github.com/seata/seata-go/pkg/common/bytes"
serror "github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
serror "github.com/seata/seata-go/pkg/util/errors"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &BranchRegisterResponseCodec{})
}

type BranchRegisterResponseCodec struct {
}
type BranchRegisterResponseCodec struct{}

func (g *BranchRegisterResponseCodec) Decode(in []byte) interface{} {
data := message.BranchRegisterResponse{}


+ 1
- 1
pkg/protocol/codec/branch_register_response_codec_test.go View File

@@ -20,7 +20,7 @@ package codec
import (
"testing"

serror "github.com/seata/seata-go/pkg/common/errors"
serror "github.com/seata/seata-go/pkg/util/errors"

"github.com/seata/seata-go/pkg/protocol/message"
"github.com/stretchr/testify/assert"


+ 2
- 3
pkg/protocol/codec/branch_rollback_req_codec.go View File

@@ -18,17 +18,16 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &BranchRollbackRequestCodec{})
}

type BranchRollbackRequestCodec struct {
}
type BranchRollbackRequestCodec struct{}

func (g *BranchRollbackRequestCodec) Decode(in []byte) interface{} {
data := message.BranchRollbackRequest{}


+ 3
- 4
pkg/protocol/codec/branch_rollback_response_codec.go View File

@@ -20,18 +20,17 @@ package codec
import (
"math"

"github.com/seata/seata-go/pkg/common/bytes"
serror "github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
serror "github.com/seata/seata-go/pkg/util/errors"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &BranchRollbackResponseCodec{})
}

type BranchRollbackResponseCodec struct {
}
type BranchRollbackResponseCodec struct{}

func (g *BranchRollbackResponseCodec) Decode(in []byte) interface{} {
data := message.BranchRollbackResponse{}


+ 1
- 1
pkg/protocol/codec/branch_rollback_response_codec_test.go View File

@@ -20,7 +20,7 @@ package codec
import (
"testing"

serror "github.com/seata/seata-go/pkg/common/errors"
serror "github.com/seata/seata-go/pkg/util/errors"

model2 "github.com/seata/seata-go/pkg/protocol/branch"



+ 2
- 2
pkg/protocol/codec/codec.go View File

@@ -21,8 +21,8 @@ import (
"bytes"
"sync"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"
"vimagination.zapto.org/byteio"
)

@@ -93,7 +93,7 @@ func (c *CodecManager) Decode(codecType CodecType, in []byte) interface{} {
}

func (c *CodecManager) Encode(codecType CodecType, in interface{}) []byte {
var result = make([]byte, 0)
result := make([]byte, 0)
msg := in.(message.MessageTypeAware)
typeCode := msg.GetTypeCode()



+ 2
- 3
pkg/protocol/codec/common_global_end_request_codec.go View File

@@ -18,12 +18,11 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

type CommonGlobalEndRequestCodec struct {
}
type CommonGlobalEndRequestCodec struct{}

func (c *CommonGlobalEndRequestCodec) Encode(in interface{}) []byte {
data, _ := in.(message.AbstractGlobalEndRequest)


+ 3
- 4
pkg/protocol/codec/common_global_end_response_codec.go View File

@@ -20,13 +20,12 @@ package codec
import (
"math"

"github.com/seata/seata-go/pkg/common/bytes"
serror "github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
serror "github.com/seata/seata-go/pkg/util/errors"
)

type CommonGlobalEndResponseCodec struct {
}
type CommonGlobalEndResponseCodec struct{}

func (c *CommonGlobalEndResponseCodec) Encode(in interface{}) []byte {
data := in.(message.AbstractGlobalEndResponse)


+ 2
- 3
pkg/protocol/codec/common_identify_request_codec.go View File

@@ -18,12 +18,11 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

type AbstractIdentifyRequestCodec struct {
}
type AbstractIdentifyRequestCodec struct{}

func (c *AbstractIdentifyRequestCodec) Encode(in interface{}) []byte {
data := in.(message.AbstractIdentifyRequest)


+ 2
- 3
pkg/protocol/codec/common_identify_response_codec.go View File

@@ -18,12 +18,11 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

type AbstractIdentifyResponseCodec struct {
}
type AbstractIdentifyResponseCodec struct{}

func (c *AbstractIdentifyResponseCodec) Encode(in interface{}) []byte {
data := in.(message.AbstractIdentifyResponse)


+ 2
- 3
pkg/protocol/codec/global_begin_request_codec.go View File

@@ -20,16 +20,15 @@ package codec
import (
"time"

"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &GlobalBeginRequestCodec{})
}

type GlobalBeginRequestCodec struct {
}
type GlobalBeginRequestCodec struct{}

func (c *GlobalBeginRequestCodec) Encode(in interface{}) []byte {
data := in.(message.GlobalBeginRequest)


+ 3
- 4
pkg/protocol/codec/global_begin_response_codec.go View File

@@ -20,17 +20,16 @@ package codec
import (
"math"

"github.com/seata/seata-go/pkg/common/bytes"
serror "github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
serror "github.com/seata/seata-go/pkg/util/errors"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &GlobalBeginResponseCodec{})
}

type GlobalBeginResponseCodec struct {
}
type GlobalBeginResponseCodec struct{}

func (c *GlobalBeginResponseCodec) Encode(in interface{}) []byte {
data := in.(message.GlobalBeginResponse)


+ 1
- 1
pkg/protocol/codec/global_begin_response_codec_test.go View File

@@ -22,8 +22,8 @@ import (

"github.com/stretchr/testify/assert"

serror "github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/protocol/message"
serror "github.com/seata/seata-go/pkg/util/errors"
)

func TestGlobalBeginResponseCodec(t *testing.T) {


+ 1
- 1
pkg/protocol/codec/global_report_request_codec.go View File

@@ -18,8 +18,8 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

type GlobalReportRequestCodec struct {


+ 2
- 3
pkg/protocol/codec/register_rm_request_codec.go View File

@@ -18,16 +18,15 @@
package codec

import (
"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/bytes"
)

func init() {
GetCodecManager().RegisterCodec(CodecTypeSeata, &RegisterRMRequestCodec{})
}

type RegisterRMRequestCodec struct {
}
type RegisterRMRequestCodec struct{}

func (g *RegisterRMRequestCodec) Decode(in []byte) interface{} {
data := message.RegisterRMRequest{}


+ 1
- 1
pkg/protocol/codec/register_rm_response_codec_test.go View File

@@ -29,7 +29,7 @@ func TestRegisterRMResponseCodec(t *testing.T) {
AbstractIdentifyResponse: message.AbstractIdentifyResponse{
AbstractResultMessage: message.AbstractResultMessage{
ResultCode: message.ResultCodeFailed,
//Msg: "TestMsg",
// Msg: "TestMsg",
},
Version: "V1,0",
Identified: false,


+ 1
- 1
pkg/protocol/message/response_message.go View File

@@ -18,8 +18,8 @@
package message

import (
"github.com/seata/seata-go/pkg/common/errors"
model2 "github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/util/errors"
)

type AbstractTransactionResponse struct {


+ 1
- 1
pkg/remoting/getty/getty_client.go View File

@@ -22,9 +22,9 @@ import (

gxtime "github.com/dubbogo/gost/time"
"github.com/pkg/errors"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/codec"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"
"go.uber.org/atomic"
)



+ 3
- 3
pkg/remoting/getty/getty_client_test.go View File

@@ -59,7 +59,7 @@ func TestGettyRemotingClient_SendAsyncResponse(t *testing.T) {

// TestGettyRemotingClient_SendAsyncRequest unit test for SendAsyncRequest function
func TestGettyRemotingClient_SendAsyncRequest(t *testing.T) {
var tests = []struct {
tests := []struct {
name string
message interface{}
}{
@@ -86,7 +86,7 @@ func TestGettyRemotingClient_SendAsyncRequest(t *testing.T) {

// Test_syncCallback unit test for syncCallback function
func Test_syncCallback(t *testing.T) {
var tests = []struct {
tests := []struct {
name string
respMsg *message.MessageFuture
reqMsg message.RpcMessage
@@ -133,7 +133,7 @@ func Test_syncCallback(t *testing.T) {

// Test_asyncCallback unit test for asyncCallback function
func Test_asyncCallback(t *testing.T) {
var tests = []struct {
tests := []struct {
name string
respMsg *message.MessageFuture
reqMsg message.RpcMessage


+ 3
- 3
pkg/remoting/getty/getty_remoting.go View File

@@ -23,8 +23,8 @@ import (

getty "github.com/apache/dubbo-getty"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"
)

const (
@@ -123,9 +123,9 @@ func (g *GettyRemoting) NotifyRpcMessageResponse(rpcMessage message.RpcMessage)
if messageFuture != nil {
messageFuture.Response = rpcMessage.Body
// todo add messageFuture.Err
//messageFuture.Err = rpcMessage.Err
// messageFuture.Err = rpcMessage.Err
messageFuture.Done <- struct{}{}
//client.msgFutures.Delete(rpcMessage.RequestID)
// client.msgFutures.Delete(rpcMessage.RequestID)
} else {
log.Infof("msg: {} is not found in msgFutures.", rpcMessage.ID)
}


+ 4
- 4
pkg/remoting/getty/getty_remoting_test.go View File

@@ -25,7 +25,7 @@ import (
)

func TestGettyRemoting_GetMessageFuture(t *testing.T) {
var tests = []struct {
tests := []struct {
name string
msgID int32
messageFuture *message.MessageFuture
@@ -61,7 +61,7 @@ func TestGettyRemoting_GetMessageFuture(t *testing.T) {
}

func TestGettyRemoting_RemoveMessageFuture(t *testing.T) {
var tests = []struct {
tests := []struct {
name string
msgID int32
messageFuture *message.MessageFuture
@@ -90,7 +90,7 @@ func TestGettyRemoting_RemoveMessageFuture(t *testing.T) {
}

func TestGettyRemoting_GetMergedMessage(t *testing.T) {
var tests = []struct {
tests := []struct {
name string
msgID int32
mergedWarpMessage *message.MergedWarpMessage
@@ -124,7 +124,7 @@ func TestGettyRemoting_GetMergedMessage(t *testing.T) {
}

func TestGettyRemoting_RemoveMergedMessageFuture(t *testing.T) {
var tests = []struct {
tests := []struct {
name string
msgID int32
mergedWarpMessage *message.MergedWarpMessage


+ 1
- 1
pkg/remoting/getty/listener.go View File

@@ -22,11 +22,11 @@ import (
"sync"

getty "github.com/apache/dubbo-getty"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/config"
"github.com/seata/seata-go/pkg/protocol/codec"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/remoting/processor"
"github.com/seata/seata-go/pkg/util/log"
"go.uber.org/atomic"
)



+ 2
- 2
pkg/remoting/getty/readwriter.go View File

@@ -20,7 +20,7 @@ package getty
import (
"fmt"

"github.com/seata/seata-go/pkg/common/bytes"
"github.com/seata/seata-go/pkg/util/bytes"

getty "github.com/apache/dubbo-getty"
"github.com/pkg/errors"
@@ -111,7 +111,7 @@ func (p *RpcPackageHandler) Read(ss getty.Session, data []byte) (interface{}, in
return nil, int(header.TotalLength), nil
}

//r := byteio.BigEndianReader{Reader: bytes.NewReader(data)}
// r := byteio.BigEndianReader{Reader: bytes.NewReader(data)}
rpcMessage := message.RpcMessage{
Codec: header.CodecType,
ID: int32(header.RequestID),


+ 1
- 1
pkg/remoting/getty/rpc_client.go View File

@@ -27,8 +27,8 @@ import (

gxsync "github.com/dubbogo/gost/sync"
"github.com/pkg/errors"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/config"
"github.com/seata/seata-go/pkg/util/log"
)

type RpcClient struct {


+ 1
- 3
pkg/remoting/getty/session_manager.go View File

@@ -30,9 +30,7 @@ const (
checkAliveInternal = 100
)

var (
sessionManager = newSessionManager()
)
var sessionManager = newSessionManager()

type SessionManager struct {
// serverAddress -> rpc_client.Session -> bool


+ 1
- 1
pkg/remoting/processor/client/client_heart_beat_processon.go View File

@@ -20,7 +20,7 @@ package client
import (
"context"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/util/log"

"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/remoting/getty"


+ 2
- 3
pkg/remoting/processor/client/client_heart_beat_processor_test.go View File

@@ -27,10 +27,10 @@ import (

func TestClientHeartBeatProcessor(t *testing.T) {
// testcases
var tests = []struct {
tests := []struct {
name string // testcase name
rpcMsg message.RpcMessage // rpcMessage case
wantErr bool //want testcase err or not
wantErr bool // want testcase err or not
}{
{
name: "chb-testcase1",
@@ -82,5 +82,4 @@ func TestClientHeartBeatProcessor(t *testing.T) {
}
})
}

}

+ 2
- 3
pkg/remoting/processor/client/client_on_response_processor.go View File

@@ -20,8 +20,8 @@ package client
import (
"context"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"

"github.com/seata/seata-go/pkg/remoting/getty"
)
@@ -42,8 +42,7 @@ func init() {
getty.GetGettyClientHandlerInstance().RegisterProcessor(message.MessageTypeRegCltResult, clientOnResponseProcessor)
}

type clientOnResponseProcessor struct {
}
type clientOnResponseProcessor struct{}

func (f *clientOnResponseProcessor) Process(ctx context.Context, rpcMessage message.RpcMessage) error {
log.Infof("the rm client received clientOnResponse msg %#v from tc server.", rpcMessage)


+ 2
- 3
pkg/remoting/processor/client/client_on_response_processor_test.go View File

@@ -27,10 +27,10 @@ import (

func TestClientOnResponseProcessor(t *testing.T) {
// testcases
var tests = []struct {
tests := []struct {
name string // testcase name
rpcMsg message.RpcMessage // rpcMessage case
wantErr bool //want testcase err or not
wantErr bool // want testcase err or not
}{
{
name: "cor-testcase1-mergeResult",
@@ -106,5 +106,4 @@ func TestClientOnResponseProcessor(t *testing.T) {
}
})
}

}

+ 2
- 3
pkg/remoting/processor/client/rm_branch_commit_processor.go View File

@@ -20,8 +20,8 @@ package client
import (
"context"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"

"github.com/seata/seata-go/pkg/remoting/getty"
"github.com/seata/seata-go/pkg/rm"
@@ -32,8 +32,7 @@ func init() {
getty.GetGettyClientHandlerInstance().RegisterProcessor(message.MessageTypeBranchCommit, rmBranchCommitProcessor)
}

type rmBranchCommitProcessor struct {
}
type rmBranchCommitProcessor struct{}

func (f *rmBranchCommitProcessor) Process(ctx context.Context, rpcMessage message.RpcMessage) error {
log.Infof("the rm client received rmBranchCommit msg %#v from tc server.", rpcMessage)


+ 2
- 4
pkg/remoting/processor/client/rm_branch_commit_processor_test.go View File

@@ -29,12 +29,11 @@ import (
)

func TestRmBranchCommitProcessor(t *testing.T) {

// testcases
var tests = []struct {
tests := []struct {
name string // testcase name
rpcMsg message.RpcMessage // rpcMessage case
wantErr bool //want testcase err or not
wantErr bool // want testcase err or not
}{
{
name: "rbc-testcase1-failure",
@@ -78,5 +77,4 @@ func TestRmBranchCommitProcessor(t *testing.T) {
}
})
}

}

+ 2
- 3
pkg/remoting/processor/client/rm_branch_rollback_processor.go View File

@@ -20,8 +20,8 @@ package client
import (
"context"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"

"github.com/seata/seata-go/pkg/remoting/getty"
"github.com/seata/seata-go/pkg/rm"
@@ -32,8 +32,7 @@ func init() {
getty.GetGettyClientHandlerInstance().RegisterProcessor(message.MessageTypeBranchRollback, rmBranchRollbackProcessor)
}

type rmBranchRollbackProcessor struct {
}
type rmBranchRollbackProcessor struct{}

func (f *rmBranchRollbackProcessor) Process(ctx context.Context, rpcMessage message.RpcMessage) error {
log.Infof("the rm client received rmBranchRollback msg %#v from tc server.", rpcMessage)


+ 2
- 4
pkg/remoting/processor/client/rm_branch_rollback_processor_test.go View File

@@ -29,12 +29,11 @@ import (
)

func TestRmBranchRollbackProcessor(t *testing.T) {

// testcases
var tests = []struct {
tests := []struct {
name string // testcase name
rpcMsg message.RpcMessage // rpcMessage case
wantErr bool //want testcase err or not
wantErr bool // want testcase err or not
}{
{
name: "rbr-testcase1-failure",
@@ -78,5 +77,4 @@ func TestRmBranchRollbackProcessor(t *testing.T) {
}
})
}

}

+ 0
- 2
pkg/rm/rm_cache_test.go View File

@@ -27,7 +27,6 @@ import (
)

func TestGetRmCacheInstance(t *testing.T) {

ctl := gomock.NewController(t)

mockResourceManager := NewMockResourceManager(ctl)
@@ -43,5 +42,4 @@ func TestGetRmCacheInstance(t *testing.T) {
actual := GetRmCacheInstance().GetResourceManager(branch.BranchTypeTCC)
assert.Equalf(t, mockResourceManager, actual, "GetRmCacheInstance()")
})

}

+ 5
- 8
pkg/rm/rm_remoting.go View File

@@ -22,10 +22,10 @@ import (

"github.com/pkg/errors"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/remoting/getty"
"github.com/seata/seata-go/pkg/util/log"
)

var (
@@ -33,9 +33,7 @@ var (
onceGettyRemoting = &sync.Once{}
)

var (
ErrBranchReportResponseFault = errors.New("branch report response fault")
)
var ErrBranchReportResponseFault = errors.New("branch report response fault")

func GetRMRemotingInstance() *RMRemoting {
if rmRemoting == nil {
@@ -46,10 +44,9 @@ func GetRMRemotingInstance() *RMRemoting {
return rmRemoting
}

type RMRemoting struct {
}
type RMRemoting struct{}

//BranchRegister Register branch of global transaction
// BranchRegister Register branch of global transaction
func (r *RMRemoting) BranchRegister(param BranchRegisterParam) (int64, error) {
request := message.BranchRegisterRequest{
Xid: param.Xid,
@@ -98,7 +95,7 @@ func (r *RMRemoting) LockQuery(param LockQueryParam) (bool, error) {
func (r *RMRemoting) RegisterResource(resource Resource) error {
req := message.RegisterRMRequest{
AbstractIdentifyRequest: message.AbstractIdentifyRequest{
//todo replace with config
// todo replace with config
Version: "1.5.2",
ApplicationId: "tcc-sample",
TransactionServiceGroup: "my_test_tx_group",


+ 2
- 2
pkg/rm/tcc/fence/fence_api.go View File

@@ -22,11 +22,11 @@ import (
"database/sql"
"fmt"

"github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/rm/tcc/fence/enum"
"github.com/seata/seata-go/pkg/rm/tcc/fence/handler"
"github.com/seata/seata-go/pkg/tm"
"github.com/seata/seata-go/pkg/util/errors"
"github.com/seata/seata-go/pkg/util/log"
)

// WithFence This method is a suspended API interface that asserts the phase timing of a transaction


+ 1
- 1
pkg/rm/tcc/fence/fence_api_test.go View File

@@ -23,7 +23,7 @@ import (
"fmt"
"testing"

"github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/util/errors"

"github.com/DATA-DOG/go-sqlmock"
"github.com/stretchr/testify/assert"


+ 2
- 3
pkg/rm/tcc/fence/handler/tcc_fence_wrapper_handler.go View File

@@ -25,12 +25,12 @@ import (
"sync"
"time"

seataErrors "github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/rm/tcc/fence/enum"
"github.com/seata/seata-go/pkg/rm/tcc/fence/store/db/dao"
"github.com/seata/seata-go/pkg/rm/tcc/fence/store/db/model"
"github.com/seata/seata-go/pkg/tm"
seataErrors "github.com/seata/seata-go/pkg/util/errors"
"github.com/seata/seata-go/pkg/util/log"
)

type tccFenceWrapperHandler struct {
@@ -138,7 +138,6 @@ func (handler *tccFenceWrapperHandler) RollbackFence(ctx context.Context, tx *sq
branchId := tm.GetBusinessActionContext(ctx).BranchId
actionName := tm.GetBusinessActionContext(ctx).ActionName
fenceDo, err := handler.tccFenceDao.QueryTCCFenceDO(tx, xid, branchId)

if err != nil {
return seataErrors.NewTccFenceError(seataErrors.RollbackFenceError,
fmt.Sprintf(" rollback fence method failed. xid= %s, branchId= %d ", xid, branchId),


+ 1
- 2
pkg/rm/tcc/fence/store/db/dao/tcc_fence_db.go View File

@@ -26,10 +26,10 @@ import (

"github.com/go-sql-driver/mysql"

"github.com/seata/seata-go/pkg/common/errors"
"github.com/seata/seata-go/pkg/rm/tcc/fence/enum"
"github.com/seata/seata-go/pkg/rm/tcc/fence/store/db/model"
sql2 "github.com/seata/seata-go/pkg/rm/tcc/fence/store/db/sql"
"github.com/seata/seata-go/pkg/util/errors"
)

var (
@@ -45,7 +45,6 @@ func GetTccFenceStoreDatabaseMapper() *TccFenceStoreDatabaseMapper {
})
}
return tccFenceStoreDatabaseMapper

}

func (t *TccFenceStoreDatabaseMapper) InitLogTableName() {


+ 0
- 1
pkg/rm/tcc/fence/store/db/dao/tcc_fence_db_test.go View File

@@ -49,7 +49,6 @@ func TestTccFenceStoreDatabaseMapper_InsertTCCFenceDO(t *testing.T) {
Status: enum.StatusSuspended,
}
db, mock, err := sqlmock.New(sqlmock.QueryMatcherOption(sqlmock.QueryMatcherEqual))

if err != nil {
t.Fatalf("open db failed msg: %v", err)
}


+ 0
- 2
pkg/rm/tcc/fence/store/db/sql/tcc_fence_store_sql.go View File

@@ -46,7 +46,6 @@ var (

func GetInsertLocalTCCLogSQL(localTccTable string) string {
return fmt.Sprintf(insertLocalTccLog, localTccTable)

}

func GetQuerySQLByBranchIdAndXid(localTccTable string) string {
@@ -59,7 +58,6 @@ func GetUpdateStatusSQLByBranchIdAndXid(localTccTable string) string {

func GetDeleteSQLByBranchIdAndXid(localTccTable string) string {
return fmt.Sprintf(deleteByBranchIdAndXid, localTccTable)

}

func GetDeleteSQLByMdfDateAndStatus(localTccTable string) string {


+ 6
- 6
pkg/rm/tcc/tcc_resource.go View File

@@ -23,12 +23,12 @@ import (
"fmt"
"sync"

"github.com/seata/seata-go/pkg/common"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/constant"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/rm"
"github.com/seata/seata-go/pkg/rm/tcc/fence/enum"
"github.com/seata/seata-go/pkg/tm"
"github.com/seata/seata-go/pkg/util/log"
)

var (
@@ -102,12 +102,12 @@ func (t *TCCResourceManager) BranchReport(ctx context.Context, param rm.BranchRe

// LockQuery query lock status of transaction branch
func (t *TCCResourceManager) LockQuery(ctx context.Context, param rm.LockQueryParam) (bool, error) {
//TODO implement me
// TODO implement me
panic("implement me")
}

func (t *TCCResourceManager) UnregisterResource(resource rm.Resource) error {
//TODO implement me
// TODO implement me
panic("implement me")
}

@@ -149,13 +149,13 @@ func (t *TCCResourceManager) BranchCommit(ctx context.Context, branchResource rm
}

func (t *TCCResourceManager) getBusinessActionContext(xid string, branchID int64, resourceID string, applicationData []byte) *tm.BusinessActionContext {
var actionContextMap = make(map[string]interface{}, 2)
actionContextMap := make(map[string]interface{}, 2)
if len(applicationData) > 0 {
var tccContext map[string]interface{}
if err := json.Unmarshal(applicationData, &tccContext); err != nil {
panic("application data failed to unmarshl as json")
}
if v, ok := tccContext[common.ActionContext]; ok {
if v, ok := tccContext[constant.ActionContext]; ok {
actionContextMap = v.(map[string]interface{})
}
}


+ 16
- 16
pkg/rm/tcc/tcc_service.go View File

@@ -24,16 +24,16 @@ import (
"sync"
"time"

gostnet "github.com/dubbogo/gost/net"
"github.com/pkg/errors"

"github.com/seata/seata-go/pkg/common"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/common/net"
"github.com/seata/seata-go/pkg/common/types"
"github.com/seata/seata-go/pkg/constant"
"github.com/seata/seata-go/pkg/protocol/branch"
"github.com/seata/seata-go/pkg/rm"
"github.com/seata/seata-go/pkg/rm/tcc/fence/enum"
"github.com/seata/seata-go/pkg/tm"
"github.com/seata/seata-go/pkg/util/log"
"github.com/seata/seata-go/pkg/util/reflectx"
)

type TCCServiceProxy struct {
@@ -73,7 +73,7 @@ func (t *TCCServiceProxy) Reference() string {
if t.referenceName != "" {
return t.referenceName
}
return types.GetReference(t.TCCResource.TwoPhaseAction.GetTwoPhaseService())
return reflectx.GetReference(t.TCCResource.TwoPhaseAction.GetTwoPhaseService())
}

func (t *TCCServiceProxy) Prepare(ctx context.Context, params interface{}) (interface{}, error) {
@@ -104,7 +104,7 @@ func (t *TCCServiceProxy) registeBranch(ctx context.Context, params interface{})
}

applicationData, _ := json.Marshal(map[string]interface{}{
common.ActionContext: actionContext,
constant.ActionContext: actionContext,
})
branchId, err := rm.GetRMRemotingInstance().BranchRegister(rm.BranchRegisterParam{
BranchType: branch.BranchTypeTCC,
@@ -126,12 +126,12 @@ func (t *TCCServiceProxy) registeBranch(ctx context.Context, params interface{})
// initActionContext init action context
func (t *TCCServiceProxy) initActionContext(params interface{}) map[string]interface{} {
actionContext := t.getActionContextParameters(params)
actionContext[common.ActionStartTime] = time.Now().UnixNano() / 1e6
actionContext[common.PrepareMethod] = t.TCCResource.TwoPhaseAction.GetPrepareMethodName()
actionContext[common.CommitMethod] = t.TCCResource.TwoPhaseAction.GetCommitMethodName()
actionContext[common.RollbackMethod] = t.TCCResource.TwoPhaseAction.GetRollbackMethodName()
actionContext[common.ActionName] = t.TCCResource.TwoPhaseAction.GetActionName()
actionContext[common.HostName] = net.GetLocalIp()
actionContext[constant.ActionStartTime] = time.Now().UnixNano() / 1e6
actionContext[constant.PrepareMethod] = t.TCCResource.TwoPhaseAction.GetPrepareMethodName()
actionContext[constant.CommitMethod] = t.TCCResource.TwoPhaseAction.GetCommitMethodName()
actionContext[constant.RollbackMethod] = t.TCCResource.TwoPhaseAction.GetRollbackMethodName()
actionContext[constant.ActionName] = t.TCCResource.TwoPhaseAction.GetActionName()
actionContext[constant.HostName], _ = gostnet.GetLocalIP()
return actionContext
}

@@ -155,7 +155,7 @@ func (t *TCCServiceProxy) getActionContextParameters(params interface{}) map[str
}
structField := typ.Field(i)
// skip ignored field
tagVal, hasTag := structField.Tag.Lookup(common.TccBusinessActionContextParameter)
tagVal, hasTag := structField.Tag.Lookup(constant.TccBusinessActionContextParameter)
if !hasTag || tagVal == `-` || tagVal == "" {
continue
}
@@ -246,8 +246,8 @@ func (t *TCCServiceProxy) GetTransactionInfo() tm.TransactionInfo {
return tm.TransactionInfo{
TimeOut: 10000,
Name: t.GetActionName(),
//Propagation, Propagation
//LockRetryInternal, int64
//LockRetryTimes int64
// Propagation, Propagation
// LockRetryInternal, int64
// LockRetryTimes int64
}
}

+ 35
- 26
pkg/rm/tcc/tcc_service_test.go View File

@@ -27,13 +27,13 @@ import (
"time"

"github.com/agiledragon/gomonkey"
gostnet "github.com/dubbogo/gost/net"
"github.com/seata/seata-go/pkg/constant"
"github.com/stretchr/testify/assert"

"github.com/seata/seata-go/pkg/common"
"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/common/net"
"github.com/seata/seata-go/pkg/rm"
"github.com/seata/seata-go/pkg/tm"
"github.com/seata/seata-go/pkg/util/log"
"github.com/seata/seata-go/sample/tcc/dubbo/client/service"
testdata2 "github.com/seata/seata-go/testdata"
)
@@ -93,15 +93,16 @@ func TestInitActionContext(t *testing.T) {
})
defer p.Reset()
result := testTccServiceProxy.initActionContext(param)
localIp, _ := gostnet.GetLocalIP()
assert.Equal(t, map[string]interface{}{
"addr": "Earth",
"Other": []int8{1, 2, 3},
common.ActionStartTime: now.UnixNano() / 1e6,
common.PrepareMethod: "Prepare",
common.CommitMethod: "Commit",
common.RollbackMethod: "Rollback",
common.ActionName: testdata2.ActionName,
common.HostName: net.GetLocalIp(),
"addr": "Earth",
"Other": []int8{1, 2, 3},
constant.ActionStartTime: now.UnixNano() / 1e6,
constant.PrepareMethod: "Prepare",
constant.CommitMethod: "Commit",
constant.RollbackMethod: "Rollback",
constant.ActionName: testdata2.ActionName,
constant.HostName: localIp,
}, result)
}

@@ -130,7 +131,7 @@ func TestGetActionContextParameters(t *testing.T) {
}

func TestGetOrCreateBusinessActionContext(t *testing.T) {
var tests = []struct {
tests := []struct {
param interface{}
want tm.BusinessActionContext
}{
@@ -151,7 +152,8 @@ func TestGetOrCreateBusinessActionContext(t *testing.T) {
"age": 12,
},
},
}, {
},
{
param: &tm.BusinessActionContext{
ActionContext: map[string]interface{}{
"name": "Jack",
@@ -164,7 +166,8 @@ func TestGetOrCreateBusinessActionContext(t *testing.T) {
"age": 13,
},
},
}, {
},
{
param: struct {
Context *tm.BusinessActionContext
}{
@@ -250,17 +253,23 @@ func TestNewTCCServiceProxy(t *testing.T) {
want *TCCServiceProxy
wantErr assert.ErrorAssertionFunc
}{
{"test1", args1, &TCCServiceProxy{
TCCResource: &TCCResource{
ResourceGroupId: `default:"DEFAULT"`,
AppName: "seata-go-mock-app-name",
TwoPhaseAction: twoPhaseAction1}}, assert.NoError,
{
"test1", args1, &TCCServiceProxy{
TCCResource: &TCCResource{
ResourceGroupId: `default:"DEFAULT"`,
AppName: "seata-go-mock-app-name",
TwoPhaseAction: twoPhaseAction1,
},
}, assert.NoError,
},
{"test2", args2, &TCCServiceProxy{
TCCResource: &TCCResource{
ResourceGroupId: `default:"DEFAULT"`,
AppName: "seata-go-mock-app-name",
TwoPhaseAction: twoPhaseAction2}}, assert.NoError,
{
"test2", args2, &TCCServiceProxy{
TCCResource: &TCCResource{
ResourceGroupId: `default:"DEFAULT"`,
AppName: "seata-go-mock-app-name",
TwoPhaseAction: twoPhaseAction2,
},
}, assert.NoError,
},
}

@@ -290,7 +299,8 @@ func TestTCCGetTransactionInfo(t1 *testing.T) {
fields fields
want tm.TransactionInfo
}{
"test1", fields{
"test1",
fields{
referenceName: "test1",
registerResourceOnce: sync.Once{},
TCCResource: &TCCResource{
@@ -310,7 +320,6 @@ func TestTCCGetTransactionInfo(t1 *testing.T) {
}
assert.Equalf(t1, tests.want, t.GetTransactionInfo(), "GetTransactionInfo()")
})

}

func GetTestTwoPhaseService() rm.TwoPhaseInterface {


+ 0
- 1
pkg/rm/two_phase.go View File

@@ -266,7 +266,6 @@ func getCommitMethod(t reflect.StructField, f reflect.Value) (string, *reflect.V
return "", nil, false
}
return t.Name, &f, true

}

func getRollbackMethod(t reflect.StructField, f reflect.Value) (string, *reflect.Value, bool) {


+ 1
- 6
pkg/rm/two_phase_test.go View File

@@ -174,8 +174,7 @@ func TestParseTwoPhaseActionExecuteMethod1(t *testing.T) {
assert.Equal(t, "twoPhaseDemoService", twoPhaseService.GetActionName())
}

type TwoPhaseDemoService2 struct {
}
type TwoPhaseDemoService2 struct{}

func (t *TwoPhaseDemoService2) Prepare(ctx context.Context, params interface{}) (bool, error) {
return false, fmt.Errorf("execute two phase prepare method, param %v", params)
@@ -211,7 +210,6 @@ func TestParseTwoPhaseActionExecuteMethod2(t *testing.T) {
}

func TestIsTwoPhaseAction(t *testing.T) {

userProvider := &testdata2.TestTwoPhaseService{}
userProvider1 := service.UserProviderInstance
type args struct {
@@ -232,11 +230,9 @@ func TestIsTwoPhaseAction(t *testing.T) {
assert.Equalf(t, tt.want, IsTwoPhaseAction(tt.args.v), "IsTwoPhaseAction(%v)", tt.args.v)
})
}

}

func TestParseTwoPhaseAction(t *testing.T) {

type args struct {
v interface{}
}
@@ -259,7 +255,6 @@ func TestParseTwoPhaseAction(t *testing.T) {
}
assert.Equalf(t, tests.want.GetTwoPhaseService(), got.GetTwoPhaseService(), "ParseTwoPhaseAction(%v)", tests.args.v)
})

}

func TestParseTwoPhaseActionByInterface(t *testing.T) {


+ 4
- 5
pkg/tm/global_transaction.go View File

@@ -25,10 +25,10 @@ import (

"github.com/pkg/errors"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/remoting/getty"
"github.com/seata/seata-go/pkg/util/backoff"
"github.com/seata/seata-go/pkg/util/log"
)

type GlobalTransaction struct {
@@ -52,8 +52,7 @@ func GetGlobalTransactionManager() *GlobalTransactionManager {
return globalTransactionManager
}

type GlobalTransactionManager struct {
}
type GlobalTransactionManager struct{}

// Begin a new global transaction with given timeout and given name.
func (g *GlobalTransactionManager) Begin(ctx context.Context, gtr *GlobalTransaction, timeout time.Duration, name string) error {
@@ -103,7 +102,7 @@ func (g *GlobalTransactionManager) Commit(ctx context.Context, gtr *GlobalTransa
MaxBackoff: 200 * time.Millisecond,
})

var req = message.GlobalCommitRequest{
req := message.GlobalCommitRequest{
AbstractGlobalEndRequest: message.AbstractGlobalEndRequest{Xid: gtr.Xid},
}
var res interface{}
@@ -146,7 +145,7 @@ func (g *GlobalTransactionManager) Rollback(ctx context.Context, gtr *GlobalTran
})

var res interface{}
var req = message.GlobalRollbackRequest{
req := message.GlobalRollbackRequest{
AbstractGlobalEndRequest: message.AbstractGlobalEndRequest{Xid: gtr.Xid},
}



+ 1
- 1
pkg/tm/global_transaction_test.go View File

@@ -128,7 +128,7 @@ func TestBegin(t *testing.T) {
assert.Nil(t, err)
}

//reset up stub
// reset up stub
if v.wantHasMock {
stub.Reset()
}


+ 1
- 1
pkg/tm/transaction_executor.go View File

@@ -24,8 +24,8 @@ import (

"github.com/pkg/errors"

"github.com/seata/seata-go/pkg/common/log"
"github.com/seata/seata-go/pkg/protocol/message"
"github.com/seata/seata-go/pkg/util/log"
)

type TransactionInfo struct {


pkg/common/bytes/buf.go → pkg/util/bytes/buf.go View File


pkg/common/bytes/buf_helper.go → pkg/util/bytes/buf_helper.go View File


pkg/common/bytes/buf_helper_test.go → pkg/util/bytes/buf_helper_test.go View File


pkg/common/bytes/buf_test.go → pkg/util/bytes/buf_test.go View File


pkg/common/errors/error.go → pkg/util/errors/error.go View File


pkg/common/errors/error_code.go → pkg/util/errors/error_code.go View File


+ 119
- 0
pkg/util/fanout/fanout.go View File

@@ -0,0 +1,119 @@
package fanout

import (
"context"
"log"
"runtime"
"sync"
)

type options struct {
worker int
buffer int
}

// Option is fanout option.
type Option func(*options)

// WithWorker with the worker of fanout.
func WithWorker(n int) Option {
return func(o *options) {
o.worker = n
}
}

// WithBuffer with the buffer of fanout.
func WithBuffer(n int) Option {
return func(o *options) {
o.buffer = n
}
}

type item struct {
f func(c context.Context)
ctx context.Context
}

// Fanout async consume data from chan.
type Fanout struct {
name string
ch chan item
options *options
waiter sync.WaitGroup

ctx context.Context
cancel func()
}

// New new a fanout struct.
func New(name string, opts ...Option) *Fanout {
if name == "" {
name = "anonymous"
}
o := &options{
worker: 1,
buffer: 1000,
}
for _, op := range opts {
op(o)
}
c := &Fanout{
ch: make(chan item, o.buffer),
name: name,
options: o,
}
c.ctx, c.cancel = context.WithCancel(context.Background())
c.waiter.Add(o.worker)
for i := 0; i < o.worker; i++ {
go c.proc()
}
return c
}

func (c *Fanout) proc() {
defer c.waiter.Done()
for {
select {
case t := <-c.ch:
wrapFunc(t.f)(t.ctx)
case <-c.ctx.Done():
return
}
}
}

func wrapFunc(f func(c context.Context)) (res func(context.Context)) {
return func(ctx context.Context) {
defer func() {
if r := recover(); r != nil {
buf := make([]byte, 64*1024)
buf = buf[:runtime.Stack(buf, false)]
log.Printf("panic in fanout proc, err: %s, stack: %s\n", r, buf)
}
}()
f(ctx)
}
}

// Do save a callback func.
func (c *Fanout) Do(ctx context.Context, f func(ctx context.Context)) error {
if f == nil || c.ctx.Err() != nil {
return c.ctx.Err()
}
select {
case c.ch <- item{f: f, ctx: ctx}:
case <-ctx.Done():
return ctx.Err()
}
return nil
}

// Close close fanout.
func (c *Fanout) Close() error {
if err := c.ctx.Err(); err != nil {
return err
}
c.cancel()
c.waiter.Wait()
return nil
}

+ 30
- 0
pkg/util/fanout/fanout_test.go View File

@@ -0,0 +1,30 @@
package fanout

import (
"context"
"testing"
"time"
)

func TestFanout_Do(t *testing.T) {
ca := New("cache", WithWorker(1), WithBuffer(1024))
var run bool
ca.Do(context.Background(), func(c context.Context) {
run = true
panic("error")
})
time.Sleep(time.Millisecond * 50)
t.Log("not panic")
if !run {
t.Fatal("expect run be true")
}
}

func TestFanout_Close(t *testing.T) {
ca := New("cache", WithWorker(1), WithBuffer(1024))
ca.Close()
err := ca.Do(context.Background(), func(c context.Context) {})
if err == nil {
t.Fatal("expect get err")
}
}

+ 99
- 0
pkg/util/flagext/cidr.go View File

@@ -0,0 +1,99 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flagext

import (
"net"
"strings"

"github.com/pkg/errors"
)

// CIDR is a network CIDR.
type CIDR struct {
Value *net.IPNet
}

// String implements flag.Value.
func (c CIDR) String() string {
if c.Value == nil {
return ""
}
return c.Value.String()
}

// Set implements flag.Value.
func (c *CIDR) Set(s string) error {
_, value, err := net.ParseCIDR(s)
if err != nil {
return err
}
c.Value = value
return nil
}

// CIDRSliceCSV is a slice of CIDRs that is parsed from a comma-separated string.
// It implements flag.Value and yaml Marshalers.
type CIDRSliceCSV []CIDR

// String implements flag.Value
func (c CIDRSliceCSV) String() string {
values := make([]string, 0, len(c))
for _, cidr := range c {
values = append(values, cidr.String())
}

return strings.Join(values, ",")
}

// Set implements flag.Value
func (c *CIDRSliceCSV) Set(s string) error {
parts := strings.Split(s, ",")

for _, part := range parts {
cidr := &CIDR{}
if err := cidr.Set(part); err != nil {
return errors.Wrapf(err, "cidr: %s", part)
}

*c = append(*c, *cidr)
}

return nil
}

// UnmarshalYAML implements yaml.Unmarshaler.
func (c *CIDRSliceCSV) UnmarshalYAML(unmarshal func(interface{}) error) error {
var s string
if err := unmarshal(&s); err != nil {
return err
}

// An empty string means no CIDRs has been configured.
if s == "" {
*c = nil
return nil
}

return c.Set(s)
}

// MarshalYAML implements yaml.Marshaler.
func (c CIDRSliceCSV) MarshalYAML() (interface{}, error) {
return c.String(), nil
}

+ 68
- 0
pkg/util/flagext/cidr_test.go View File

@@ -0,0 +1,68 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flagext

import (
"testing"

"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v2"
)

func Test_CIDRSliceCSV_YamlMarshaling(t *testing.T) {
type TestStruct struct {
CIDRs CIDRSliceCSV `yaml:"cidrs"`
}

tests := map[string]struct {
input string
expected []string
}{
"should marshal empty config": {
input: "cidrs: \"\"\n",
expected: nil,
},
"should marshal single value": {
input: "cidrs: 127.0.0.1/32\n",
expected: []string{"127.0.0.1/32"},
},
"should marshal multiple comma-separated values": {
input: "cidrs: 127.0.0.1/32,10.0.10.0/28,fdf8:f53b:82e4::/100,192.168.0.0/20\n",
expected: []string{"127.0.0.1/32", "10.0.10.0/28", "fdf8:f53b:82e4::/100", "192.168.0.0/20"},
},
}

for name, tc := range tests {
t.Run(name, func(t *testing.T) {
// Unmarshal.
actual := TestStruct{}
err := yaml.Unmarshal([]byte(tc.input), &actual)
assert.NoError(t, err)

assert.Len(t, actual.CIDRs, len(tc.expected))
for idx, cidr := range actual.CIDRs {
assert.Equal(t, tc.expected[idx], cidr.String())
}

// Marshal.
out, err := yaml.Marshal(actual)
assert.NoError(t, err)
assert.Equal(t, tc.input, string(out))
})
}
}

+ 76
- 0
pkg/util/flagext/day.go View File

@@ -0,0 +1,76 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flagext

import (
"time"

"github.com/prometheus/common/model"
)

const secondsInDay = 24 * 60 * 60

// DayValue is a model.Time that can be used as a flag.
// NB it only parses days!
type DayValue struct {
model.Time
set bool
}

// NewDayValue makes a new DayValue; will round t down to the nearest midnight.
func NewDayValue(t model.Time) DayValue {
return DayValue{
Time: model.TimeFromUnix((t.Unix() / secondsInDay) * secondsInDay),
set: true,
}
}

// String implements flag.Value
func (v DayValue) String() string {
return v.Time.Time().Format(time.RFC3339)
}

// Set implements flag.Value
func (v *DayValue) Set(s string) error {
t, err := time.Parse("2006-01-02", s)
if err != nil {
return err
}
v.Time = model.TimeFromUnix(t.Unix())
v.set = true
return nil
}

// IsSet returns true is the DayValue has been set.
func (v *DayValue) IsSet() bool {
return v.set
}

// UnmarshalYAML implements yaml.Unmarshaler.
func (v *DayValue) UnmarshalYAML(unmarshal func(interface{}) error) error {
var s string
if err := unmarshal(&s); err != nil {
return err
}
return v.Set(s)
}

// MarshalYAML implements yaml.Marshaler.
func (v DayValue) MarshalYAML() (interface{}, error) {
return v.Time.Time().Format("2006-01-02"), nil
}

+ 71
- 0
pkg/util/flagext/day_test.go View File

@@ -0,0 +1,71 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flagext

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
)

func TestDayValueYAML(t *testing.T) {
// Test embedding of DayValue.
{
type TestStruct struct {
Day DayValue `yaml:"day"`
}

var testStruct TestStruct
require.NoError(t, testStruct.Day.Set("1985-06-02"))
expected := []byte(`day: "1985-06-02"
`)

actual, err := yaml.Marshal(testStruct)
require.NoError(t, err)
assert.Equal(t, expected, actual)

var actualStruct TestStruct
err = yaml.Unmarshal(expected, &actualStruct)
require.NoError(t, err)
assert.Equal(t, testStruct, actualStruct)
}

// Test pointers of DayValue.
{
type TestStruct struct {
Day *DayValue `yaml:"day"`
}

var testStruct TestStruct
testStruct.Day = &DayValue{}
require.NoError(t, testStruct.Day.Set("1985-06-02"))
expected := []byte(`day: "1985-06-02"
`)

actual, err := yaml.Marshal(testStruct)
require.NoError(t, err)
assert.Equal(t, expected, actual)

var actualStruct TestStruct
err = yaml.Unmarshal(expected, &actualStruct)
require.NoError(t, err)
assert.Equal(t, testStruct, actualStruct)
}
}

+ 54
- 0
pkg/util/flagext/deprecated.go View File

@@ -0,0 +1,54 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flagext

import (
"flag"

"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"

"github.com/seata/seata-go/pkg/util/log"
)

// DeprecatedFlagsUsed is the metric that counts deprecated flags set.
var DeprecatedFlagsUsed = promauto.NewCounter(
prometheus.CounterOpts{
Namespace: "cortex",
Name: "deprecated_flags_inuse_total",
Help: "The number of deprecated flags currently set.",
})

type deprecatedFlag struct {
name string
}

func (deprecatedFlag) String() string {
return "deprecated"
}

func (d deprecatedFlag) Set(string) error {
log.Infof("msg", "flag disabled", "flag", d.name)
DeprecatedFlagsUsed.Inc()
return nil
}

// DeprecatedFlag logs a warning when you try to use it.
func DeprecatedFlag(f *flag.FlagSet, name, message string) {
f.Var(deprecatedFlag{name}, name, message)
}

pkg/common/runtime/goroutine.go → pkg/util/flagext/ignored.go View File

@@ -15,4 +15,25 @@
* limitations under the License.
*/

package runtime
package flagext

import (
"flag"
)

type ignoredFlag struct {
name string
}

func (ignoredFlag) String() string {
return "ignored"
}

func (d ignoredFlag) Set(string) error {
return nil
}

// IgnoredFlag ignores set value, without any warning
func IgnoredFlag(f *flag.FlagSet, name, message string) {
f.Var(ignoredFlag{name}, name, message)
}

pkg/common/util/slice_to_str.go → pkg/util/flagext/register.go View File

@@ -15,27 +15,27 @@
* limitations under the License.
*/

package util
package flagext

import (
"errors"
"strconv"
"strings"
)
import "flag"

// Int64Slice2Str
func Int64Slice2Str(values interface{}, sep string) (string, error) {
v, ok := values.([]int64)
if !ok {
return "", errors.New("param type is fault")
}

var valuesText []string
// Registerer is a thing that can RegisterFlags
type Registerer interface {
RegisterFlags(*flag.FlagSet)
}

for i := range v {
text := strconv.FormatInt(v[i], 10)
valuesText = append(valuesText, text)
// RegisterFlags registers flags with the provided Registerers
func RegisterFlags(rs ...Registerer) {
for _, r := range rs {
r.RegisterFlags(flag.CommandLine)
}
}

return strings.Join(valuesText, sep), nil
// DefaultValues initiates a set of configs (Registerers) with their defaults.
func DefaultValues(rs ...Registerer) {
fs := flag.NewFlagSet("", flag.PanicOnError)
for _, r := range rs {
r.RegisterFlags(fs)
}
_ = fs.Parse([]string{})
}

+ 51
- 0
pkg/util/flagext/secret.go View File

@@ -0,0 +1,51 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flagext

type Secret struct {
Value string
}

// String implements flag.Value
func (v Secret) String() string {
return v.Value
}

// Set implements flag.Value
func (v *Secret) Set(s string) error {
v.Value = s
return nil
}

// UnmarshalYAML implements yaml.Unmarshaler.
func (v *Secret) UnmarshalYAML(unmarshal func(interface{}) error) error {
var s string
if err := unmarshal(&s); err != nil {
return err
}

return v.Set(s)
}

// MarshalYAML implements yaml.Marshaler.
func (v Secret) MarshalYAML() (interface{}, error) {
if len(v.Value) == 0 {
return "", nil
}
return "********", nil
}

+ 94
- 0
pkg/util/flagext/secret_test.go View File

@@ -0,0 +1,94 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package flagext

import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v2"
)

func TestSecretdYAML(t *testing.T) {
// Test embedding of Secret.
{
type TestStruct struct {
Secret Secret `yaml:"secret"`
}

var testStruct TestStruct
require.NoError(t, testStruct.Secret.Set("pa55w0rd"))
expected := []byte(`secret: '********'
`)

actual, err := yaml.Marshal(testStruct)
require.NoError(t, err)
assert.Equal(t, expected, actual)

var actualStruct TestStruct
yamlSecret := []byte(`secret: pa55w0rd
`)
err = yaml.Unmarshal(yamlSecret, &actualStruct)
require.NoError(t, err)
assert.Equal(t, testStruct, actualStruct)
}

// Test pointers of Secret.
{
type TestStruct struct {
Secret *Secret `yaml:"secret"`
}

var testStruct TestStruct
testStruct.Secret = &Secret{}
require.NoError(t, testStruct.Secret.Set("pa55w0rd"))
expected := []byte(`secret: '********'
`)

actual, err := yaml.Marshal(testStruct)
require.NoError(t, err)
assert.Equal(t, expected, actual)

var actualStruct TestStruct
yamlSecret := []byte(`secret: pa55w0rd
`)
err = yaml.Unmarshal(yamlSecret, &actualStruct)
require.NoError(t, err)
assert.Equal(t, testStruct, actualStruct)
}

// Test no value set in Secret.
{
type TestStruct struct {
Secret Secret `yaml:"secret"`
}
var testStruct TestStruct
expected := []byte(`secret: ""
`)

actual, err := yaml.Marshal(testStruct)
require.NoError(t, err)
assert.Equal(t, expected, actual)

var actualStruct TestStruct
err = yaml.Unmarshal(expected, &actualStruct)
require.NoError(t, err)
assert.Equal(t, testStruct, actualStruct)
}
}

pkg/common/net/net_utils.go → pkg/util/flagext/stringslice.go View File

@@ -15,9 +15,20 @@
* limitations under the License.
*/

package net
package flagext

func GetLocalIp() string {
// todo
return "127.0.0.1"
import "fmt"

// StringSlice is a slice of strings that implements flag.Value
type StringSlice []string

// String implements flag.Value
func (v StringSlice) String() string {
return fmt.Sprintf("%s", []string(v))
}

// Set implements flag.Value
func (v *StringSlice) Set(s string) error {
*v = append(*v, s)
return nil
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save