mirror of
https://github.com/redis/go-redis.git
synced 2025-11-30 18:01:23 +03:00
* Add search module builders and tests (#1) * Add search module builders and tests * Add tests * Use builders and Actions in more clean way * Update search_builders.go Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> * Update search_builders.go Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> * Apply suggestions from code review Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> * feat(routing): add internal request/response policy enums * feat: load the policy table in cluster client (#4) * feat: load the policy table in cluster client * Remove comments * modify Tips and command pplicy in commandInfo (#5) * centralize cluster command routing in osscluster_router.go and refactor osscluster.go (#6) * centralize cluster command routing in osscluster_router.go and refactor osscluster.go * enalbe ci on all branches * Add debug prints * Add debug prints * FIX: deal with nil policy * FIX: fixing clusterClient process * chore(osscluster): simplify switch case * wip(command): ai generated clone method for commands * feat: implement response aggregator for Redis cluster commands * feat: implement response aggregator for Redis cluster commands * fix: solve concurrency errors * fix: solve concurrency errors * return MaxRedirects settings * remove locks from getCommandPolicy * Handle MOVED errors more robustly, remove cluster reloading at exectutions, ennsure better routing * Fix: supports Process hook test * Fix: remove response aggregation for single shard commands * Add more preformant type conversion for Cmd type * Add router logic into processPipeline --------- Co-authored-by: Nedyalko Dyakov <nedyalko.dyakov@gmail.com> * remove thread debugging code * remove thread debugging code && reject commands with policy that cannot be used in pipeline * refactor processPipline and cmdType enum * remove FDescribe from cluster tests * Add tests * fix aggregation test * fix mget test * fix mget test * remove aggregateKeyedResponses * added scaffolding for the req-resp manager * added default policies for the search commands * split command map into module->command * cleanup, added logic to refresh the cache * added reactive cache refresh * revert cluster refresh * fixed lint * addresed first batch of comments * rewrote aggregator implementations with atomic for native or nearnative primitives * addressed more comments, fixed lint * added batch aggregator operations * fixed lint * updated batch aggregator, fixed extractcommandvalue * fixed lint * added batching to aggregateResponses * fixed deadlocks * changed aggregator logic, added error params * added preemptive return to the aggregators * more work on the aggregators * updated and and or aggregators * fixed lint * added configurable policy resolvers * slight refactor * removed the interface, slight refactor * change func signature from cmdName to cmder * added nil safety assertions * few small refactors * added read only policies * removed leftover prints * Rebased to master, resolved comnflicts * fixed lint * updated gha * fixed tests, minor consistency refactor * preallocated simple errors * changed numeric aggregators to use float64 * speculative test fix * Update command.go Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> * Update main_test.go Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> * Add static shard picker * Fix nil value handling in command aggregation * Modify the Clone method to return a shallow copy * Add clone method to digest command * Optimize keyless command routing to respect ShardPicker policy * Remove MGET references * Fix MGET aggregation to map individual values to keys across shards * Add clone method to hybrid search commands * Undo changes in route keyless test * remove comments * Add test for DisableRoutingPolicies option * Add Routing Policies Comprehensive Test Suite and Fix multi keyed aggregation for different step --------- Co-authored-by: Nedyalko Dyakov <1547186+ndyakov@users.noreply.github.com> Co-authored-by: Nedyalko Dyakov <nedyalko.dyakov@gmail.com> Co-authored-by: Hristo Temelski <hristo.temelski@redis.com>
145 lines
2.8 KiB
Go
145 lines
2.8 KiB
Go
package routing
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
type RequestPolicy uint8
|
|
|
|
const (
|
|
ReqDefault RequestPolicy = iota
|
|
|
|
ReqAllNodes
|
|
|
|
ReqAllShards
|
|
|
|
ReqMultiShard
|
|
|
|
ReqSpecial
|
|
)
|
|
|
|
const (
|
|
ReadOnlyCMD string = "readonly"
|
|
)
|
|
|
|
func (p RequestPolicy) String() string {
|
|
switch p {
|
|
case ReqDefault:
|
|
return "default"
|
|
case ReqAllNodes:
|
|
return "all_nodes"
|
|
case ReqAllShards:
|
|
return "all_shards"
|
|
case ReqMultiShard:
|
|
return "multi_shard"
|
|
case ReqSpecial:
|
|
return "special"
|
|
default:
|
|
return fmt.Sprintf("unknown_request_policy(%d)", p)
|
|
}
|
|
}
|
|
|
|
func ParseRequestPolicy(raw string) (RequestPolicy, error) {
|
|
switch strings.ToLower(raw) {
|
|
case "", "default", "none":
|
|
return ReqDefault, nil
|
|
case "all_nodes":
|
|
return ReqAllNodes, nil
|
|
case "all_shards":
|
|
return ReqAllShards, nil
|
|
case "multi_shard":
|
|
return ReqMultiShard, nil
|
|
case "special":
|
|
return ReqSpecial, nil
|
|
default:
|
|
return ReqDefault, fmt.Errorf("routing: unknown request_policy %q", raw)
|
|
}
|
|
}
|
|
|
|
type ResponsePolicy uint8
|
|
|
|
const (
|
|
RespDefaultKeyless ResponsePolicy = iota
|
|
RespDefaultHashSlot
|
|
RespAllSucceeded
|
|
RespOneSucceeded
|
|
RespAggSum
|
|
RespAggMin
|
|
RespAggMax
|
|
RespAggLogicalAnd
|
|
RespAggLogicalOr
|
|
RespSpecial
|
|
)
|
|
|
|
func (p ResponsePolicy) String() string {
|
|
switch p {
|
|
case RespDefaultKeyless:
|
|
return "default(keyless)"
|
|
case RespDefaultHashSlot:
|
|
return "default(hashslot)"
|
|
case RespAllSucceeded:
|
|
return "all_succeeded"
|
|
case RespOneSucceeded:
|
|
return "one_succeeded"
|
|
case RespAggSum:
|
|
return "agg_sum"
|
|
case RespAggMin:
|
|
return "agg_min"
|
|
case RespAggMax:
|
|
return "agg_max"
|
|
case RespAggLogicalAnd:
|
|
return "agg_logical_and"
|
|
case RespAggLogicalOr:
|
|
return "agg_logical_or"
|
|
case RespSpecial:
|
|
return "special"
|
|
default:
|
|
return "all_succeeded"
|
|
}
|
|
}
|
|
|
|
func ParseResponsePolicy(raw string) (ResponsePolicy, error) {
|
|
switch strings.ToLower(raw) {
|
|
case "default(keyless)":
|
|
return RespDefaultKeyless, nil
|
|
case "default(hashslot)":
|
|
return RespDefaultHashSlot, nil
|
|
case "all_succeeded":
|
|
return RespAllSucceeded, nil
|
|
case "one_succeeded":
|
|
return RespOneSucceeded, nil
|
|
case "agg_sum":
|
|
return RespAggSum, nil
|
|
case "agg_min":
|
|
return RespAggMin, nil
|
|
case "agg_max":
|
|
return RespAggMax, nil
|
|
case "agg_logical_and":
|
|
return RespAggLogicalAnd, nil
|
|
case "agg_logical_or":
|
|
return RespAggLogicalOr, nil
|
|
case "special":
|
|
return RespSpecial, nil
|
|
default:
|
|
return RespDefaultKeyless, fmt.Errorf("routing: unknown response_policy %q", raw)
|
|
}
|
|
}
|
|
|
|
type CommandPolicy struct {
|
|
Request RequestPolicy
|
|
Response ResponsePolicy
|
|
// Tips that are not request_policy or response_policy
|
|
// e.g nondeterministic_output, nondeterministic_output_order.
|
|
Tips map[string]string
|
|
}
|
|
|
|
func (p *CommandPolicy) CanBeUsedInPipeline() bool {
|
|
return p.Request != ReqAllNodes && p.Request != ReqAllShards && p.Request != ReqMultiShard
|
|
}
|
|
|
|
func (p *CommandPolicy) IsReadOnly() bool {
|
|
_, readOnly := p.Tips[ReadOnlyCMD]
|
|
return readOnly
|
|
}
|