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.