forked from hashicorp/consul
-
Notifications
You must be signed in to change notification settings - Fork 0
/
txn.go
169 lines (141 loc) · 4.51 KB
/
txn.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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package structs
import (
"errors"
"fmt"
"github.com/hernad/consul/api"
multierror "github.com/hashicorp/go-multierror"
)
// TxnKVOp is used to define a single operation on the KVS inside a
// transaction.
type TxnKVOp struct {
Verb api.KVOp
DirEnt DirEntry
}
// TxnKVResult is used to define the result of a single operation on the KVS
// inside a transaction.
type TxnKVResult *DirEntry
// TxnNodeOp is used to define a single operation on a node in the catalog inside
// a transaction.
type TxnNodeOp struct {
Verb api.NodeOp
Node Node
}
// TxnNodeResult is used to define the result of a single operation on a node
// in the catalog inside a transaction.
type TxnNodeResult *Node
// TxnServiceOp is used to define a single operation on a service in the catalog inside
// a transaction.
type TxnServiceOp struct {
Verb api.ServiceOp
Node string
Service NodeService
}
// TxnServiceResult is used to define the result of a single operation on a service
// in the catalog inside a transaction.
type TxnServiceResult *NodeService
// TxnCheckOp is used to define a single operation on a health check inside a
// transaction.
type TxnCheckOp struct {
Verb api.CheckOp
Check HealthCheck
}
// TxnCheckResult is used to define the result of a single operation on a
// session inside a transaction.
type TxnCheckResult *HealthCheck
// TxnSessionOp is used to define a single operation on a session inside a
// transaction.
type TxnSessionOp struct {
Verb api.SessionOp
Session Session
}
// TxnIntentionOp is used to define a single operation on an Intention inside a
// transaction.
//
// Deprecated: see TxnOp.Intention description
type TxnIntentionOp IntentionRequest
// TxnOp is used to define a single operation inside a transaction. Only one
// of the types should be filled out per entry.
type TxnOp struct {
KV *TxnKVOp
Node *TxnNodeOp
Service *TxnServiceOp
Check *TxnCheckOp
Session *TxnSessionOp
// Intention was an internal-only (not exposed in API or RPC)
// implementation detail of legacy intention replication. This is
// deprecated but retained for backwards compatibility with versions
// of consul pre-dating 1.9.0. We need it for two reasons:
//
// 1. If a secondary DC is upgraded first, we need to continue to
// replicate legacy intentions UNTIL the primary DC is upgraded.
// Legacy intention replication exclusively writes using a TxnOp.
// 2. If we attempt to reprocess raft-log contents pre-dating 1.9.0
// (such as when updating a secondary DC) we need to be able to
// recreate the state machine from the snapshot and whatever raft logs are
// present.
Intention *TxnIntentionOp
}
// TxnOps is a list of operations within a transaction.
type TxnOps []*TxnOp
// TxnRequest is used to apply multiple operations to the state store in a
// single transaction
type TxnRequest struct {
Datacenter string
Ops TxnOps
WriteRequest
}
func (r *TxnRequest) RequestDatacenter() string {
return r.Datacenter
}
// TxnReadRequest is used as a fast path for read-only transactions that don't
// modify the state store.
type TxnReadRequest struct {
Datacenter string
Ops TxnOps
QueryOptions
}
func (r *TxnReadRequest) RequestDatacenter() string {
return r.Datacenter
}
// TxnError is used to return information about an error for a specific
// operation.
type TxnError struct {
OpIndex int
What string
}
// Error returns the string representation of an atomic error.
func (e TxnError) Error() string {
return fmt.Sprintf("op %d: %s", e.OpIndex, e.What)
}
// TxnErrors is a list of TxnError entries.
type TxnErrors []*TxnError
// TxnResult is used to define the result of a given operation inside a
// transaction. Only one of the types should be filled out per entry.
type TxnResult struct {
KV TxnKVResult `json:",omitempty"`
Node TxnNodeResult `json:",omitempty"`
Service TxnServiceResult `json:",omitempty"`
Check TxnCheckResult `json:",omitempty"`
}
// TxnResults is a list of TxnResult entries.
type TxnResults []*TxnResult
// TxnResponse is the structure returned by a TxnRequest.
type TxnResponse struct {
Results TxnResults
Errors TxnErrors
}
// Error returns an aggregate of all errors in this TxnResponse.
func (r TxnResponse) Error() error {
var errs error
for _, err := range r.Errors {
errs = multierror.Append(errs, errors.New(err.Error()))
}
return errs
}
// TxnReadResponse is the structure returned by a TxnReadRequest.
type TxnReadResponse struct {
TxnResponse
QueryMeta
}