Skip to content

Commit 0bfe4dc

Browse files
committed
fix: now dsl.Execute() rolls back when error occurred
And now TrxIDKey is not included in context.
1 parent 102ab7b commit 0bfe4dc

File tree

2 files changed

+82
-54
lines changed

2 files changed

+82
-54
lines changed

dsl/dslctx/dslctx.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package dslctx
2+
3+
import (
4+
"context"
5+
"errors"
6+
7+
"github.com/vim-volt/volt/config"
8+
"github.com/vim-volt/volt/lockjson"
9+
)
10+
11+
// KeyType is the type of the key of context specified for Execute()
12+
type KeyType uint
13+
14+
const (
15+
// TrxIDKey is the key to get transaction ID
16+
TrxIDKey KeyType = iota
17+
// LockJSONKey is the key to get *lockjson.LockJSON value
18+
LockJSONKey
19+
// ConfigKey is the key to get *config.Config value
20+
ConfigKey
21+
)
22+
23+
// WithDSLValues adds given values
24+
func WithDSLValues(ctx context.Context, lockJSON *lockjson.LockJSON, cfg *config.Config) context.Context {
25+
ctx = context.WithValue(ctx, LockJSONKey, lockJSON)
26+
ctx = context.WithValue(ctx, ConfigKey, cfg)
27+
return ctx
28+
}
29+
30+
// Validate validates if required keys exist in ctx
31+
func Validate(ctx context.Context) error {
32+
for _, required := range []struct {
33+
key KeyType
34+
validate func(interface{}) error
35+
}{
36+
{LockJSONKey, validateLockJSON},
37+
{ConfigKey, validateConfig},
38+
} {
39+
if err := required.validate(ctx.Value(required.key)); err != nil {
40+
return err
41+
}
42+
}
43+
return nil
44+
}
45+
46+
func validateLockJSON(v interface{}) error {
47+
if v == nil {
48+
return errors.New("no lock.json key in context")
49+
}
50+
if _, ok := v.(*lockjson.LockJSON); !ok {
51+
return errors.New("invalid lock.json data in context")
52+
}
53+
return nil
54+
}
55+
56+
func validateConfig(v interface{}) error {
57+
if v == nil {
58+
return errors.New("no config.toml key in context")
59+
}
60+
if _, ok := v.(*config.Config); !ok {
61+
return errors.New("invalid config.toml data in context")
62+
}
63+
return nil
64+
}

dsl/execute.go

Lines changed: 18 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4,68 +4,32 @@ import (
44
"context"
55

66
"github.com/pkg/errors"
7-
"github.com/vim-volt/volt/config"
8-
"github.com/vim-volt/volt/dsl/ops"
7+
"github.com/vim-volt/volt/dsl/dslctx"
98
"github.com/vim-volt/volt/dsl/types"
10-
"github.com/vim-volt/volt/lockjson"
119
"github.com/vim-volt/volt/transaction"
1210
)
1311

14-
// CtxKeyType is the type of the key of context specified for Execute()
15-
type CtxKeyType uint
16-
17-
const (
18-
// CtxTrxIDKey is the key to get transaction ID
19-
CtxTrxIDKey CtxKeyType = iota
20-
// CtxLockJSONKey is the key to get *lockjson.LockJSON value
21-
CtxLockJSONKey
22-
// CtxConfigKey is the key to get *config.Config value
23-
CtxConfigKey
24-
)
25-
2612
// Execute executes given expr with given ctx.
27-
func Execute(ctx context.Context, expr types.Expr) (val types.Value, rollback func(), err error) {
28-
for _, required := range []struct {
29-
key CtxKeyType
30-
validate func(interface{}) error
31-
}{
32-
{CtxLockJSONKey, validateLockJSON},
33-
{CtxConfigKey, validateConfig},
34-
{CtxTrxIDKey, validateTrxID},
35-
} {
36-
if err := required.validate(ctx.Value(required.key)); err != nil {
37-
return nil, ops.NoRollback, err
38-
}
13+
func Execute(ctx context.Context, expr types.Expr) (_ types.Value, result error) {
14+
if err := dslctx.Validate(ctx); err != nil {
15+
return nil, err
3916
}
40-
return expr.Eval(ctx)
41-
}
4217

43-
func validateLockJSON(v interface{}) error {
44-
if v == nil {
45-
return errors.New("no lock.json key in context")
46-
}
47-
if _, ok := v.(*lockjson.LockJSON); !ok {
48-
return errors.New("invalid lock.json data in context")
18+
// Begin transaction
19+
trx, err := transaction.Start()
20+
if err != nil {
21+
return nil, err
4922
}
50-
return nil
51-
}
52-
53-
func validateConfig(v interface{}) error {
54-
if v == nil {
55-
return errors.New("no config.toml key in context")
56-
}
57-
if _, ok := v.(*config.Config); !ok {
58-
return errors.New("invalid config.toml data in context")
59-
}
60-
return nil
61-
}
23+
defer func() {
24+
if err := trx.Done(); err != nil {
25+
result = err
26+
}
27+
}()
6228

63-
func validateTrxID(v interface{}) error {
64-
if v == nil {
65-
return errors.New("no transaction ID key in context")
66-
}
67-
if _, ok := v.(transaction.TrxID); !ok {
68-
return errors.New("invalid transaction ID data in context")
29+
val, rollback, err := expr.Eval(ctx)
30+
if err != nil {
31+
rollback()
32+
return nil, errors.Wrap(err, "expression returned an error")
6933
}
70-
return nil
34+
return val, nil
7135
}

0 commit comments

Comments
 (0)