v0.13.1 folder restructure, test script added, format adapter async fix
This commit is contained in:
@@ -0,0 +1,222 @@
|
||||
package pipeline
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"logwisp/internal/plugin"
|
||||
"logwisp/internal/session"
|
||||
"logwisp/internal/sink"
|
||||
"logwisp/internal/source"
|
||||
|
||||
"github.com/lixenwraith/log"
|
||||
)
|
||||
|
||||
// SourceFactory creates source instances with required dependencies
|
||||
type SourceFactory func(
|
||||
id string,
|
||||
config map[string]any,
|
||||
logger *log.Logger,
|
||||
sessions *session.Proxy,
|
||||
) (source.Source, error)
|
||||
|
||||
// SinkFactory creates sink instances with required dependencies
|
||||
type SinkFactory func(
|
||||
id string,
|
||||
config map[string]any,
|
||||
logger *log.Logger,
|
||||
sessions *session.Proxy,
|
||||
) (sink.Sink, error)
|
||||
|
||||
// Registry manages plugin instances for a single pipeline
|
||||
type Registry struct {
|
||||
pipelineName string
|
||||
|
||||
// Instance tracking
|
||||
sourceInstances map[string]source.Source
|
||||
sinkInstances map[string]sink.Sink
|
||||
// Type count tracking (for single instance enforcement)
|
||||
sourceTypeCounts map[string]int
|
||||
sinkTypeCounts map[string]int
|
||||
|
||||
mu sync.RWMutex
|
||||
logger *log.Logger
|
||||
}
|
||||
|
||||
// NewRegistry creates a new registry for a pipeline
|
||||
func NewRegistry(pipelineName string, logger *log.Logger) *Registry {
|
||||
return &Registry{
|
||||
pipelineName: pipelineName,
|
||||
sourceInstances: make(map[string]source.Source),
|
||||
sinkInstances: make(map[string]sink.Sink),
|
||||
sourceTypeCounts: make(map[string]int),
|
||||
sinkTypeCounts: make(map[string]int),
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// CreateSource creates and tracks a source instance
|
||||
func (r *Registry) CreateSource(
|
||||
id string,
|
||||
pluginType string,
|
||||
config map[string]any,
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (source.Source, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
// Check for duplicate instance ID
|
||||
if _, exists := r.sourceInstances[id]; exists {
|
||||
return nil, fmt.Errorf("source instance with ID %s already exists", id)
|
||||
}
|
||||
|
||||
// Check single instance constraint
|
||||
if meta, ok := plugin.GetSourceMetadata(pluginType); ok {
|
||||
if meta.MaxInstances == 1 && r.sourceTypeCounts[pluginType] >= 1 {
|
||||
return nil, fmt.Errorf("source type %s only allows single instance", pluginType)
|
||||
}
|
||||
}
|
||||
|
||||
// Get source constructor
|
||||
constructor, ok := plugin.GetSource(pluginType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown source type: %s", pluginType)
|
||||
}
|
||||
|
||||
// Create instance
|
||||
src, err := constructor(id, config, logger, proxy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create source %s: %w", id, err)
|
||||
}
|
||||
|
||||
// Track instance
|
||||
r.sourceInstances[id] = src
|
||||
r.sourceTypeCounts[pluginType]++
|
||||
|
||||
r.logger.Info("msg", "Created source instance",
|
||||
"pipeline", r.pipelineName,
|
||||
"id", id,
|
||||
"type", pluginType)
|
||||
|
||||
return src, nil
|
||||
}
|
||||
|
||||
// CreateSink creates and tracks a sink instance
|
||||
func (r *Registry) CreateSink(
|
||||
id string,
|
||||
pluginType string,
|
||||
config map[string]any,
|
||||
logger *log.Logger,
|
||||
proxy *session.Proxy,
|
||||
) (sink.Sink, error) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
// Check for duplicate instance ID
|
||||
if _, exists := r.sinkInstances[id]; exists {
|
||||
return nil, fmt.Errorf("sink instance with ID %s already exists", id)
|
||||
}
|
||||
|
||||
// Check single instance constraint
|
||||
if meta, ok := plugin.GetSinkMetadata(pluginType); ok {
|
||||
if meta.MaxInstances == 1 && r.sinkTypeCounts[pluginType] >= 1 {
|
||||
return nil, fmt.Errorf("sink type %s only allows single instance", pluginType)
|
||||
}
|
||||
}
|
||||
|
||||
// Get sink constructor
|
||||
constructor, ok := plugin.GetSink(pluginType)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unknown sink type: %s", pluginType)
|
||||
}
|
||||
|
||||
// Create instance
|
||||
snk, err := constructor(id, config, logger, proxy)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create sink %s: %w", id, err)
|
||||
}
|
||||
|
||||
// Track instance
|
||||
r.sinkInstances[id] = snk
|
||||
r.sinkTypeCounts[pluginType]++
|
||||
|
||||
r.logger.Info("msg", "Created sink instance",
|
||||
"pipeline", r.pipelineName,
|
||||
"id", id,
|
||||
"type", pluginType)
|
||||
|
||||
return snk, nil
|
||||
}
|
||||
|
||||
// GetSourceInstance retrieves a source instance by ID
|
||||
func (r *Registry) GetSourceInstance(id string) (source.Source, bool) {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
src, exists := r.sourceInstances[id]
|
||||
return src, exists
|
||||
}
|
||||
|
||||
// GetSinkInstance retrieves a sink instance by ID
|
||||
func (r *Registry) GetSinkInstance(id string) (sink.Sink, bool) {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
snk, exists := r.sinkInstances[id]
|
||||
return snk, exists
|
||||
}
|
||||
|
||||
// GetAllSources returns all source instances
|
||||
func (r *Registry) GetAllSources() map[string]source.Source {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
|
||||
sources := make(map[string]source.Source, len(r.sourceInstances))
|
||||
for k, v := range r.sourceInstances {
|
||||
sources[k] = v
|
||||
}
|
||||
return sources
|
||||
}
|
||||
|
||||
// GetAllSinks returns all sink instances
|
||||
func (r *Registry) GetAllSinks() map[string]sink.Sink {
|
||||
r.mu.RLock()
|
||||
defer r.mu.RUnlock()
|
||||
|
||||
sinks := make(map[string]sink.Sink, len(r.sinkInstances))
|
||||
for k, v := range r.sinkInstances {
|
||||
sinks[k] = v
|
||||
}
|
||||
return sinks
|
||||
}
|
||||
|
||||
// RemoveSource removes a source instance
|
||||
func (r *Registry) RemoveSource(id string) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
// Decrement type count
|
||||
if src, exists := r.sourceInstances[id]; exists {
|
||||
stats := src.GetStats()
|
||||
if pluginType, ok := stats.Details["type"].(string); ok {
|
||||
r.sourceTypeCounts[pluginType]--
|
||||
}
|
||||
}
|
||||
|
||||
delete(r.sourceInstances, id)
|
||||
}
|
||||
|
||||
// RemoveSink removes a sink instance
|
||||
func (r *Registry) RemoveSink(id string) {
|
||||
r.mu.Lock()
|
||||
defer r.mu.Unlock()
|
||||
|
||||
// Decrement type count
|
||||
if snk, exists := r.sinkInstances[id]; exists {
|
||||
stats := snk.GetStats()
|
||||
if pluginType, ok := stats.Details["type"].(string); ok {
|
||||
r.sinkTypeCounts[pluginType]--
|
||||
}
|
||||
}
|
||||
|
||||
delete(r.sinkInstances, id)
|
||||
}
|
||||
Reference in New Issue
Block a user