depman

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Dec 30, 2024 License: MIT Imports: 6 Imported by: 0

README

depman - Dependency Manager Go Reference

depman is the nickname of most valuable Duelist in Valorant.

depman is a dependency manager for runtime in Go.

Documentation

Overview

Package depman provides a simple dependency manager for resources. The basic idea is to write a specification for creating a resource, and then create the resource according to that specification. The specification is managed according to Go's comparison operation specification, and if the specifications are the same, the same resource will be returned. In other words, by creating the specification carefully, you can manage the extent to which resources are shared.

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrResourceSpecIsNotComparable = errors.New("resource spec is not comparable")
	ErrCycleDependency             = errors.New("cycle dependency")
	ErrResourceManagerClosed       = errors.New("resource manager was closed")
	ErrResourceManagerAborted      = errors.New("resource manager was aborted")
)

Functions

func ContextWithResourceManager added in v0.2.0

func ContextWithResourceManager(ctx context.Context, rm ResourceManager) context.Context

func RequestResource

func RequestResource[T any](ctx context.Context, spec ResourceSpec[T]) (T, error)
Example
package main

import (
	"context"
	"errors"
	"fmt"
	"sync"

	"github.com/vvakame/depman"
)

var mutex sync.Mutex
var intValue int

type SharedResourceSpec struct{}

func (spec SharedResourceSpec) CreateResource(ctx context.Context) (int, depman.CloseFn, error) {
	mutex.Lock()
	defer mutex.Unlock()

	intValue++

	return intValue, nil, nil
}

type DedicatedResourceSpec struct {
	PtrValue *string
}

func (spec *DedicatedResourceSpec) CreateResource(ctx context.Context) (func(error), depman.CloseFn, error) {
	var err error
	retFn := func(closeErr error) {
		err = closeErr
	}
	closeFun := func(ctx context.Context) error {
		return err
	}

	return retFn, closeFun, nil
}

func main() {
	m := depman.NewManager()
	ctx := depman.ContextWithResourceManager(context.Background(), m)

	// https://go.dev/ref/spec#Comparison_operators
	// > Struct types are comparable if all their field types are comparable
	// This means that the following comparison becomes true.
	if (SharedResourceSpec{}) != (SharedResourceSpec{}) {
		panic("unexpected behavior")
	}

	// run CreateResource method once
	v, err := depman.RequestResource(ctx, SharedResourceSpec{})
	if err != nil {
		panic(err)
	}
	fmt.Println(v)

	// request resource again.
	// and its value is the same as the previous one.
	// because the specification is the same.
	v, err = depman.RequestResource(ctx, SharedResourceSpec{})
	if err != nil {
		panic(err)
	}
	fmt.Println(v)

	err = m.CloseAll(ctx)
	if err != nil {
		panic(err)
	}

	m = depman.NewManager()
	ctx = depman.ContextWithResourceManager(ctx, m)

	// https://go.dev/ref/spec#Comparison_operators
	// > Pointer types are comparable. Two pointer values are equal if they point to the same variable or if both have value nil.
	// This means that the following comparison becomes false.
	spec1 := &DedicatedResourceSpec{}
	spec2 := &DedicatedResourceSpec{}
	if (spec1) == (spec2) {
		panic("unexpected behavior")
	}

	closeErr1 := errors.New("close error 1")
	errFn1, err := depman.RequestResource(ctx, &DedicatedResourceSpec{})
	if err != nil {
		panic(err)
	}
	errFn1(closeErr1)

	closeErr2 := errors.New("close error 2")
	errFn2, err := depman.RequestResource(ctx, &DedicatedResourceSpec{})
	if err != nil {
		panic(err)
	}
	errFn2(closeErr2)

	err = m.CloseAll(ctx)
	if !errors.Is(err, closeErr1) {
		panic("unexpected result")
	}
	if !errors.Is(err, closeErr2) {
		panic("unexpected result")
	}

}
Output:
1
1
Example (SpecCascade)
package main

import (
	"context"
	"fmt"

	"github.com/vvakame/depman"
)

type SumSpec struct {
	Value   int
	current int
	sum     int
}

func (spec SumSpec) CreateResource(ctx context.Context) (int, depman.CloseFn, error) {
	fmt.Println(spec.current)
	if spec.Value == spec.current {
		return spec.sum, nil, nil
	}
	nextSpec := SumSpec{
		Value:   spec.Value,
		current: spec.current + 1,
		sum:     spec.sum + spec.current + 1,
	}
	v, err := depman.RequestResource(ctx, nextSpec)
	return v, nil, err
}

func main() {
	m := depman.NewManager()
	ctx := depman.ContextWithResourceManager(context.Background(), m)

	v, err := depman.RequestResource(ctx, SumSpec{Value: 10})
	if err != nil {
		panic(err)
	}
	fmt.Println(v)

	// cached. so no output in resource creation process.
	v, err = depman.RequestResource(ctx, SumSpec{Value: 10})
	if err != nil {
		panic(err)
	}
	fmt.Println(v)

}
Output:
0
1
2
3
4
5
6
7
8
9
10
55
55

func SetResource added in v0.1.1

func SetResource[T any](ctx context.Context, spec ResourceSpec[T], res T) error
Example
package main

import (
	"context"
	"fmt"

	"github.com/vvakame/depman"
)

type CallbackFnSpec struct {
	Callback func()
}

func (spec *CallbackFnSpec) CreateResource(ctx context.Context) (int, depman.CloseFn, error) {
	spec.Callback()
	return 0, nil, nil
}

func main() {
	m := depman.NewManager()
	ctx := depman.ContextWithResourceManager(context.Background(), m)

	spec := &CallbackFnSpec{
		Callback: func() {
			fmt.Println("callback")
		},
	}
	err := depman.SetResource(ctx, spec, 100)
	if err != nil {
		panic(err)
	}

	// cached. so callback function never called.
	v, err := depman.RequestResource(ctx, spec)
	if err != nil {
		panic(err)
	}
	fmt.Println(v)

}
Output:
100

Types

type CloseFn

type CloseFn = func(ctx context.Context) error

type ResourceManager

type ResourceManager interface {
	CloseAll(ctx context.Context) error
	// contains filtered or unexported methods
}

func NewManager

func NewManager() ResourceManager

func ResourceManagerFromContext added in v0.2.0

func ResourceManagerFromContext(ctx context.Context) ResourceManager

type ResourceSpec

type ResourceSpec[T any] interface {
	CreateResource(ctx context.Context) (T, CloseFn, error)
}

Jump to

Keyboard shortcuts

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