68 lines
2.4 KiB
Go
68 lines
2.4 KiB
Go
// Package rpc implements an optional, versioned JSON protocol over ws sessions.
|
|
// Both endpoints may issue calls and events. It does not provide durable delivery.
|
|
package rpc
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
)
|
|
|
|
const Subprotocol = "go-omni.rpc.v1"
|
|
|
|
var (
|
|
ErrClosed = errors.New("rpc: closed")
|
|
ErrNotConnected = errors.New("rpc: not connected")
|
|
ErrBusy = errors.New("rpc: capacity reached")
|
|
ErrProtocol = errors.New("rpc: invalid protocol message")
|
|
)
|
|
|
|
// Config bounds allocations, concurrency, and the lifetime of incoming work.
|
|
// Zero fields select defaults. A canceled handler must return before Wait succeeds.
|
|
type Config struct {
|
|
MaxMessageBytes int `json:"maxMessageBytes"`
|
|
MaxPending int `json:"maxPending"`
|
|
MaxConcurrent int `json:"maxConcurrent"`
|
|
CallTimeout time.Duration `json:"callTimeout"`
|
|
WriteTimeout time.Duration `json:"writeTimeout"`
|
|
// OnEventError observes local notification failures; they have no reply on
|
|
// the wire. This callback runs within the handler completion barrier.
|
|
OnEventError func(context.Context, error) `json:"-"`
|
|
}
|
|
|
|
func DefaultConfig() Config {
|
|
return Config{MaxMessageBytes: 1 << 20, MaxPending: 128, MaxConcurrent: 32, CallTimeout: 30 * time.Second, WriteTimeout: 5 * time.Second}
|
|
}
|
|
func (c Config) Validate() error { _, err := normalize(c); return err }
|
|
func normalize(c Config) (Config, error) {
|
|
if c.MaxMessageBytes < 0 || c.MaxMessageBytes > 16<<20 || c.MaxPending < 0 || c.MaxPending > 65536 || c.MaxConcurrent < 0 || c.MaxConcurrent > 4096 || c.CallTimeout < 0 || c.CallTimeout > 24*time.Hour || c.WriteTimeout < 0 || c.WriteTimeout > time.Minute {
|
|
return c, errors.New("rpc: configuration exceeds supported bounds")
|
|
}
|
|
d := DefaultConfig()
|
|
if c.MaxMessageBytes == 0 {
|
|
c.MaxMessageBytes = d.MaxMessageBytes
|
|
}
|
|
if c.MaxPending == 0 {
|
|
c.MaxPending = d.MaxPending
|
|
}
|
|
if c.MaxConcurrent == 0 {
|
|
c.MaxConcurrent = d.MaxConcurrent
|
|
}
|
|
if c.CallTimeout == 0 {
|
|
c.CallTimeout = d.CallTimeout
|
|
}
|
|
if c.WriteTimeout == 0 {
|
|
c.WriteTimeout = d.WriteTimeout
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// Error is an explicitly public error. Only this type's code/message may be
|
|
// sent to the other endpoint; all other handler errors become INTERNAL.
|
|
type Error struct {
|
|
Code string `json:"code"`
|
|
Message string `json:"message"`
|
|
}
|
|
|
|
func (e *Error) Error() string { return "rpc: " + e.Code }
|