typed

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 12, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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

func DecodeInt64(data []byte) int64

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

type BloomValue struct {
	CapacityBits  uint64
	HashFunctions uint32
	ApproxSize    uint64
}

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

func NewHLLClient(inner Inner) *HLLClient

NewHLLClient wraps the generic QueryService client with HLL cardinality-estimate responses.

func (*HLLClient) Get

func (c *HLLClient) Get(ctx context.Context, entity string, opts ...Option) (HLLValue, bool, error)

Get returns the cardinality estimate for the entity's all-time sketch.

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

type HLLValue struct {
	Cardinality uint64
	ByteLen     int
}

HLLValue carries the estimated cardinality plus the byte length of the underlying sketch (useful for cluster-wide capacity tracking).

type Inner

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

func NewSumClient(inner Inner) *SumClient

NewSumClient wraps the generic QueryService client with typed int64 responses. Use for any pipeline whose monoid is Sum / Count / Min / Max.

func (*SumClient) Get

func (c *SumClient) Get(ctx context.Context, entity string, opts ...Option) (int64, bool, error)

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.

func (*SumClient) GetWindow

func (c *SumClient) GetWindow(ctx context.Context, entity string, duration time.Duration, opts ...Option) (int64, error)

GetWindow returns the merged value over the most-recent `duration` for the given entity. Pipeline must be windowed.

func (*SumClient) GetWindowMany

func (c *SumClient) GetWindowMany(ctx context.Context, entities []string, duration time.Duration, opts ...Option) ([]int64, error)

GetWindowMany is the batched analog of GetWindow — fetches windowed values for N entities in one round-trip.

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.

type TopKItem

type TopKItem struct {
	Key   string
	Count uint64
}

TopKItem is one (key, count) pair from a Misra-Gries summary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL