dataloader

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Dec 29, 2022 License: Apache-2.0 Imports: 4 Imported by: 0

README

go-dataloader

A clean, safe, user-friendly implementation of GraphQL's Dataloader, written with generics in go.

Features

  • written in generics with strong type
  • nearly same interface with original nodejs version dataloader
  • promise like thunk design, simply call val, err := loader.Load(ctx, id).Get(ctx)
  • customizable cache, easily wrap lru or redis.
  • customizable scheduler, can manual dispatch, or use time window (default)

Requirement

  • go >= 1.18

Getting Started

package main

import (
    "context"
    "fmt"

    "github.com/yckao/go-dataloader"
)

type ExampleData struct {
    Message string
}

// batch load function is provided by user
// incoming context is the context when create the loader
// return value can set either Result.Value or Result.Error
func batchLoadFn(ctx context.Context, keys []string) []dataloader.Result[*ExampleData] {
    result := make([]dataloader.Result[*ExampleData], len(keys))
    for index, key := range keys {
        result[index] = dataloader.Result[*ExampleData]{
            Value: &ExampleData{
                Message: fmt.Sprintf("Hello %s", key),
            },
        }
    }
    return result
}

func main() {
    ctx := context.Background()

    // context is the dataloader belong to
    // first generics type is the type of key
    // second generics type is the type of value
    // third generics type is cache key
    // user can provide custom cache function to map orignal key to other
    loader := dataloader.New[string, *ExampleData, string](ctx, batchLoadFn)

    // load is a synchronize function return a promise like thunk
    thunk := loader.Load(ctx, "World")

    // get will wait until thunk value or error is set
    val, err := thunk.Get(ctx)

    fmt.Printf("value: %v, err: %v\n", val, err)
}

TODO

  • Examples
  • Docs
  • Support hooks for observability
  • Rewrite tests with mock

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUncomparableKey  = errors.New("cannot use uncomparable key in mirror cache key function")
	ErrUnconvertibleKey = errors.New("cannot use convert key to cache key function")
)

Functions

func WithBatch

func WithBatch[K interface{}, V interface{}, C comparable](useBatch bool) option[K, V, C]

func WithBatchScheduleFn

func WithBatchScheduleFn[K interface{}, V interface{}, C comparable](batchScheduleFn BatchScheduleFn) option[K, V, C]

func WithCacheKeyFn

func WithCacheKeyFn[K interface{}, V interface{}, C comparable](cacheKeyFn CacheKeyFn[K, C]) option[K, V, C]

func WithCacheMap

func WithCacheMap[K interface{}, V interface{}, C comparable](cacheMap CacheMap[C, *Thunk[V]]) option[K, V, C]

func WithMaxBatchSize

func WithMaxBatchSize[K interface{}, V interface{}, C comparable](maxBatchSize int) option[K, V, C]

Types

type Batch

type Batch interface {
	Full() <-chan struct{}
	Dispatch() <-chan struct{}
}

type BatchLoadFn

type BatchLoadFn[K interface{}, V interface{}] func(context.Context, []K) []Result[V]

type BatchScheduleFn

type BatchScheduleFn func(ctx context.Context, batch Batch, callback func())

func NewTimeWindowScheduler

func NewTimeWindowScheduler(t time.Duration) BatchScheduleFn

type CacheKeyFn

type CacheKeyFn[K interface{}, C comparable] func(ctx context.Context, key K) (C, error)

func NewMirrorCacheKey

func NewMirrorCacheKey[K interface{}, C comparable]() CacheKeyFn[K, C]

type CacheKeyFunc

type CacheKeyFunc[K interface{}, C comparable] func(ctx context.Context, key K) (C, error)

type CacheMap

type CacheMap[C comparable, V interface{}] interface {
	Get(ctx context.Context, key C) (V, error)
	Set(ctx context.Context, key C, val V) error
	Delete(ctx context.Context, key C) error
	Clear(ctx context.Context) error
}

type DataLoader

type DataLoader[K interface{}, V interface{}, C comparable] interface {
	Load(context.Context, K) *Thunk[V]
	LoadMany(context.Context, []K) []*Thunk[V]
	Clear(context.Context, K) DataLoader[K, V, C]
	ClearAll(ctx context.Context) DataLoader[K, V, C]
	Prime(context.Context, K, V) DataLoader[K, V, C]
	Dispatch()
}

func New

func New[K interface{}, V interface{}, C comparable](ctx context.Context, batchLoadFn BatchLoadFn[K, V], options ...option[K, V, C]) DataLoader[K, V, C]

type InMemoryCache

type InMemoryCache[C comparable, V interface{}] struct {
	// contains filtered or unexported fields
}

func NewInMemoryCache

func NewInMemoryCache[C comparable, V interface{}]() *InMemoryCache[C, V]

func (*InMemoryCache[C, V]) Clear

func (c *InMemoryCache[C, V]) Clear(ctx context.Context) error

func (*InMemoryCache[C, V]) Delete

func (c *InMemoryCache[C, V]) Delete(ctx context.Context, key C) error

func (*InMemoryCache[C, V]) Get

func (c *InMemoryCache[C, V]) Get(ctx context.Context, key C) (V, error)

func (*InMemoryCache[C, V]) Set

func (c *InMemoryCache[C, V]) Set(ctx context.Context, key C, val V) error

type NoCache

type NoCache[C comparable, V interface{}] struct{}

func NewNoCache

func NewNoCache[C comparable, V interface{}]() *NoCache[C, V]

func (*NoCache[C, V]) Clear

func (c *NoCache[C, V]) Clear(ctx context.Context) error

func (*NoCache[C, V]) Delete

func (c *NoCache[C, V]) Delete(ctx context.Context, key C) error

func (*NoCache[C, V]) Get

func (c *NoCache[C, V]) Get(ctx context.Context, key C) (V, error)

func (*NoCache[C, V]) Set

func (c *NoCache[C, V]) Set(ctx context.Context, key C, val V) error

type Result

type Result[V interface{}] struct {
	Value V
	Error error
}

type Thunk

type Thunk[V interface{}] struct {
	// contains filtered or unexported fields
}

func NewThunk

func NewThunk[V interface{}]() *Thunk[V]

func (*Thunk[V]) Get

func (a *Thunk[V]) Get(ctx context.Context) (V, error)

Directories

Path Synopsis
examples
basic command

Jump to

Keyboard shortcuts

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