Documentation
¶
Overview ¶
Package component provides a flexible and extensible component system for building modular applications. It defines interfaces and structures for creating, managing, and controlling the lifecycle of components within an application.
Index ¶
- func Register(name string, creator func() Component)
- func RegisterFuncs(name string, funcs lifecycle.Funcs)
- type BaseComponent
- func (c *BaseComponent) Init(ctx context.Context) error
- func (c *BaseComponent) Logger() *slog.Logger
- func (c *BaseComponent[T]) Options() *T
- func (c *BaseComponent[T]) Setup(container Container, config *Config, rewrite bool) error
- func (c *BaseComponent) Shutdown(ctx context.Context) error
- func (c *BaseComponent) Start(ctx context.Context) error
- func (c *BaseComponent) String() string
- func (c *BaseComponent) Uninit(ctx context.Context) error
- type BaseComponentWithRefs
- func (c *BaseComponentWithRefs) Init(ctx context.Context) error
- func (c *BaseComponentWithRefs) Logger() *slog.Logger
- func (c *BaseComponentWithRefs[T, R]) Refs() *R
- func (c *BaseComponentWithRefs[T, R]) Setup(container Container, config *Config, rewrite bool) error
- func (c *BaseComponentWithRefs) Shutdown(ctx context.Context) error
- func (c *BaseComponentWithRefs) Start(ctx context.Context) error
- func (c *BaseComponentWithRefs) String() string
- func (c *BaseComponentWithRefs) Uninit(ctx context.Context) error
- type Component
- type Config
- type Container
- type Group
- func (g *Group) AddComponent(uuid string, com Component) Component
- func (g *Group) GetComponent(uuid string) Component
- func (g *Group) Init(ctx context.Context) error
- func (g *Group) Shutdown(ctx context.Context) error
- func (g *Group) Start(ctx context.Context) error
- func (g *Group) Uninit(ctx context.Context) error
- type OptionalReference
- type Reference
- type Resolver
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Register ¶
Register makes a component creator available by the provided name. It panics if Register is called twice with the same name or if creator is nil.
func RegisterFuncs ¶
RegisterFuncs registers a component creator with lifecycle functions.
Types ¶
type BaseComponent ¶
type BaseComponent[T any] struct { // contains filtered or unexported fields }
BaseComponent provides a basic implementation of the Component interface.
Example ¶
Example test to demonstrate usage of the component package
package main
import (
"context"
"errors"
"fmt"
"log/slog"
"github.com/gopherd/core/component"
"github.com/gopherd/core/typing"
)
// mockComponent is a mock implementation of the Component interface for testing
type mockComponent struct {
component.BaseComponent[mockOptions]
initCalled bool
uninitCalled bool
startCalled bool
shutdownCalled bool
initError bool
startError bool
shutdownError bool
uninitError bool
}
type mockOptions struct {
Value string
}
func (m *mockComponent) Init(ctx context.Context) error {
m.initCalled = true
if m.initError {
return errors.New("mock init error")
}
return nil
}
func (m *mockComponent) Uninit(ctx context.Context) error {
m.uninitCalled = true
if m.uninitError {
return errors.New("mock uninit error")
}
return nil
}
func (m *mockComponent) Start(ctx context.Context) error {
m.startCalled = true
if m.startError {
return errors.New("mock start error")
}
return nil
}
func (m *mockComponent) Shutdown(ctx context.Context) error {
m.shutdownCalled = true
if m.shutdownError {
return errors.New("mock shutdown error")
}
return nil
}
// mockContainer is a mock implementation of the Container interface for testing
type mockContainer struct {
components map[string]component.Component
logger *slog.Logger
}
func newMockContainer() *mockContainer {
return &mockContainer{
components: make(map[string]component.Component),
logger: slog.Default(),
}
}
func (c *mockContainer) GetComponent(uuid string) component.Component {
return c.components[uuid]
}
func (c *mockContainer) Logger() *slog.Logger {
return c.logger
}
func main() {
// Create a mock component
mc := &mockComponent{}
// Setup the component
container := newMockContainer()
config := component.Config{
Name: "ExampleComponent",
UUID: "example-uuid",
Options: typing.NewRawObject(`{"Value":"example"}`),
}
err := mc.Setup(container, &config, false)
if err != nil {
fmt.Printf("Failed to setup component: %v\n", err)
return
}
// Use the component
fmt.Println(mc.String())
fmt.Println(mc.Options().Value)
}
Output: ExampleComponent#example-uuid example
func (*BaseComponent[T]) Options ¶
func (c *BaseComponent[T]) Options() *T
Options returns a pointer to the component's options.
func (*BaseComponent[T]) Setup ¶
func (c *BaseComponent[T]) Setup(container Container, config *Config, rewrite bool) error
Setup implements the Component Setup method.
type BaseComponentWithRefs ¶
type BaseComponentWithRefs[T, R any] struct { BaseComponent[T] // contains filtered or unexported fields }
BaseComponentWithRefs provides a basic implementation of the Component interface with references.
func (*BaseComponentWithRefs[T, R]) Refs ¶
func (c *BaseComponentWithRefs[T, R]) Refs() *R
Refs returns a pointer to the component's references.
func (*BaseComponentWithRefs[T, R]) Setup ¶
func (c *BaseComponentWithRefs[T, R]) Setup(container Container, config *Config, rewrite bool) error
Setup implements the Component Setup method.
type Component ¶
type Component interface {
lifecycle.Lifecycle
fmt.Stringer
// Setup sets up the component with the given container and configuration.
// If rewrite is true, the component should rewrite the configuration.
Setup(c Container, cfg *Config, rewrite bool) error
// Logger returns the logger instance for the component.
// Logger must be guranteed to return a non-nil logger instance after Setup is called.
Logger() *slog.Logger
}
Component defines the interface for a generic logic component.
type Config ¶
type Config struct {
// Name is the component name. It's required.
Name string
// UUID is the unique identifier for the component. It can be empty.
UUID string `json:",omitempty"`
// Refs is the references to other components.
Refs typing.RawObject `json:",omitempty"`
// Options is the configuration options for the component.
Options typing.RawObject `json:",omitempty"`
// TemplateUUID determines if the UUID should be templated.
// If not set, the default value is determined by the service.
TemplateUUID *typing.Bool `json:",omitempty"`
// TemplateRefs determines if the Refs should be templated.
// If not set, the default value is determined by the service.
TemplateRefs *typing.Bool `json:",omitempty"`
// TemplateOptions determines if the Options should be templated.
// If not set, the default value is determined by the service.
TemplateOptions *typing.Bool `json:",omitempty"`
}
Config defines the configuration structure for creating a component.
type Container ¶
type Container interface {
// GetComponent returns a component by its UUID.
GetComponent(uuid string) Component
// Logger returns the logger instance for the container.
Logger() *slog.Logger
}
Container represents a generic container that can hold components.
type Group ¶
type Group struct {
// contains filtered or unexported fields
}
Group manages a group of components.
Example ¶
package main
import (
"context"
"errors"
"fmt"
"log/slog"
"github.com/gopherd/core/component"
)
// mockComponent is a mock implementation of the Component interface for testing
type mockComponent struct {
component.BaseComponent[mockOptions]
initCalled bool
uninitCalled bool
startCalled bool
shutdownCalled bool
initError bool
startError bool
shutdownError bool
uninitError bool
}
type mockOptions struct {
Value string
}
func (m *mockComponent) Init(ctx context.Context) error {
m.initCalled = true
if m.initError {
return errors.New("mock init error")
}
return nil
}
func (m *mockComponent) Uninit(ctx context.Context) error {
m.uninitCalled = true
if m.uninitError {
return errors.New("mock uninit error")
}
return nil
}
func (m *mockComponent) Start(ctx context.Context) error {
m.startCalled = true
if m.startError {
return errors.New("mock start error")
}
return nil
}
func (m *mockComponent) Shutdown(ctx context.Context) error {
m.shutdownCalled = true
if m.shutdownError {
return errors.New("mock shutdown error")
}
return nil
}
// mockContainer is a mock implementation of the Container interface for testing
type mockContainer struct {
components map[string]component.Component
logger *slog.Logger
}
func newMockContainer() *mockContainer {
return &mockContainer{
components: make(map[string]component.Component),
logger: slog.Default(),
}
}
func (c *mockContainer) GetComponent(uuid string) component.Component {
return c.components[uuid]
}
func (c *mockContainer) Logger() *slog.Logger {
return c.logger
}
func main() {
// Create a new group
group := component.NewGroup()
// Create and add components to the group
for i := 0; i < 3; i++ {
mc := &mockComponent{}
uuid := fmt.Sprintf("example-uuid-%d", i)
container := newMockContainer()
_ = mc.Setup(container, &component.Config{Name: fmt.Sprintf("ExampleComponent-%d", i), UUID: uuid}, false)
group.AddComponent(uuid, mc)
}
// Use the group to manage component lifecycle
ctx := context.Background()
_ = group.Init(ctx)
_ = group.Start(ctx)
// Simulate some work
fmt.Println("Components are running...")
// Shutdown and uninitialize
_ = group.Shutdown(ctx)
_ = group.Uninit(ctx)
fmt.Println("All components have been shut down")
}
Output: Components are running... All components have been shut down
func (*Group) AddComponent ¶
AddComponent adds a component to the group. It returns nil if a component with the same UUID already exists.
func (*Group) GetComponent ¶
GetComponent retrieves a component by its UUID.
type OptionalReference ¶
OptionalReference represents an optional reference to another component. If the UUID is empty, the reference is ignored, and Component returns nil.
func OptionalRef ¶
func OptionalRef[T any](uuid string) OptionalReference[T]
OptionalRef creates an optional reference to a component with the given UUID.
func (*OptionalReference[T]) Resolve ¶
func (r *OptionalReference[T]) Resolve(container Container) error
Resolve resolves the reference for the component.
type Reference ¶
type Reference[T any] struct { // contains filtered or unexported fields }
Reference represents a reference to another component.
func (Reference[T]) Component ¶
func (r Reference[T]) Component() T
Component returns the referenced component.
func (Reference[T]) MarshalJSON ¶
MarshalJSON marshals the referenced component UUID to JSON.
func (*Reference[T]) UnmarshalJSON ¶
UnmarshalJSON unmarshals the referenced component UUID from JSON.