-
Notifications
You must be signed in to change notification settings - Fork 3
/
sugar.go
118 lines (97 loc) · 2.84 KB
/
sugar.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
package vshard_router //nolint:revive
import (
"context"
"fmt"
"github.com/tarantool/go-tarantool/v2/pool"
)
// CallRequest helps you to create a call request object for execution
// by a Connection.
type CallRequest struct {
ctx context.Context
fnc string
args interface{}
bucketID uint64
}
// CallResponse is a backwards-compatible structure with go-tarantool for easier replacement.
type CallResponse struct {
rawResp interface{}
getTypedFnc StorageResultTypedFunc
err error
}
// NewCallRequest returns a new empty CallRequest.
func NewCallRequest(function string) *CallRequest {
req := new(CallRequest)
req.fnc = function
return req
}
// Do perform a request synchronously on the connection.
// It is important that the logic of this method is different from go-tarantool.
func (r *Router) Do(req *CallRequest, userMode pool.Mode) *CallResponse {
ctx := req.ctx
bucketID := req.bucketID
resp := new(CallResponse)
if req.fnc == "" {
resp.err = fmt.Errorf("func name is empty")
return resp
}
if req.args == nil {
resp.err = fmt.Errorf("no request args")
return resp
}
if req.bucketID == 0 {
if r.cfg.BucketGetter == nil {
resp.err = fmt.Errorf("bucket id for request is not set")
return resp
}
bucketID = r.cfg.BucketGetter(ctx)
}
vshardMode := ReadMode
// If the user says he prefers to do it on the master,
// then he agrees that it will go to the replica, which means he will not write.
if userMode == pool.RW {
vshardMode = WriteMode
}
resp.rawResp, resp.getTypedFnc, resp.err = r.RouterCallImpl(ctx,
bucketID,
CallOpts{
Timeout: r.cfg.RequestTimeout,
PoolMode: userMode,
VshardMode: vshardMode,
},
req.fnc,
req.args)
return resp
}
// Args sets the args for the eval request.
// Note: default value is empty.
func (req *CallRequest) Args(args interface{}) *CallRequest {
req.args = args
return req
}
// Context sets a passed context to the request.
func (req *CallRequest) Context(ctx context.Context) *CallRequest {
req.ctx = ctx
return req
}
// BucketID method that sets the bucketID for your request.
// You can ignore this parameter if you have a bucketGetter.
// However, this method has a higher priority.
func (req *CallRequest) BucketID(bucketID uint64) *CallRequest {
req.bucketID = bucketID
return req
}
// GetTyped waits synchronously for response and calls msgpack.Decoder.Decode(result) if no error happens.
func (resp *CallResponse) GetTyped(result interface{}) error {
if resp.err != nil {
return resp.err
}
return resp.getTypedFnc(result)
}
// Get implementation now works synchronously for response.
// The interface was created purely for convenient migration to go-vshard-router from go-tarantool.
func (resp *CallResponse) Get() ([]interface{}, error) {
if resp.err != nil {
return nil, resp.err
}
return []interface{}{resp.rawResp}, nil
}