depman

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Dec 29, 2024 License: MIT Imports: 5 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.

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, rm depman.ResourceManager) (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, rm, nextSpec)
	return v, nil, err
}

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

	m := depman.NewManager()

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

	// cached. so no output in resource creation process.
	v, err = depman.RequestResource(ctx, m, 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
Example (SpecComparison)
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, rm depman.ResourceManager) (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, rm depman.ResourceManager) (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() {
	ctx := context.Background()

	m := depman.NewManager()

	// 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, m, 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, m, SharedResourceSpec{})
	if err != nil {
		panic(err)
	}
	fmt.Println(v)

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

	m = depman.NewManager()

	// 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, m, &DedicatedResourceSpec{})
	if err != nil {
		panic(err)
	}
	errFn1(closeErr1)

	closeErr2 := errors.New("close error 2")
	errFn2, err := depman.RequestResource(ctx, m, &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

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	ErrResourceSpecIsNotComparable = errors.New("resource spec is not comparable")
)

Functions

func RequestResource

func RequestResource[T any](ctx context.Context, rm ResourceManager, spec ResourceSpec[T]) (T, error)

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

type ResourceSpec

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

Jump to

Keyboard shortcuts

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