Documentation
¶
Overview ¶
Package typed provides typed wrappers around the generic Murmur QueryService — the building block for application services that want to expose typed protos to their callers rather than the generic Value{bytes} shape.
Why this exists ¶
Murmur's `pkg/query/grpc.QueryService` returns `Value{present, data}` where `data` is the wire-encoded monoid value (int64-LE for Sum/Count/Min/Max, marshaled HLL/TopK/Bloom for sketches). Clients decode the bytes per the pipeline's monoid kind. This is right for Murmur — it keeps the service monoid-agnostic — but it pushes decoding boilerplate to every caller.
The typed-wrapper pattern: an application service exposes its OWN Connect-RPC API with typed responses (e.g. count-core's `BotInteractionCountService.GetBotInteractionCount(...) → int64`). The implementation calls the underlying Murmur QueryService, decodes the bytes via this package, and returns the typed shape. Callers see typed protos; Murmur stays generic.
This package ships the decoders + thin typed-client wrappers for the shipped monoid kinds: Sum/Count/Min/Max (int64), HLL, TopK, Bloom. Full per-pipeline codegen — generating a typed `*ServerStub` per pipeline — is Phase 2 roadmap; this package is the building block it would generate against.
Usage ¶
Wrap a generic Murmur QueryService client once:
rawClient := murmurv1connect.NewQueryServiceClient(httpClient, baseURL)
likes := typed.NewSumClient(rawClient)
// Now: typed Get / GetMany / GetWindow.
count, present, err := likes.Get(ctx, "post-123")
counts, err := likes.GetMany(ctx, []string{"post-123", "post-456"})
last24h, err := likes.GetWindow(ctx, "post-123", 24*time.Hour)
Build your own Connect-RPC service against the typed client:
type CountCoreServer struct {
likes *typed.SumClient
unique *typed.HLLClient
}
func (s *CountCoreServer) GetBotInteractionCount(ctx, req) (resp, error) {
n, ok, err := s.likes.Get(ctx, req.GetEntity())
if err != nil { return nil, connect.NewError(...) }
return &countpb.GetBotInteractionCountResponse{
Count: n,
Present: ok,
}, nil
}
The application's Connect-RPC service is whatever proto shape it wants; the typed client hides the bytes-decoding from it.
Index ¶
- Variables
- func DecodeInt64(data []byte) int64
- type BloomClient
- func (c *BloomClient) Get(ctx context.Context, entity string, opts ...Option) (BloomValue, bool, error)
- func (c *BloomClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) (BloomValue, error)
- func (c *BloomClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([]BloomValue, error)
- type BloomValue
- type HLLClient
- func (c *HLLClient) Get(ctx context.Context, entity string, opts ...Option) (HLLValue, bool, error)
- func (c *HLLClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) (HLLValue, error)
- func (c *HLLClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([]HLLValue, error)
- type HLLValue
- type Inner
- type Option
- type SumClient
- func (c *SumClient) Get(ctx context.Context, entity string, opts ...Option) (int64, bool, error)
- func (c *SumClient) GetMany(ctx context.Context, entities []string, opts ...Option) ([]int64, []bool, error)
- func (c *SumClient) GetRange(ctx context.Context, entity string, start, end time.Time, opts ...Option) (int64, error)
- func (c *SumClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) (int64, error)
- func (c *SumClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([]int64, error)
- type TopKClient
- func (c *TopKClient) Get(ctx context.Context, entity string, opts ...Option) ([]TopKItem, bool, error)
- func (c *TopKClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) ([]TopKItem, error)
- func (c *TopKClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([][]TopKItem, error)
- type TopKItem
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupported = errors.New("typed client: operation not supported by underlying pipeline")
ErrUnsupported is returned by adapters that don't implement an optional method (e.g., calling GetWindow on a SumClient that only wraps a non-windowed pipeline). Wrapped via fmt.Errorf at the call site.
Functions ¶
func DecodeInt64 ¶
DecodeInt64 decodes an 8-byte little-endian int64. Mirrors the `mgrpc.Int64LE` encoder used server-side. Returns 0 for short inputs.
Types ¶
type BloomClient ¶
type BloomClient struct {
// contains filtered or unexported fields
}
BloomClient is the typed wrapper for Bloom-filter pipelines.
func NewBloomClient ¶
func NewBloomClient(inner Inner) *BloomClient
NewBloomClient wraps the generic QueryService client with Bloom approximate-size responses.
func (*BloomClient) Get ¶
func (c *BloomClient) Get(ctx context.Context, entity string, opts ...Option) (BloomValue, bool, error)
Get returns the Bloom filter's shape for the entity's all-time sketch.
func (*BloomClient) GetWindow ¶
func (c *BloomClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) (BloomValue, error)
GetWindow returns the merged Bloom-filter shape over the most-recent `duration`. The merged sketch's capacity / hash count match the per-bucket sketches' shape; ApproxSize reflects the union over the window's buckets.
func (*BloomClient) GetWindowMany ¶
func (c *BloomClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([]BloomValue, error)
GetWindowMany is the batched analog of GetWindow — fetches the merged Bloom-filter shape for N entities in one round-trip. Returns parallel arrays: out[i] is the BloomValue for entities[i]; missing entities yield a zero-valued BloomValue.
type BloomValue ¶
BloomValue carries the Bloom filter's shape — capacity (bits), the number of hash functions, and the approximate set size derived from the populated bit count.
type HLLClient ¶
type HLLClient struct {
// contains filtered or unexported fields
}
HLLClient is the typed wrapper for HLL pipelines whose state is the axiomhq/hyperloglog byte format. Returns cardinality estimates rather than raw sketch bytes.
func NewHLLClient ¶
NewHLLClient wraps the generic QueryService client with HLL cardinality-estimate responses.
func (*HLLClient) GetWindow ¶
func (c *HLLClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) (HLLValue, error)
GetWindow returns the cardinality estimate over the most-recent `duration`.
func (*HLLClient) GetWindowMany ¶
func (c *HLLClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([]HLLValue, error)
GetWindowMany is the batched analog of GetWindow — fetches windowed cardinalities for N entities in one round-trip. Returns parallel arrays: out[i] is the cardinality estimate for entities[i]; missing entities yield a zero-valued HLLValue.
type HLLValue ¶
HLLValue carries the estimated cardinality plus the byte length of the underlying sketch (useful for cluster-wide capacity tracking).
type Inner ¶
type Inner = murmurv1connect.QueryServiceClient
Inner is the underlying Connect-RPC client shape this package wraps. Production: the generated `murmurv1connect.QueryServiceClient`. Tests: a fake satisfying the same shape.
type Option ¶
type Option func(*queryOptions)
Option configures a typed Get / GetMany / GetWindow / GetRange call.
func WithFreshRead ¶
func WithFreshRead() Option
WithFreshRead sets the underlying request's fresh_read flag, bypassing server-side singleflight + cache layers. Used for read-your-writes flows.
type SumClient ¶
type SumClient struct {
// contains filtered or unexported fields
}
SumClient is the typed wrapper for Sum / Count / Min / Max pipelines whose state is `int64` and whose wire shape is 8-byte little-endian. The same client works against any of those four monoid kinds — they all encode int64 the same way.
func NewSumClient ¶
NewSumClient wraps the generic QueryService client with typed int64 responses. Use for any pipeline whose monoid is Sum / Count / Min / Max.
func (*SumClient) Get ¶
Get returns the all-time aggregation value for entity. The bool reports whether the entity exists in the store; missing entities return (0, false, nil). Use this for non-windowed pipelines.
func (*SumClient) GetMany ¶
func (c *SumClient) GetMany(ctx context.Context, entities []string, opts ...Option) ([]int64, []bool, error)
GetMany batches Get for many entities. Order matches input order; missing entities return 0 in the value slice with the corresponding bool false in the present slice.
func (*SumClient) GetRange ¶
func (c *SumClient) GetRange(ctx context.Context, entity string, start, end time.Time, opts ...Option) (int64, error)
GetRange returns the merged value over the absolute time range [start, end] for the given entity. Pipeline must be windowed.
type TopKClient ¶
type TopKClient struct {
// contains filtered or unexported fields
}
TopKClient is the typed wrapper for Misra-Gries Top-K pipelines. Returns ranked items rather than raw sketch bytes.
func NewTopKClient ¶
func NewTopKClient(inner Inner) *TopKClient
NewTopKClient wraps the generic QueryService client with TopK item-list responses.
func (*TopKClient) Get ¶
func (c *TopKClient) Get(ctx context.Context, entity string, opts ...Option) ([]TopKItem, bool, error)
Get returns the ranked top-K items for the entity's all-time sketch. Items are ordered by descending count.
func (*TopKClient) GetWindow ¶
func (c *TopKClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) ([]TopKItem, error)
GetWindow returns the ranked top-K items over the most-recent `duration`.
func (*TopKClient) GetWindowMany ¶
func (c *TopKClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([][]TopKItem, error)
GetWindowMany is the batched analog of GetWindow — fetches windowed ranked-item lists for N entities in one round-trip. Returns parallel arrays: out[i] is the ranked items for entities[i]; missing entities yield a nil slice.