good morning!!!!

Skip to content
Snippets Groups Projects
Commit 86cb5563 authored by Thomas Guinther's avatar Thomas Guinther
Browse files

add support for replication critic ("replication_latency" directive)

make the original "latency" directive more versatile and alias it with the new preferred directive "query_latency"
use caddy.ParseDuration rather than time.ParseDuration
parent b7723aa4
No related branches found
No related tags found
No related merge requests found
......@@ -2,8 +2,6 @@ package gatcaddyfile
import (
"gfx.cafe/gfx/pggat/lib/gat/handlers/pool/critics/replication"
"time"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
......@@ -14,49 +12,62 @@ import (
func init() {
// Register a directive for the latency critic which measures query response
// time as the determining factor for load balancing between replicas
RegisterDirective(Critic, "latency", func(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
module := &latency.Critic{
Validity: caddy.Duration(5 * time.Minute),
}
// parse nested format
if d.NextBlock(d.Nesting()) {
return parseLatency(module, d, warnings)
}
// parse legacy format
if !d.NextArg() {
return nil, d.ArgErr()
}
threshold, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
module.Threshold = caddy.Duration(threshold)
if d.NextArg() {
// optional validity
var validity time.Duration
validity, err = caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
module.Validity = caddy.Duration(validity)
}
//
// Config Format
//
// * All fields are optional and will fall back to a suitable default
// * Duration values use caddy.Duration syntax
//
// penalize query_latency [query_threshold duration [validity duration]]
//
// -or-
//
// penalize query_latency {
// [query_threshold] {duration}
// [validity] {duration}
// }
//
// pool basic session {
// penalize query_latency # use the defaults
// penalize query_latency 500ms # set query threshold w/ default validity
// penalize query_latency 500ms 3m # set query threshold and validity
// penalize query_latency {
// query_threshold 300ms
// validity 5m
// }
// }
RegisterDirective(Critic, "query_latency", func(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
return parseQueryCritic(d, warnings)
})
return module, nil
// legacy directive for query_latency
RegisterDirective(Critic, "latency", func(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
return parseQueryCritic(d, warnings)
})
// Register a directive handler for the replication critic which uses
// replication lag as a determining factor for load balancing between replicas
RegisterDirective(Critic, "replication", func(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
module := &replication.Critic{
Validity: caddy.Duration(2 * time.Minute),
}
// replication lag as a determining factor for load balancing between
// replicas
//
// Config format
//
// * All fields are optional and will fall back to a suitable default
// * Duration values use caddy.Duration syntax
//
// pool basic session {
// penalize replication_latency # valid declaration. Use default values
//
// penalize replication_latency {
// replication_threshold 3s
// query_threshold 300ms
// validity 5m
// }
// }
RegisterDirective(Critic, "replication_latency", func(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
module := replication.NewCritic()
if !d.NextBlock(d.Nesting()) {
return nil, d.ArgErr()
return module, nil
}
for {
......@@ -71,23 +82,34 @@ func init() {
return nil, d.ArgErr()
}
validity, err := time.ParseDuration(d.Val())
validity, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
module.Validity = caddy.Duration(validity)
case "threshold":
case "replication_threshold":
if !d.NextArg() {
return nil, d.ArgErr()
}
threshold, err := time.ParseDuration(d.Val())
threshold, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
module.Threshold = caddy.Duration(threshold)
module.ReplicationThreshold = caddy.Duration(threshold)
case "query_threshold":
if !d.NextArg() {
return nil, d.ArgErr()
}
threshold, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
module.QueryThreshold = caddy.Duration(threshold)
default:
return nil, d.ArgErr()
}
......@@ -101,7 +123,39 @@ func init() {
})
}
func parseLatency(critic *latency.Critic, d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
func parseQueryCritic(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) {
module := latency.NewCritic()
// parse block format
if d.NextBlock(d.Nesting()) {
return parseLatency(module, d, warnings)
}
// use the defaults
if !d.NextArg() {
return module, nil
}
// parse legacy format
dur, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
module.QueryThreshold = caddy.Duration(dur)
if d.NextArg() {
// optional validity
dur, err = caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
module.Validity = caddy.Duration(dur)
}
return module, nil
}
func parseLatency(critic *latency.Critic, d *caddyfile.Dispenser, _ *[]caddyconfig.Warning) (caddy.Module, error) {
for {
if d.Val() == "}" {
break
......@@ -114,23 +168,23 @@ func parseLatency(critic *latency.Critic, d *caddyfile.Dispenser, warnings *[]ca
return nil, d.ArgErr()
}
validity, err := time.ParseDuration(d.Val())
validity, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
critic.Validity = caddy.Duration(validity)
case "threshold":
case "query_threshold":
if !d.NextArg() {
return nil, d.ArgErr()
}
threshold, err := time.ParseDuration(d.Val())
threshold, err := caddy.ParseDuration(d.Val())
if err != nil {
return nil, d.WrapErr(err)
}
critic.Threshold = caddy.Duration(threshold)
critic.QueryThreshold = caddy.Duration(threshold)
default:
return nil, d.ArgErr()
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment