Ctrl K
ComunidadGuías…

bldr/util/cstate/op.go

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package cstate

import (
	"context"
	"sync"
)

// CStateWriter is passed to the CState callback with a SetObj function.
type CStateWriter[T any] struct {
	*CState[T]
}

// SetObj sets the object.
func (w *CStateWriter[T]) SetObj(obj T) {
	w.obj = obj
}

// queuedOp is an operation queued for Execute to process.
type queuedOp[T any] struct {
	// ctx is the operation context
	ctx context.Context
	// resCh is written to when the operation completes.
	// if ctx is canceled, it will not be written to.
	resCh chan error
	// resOnce ensures resCh is written to only once.
	resOnce sync.Once
	// op is the operation to apply
	op func(ctx context.Context, obj *CStateWriter[T]) (dirty bool, err error)
	// dirty indicates if the state is dirty after calling the op.
	// written before resCh is resolved.
	// read only after resCh is resolved.
	dirty bool
}

// newQueuedOp builds a new remoteOp.
// be sure resCh is buffered and won't block.
// doOp is called while mtx is locked.
func newQueuedOp[T any](
	ctx context.Context,
	resCh chan error,
	op func(ctx context.Context, obj *CStateWriter[T]) (dirty bool, err error),
) *queuedOp[T] {
	return &queuedOp[T]{
		ctx:   ctx,
		resCh: resCh,
		op:    op,
	}
}

// finish marks the operation as complete.
// called by Execute
func (r *queuedOp[T]) finish(err error, dirty bool) {
	r.resOnce.Do(func() {
		r.dirty = dirty
		select {
		case r.resCh <- err:
		default:
		}
	})
}