Skip to content

Commit db2f585

Browse files
authored
domin: fix do not marshal RuleOp correctly (#43276) (#43279)
close #43070
1 parent 0291f22 commit db2f585

File tree

3 files changed

+124
-4
lines changed

3 files changed

+124
-4
lines changed

domain/infosync/BUILD.bazel

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ go_test(
6161
srcs = ["info_test.go"],
6262
embed = [":infosync"],
6363
flaky = True,
64-
shard_count = 3,
64+
shard_count = 4,
6565
deps = [
6666
"//ddl/placement",
6767
"//ddl/util",

domain/infosync/info_test.go

+40
Original file line numberDiff line numberDiff line change
@@ -284,3 +284,43 @@ func TestTiFlashManager(t *testing.T) {
284284

285285
CloseTiFlashManager(ctx)
286286
}
287+
288+
func TestRuleOp(t *testing.T) {
289+
rule := MakeNewRule(1, 2, []string{"a"})
290+
ruleOp := RuleOp{
291+
TiFlashRule: &rule,
292+
Action: RuleOpAdd,
293+
DeleteByIDPrefix: false,
294+
}
295+
j, err := json.Marshal(&ruleOp)
296+
require.NoError(t, err)
297+
ruleOpExpect := &RuleOp{}
298+
json.Unmarshal(j, ruleOpExpect)
299+
require.Equal(t, ruleOp.Action, ruleOpExpect.Action)
300+
require.Equal(t, *ruleOp.TiFlashRule, *ruleOpExpect.TiFlashRule)
301+
ruleOps := make([]RuleOp, 0, 2)
302+
for i := 0; i < 10; i += 2 {
303+
rule := MakeNewRule(int64(i), 2, []string{"a"})
304+
ruleOps = append(ruleOps, RuleOp{
305+
TiFlashRule: &rule,
306+
Action: RuleOpAdd,
307+
DeleteByIDPrefix: false,
308+
})
309+
}
310+
for i := 1; i < 10; i += 2 {
311+
rule := MakeNewRule(int64(i), 2, []string{"b"})
312+
ruleOps = append(ruleOps, RuleOp{
313+
TiFlashRule: &rule,
314+
Action: RuleOpDel,
315+
DeleteByIDPrefix: false,
316+
})
317+
}
318+
j, err = json.Marshal(ruleOps)
319+
require.NoError(t, err)
320+
var ruleOpsExpect []RuleOp
321+
json.Unmarshal(j, &ruleOpsExpect)
322+
for i := 0; i < len(ruleOps); i++ {
323+
require.Equal(t, ruleOps[i].Action, ruleOpsExpect[i].Action)
324+
require.Equal(t, *ruleOps[i].TiFlashRule, *ruleOpsExpect[i].TiFlashRule)
325+
}
326+
}

domain/infosync/tiflash_manager.go

+83-3
Original file line numberDiff line numberDiff line change
@@ -310,9 +310,89 @@ const (
310310
// RuleOp is for batching placement rule actions. The action type is
311311
// distinguished by the field `Action`.
312312
type RuleOp struct {
313-
*placement.TiFlashRule // information of the placement rule to add/delete the operation type
314-
Action RuleOpType `json:"action"`
315-
DeleteByIDPrefix bool `json:"delete_by_id_prefix"` // if action == delete, delete by the prefix of id
313+
*placement.TiFlashRule // information of the placement rule to add/delete the operation type
314+
Action RuleOpType
315+
DeleteByIDPrefix bool // if action == delete, delete by the prefix of id
316+
}
317+
318+
var _ json.Marshaler = (*RuleOp)(nil)
319+
var _ json.Unmarshaler = (*RuleOp)(nil)
320+
321+
type ruleOp struct {
322+
GroupID string `json:"group_id"`
323+
ID string `json:"id"`
324+
Index int `json:"index,omitempty"`
325+
Override bool `json:"override,omitempty"`
326+
Role placement.PeerRoleType `json:"role"`
327+
Count int `json:"count"`
328+
Constraints placement.Constraints `json:"label_constraints,omitempty"`
329+
LocationLabels []string `json:"location_labels,omitempty"`
330+
IsolationLevel string `json:"isolation_level,omitempty"`
331+
StartKeyHex string `json:"start_key"`
332+
EndKeyHex string `json:"end_key"`
333+
Action RuleOpType `json:"action"`
334+
DeleteByIDPrefix bool `json:"delete_by_id_prefix"`
335+
}
336+
337+
// MarshalJSON implements json.Marshaler interface for RuleOp.
338+
func (r *RuleOp) MarshalJSON() ([]byte, error) {
339+
return json.Marshal(&ruleOp{
340+
GroupID: r.GroupID,
341+
ID: r.ID,
342+
Index: r.Index,
343+
Override: r.Override,
344+
Role: r.Role,
345+
Count: r.Count,
346+
Constraints: r.Constraints,
347+
LocationLabels: r.LocationLabels,
348+
IsolationLevel: r.IsolationLevel,
349+
StartKeyHex: hex.EncodeToString(codec.EncodeBytes(nil, r.StartKey)),
350+
EndKeyHex: hex.EncodeToString(codec.EncodeBytes(nil, r.EndKey)),
351+
Action: r.Action,
352+
DeleteByIDPrefix: r.DeleteByIDPrefix,
353+
})
354+
}
355+
356+
// UnmarshalJSON implements json.Unmarshaler interface for RuleOp.
357+
func (r *RuleOp) UnmarshalJSON(bytes []byte) error {
358+
var rule ruleOp
359+
if err := json.Unmarshal(bytes, &rule); err != nil {
360+
return err
361+
}
362+
*r = RuleOp{
363+
TiFlashRule: &placement.TiFlashRule{
364+
GroupID: rule.GroupID,
365+
ID: rule.ID,
366+
Index: rule.Index,
367+
Override: rule.Override,
368+
Role: rule.Role,
369+
Count: rule.Count,
370+
Constraints: rule.Constraints,
371+
LocationLabels: rule.LocationLabels,
372+
IsolationLevel: rule.IsolationLevel,
373+
},
374+
Action: rule.Action,
375+
DeleteByIDPrefix: rule.DeleteByIDPrefix,
376+
}
377+
378+
startKey, err := hex.DecodeString(rule.StartKeyHex)
379+
if err != nil {
380+
return err
381+
}
382+
383+
endKey, err := hex.DecodeString(rule.EndKeyHex)
384+
if err != nil {
385+
return err
386+
}
387+
388+
_, r.StartKey, err = codec.DecodeBytes(startKey, nil)
389+
if err != nil {
390+
return err
391+
}
392+
393+
_, r.EndKey, err = codec.DecodeBytes(endKey, nil)
394+
395+
return err
316396
}
317397

318398
func (m *TiFlashReplicaManagerCtx) doSetPlacementRuleBatch(ctx context.Context, rules []placement.TiFlashRule) error {

0 commit comments

Comments
 (0)