Option is skyl's functional-option type. Every option is a function that
mutates a *Client during construction, and they are applied in the order you
pass them.
Reference#
type Option func(*Client)
Caveats
- Options are applied in order, so a later one overrides an earlier one of the same kind.
- Invalid values are ignored, not rejected. A negative retry count or a non-positive delay leaves the default in place — there is no error return.
- Options configure the
Client, never the transport. HTTP concerns are provider options.
The options#
| Option | Default | Bounds |
|---|---|---|
| WithMaxRetries(n) | 3 | How many times a retryable failure is retried |
| WithRetryDelay(base, max) | 500ms / 30s | skyl's computed backoff |
| WithRetryAfterCap(d) | 5m | A provider's own Retry-After hint |
| WithTimeout(d) | 10m | A single attempt |
| WithHook(h) | none | Nothing — it registers an observer |
Usage#
A production configuration
client := skyl.New(p,
skyl.WithMaxRetries(5),
skyl.WithRetryDelay(time.Second, time.Minute),
skyl.WithRetryAfterCap(2*time.Minute),
skyl.WithTimeout(90*time.Second),
skyl.WithHook(telemetry.Hook),
)client := skyl.New(p,
skyl.WithMaxRetries(5),
skyl.WithRetryDelay(time.Second, time.Minute),
skyl.WithRetryAfterCap(2*time.Minute),
skyl.WithTimeout(90*time.Second),
skyl.WithHook(telemetry.Hook),
)Reusable option sets
// Options are values, so a policy is just a slice.
func policy(env string) []skyl.Option {
switch env {
case "test":
// Same retry count, negligible wall-clock.
return []skyl.Option{
skyl.WithMaxRetries(3),
skyl.WithRetryDelay(time.Millisecond, 10*time.Millisecond),
skyl.WithRetryAfterCap(50 * time.Millisecond),
}
default:
return []skyl.Option{
skyl.WithMaxRetries(4),
skyl.WithTimeout(2 * time.Minute),
}
}
}
client := skyl.New(p, policy(os.Getenv("APP_ENV"))...)// Options are values, so a policy is just a slice.
func policy(env string) []skyl.Option {
switch env {
case "test":
// Same retry count, negligible wall-clock.
return []skyl.Option{
skyl.WithMaxRetries(3),
skyl.WithRetryDelay(time.Millisecond, 10*time.Millisecond),
skyl.WithRetryAfterCap(50 * time.Millisecond),
}
default:
return []skyl.Option{
skyl.WithMaxRetries(4),
skyl.WithTimeout(2 * time.Minute),
}
}
}
client := skyl.New(p, policy(os.Getenv("APP_ENV"))...)Writing your own option
// Option is an exported func type, so you can compose your own from the
// built-in ones — useful for encoding a house style once.
func WithHouseDefaults() skyl.Option {
return func(c *skyl.Client) {
skyl.WithMaxRetries(4)(c)
skyl.WithTimeout(90 * time.Second)(c)
}
}// Option is an exported func type, so you can compose your own from the
// built-in ones — useful for encoding a house style once.
func WithHouseDefaults() skyl.Option {
return func(c *skyl.Client) {
skyl.WithMaxRetries(4)(c)
skyl.WithTimeout(90 * time.Second)(c)
}
}Troubleshooting#
My option had no effect
Either the value was invalid and silently ignored — check for a negative or zero argument — or a later option of the same kind overrode it.
There is no WithHTTPClient
Correct: the HTTP client is a provider option, because the adapter performs
the request. Use openai.WithHTTPClient(hc), gemini.WithHTTPClient(hc), and
so on.
There is no WithBaseURL either
Same reason. A base URL identifies one vendor's host, so it belongs to the
adapter: openai.WithBaseURL(...).