diff --git a/lib/gat/gatcaddyfile/pool.go b/lib/gat/gatcaddyfile/pool.go index 856859eddce12b9ce88499110cb5aae90ddd8f13..32572f84d963270e6c7797f4633642eaf010bd70 100644 --- a/lib/gat/gatcaddyfile/pool.go +++ b/lib/gat/gatcaddyfile/pool.go @@ -1,7 +1,159 @@ package gatcaddyfile -import "gfx.cafe/gfx/pggat/lib/gat/handlers/pool/pools/basic" +import ( + "time" + + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + + "gfx.cafe/gfx/pggat/lib/gat/handlers/pool/pools/basic" + "gfx.cafe/gfx/pggat/lib/util/strutil" +) + +func defaultPoolConfig(base basic.Config) basic.Config { + base.ServerIdleTimeout = caddy.Duration(5 * time.Minute) + base.ServerReconnectInitialTime = caddy.Duration(5 * time.Second) + base.ServerReconnectMaxTime = caddy.Duration(1 * time.Minute) + base.TrackedParameters = []strutil.CIString{ + strutil.MakeCIString("client_encoding"), + strutil.MakeCIString("datestyle"), + strutil.MakeCIString("timezone"), + strutil.MakeCIString("standard_conforming_strings"), + strutil.MakeCIString("application_name"), + } + return base +} var defaultPool = &basic.Factory{ - Config: basic.Transaction, + Config: defaultPoolConfig(basic.Transaction), +} + +func init() { + RegisterDirective(Pool, "basic", func(d *caddyfile.Dispenser, warnings *[]caddyconfig.Warning) (caddy.Module, error) { + module := *defaultPool + + if d.NextArg() { + switch d.Val() { + case "transaction": + module.Config = defaultPoolConfig(basic.Transaction) + case "session": + module.Config = defaultPoolConfig(basic.Session) + default: + return nil, d.ArgErr() + } + } else { + if !d.NextBlock(d.Nesting()) { + return nil, d.ArgErr() + } + + for { + if d.Val() == "}" { + break + } + + directive := d.Val() + switch directive { + case "pooler": + if !d.NextArg() { + return nil, d.ArgErr() + } + + var err error + module.RawPoolerFactory, err = UnmarshalDirectiveJSONModuleObject( + d, + Pooler, + "pooler", + warnings, + ) + if err != nil { + return nil, err + } + case "release_after_transaction": + if d.NextArg() { + switch d.Val() { + case "true": + module.ReleaseAfterTransaction = true + case "false": + module.ReleaseAfterTransaction = false + default: + return nil, d.ArgErr() + } + } else { + module.ReleaseAfterTransaction = true + } + case "parameter_status_sync": + if !d.NextArg() { + return nil, d.ArgErr() + } + + module.ParameterStatusSync = basic.ParameterStatusSync(d.Val()) + case "extended_query_sync": + if d.NextArg() { + switch d.Val() { + case "true": + module.ExtendedQuerySync = true + case "false": + module.ExtendedQuerySync = false + default: + return nil, d.ArgErr() + } + } else { + module.ExtendedQuerySync = true + } + case "reset_query": + if !d.NextArg() { + return nil, d.ArgErr() + } + + module.ServerResetQuery = d.Val() + case "idle_timeout": + if !d.NextArg() { + return nil, d.ArgErr() + } + + val, err := time.ParseDuration(d.Val()) + if err != nil { + return nil, d.WrapErr(err) + } + + module.ServerIdleTimeout = caddy.Duration(val) + case "reconnect": + if !d.NextArg() { + return nil, d.ArgErr() + } + + initialTime, err := time.ParseDuration(d.Val()) + if err != nil { + return nil, d.WrapErr(err) + } + + maxTime := initialTime + if d.NextArg() { + maxTime, err = time.ParseDuration(d.Val()) + if err != nil { + return nil, d.WrapErr(err) + } + } + + module.ServerReconnectInitialTime = caddy.Duration(initialTime) + module.ServerReconnectMaxTime = caddy.Duration(maxTime) + case "track": + if !d.NextArg() { + return nil, d.ArgErr() + } + + module.TrackedParameters = append(module.TrackedParameters, strutil.MakeCIString(d.Val())) + default: + return nil, d.ArgErr() + } + + if !d.NextLine() { + return nil, d.EOFErr() + } + } + } + + return &module, nil + }) } diff --git a/lib/gat/gatcaddyfile/pooler.go b/lib/gat/gatcaddyfile/pooler.go new file mode 100644 index 0000000000000000000000000000000000000000..a129c5fb1be8ce1ccdb0d880135146d8b846f34a --- /dev/null +++ b/lib/gat/gatcaddyfile/pooler.go @@ -0,0 +1,19 @@ +package gatcaddyfile + +import ( + "github.com/caddyserver/caddy/v2" + "github.com/caddyserver/caddy/v2/caddyconfig" + "github.com/caddyserver/caddy/v2/caddyconfig/caddyfile" + + "gfx.cafe/gfx/pggat/lib/gat/handlers/pool/poolers/lifo" + "gfx.cafe/gfx/pggat/lib/gat/handlers/pool/poolers/rob" +) + +func init() { + RegisterDirective(Pooler, "lifo", func(d *caddyfile.Dispenser, _ *[]caddyconfig.Warning) (caddy.Module, error) { + return &lifo.Factory{}, nil + }) + RegisterDirective(Pooler, "rob", func(d *caddyfile.Dispenser, _ *[]caddyconfig.Warning) (caddy.Module, error) { + return &rob.Factory{}, nil + }) +} diff --git a/lib/gat/handlers/allowed_startup_parameters/module.go b/lib/gat/handlers/allowed_startup_parameters/module.go index f23ab20e767f24769ecd06b515263126b18c929b..d797381bbf9acb82b5caf631476e577531751c27 100644 --- a/lib/gat/handlers/allowed_startup_parameters/module.go +++ b/lib/gat/handlers/allowed_startup_parameters/module.go @@ -17,7 +17,7 @@ func init() { } type Module struct { - Parameters []strutil.CIString `json:"parameters"` + Parameters []strutil.CIString `json:"parameters,omitempty"` } func (T *Module) CaddyModule() caddy.ModuleInfo { diff --git a/lib/gat/handlers/pool/dialer.go b/lib/gat/handlers/pool/dialer.go index 140c1474b39a79675949bb8e0522cfe77181f495..552bca1187158b386a657cb9c4d5061ebfa10423 100644 --- a/lib/gat/handlers/pool/dialer.go +++ b/lib/gat/handlers/pool/dialer.go @@ -26,7 +26,7 @@ type Dialer struct { RawSSL json.RawMessage `json:"ssl,omitempty" caddy:"namespace=pggat.ssl.clients inline_key=provider"` RawPassword string `json:"password"` - RawParameters map[string]string `json:"parameters"` + RawParameters map[string]string `json:"parameters,omitempty"` SSLConfig *tls.Config `json:"-"` Credentials auth.Credentials `json:"-"`