mirror of
https://github.com/jwetzell/showbridge-go.git
synced 2026-04-26 21:05:30 +00:00
split out module and route creation in router and router output only does one module
This commit is contained in:
@@ -22,10 +22,10 @@ type HTTPServer struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ResponseIOError struct {
|
type ResponseIOError struct {
|
||||||
Index int `json:"index"`
|
Index int `json:"index"`
|
||||||
OutputErrors []string `json:"outputErrors"`
|
OutputError *string `json:"outputError"`
|
||||||
ProcessError *string `json:"processError"`
|
ProcessError *string `json:"processError"`
|
||||||
InputError *string `json:"inputError"`
|
InputError *string `json:"inputError"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type IOResponseData struct {
|
type IOResponseData struct {
|
||||||
@@ -113,14 +113,9 @@ func (hs *HTTPServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
errorToAdd.ProcessError = &errorMsg
|
errorToAdd.ProcessError = &errorMsg
|
||||||
}
|
}
|
||||||
|
|
||||||
if responseIOError.OutputErrors != nil {
|
if responseIOError.OutputError != nil {
|
||||||
outputErrorMsgs := []string{}
|
errorMsg := responseIOError.OutputError.Error()
|
||||||
|
errorToAdd.OutputError = &errorMsg
|
||||||
for _, outputError := range responseIOError.OutputErrors {
|
|
||||||
outputErrorMsgs = append(outputErrorMsgs, outputError.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
errorToAdd.OutputErrors = outputErrorMsgs
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response.IOErrors = append(response.IOErrors, errorToAdd)
|
response.IOErrors = append(response.IOErrors, errorToAdd)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ type RouteError struct {
|
|||||||
|
|
||||||
type RouteIOError struct {
|
type RouteIOError struct {
|
||||||
Index int
|
Index int
|
||||||
OutputErrors []error
|
OutputError error
|
||||||
ProcessError error
|
ProcessError error
|
||||||
InputError error
|
InputError error
|
||||||
}
|
}
|
||||||
|
|||||||
160
router.go
160
router.go
@@ -16,8 +16,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Router struct {
|
type Router struct {
|
||||||
contextCancel context.CancelFunc
|
contextCancel context.CancelFunc
|
||||||
Context context.Context
|
Context context.Context
|
||||||
|
// TODO(jwetzell): change to map for faster lookup
|
||||||
ModuleInstances []module.Module
|
ModuleInstances []module.Module
|
||||||
RouteInstances []route.Route
|
RouteInstances []route.Route
|
||||||
moduleWait sync.WaitGroup
|
moduleWait sync.WaitGroup
|
||||||
@@ -25,6 +26,52 @@ type Router struct {
|
|||||||
tracer trace.Tracer
|
tracer trace.Tracer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Router) addModule(moduleDecl config.ModuleConfig) error {
|
||||||
|
if moduleDecl.Id == "" {
|
||||||
|
return errors.New("module id cannot be empty")
|
||||||
|
}
|
||||||
|
moduleInfo, ok := module.ModuleRegistry[moduleDecl.Type]
|
||||||
|
if !ok {
|
||||||
|
return errors.New("module type not defined")
|
||||||
|
}
|
||||||
|
|
||||||
|
moduleInstanceExists := false
|
||||||
|
for _, moduleInstance := range r.ModuleInstances {
|
||||||
|
if moduleInstance.Id() == moduleDecl.Id {
|
||||||
|
moduleInstanceExists = true
|
||||||
|
return errors.New("duplicate module id")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !moduleInstanceExists {
|
||||||
|
moduleInstance, err := moduleInfo.New(moduleDecl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
r.ModuleInstances = append(r.ModuleInstances, moduleInstance)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Router) addRoute(routeDecl config.RouteConfig) error {
|
||||||
|
routeInstance, err := route.NewRoute(routeDecl)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
r.RouteInstances = append(r.RouteInstances, routeInstance)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Router) getModule(moduleId string) module.Module {
|
||||||
|
for _, moduleInstance := range r.ModuleInstances {
|
||||||
|
if moduleInstance.Id() == moduleId {
|
||||||
|
return moduleInstance
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func NewRouter(config config.Config, tracer trace.Tracer) (*Router, []module.ModuleError, []route.RouteError) {
|
func NewRouter(config config.Config, tracer trace.Tracer) (*Router, []module.ModuleError, []route.RouteError) {
|
||||||
|
|
||||||
router := Router{
|
router := Router{
|
||||||
@@ -39,69 +86,24 @@ func NewRouter(config config.Config, tracer trace.Tracer) (*Router, []module.Mod
|
|||||||
|
|
||||||
for moduleIndex, moduleDecl := range config.Modules {
|
for moduleIndex, moduleDecl := range config.Modules {
|
||||||
|
|
||||||
if moduleDecl.Id == "" {
|
err := router.addModule(moduleDecl)
|
||||||
|
if err != nil {
|
||||||
if moduleErrors == nil {
|
if moduleErrors == nil {
|
||||||
moduleErrors = []module.ModuleError{}
|
moduleErrors = []module.ModuleError{}
|
||||||
}
|
}
|
||||||
moduleErrors = append(moduleErrors, module.ModuleError{
|
moduleErrors = append(moduleErrors, module.ModuleError{
|
||||||
Index: moduleIndex,
|
Index: moduleIndex,
|
||||||
Config: moduleDecl,
|
Config: moduleDecl,
|
||||||
Error: errors.New("module id cannot be empty"),
|
Error: err,
|
||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
moduleInfo, ok := module.ModuleRegistry[moduleDecl.Type]
|
|
||||||
if !ok {
|
|
||||||
if moduleErrors == nil {
|
|
||||||
moduleErrors = []module.ModuleError{}
|
|
||||||
}
|
|
||||||
moduleErrors = append(moduleErrors, module.ModuleError{
|
|
||||||
Index: moduleIndex,
|
|
||||||
Config: moduleDecl,
|
|
||||||
Error: errors.New("module type not defined"),
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
moduleInstanceExists := false
|
|
||||||
for _, moduleInstance := range router.ModuleInstances {
|
|
||||||
if moduleInstance.Id() == moduleDecl.Id {
|
|
||||||
moduleInstanceExists = true
|
|
||||||
if moduleErrors == nil {
|
|
||||||
moduleErrors = []module.ModuleError{}
|
|
||||||
}
|
|
||||||
moduleErrors = append(moduleErrors, module.ModuleError{
|
|
||||||
Index: moduleIndex,
|
|
||||||
Config: moduleDecl,
|
|
||||||
Error: errors.New("duplicate module id"),
|
|
||||||
})
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !moduleInstanceExists {
|
|
||||||
moduleInstance, err := moduleInfo.New(moduleDecl)
|
|
||||||
if err != nil {
|
|
||||||
if moduleErrors == nil {
|
|
||||||
moduleErrors = []module.ModuleError{}
|
|
||||||
}
|
|
||||||
moduleErrors = append(moduleErrors, module.ModuleError{
|
|
||||||
Index: moduleIndex,
|
|
||||||
Config: moduleDecl,
|
|
||||||
Error: err,
|
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
router.ModuleInstances = append(router.ModuleInstances, moduleInstance)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var routeErrors []route.RouteError
|
var routeErrors []route.RouteError
|
||||||
for routeIndex, routeDecl := range config.Routes {
|
for routeIndex, routeDecl := range config.Routes {
|
||||||
routeInstance, err := route.NewRoute(routeDecl)
|
err := router.addRoute(routeDecl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if routeErrors == nil {
|
if routeErrors == nil {
|
||||||
routeErrors = []route.RouteError{}
|
routeErrors = []route.RouteError{}
|
||||||
@@ -113,7 +115,6 @@ func NewRouter(config config.Config, tracer trace.Tracer) (*Router, []module.Mod
|
|||||||
})
|
})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
router.RouteInstances = append(router.RouteInstances, routeInstance)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return &router, moduleErrors, routeErrors
|
return &router, moduleErrors, routeErrors
|
||||||
@@ -179,14 +180,14 @@ func (r *Router) HandleInput(ctx context.Context, sourceId string, payload any)
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
outputErrors := r.HandleOutput(routeCtx, routeInstance.Output(), payload)
|
outputError := r.HandleOutput(routeCtx, routeInstance.Output(), payload)
|
||||||
if outputErrors != nil {
|
if outputError != nil {
|
||||||
if routeIOErrors == nil {
|
if routeIOErrors == nil {
|
||||||
routeIOErrors = []route.RouteIOError{}
|
routeIOErrors = []route.RouteIOError{}
|
||||||
}
|
}
|
||||||
routeIOErrors = append(routeIOErrors, route.RouteIOError{
|
routeIOErrors = append(routeIOErrors, route.RouteIOError{
|
||||||
Index: routeIndex,
|
Index: routeIndex,
|
||||||
OutputErrors: outputErrors,
|
OutputError: outputError,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
routeSpan.End()
|
routeSpan.End()
|
||||||
@@ -197,36 +198,31 @@ func (r *Router) HandleInput(ctx context.Context, sourceId string, payload any)
|
|||||||
return routeFound, routeIOErrors
|
return routeFound, routeIOErrors
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Router) HandleOutput(ctx context.Context, destinationId string, payload any) []error {
|
func (r *Router) HandleOutput(ctx context.Context, destinationId string, payload any) error {
|
||||||
spanCtx, span := r.tracer.Start(ctx, "router.output", trace.WithAttributes(attribute.String("destination.id", destinationId)))
|
spanCtx, span := r.tracer.Start(ctx, "router.output", trace.WithAttributes(attribute.String("destination.id", destinationId)))
|
||||||
defer span.End()
|
defer span.End()
|
||||||
var outputErrors []error
|
|
||||||
for _, moduleInstance := range r.ModuleInstances {
|
destinationModule := r.getModule(destinationId)
|
||||||
if moduleInstance.Id() == destinationId {
|
|
||||||
moduleSpanCtx, moduleSpan := r.tracer.Start(spanCtx, "module.output", trace.WithAttributes(attribute.String("module.id", moduleInstance.Id()), attribute.String("module.type", moduleInstance.Type())))
|
if destinationModule == nil {
|
||||||
err := moduleInstance.Output(moduleSpanCtx, payload)
|
err := errors.New("no module found for destination id")
|
||||||
if err != nil {
|
span.SetStatus(codes.Error, err.Error())
|
||||||
if outputErrors == nil {
|
span.RecordError(err)
|
||||||
outputErrors = []error{}
|
r.logger.Error("no module found for destination id", "destinationId", destinationId)
|
||||||
}
|
return err
|
||||||
outputErrors = append(outputErrors, err)
|
|
||||||
moduleSpan.SetStatus(codes.Error, err.Error())
|
|
||||||
moduleSpan.RecordError(err)
|
|
||||||
r.logger.Error("module output encountered error", "module", moduleInstance.Id(), "error", err)
|
|
||||||
} else {
|
|
||||||
moduleSpan.SetStatus(codes.Ok, "module output successful")
|
|
||||||
}
|
|
||||||
moduleSpan.End()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if outputErrors != nil {
|
moduleOutputCtx, moduleOutputSpan := r.tracer.Start(spanCtx, "module.output", trace.WithAttributes(attribute.String("module.id", destinationModule.Id()), attribute.String("module.type", destinationModule.Type())))
|
||||||
span.SetStatus(codes.Error, "router output error")
|
defer moduleOutputSpan.End()
|
||||||
for _, outputError := range outputErrors {
|
err := destinationModule.Output(moduleOutputCtx, payload)
|
||||||
span.RecordError(outputError)
|
if err != nil {
|
||||||
}
|
moduleOutputSpan.SetStatus(codes.Error, err.Error())
|
||||||
|
moduleOutputSpan.RecordError(err)
|
||||||
|
r.logger.Error("module output encountered error", "module", destinationModule.Id(), "error", err)
|
||||||
|
return err
|
||||||
} else {
|
} else {
|
||||||
span.SetStatus(codes.Ok, "router output successful")
|
moduleOutputSpan.SetStatus(codes.Ok, "module output successful")
|
||||||
}
|
}
|
||||||
return outputErrors
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user