go-transaction-manager

Форк
0
124 строки · 2.9 Кб
1
package manager
2

3
import (
4
	"context"
5

6
	"github.com/avito-tech/go-transaction-manager/trm/v2"
7
)
8

9
// ChainedMW starts transactions in the order given and commit/rollback in reverse order.
10
//
11
// WARNING: Rollback of last transactions isn't affected done commits.
12
// ChainedMW should be only used if the application can tolerate or
13
// recover from an inconsistent state caused by partially committed transactions.
14
type ChainedMW struct {
15
	do             nextDo
16
	doWithSettings nextDoWithSettings
17
}
18

19
// NewChained creates *ChainedMW or chained trm.Manager.
20
func NewChained(mm []trm.Manager, _ ...Opt) (*ChainedMW, error) {
21
	if len(mm) == 0 {
22
		return &ChainedMW{
23
			do:             nilNextDo,
24
			doWithSettings: nilNextDoWithSettings,
25
		}, nil
26
	}
27

28
	last := len(mm) - 1
29
	do := newLastDo(mm[last])
30
	doWithSettings := newLastDoWithSettings(mm[last])
31

32
	for index := last - 1; index >= 0; index-- {
33
		do = newNextDo(mm[index], do)
34
		doWithSettings = newNextDoWithSettings(mm[index], doWithSettings)
35
	}
36

37
	return &ChainedMW{
38
		do:             do,
39
		doWithSettings: doWithSettings,
40
	}, nil
41
}
42

43
// MustChained returns ChainedMW if err is nil and panics otherwise.
44
func MustChained(mm []trm.Manager, oo ...Opt) *ChainedMW {
45
	s, err := NewChained(mm, oo...)
46
	if err != nil {
47
		panic(err)
48
	}
49

50
	return s
51
}
52

53
//revive:disable:exported
54
func (c *ChainedMW) Do(
55
	ctx context.Context,
56
	fn func(ctx context.Context) error,
57
) error {
58
	return c.do(ctx, fn)
59
}
60

61
type callback func(ctx context.Context) error
62

63
type nextDo func(ctx context.Context, fn callback) error
64

65
func nilNextDo(ctx context.Context, fn callback) error {
66
	return fn(ctx)
67
}
68

69
func newNextDo(m trm.Manager, n nextDo) nextDo {
70
	return func(ctx context.Context, fn callback) error {
71
		return m.Do(ctx, func(ctx context.Context) error {
72
			return n(ctx, fn)
73
		})
74
	}
75
}
76

77
func newLastDo(m trm.Manager) nextDo {
78
	return func(ctx context.Context, fn callback) error {
79
		return m.Do(ctx, fn)
80
	}
81
}
82

83
// DoWithSettings is an implementation of trm.Manager.
84
//
85
// WARNING: trm.CtxKey should not be set in trm.Settings otherwise all trm.Manager would get same trm.Transaction from context.Context.
86
func (c *ChainedMW) DoWithSettings(
87
	ctx context.Context,
88
	s trm.Settings,
89
	fn func(ctx context.Context) error,
90
) error {
91
	return c.doWithSettings(ctx, s, fn)
92
}
93

94
type nextDoWithSettings func(context.Context, trm.Settings, callback) error
95

96
func nilNextDoWithSettings(
97
	ctx context.Context,
98
	_ trm.Settings,
99
	fn callback,
100
) error {
101
	return fn(ctx)
102
}
103

104
func newNextDoWithSettings(m trm.Manager, n nextDoWithSettings) nextDoWithSettings {
105
	return func(
106
		ctx context.Context,
107
		s trm.Settings,
108
		fn callback,
109
	) error {
110
		return m.DoWithSettings(ctx, s, func(ctx context.Context) error {
111
			return n(ctx, s, fn)
112
		})
113
	}
114
}
115

116
func newLastDoWithSettings(m trm.Manager) nextDoWithSettings {
117
	return func(
118
		ctx context.Context,
119
		s trm.Settings,
120
		fn callback,
121
	) error {
122
		return m.DoWithSettings(ctx, s, fn)
123
	}
124
}
125

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.