Documentation
¶
Overview ¶
Package uow provides a framework-agnostic Unit of Work and transaction manager for single-binding execution flows.
The package is designed around a small public contract:
- owners resolve one immutable binding per execution
- repositories and services consume UnitOfWork from context
- explicit and ambient execution paths share the same resolver and transaction semantics
- nested transactions are either strict or emulated, depending on Config
The core package is transport-neutral. HTTP and ORM integrations belong in separate packages built on top of Manager, Resolver, and UnitOfWork.
Index ¶
- Variables
- func TenantIDFromContext(ctx context.Context) (string, bool)
- func With(ctx context.Context, uow UnitOfWork) context.Context
- func WithBindingOverride(ctx context.Context, override BindingOverride) context.Context
- func WithTenantID(ctx context.Context, tenantID string) context.Context
- type Adapter
- type BeginOptions
- type BindingInfo
- type BindingOverride
- type BindingResolver
- type Capabilities
- type Config
- type ContextTenantPolicy
- type ErrorKind
- type ExecOption
- type ExecutionConfig
- type Executor
- type FinalizeInput
- type FinalizePolicy
- type Hooks
- type Interceptor
- type IsolationLevel
- type Manager
- func (m *Manager) Attach(ctx context.Context) (context.Context, UnitOfWork, error)
- func (m *Manager) Bind(ctx context.Context, cfg ExecutionConfig) (context.Context, UnitOfWork, error)
- func (m *Manager) Do(ctx context.Context, cfg ExecutionConfig, fn func(ctx context.Context) error) errordeprecated
- func (m *Manager) InNestedTx(ctx context.Context, opts NestedOptions, fn func(ctx context.Context) error) error
- func (m *Manager) InTx(ctx context.Context, cfg TxConfig, fn func(ctx context.Context) error) error
- func (m *Manager) ResolveBinding(ctx context.Context, req ResolutionRequest) (ResolvedBinding, error)
- func (m *Manager) ResolveInfo(ctx context.Context, req ResolutionRequest) (BindingInfo, error)
- func (m *Manager) Run(ctx context.Context, cfg ExecutionConfig, fn func(ctx context.Context) error) error
- type ManagerOptions
- type NestedMode
- type NestedOptions
- type Option
- func WithAdapter(name string) Option
- func WithAdapterSelector(selector Selector) Option
- func WithClient(name string) Option
- func WithClientSelector(selector Selector) Option
- func WithIsolation(level IsolationLevel) Option
- func WithLabel(label string) Option
- func WithReadOnly() Option
- func WithTenant(id string) Option
- func WithTenantSelector(selector Selector) Option
- func WithTimeout(timeout time.Duration) Option
- type Registration
- type Registry
- type ResolutionMode
- type ResolutionRequest
- type ResolvedBinding
- type Resolver
- type RootController
- type Selector
- type TenantResolutionPolicy
- type TransactionMode
- type TransactionalMode
- type Tx
- type TxConfig
- type TxMeta
- type TxOption
- type TxScope
- type UOWError
- type UnitOfWork
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNoAdapterRegistered indicates that the registry is empty. ErrNoAdapterRegistered = errors.New("uow: no adapter registered") // ErrAdapterNotFound indicates that a requested adapter could not be resolved. ErrAdapterNotFound = errors.New("uow: adapter not found") // ErrClientNotFound indicates that a requested client could not be resolved. ErrClientNotFound = errors.New("uow: client not found") // ErrTenantNotResolved indicates that a required tenant was not available. ErrTenantNotResolved = errors.New("uow: tenant not resolved") // ErrTenantBindingNotFound indicates that a tenant-specific binding could not // be resolved. ErrTenantBindingNotFound = errors.New("uow: tenant binding not found") // ErrUOWNotFound indicates that no UnitOfWork is present in context. ErrUOWNotFound = errors.New("uow: unit of work not found") // ErrTxAlreadyClosed indicates that a scope was already finalized. ErrTxAlreadyClosed = errors.New("uow: transaction already closed") // ErrNestedTxUnsupported indicates that strict nested transactions are // unsupported by the selected adapter. ErrNestedTxUnsupported = errors.New("uow: nested transaction unsupported") // ErrRootTxUnsupported indicates that root transactions are unsupported by the // selected adapter. ErrRootTxUnsupported = errors.New("uow: root transaction unsupported") // ErrBeginAborted indicates that begin was vetoed before the adapter call. ErrBeginAborted = errors.New("uow: begin aborted") // ErrBeginFailed indicates that begin failed after the adapter call path was // entered. ErrBeginFailed = errors.New("uow: begin failed") // ErrCommitAborted indicates that commit failed and rollback succeeded. ErrCommitAborted = errors.New("uow: commit aborted") // ErrRollbackFailed indicates that rollback itself failed. ErrRollbackFailed = errors.New("uow: rollback failed") // ErrFinalizationFailed indicates that multiple finalization failures need to // be preserved together. ErrFinalizationFailed = errors.New("uow: finalization failed") // ErrBindingOverrideConflict indicates conflicting explicit and context // selectors. ErrBindingOverrideConflict = errors.New("uow: binding override conflict") // ErrRootOwnershipViolation indicates an attempt to control a root // transaction outside the owning lifecycle. ErrRootOwnershipViolation = errors.New("uow: root ownership violation") // ErrNoActiveTransaction indicates that no root transaction is active. ErrNoActiveTransaction = errors.New("uow: no active transaction") // ErrRollbackOnly indicates that commit is blocked by rollback-only state. ErrRollbackOnly = errors.New("uow: rollback only") // ErrBindingImmutable indicates that a UnitOfWork binding cannot change. ErrBindingImmutable = errors.New("uow: binding immutable") // ErrMultipleRootBindingsForbidden indicates that a single execution cannot // open multiple root bindings. ErrMultipleRootBindingsForbidden = errors.New("uow: multiple root bindings forbidden") // ErrScopeOrderViolation indicates nested scope finalization out of order. ErrScopeOrderViolation = errors.New("uow: scope order violation") // ErrContextCancelled indicates that execution was cancelled before commit. ErrContextCancelled = errors.New("uow: context cancelled") )
Functions ¶
func TenantIDFromContext ¶
TenantIDFromContext returns the tenant identity stored in context.
func With ¶
func With(ctx context.Context, uow UnitOfWork) context.Context
With stores a UnitOfWork in context.
func WithBindingOverride ¶
func WithBindingOverride(ctx context.Context, override BindingOverride) context.Context
WithBindingOverride stores a binding override in context.
Types ¶
type Adapter ¶
type Adapter interface {
Name() string
Capabilities() Capabilities
Begin(ctx context.Context, client any, opts BeginOptions) (Tx, error)
BeginNested(ctx context.Context, parent Tx, opts NestedOptions) (Tx, error)
Commit(ctx context.Context, tx Tx) error
Rollback(ctx context.Context, tx Tx) error
Unwrap(tx Tx) any
}
Adapter abstracts a transactional backend.
type BeginOptions ¶
type BeginOptions struct {
ReadOnly bool
IsolationLevel IsolationLevel
Timeout time.Duration
Label string
}
BeginOptions defines root transaction begin preferences.
type BindingInfo ¶
BindingInfo exposes resolved execution metadata without backend objects.
type BindingOverride ¶
BindingOverride is the context-carried override surface for binding selection.
func BindingOverrideFrom ¶
func BindingOverrideFrom(ctx context.Context) (BindingOverride, bool)
BindingOverrideFrom returns the binding override stored in context.
type BindingResolver ¶
type BindingResolver interface {
ResolveBinding(ctx context.Context, req ResolutionRequest) (ResolvedBinding, error)
}
BindingResolver resolves owner-facing backend bindings.
Repository and service code should continue to consume UnitOfWork instead of using ResolvedBinding directly.
type Capabilities ¶
type Capabilities struct {
RootTransaction bool
NestedTransaction bool
Savepoints bool
ReadOnlyTx bool
IsolationLevels bool
Timeouts bool
MultiTenantAware bool
}
Capabilities describes an adapter's transaction features.
type Config ¶
type Config struct {
NestedMode NestedMode
TransactionMode TransactionMode
DefaultAdapterName string
DefaultClientName string
DefaultFinalizePolicy FinalizePolicy
StrictOptionEnforcement bool
AllowOptionDowngrade bool
RequireTenantResolution bool
}
Config controls resolver and transaction behavior.
func ConfigFromEnv ¶
ConfigFromEnv loads Config from environment variables using the provided prefix. The prefix defaults to UOW when empty.
Supported keys are:
- <PREFIX>_NESTED_MODE
- <PREFIX>_TRANSACTION_MODE
- <PREFIX>_DEFAULT_ADAPTER_NAME
- <PREFIX>_DEFAULT_CLIENT_NAME
- <PREFIX>_STRICT_OPTION_ENFORCEMENT
- <PREFIX>_ALLOW_OPTION_DOWNGRADE
- <PREFIX>_REQUIRE_TENANT_RESOLUTION
- <PREFIX>_DEFAULT_FINALIZE_POLICY (supports only "default")
func DefaultConfig ¶
func DefaultConfig() Config
DefaultConfig returns the package defaults defined by the specification.
type ContextTenantPolicy ¶
type ContextTenantPolicy struct{}
ContextTenantPolicy resolves the tenant identity from WithTenantID.
func (ContextTenantPolicy) ResolveTenant ¶
func (ContextTenantPolicy) ResolveTenant(ctx context.Context) (string, error)
ResolveTenant implements TenantResolutionPolicy.
type ErrorKind ¶
type ErrorKind int
ErrorKind categorizes package errors for programmatic inspection.
const ( // ErrKindConfig indicates invalid configuration or input. ErrKindConfig ErrorKind = iota // ErrKindAdapter indicates backend adapter capability or lifecycle failures. ErrKindAdapter // ErrKindResolver indicates binding resolution failures. ErrKindResolver // ErrKindTransaction indicates transaction lifecycle failures. ErrKindTransaction // ErrKindState indicates invalid UnitOfWork state transitions. ErrKindState // ErrKindTenant indicates tenant resolution failures. ErrKindTenant )
type ExecOption ¶ added in v1.1.0
type ExecOption interface {
// contains filtered or unexported methods
}
ExecOption configures ambient execution settings for Exec(...).
func WithTransactional ¶ added in v1.1.0
func WithTransactional(mode TransactionalMode) ExecOption
WithTransactional configures ambient transaction behavior for Exec(...).
type ExecutionConfig ¶
type ExecutionConfig struct {
AdapterName Selector
ClientName Selector
TenantID Selector
Transactional TransactionalMode
ReadOnly bool
IsolationLevel IsolationLevel
Timeout time.Duration
Label string
}
ExecutionConfig controls managed ambient execution.
The zero value leaves binding selection unspecified, inherits the Manager's ambient transaction mode, and requests default backend transaction options.
func Exec ¶ added in v1.1.0
func Exec(opts ...ExecOption) ExecutionConfig
Exec builds an ExecutionConfig from additive option helpers.
func (ExecutionConfig) Validate ¶ added in v1.1.0
func (c ExecutionConfig) Validate() error
Validate validates an ambient execution configuration.
type Executor ¶
type Executor interface {
InTx(ctx context.Context, cfg TxConfig, fn func(ctx context.Context) error) error
InNestedTx(ctx context.Context, opts NestedOptions, fn func(ctx context.Context) error) error
}
Executor executes explicit transactional callbacks.
type FinalizeInput ¶
type FinalizeInput struct {
Err error
PanicValue any
ContextCancelled bool
UOW UnitOfWork
}
FinalizeInput is passed to a root finalization policy.
type FinalizePolicy ¶
type FinalizePolicy interface {
ShouldRollback(ctx context.Context, input FinalizeInput) bool
}
FinalizePolicy decides whether a managed root transaction should rollback.
Rollback-only and context cancellation remain hard rollback conditions even when a custom policy is configured.
type Hooks ¶
type Hooks interface {
OnBegin(ctx context.Context, meta TxMeta)
OnCommit(ctx context.Context, meta TxMeta, err error)
OnRollback(ctx context.Context, meta TxMeta, err error)
OnNestedBegin(ctx context.Context, meta TxMeta)
}
Hooks observes transaction lifecycle events after the corresponding interceptor phase.
type Interceptor ¶
type Interceptor interface {
BeforeBegin(ctx context.Context, meta TxMeta) error
AfterBegin(ctx context.Context, meta TxMeta, err error)
BeforeCommit(ctx context.Context, meta TxMeta) error
AfterCommit(ctx context.Context, meta TxMeta, err error)
BeforeRollback(ctx context.Context, meta TxMeta) error
AfterRollback(ctx context.Context, meta TxMeta, err error)
}
Interceptor participates in transaction lifecycle phases.
type IsolationLevel ¶
type IsolationLevel string
IsolationLevel is a backend-agnostic transaction isolation preference.
The zero value leaves isolation unspecified.
const ( // IsolationReadUncommitted requests read-uncommitted semantics. IsolationReadUncommitted IsolationLevel = "read_uncommitted" // IsolationReadCommitted requests read-committed semantics. IsolationReadCommitted IsolationLevel = "read_committed" // IsolationRepeatableRead requests repeatable-read semantics. IsolationRepeatableRead IsolationLevel = "repeatable_read" // IsolationSnapshot requests snapshot semantics. IsolationSnapshot IsolationLevel = "snapshot" // IsolationSerializable requests serializable semantics. IsolationSerializable IsolationLevel = "serializable" )
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager owns binding resolution and managed execution.
func NewManager ¶
func NewManager(registry *Registry, cfg Config, opts ManagerOptions) (*Manager, error)
NewManager constructs a Manager.
func (*Manager) Attach ¶ added in v1.1.0
Attach resolves or reuses a default execution-scoped UnitOfWork.
func (*Manager) Bind ¶
func (m *Manager) Bind(ctx context.Context, cfg ExecutionConfig) (context.Context, UnitOfWork, error)
Bind resolves or reuses a non-transactional execution-scoped UnitOfWork.
func (*Manager) InNestedTx ¶
func (m *Manager) InNestedTx(ctx context.Context, opts NestedOptions, fn func(ctx context.Context) error) error
InNestedTx executes fn in a nested transaction scope.
func (*Manager) InTx ¶
InTx executes fn in a root transaction or nested scope.
Example ¶
adapter := newMockAdapter(Capabilities{RootTransaction: true})
registry := NewRegistry()
if err := registry.Register(defaultRegistration(adapter)); err != nil {
panic(err)
}
manager, err := NewManager(registry, DefaultConfig(), ManagerOptions{})
if err != nil {
panic(err)
}
err = manager.InTx(context.Background(), RootTx(
WithLabel("example"),
), func(ctx context.Context) error {
u := MustFrom(ctx)
fmt.Printf("%s/%s tx=%v\n", u.Binding().AdapterName, u.Binding().ClientName, u.InTransaction())
return nil
})
if err != nil {
panic(err)
}
Output: mock/primary tx=true
func (*Manager) ResolveBinding ¶
func (m *Manager) ResolveBinding(ctx context.Context, req ResolutionRequest) (ResolvedBinding, error)
ResolveBinding resolves an owner-facing binding.
func (*Manager) ResolveInfo ¶
func (m *Manager) ResolveInfo(ctx context.Context, req ResolutionRequest) (BindingInfo, error)
ResolveInfo resolves public binding metadata.
type ManagerOptions ¶
type ManagerOptions struct {
TenantPolicy TenantResolutionPolicy
Hooks Hooks
Interceptors []Interceptor
Logger *slog.Logger
}
ManagerOptions configures optional collaborators for Manager.
type NestedMode ¶
type NestedMode int
NestedMode controls how nested transactions behave once a root transaction exists.
const ( // NestedStrict requires adapter-level nested transaction or savepoint // support. NestedStrict NestedMode = iota // NestedEmulated keeps nesting at the UnitOfWork layer and turns nested // rollback into root rollback-only. NestedEmulated )
func ParseNestedMode ¶
func ParseNestedMode(value string) (NestedMode, error)
ParseNestedMode parses a string representation of NestedMode.
type NestedOptions ¶
type NestedOptions struct {
Label string
}
NestedOptions defines nested transaction begin preferences.
type Option ¶ added in v1.1.0
type Option interface {
TxOption
ExecOption
}
Option configures shared fields supported by both Exec(...) and RootTx(...).
func WithAdapter ¶ added in v1.1.0
WithAdapter selects a concrete adapter name for Exec(...) or RootTx(...).
func WithAdapterSelector ¶ added in v1.1.0
WithAdapterSelector applies an adapter selector to Exec(...) or RootTx(...).
func WithClient ¶ added in v1.1.0
WithClient selects a concrete client name for Exec(...) or RootTx(...).
func WithClientSelector ¶ added in v1.1.0
WithClientSelector applies a client selector to Exec(...) or RootTx(...).
func WithIsolation ¶ added in v1.1.0
func WithIsolation(level IsolationLevel) Option
WithIsolation requests a specific transaction isolation level.
func WithReadOnly ¶ added in v1.1.0
func WithReadOnly() Option
WithReadOnly requests a read-only root transaction.
func WithTenant ¶ added in v1.1.0
WithTenant selects a concrete tenant id for Exec(...) or RootTx(...).
func WithTenantSelector ¶ added in v1.1.0
WithTenantSelector applies a tenant selector to Exec(...) or RootTx(...).
func WithTimeout ¶ added in v1.1.0
WithTimeout requests a transaction timeout.
type Registration ¶
type Registration struct {
AdapterName string
ClientName string
TenantID string
Adapter Adapter
Client any
Default bool
Tags map[string]string
}
Registration registers an adapter/client pair, optionally scoped to a tenant.
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry stores adapter/client registrations used by the resolver.
Reads are safe for concurrent use. Writes are serialized.
func (*Registry) MustRegister ¶
func (r *Registry) MustRegister(reg Registration)
MustRegister registers a binding and panics on error.
func (*Registry) Register ¶
func (r *Registry) Register(reg Registration) error
Register registers one adapter/client binding.
func (*Registry) Registrations ¶
func (r *Registry) Registrations() []Registration
Registrations returns a snapshot of the current registrations.
type ResolutionMode ¶
type ResolutionMode int
ResolutionMode controls selector precedence during binding resolution.
const ( // ResolutionAmbient applies BindingOverride before an ambient request. ResolutionAmbient ResolutionMode = iota // ResolutionExplicit applies explicit selectors before BindingOverride. ResolutionExplicit )
type ResolutionRequest ¶
type ResolutionRequest struct {
Mode ResolutionMode
AdapterName Selector
ClientName Selector
TenantID Selector
}
ResolutionRequest describes a binding lookup request.
type ResolvedBinding ¶
type ResolvedBinding struct {
BindingInfo
Adapter Adapter
Client any
}
ResolvedBinding is the owner-facing resolved binding used to create a UnitOfWork.
type Resolver ¶
type Resolver interface {
ResolveInfo(ctx context.Context, req ResolutionRequest) (BindingInfo, error)
}
Resolver resolves public binding metadata.
type RootController ¶
type RootController interface {
CommitRoot(ctx context.Context) error
RollbackRoot(ctx context.Context) error
}
RootController finalizes the active root transaction for owner-managed execution.
type Selector ¶
Selector represents an optional explicit binding selection.
The zero value leaves the selector unspecified. A set selector with an empty value explicitly requests the default or non-tenant choice for that field. Use Select to lock a concrete value, DefaultSelection to request the default selection explicitly, and NoTenant as a clearer tenant-specific alias for an explicit empty selection.
func DefaultSelection ¶ added in v1.1.0
func DefaultSelection() Selector
DefaultSelection returns a Selector that explicitly chooses the default binding for adapter or client resolution.
func NoTenant ¶ added in v1.1.0
func NoTenant() Selector
NoTenant returns a Selector that explicitly opts out of tenant selection.
It is equivalent to DefaultSelection but reads more clearly when used for tenant selectors.
func Select ¶ added in v1.1.0
Select returns a Selector locked to one trimmed value.
Prefer SelectAdapter, SelectClient, or SelectTenant when the target field is known — they communicate intent at the call site.
func SelectAdapter ¶ added in v1.1.0
SelectAdapter returns a Selector that explicitly chooses a named adapter.
func SelectClient ¶ added in v1.1.0
SelectClient returns a Selector that explicitly chooses a named client.
func SelectTenant ¶ added in v1.1.0
SelectTenant returns a Selector that explicitly chooses a named tenant.
type TenantResolutionPolicy ¶
TenantResolutionPolicy resolves a tenant identity from context.
type TransactionMode ¶
type TransactionMode int
TransactionMode controls whether ambient execution starts transactions automatically.
const ( // ExplicitOnly starts a transaction only when an explicit transactional API // is invoked. ExplicitOnly TransactionMode = iota // GlobalAuto starts a transaction for ambient executions unless they opt out. GlobalAuto )
func ParseTransactionMode ¶
func ParseTransactionMode(value string) (TransactionMode, error)
ParseTransactionMode parses a string representation of TransactionMode.
func (TransactionMode) String ¶
func (m TransactionMode) String() string
String implements fmt.Stringer.
type TransactionalMode ¶
type TransactionalMode int
TransactionalMode controls transaction activation for ambient execution.
const ( // TransactionalInherit follows the effective transaction mode. TransactionalInherit TransactionalMode = iota // TransactionalOff disables automatic root transaction creation. TransactionalOff // TransactionalOn forces automatic root transaction creation for the // managed ambient execution. TransactionalOn )
func (TransactionalMode) String ¶
func (m TransactionalMode) String() string
String implements fmt.Stringer.
type TxConfig ¶
type TxConfig struct {
AdapterName Selector
ClientName Selector
TenantID Selector
ReadOnly bool
IsolationLevel IsolationLevel
Timeout time.Duration
Label string
}
TxConfig controls explicit root transaction execution.
The zero value selects the default binding and starts a read-write root transaction with default backend options.
func TxConfigFromExecution ¶ added in v1.1.0
func TxConfigFromExecution(cfg ExecutionConfig) (TxConfig, error)
TxConfigFromExecution copies the shared transaction fields from an ExecutionConfig into a TxConfig after validating the ambient config.
Example ¶
execCfg := Exec(
WithClient("primary"),
WithTransactional(TransactionalOn),
WithReadOnly(),
WithLabel("reporting"),
)
txCfg, err := TxConfigFromExecution(execCfg)
if err != nil {
panic(err)
}
fmt.Printf("client=%s readOnly=%v label=%s\n", txCfg.ClientName.Value, txCfg.ReadOnly, txCfg.Label)
Output: client=primary readOnly=true label=reporting
type TxMeta ¶
type TxMeta struct {
TxID string
TraceID string
SpanID string
AdapterName string
ClientName string
TenantID string
Depth int
Label string
RollbackCause error
}
TxMeta describes a transaction lifecycle event.
type TxOption ¶ added in v1.1.0
type TxOption interface {
// contains filtered or unexported methods
}
TxOption configures shared transactional settings for RootTx(...).
type TxScope ¶
type TxScope interface {
Tx() Tx
Commit(ctx context.Context) error
Rollback(ctx context.Context) error
}
TxScope is the lexical nested transaction scope handle.
type UnitOfWork ¶
type UnitOfWork interface {
Binding() BindingInfo
InTransaction() bool
Root() (Tx, bool)
Current() (Tx, bool)
CurrentHandle() any
BeginNested(ctx context.Context, opts NestedOptions) (TxScope, error)
SetRollbackOnly(reason error) error
IsRollbackOnly() bool
RollbackReason() error
}
UnitOfWork is the application-facing execution-scoped transaction facade.
Implementations are safe for concurrent use within one execution, but remain execution-scoped values and should not be reused after their owning request or job has completed.
func From ¶
func From(ctx context.Context) (UnitOfWork, bool)
From returns the UnitOfWork stored in context.
func MustFrom ¶
func MustFrom(ctx context.Context) UnitOfWork
MustFrom returns the UnitOfWork stored in context or panics with ErrUOWNotFound.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
adapters
|
|
|
gorm
Package gormadapter provides a first-party uow adapter for GORM.
|
Package gormadapter provides a first-party uow adapter for GORM. |
|
sql
Package sqladapter provides a first-party uow adapter for database/sql.
|
Package sqladapter provides a first-party uow adapter for database/sql. |
|
examples
|
|
|
callbacks
command
|
|
|
controller-service-repository
command
|
|
|
fiber-selective-routes
command
|
|
|
gorm
command
|
|
|
http
command
|
|
|
nested-transactions
command
|
|
|
framework
|
|
|
fiber
Package fiberuow provides native Fiber v2 integration for github.com/pakasa-io/uow.
|
Package fiberuow provides native Fiber v2 integration for github.com/pakasa-io/uow. |
|
http
Package httpuow provides net/http integration for github.com/pakasa-io/uow.
|
Package httpuow provides net/http integration for github.com/pakasa-io/uow. |