Documentation
¶
Index ¶
Constants ¶
const (
PrefixKey = "__host"
)
Variables ¶
var ( // ErrQueueClosed is returned by operations on a closed Queue. ErrQueueClosed = errors.New("storage: queue closed") // ErrTopicAlreadySubscribed reports a second handler for one topic. // Registration is rejected rather than silently replacing the first, which // is what the previous Register did. ErrTopicAlreadySubscribed = errors.New("storage: topic already subscribed") // ErrNoHandler reports a message published to a topic nobody consumes. ErrNoHandler = errors.New("storage: no handler for topic") // ErrNilHandler reports a subscription with nothing to deliver to. ErrNilHandler = errors.New("storage: nil handler") // ErrQueueAlreadyStarted reports a second call to Start, or a Subscribe // that arrived too late to take effect. ErrQueueAlreadyStarted = errors.New("storage: queue already started") )
var ErrCacheClosed = errors.New("storage: cache closed")
ErrCacheClosed is returned by operations on a closed Cache.
var ErrCacheMiss = errors.New("storage: cache miss")
ErrCacheMiss reports that a key is absent.
A key that never existed and a key that has expired are the same fact and return the same error. Callers must test with errors.Is; treating any non-nil error as "no data" turns a backend outage into a full cache bypass and stampedes the database.
Functions ¶
This section is empty.
Types ¶
type AdapterCache
deprecated
type AdapterCache interface {
String() string
Get(key string) (string, error)
Set(key string, val interface{}, expire int) error
Del(key string) error
HashGet(hk, key string) (string, error)
HashDel(hk, key string) error
Increase(key string) error
Decrease(key string) error
Expire(key string, dur time.Duration) error
}
AdapterCache is the original cache contract.
Deprecated: use Cache. This interface cannot report a miss (Get returns an empty string and a nil error for both an absent key and a stored empty string), carries no context, has no Close, and its Hash family shares one flat key space with ordinary keys. Wrap a Cache with LegacyAdapter to keep existing call sites working. To be removed in v2.0.0.
func LegacyAdapter ¶
func LegacyAdapter(c Cache) AdapterCache
LegacyAdapter exposes a Cache through the older AdapterCache interface, so a new backend can be adopted without touching the call sites that still take AdapterCache — captcha.NewCacheStore and Runtime.SetCacheAdapter among them.
It cannot repair the older contract, only preserve it:
- Get reports a miss as ("", nil), which is indistinguishable from a stored empty string. Callers that need to tell them apart must move to Cache.
- HashGet and HashDel concatenate their arguments, matching the previous in-memory behaviour. That shares one flat key space with ordinary keys, so HashGet("a", "bc") and Set("abc", …) collide. The Hash family is not carried over to Cache for this reason.
type AdapterQueue ¶
type AdapterQueue interface {
String() string
Append(message Messager) error
Register(name string, f ConsumerFunc)
Run()
Shutdown()
}
func LegacyQueueAdapter ¶
func LegacyQueueAdapter(q Queue) AdapterQueue
LegacyQueueAdapter exposes a Queue through the older AdapterQueue interface, so a backend can be selected by configuration without changing the call sites that still take AdapterQueue.
It cannot repair the older contract, only preserve it:
- Register returns nothing, so a rejected topic or an unreachable backend can only be logged. Subscribe reports both; use it where that matters.
- ConsumerFunc takes no context, so a cancelled Start does not reach a handler that is already running.
- Messager counts errors while Message counts deliveries. GetErrorCount is therefore Attempts minus one, since the first delivery has not failed.
type Cache ¶
type Cache interface {
// Get returns the value stored under key, or ErrCacheMiss when the key is
// absent or expired. An empty string is a legal value and is returned with
// a nil error.
Get(ctx context.Context, key string) (string, error)
// Set stores a value with a time to live. A ttl of zero or less means the
// entry never expires.
Set(ctx context.Context, key, val string, ttl time.Duration) error
// Del removes keys. Removing an absent key is not an error.
Del(ctx context.Context, keys ...string) error
// Incr atomically adds delta and returns the resulting value. An absent key
// starts from zero. delta may be negative. A key created this way has no
// ttl; call Expire to add one. The read-modify-write must be atomic.
Incr(ctx context.Context, key string, delta int64) (int64, error)
// Expire resets the time to live, returning ErrCacheMiss when the key is
// absent. A ttl of zero or less makes the entry permanent.
Expire(ctx context.Context, key string, ttl time.Duration) error
// Close releases the underlying resources. It is idempotent. Afterwards
// every other method returns ErrCacheClosed, unless ctx is already done,
// in which case the context error wins.
io.Closer
}
Cache is the contract for a key/value cache.
Implementations must honour ctx cancellation and deadlines, and must not swallow ctx.Err(). The context is checked first: a cancelled context yields its own error even on a closed Cache, so a caller that gave up is never told something else went wrong.
func WithPrefix ¶
WithPrefix returns a Cache that prefixes every key, so that several applications can share one backend.
This is a decorator rather than a method on the interface, mirroring the Logger decorators already used in this repository.
type ConsumerFunc ¶
type Handler ¶
Handler processes one message. Returning an error marks the delivery as failed; whether that leads to a retry is the implementation's decision, but Attempts must reflect it.
type Message ¶
type Message struct {
// ID is assigned by the queue on publish. It is ignored on input.
ID string
// Topic routes the message to a handler.
Topic string
// Values carries the payload.
//
// Only string values are guaranteed to arrive unchanged. Everything else is
// undefined across implementations, because a broker-backed queue has to
// serialise the map and an in-process one does not: the Redis queue returns
// a published int as a float64, the memory queue returns the int. Use
// strings, or encode the payload yourself.
Values map[string]interface{}
// Attempts counts deliveries of this message, starting at 1. A handler can
// use it to give up on a message that keeps failing.
Attempts int
}
Message is a queued message.
It is a struct, not an interface: the previous Messager was ten getters and setters with a single implementation, so the indirection bought nothing. Values is a map rather than a byte slice to match the field model of Redis streams, which is the intended backend.
type Queue ¶
type Queue interface {
// Publish enqueues a message. The topic must have a subscriber, otherwise
// ErrNoHandler is returned rather than dropping the message silently.
Publish(ctx context.Context, msg Message) error
// Subscribe registers the handler for a topic. It must be called before
// Start, because an implementation may fix its set of topics there and a
// late subscription would then let Publish succeed with nothing reading it.
//
// Where more than one rule is broken at once, every implementation has to
// answer alike: a bad argument outranks the queue's state, and among
// states the terminal one outranks the rest. So ErrNilHandler, then
// ErrQueueClosed, then ErrQueueAlreadyStarted, then
// ErrTopicAlreadySubscribed.
Subscribe(topic string, h Handler) error
// Start begins consuming and blocks until ctx is done or an unrecoverable
// error occurs. A context cancellation is not an error.
Start(ctx context.Context) error
// Close stops accepting new messages and waits for in-flight deliveries to
// finish. It is idempotent. Bound the wait with a context of your own if
// you need to.
io.Closer
}
Queue is the contract for a message queue.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cachetest provides a black-box conformance suite for storage.Cache implementations.
|
Package cachetest provides a black-box conformance suite for storage.Cache implementations. |
|
Package redis implements storage.Cache and storage.Queue on top of Redis.
|
Package redis implements storage.Cache and storage.Queue on top of Redis. |