closes #403 Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org> Reviewed-on: #407 Co-authored-by: Vasiliy Tolstov <v.tolstov@unistack.org> Co-committed-by: Vasiliy Tolstov <v.tolstov@unistack.org>
111 lines
3.0 KiB
Go
111 lines
3.0 KiB
Go
package sql
|
|
|
|
import (
|
|
"context"
|
|
"math"
|
|
|
|
"golang.yandex/hasql/v2"
|
|
)
|
|
|
|
// ClusterOptions contains cluster specific options
|
|
type ClusterOptions struct {
|
|
NodeChecker hasql.NodeChecker
|
|
NodePicker hasql.NodePicker[Querier]
|
|
NodeDiscoverer hasql.NodeDiscoverer[Querier]
|
|
Options []hasql.ClusterOpt[Querier]
|
|
Context context.Context
|
|
Retries int
|
|
NodePriority map[string]int32
|
|
NodeStateCriterion hasql.NodeStateCriterion
|
|
}
|
|
|
|
// ClusterOption apply cluster options to ClusterOptions
|
|
type ClusterOption func(*ClusterOptions)
|
|
|
|
// WithClusterNodeChecker pass hasql.NodeChecker to cluster options
|
|
func WithClusterNodeChecker(c hasql.NodeChecker) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
o.NodeChecker = c
|
|
}
|
|
}
|
|
|
|
// WithClusterNodePicker pass hasql.NodePicker to cluster options
|
|
func WithClusterNodePicker(p hasql.NodePicker[Querier]) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
o.NodePicker = p
|
|
}
|
|
}
|
|
|
|
// WithClusterNodeDiscoverer pass hasql.NodeDiscoverer to cluster options
|
|
func WithClusterNodeDiscoverer(d hasql.NodeDiscoverer[Querier]) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
o.NodeDiscoverer = d
|
|
}
|
|
}
|
|
|
|
// WithRetries retry count on other nodes in case of error
|
|
func WithRetries(n int) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
o.Retries = n
|
|
}
|
|
}
|
|
|
|
// WithClusterContext pass context.Context to cluster options and used for checks
|
|
func WithClusterContext(ctx context.Context) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
o.Context = ctx
|
|
}
|
|
}
|
|
|
|
// WithClusterOptions pass hasql.ClusterOpt
|
|
func WithClusterOptions(opts ...hasql.ClusterOpt[Querier]) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
o.Options = append(o.Options, opts...)
|
|
}
|
|
}
|
|
|
|
// WithClusterNodeStateCriterion pass default hasql.NodeStateCriterion
|
|
func WithClusterNodeStateCriterion(c hasql.NodeStateCriterion) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
o.NodeStateCriterion = c
|
|
}
|
|
}
|
|
|
|
type ClusterNode struct {
|
|
Name string
|
|
DB Querier
|
|
Priority int32
|
|
}
|
|
|
|
// WithClusterNodes create cluster with static NodeDiscoverer
|
|
func WithClusterNodes(cns ...ClusterNode) ClusterOption {
|
|
return func(o *ClusterOptions) {
|
|
nodes := make([]*hasql.Node[Querier], 0, len(cns))
|
|
if o.NodePriority == nil {
|
|
o.NodePriority = make(map[string]int32, len(cns))
|
|
}
|
|
for _, cn := range cns {
|
|
nodes = append(nodes, hasql.NewNode(cn.Name, cn.DB))
|
|
if cn.Priority == 0 {
|
|
cn.Priority = math.MaxInt32
|
|
}
|
|
o.NodePriority[cn.Name] = cn.Priority
|
|
}
|
|
o.NodeDiscoverer = hasql.NewStaticNodeDiscoverer(nodes...)
|
|
}
|
|
}
|
|
|
|
type nodeStateCriterionKey struct{}
|
|
|
|
// NodeStateCriterion inject hasql.NodeStateCriterion to context
|
|
func NodeStateCriterion(ctx context.Context, c hasql.NodeStateCriterion) context.Context {
|
|
return context.WithValue(ctx, nodeStateCriterionKey{}, c)
|
|
}
|
|
|
|
func (c *Cluster) getNodeStateCriterion(ctx context.Context) hasql.NodeStateCriterion {
|
|
if v, ok := ctx.Value(nodeStateCriterionKey{}).(hasql.NodeStateCriterion); ok {
|
|
return v
|
|
}
|
|
return c.options.NodeStateCriterion
|
|
}
|