Skip to content

Commit

Permalink
Debug mode
Browse files Browse the repository at this point in the history
  • Loading branch information
hovsep committed Feb 4, 2025
1 parent 22e7e62 commit 5888cf0
Show file tree
Hide file tree
Showing 10 changed files with 133 additions and 107 deletions.
36 changes: 36 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package fmesh

import "log"

const UnlimitedCycles = 0

type Config struct {
// ErrorHandlingStrategy defines how f-mesh will handle errors and panics
ErrorHandlingStrategy ErrorHandlingStrategy
// CyclesLimit defines max number of activation cycles, 0 means no limit
CyclesLimit int
// Debug flag enabled debug mode, when additional information will be logged
Debug bool
Logger *log.Logger
}

var defaultConfig = &Config{
ErrorHandlingStrategy: StopOnFirstErrorOrPanic,
CyclesLimit: 1000,
Debug: false,
Logger: getDefaultLogger(),
}

// withConfig sets the configuration and returns the f-mesh
func (fm *FMesh) withConfig(config *Config) *FMesh {
if fm.HasErr() {
return fm
}

Check warning on line 28 in config.go

View check run for this annotation

Codecov / codecov/patch

config.go#L27-L28

Added lines #L27 - L28 were not covered by tests

fm.config = config

if fm.Logger() == nil {
fm.config.Logger = getDefaultLogger()
}
return fm
}
2 changes: 1 addition & 1 deletion examples/async_input/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func getMesh() *fmesh.FMesh {
//Define pipes
crawler.OutputByName("errors").PipeTo(logger.InputByName("error"))

return fmesh.New("web scraper").WithConfig(fmesh.Config{
return fmesh.NewWithConfig("web scraper", &fmesh.Config{

Check warning on line 152 in examples/async_input/main.go

View check run for this annotation

Codecov / codecov/patch

examples/async_input/main.go#L152

Added line #L152 was not covered by tests
ErrorHandlingStrategy: fmesh.StopOnFirstErrorOrPanic,
}).WithComponents(crawler, logger)

Expand Down
10 changes: 5 additions & 5 deletions examples/stateful_electric_circuit/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,12 @@ func main() {
battery.OutputByName("power_supply").PipeTo(lightbulb.InputByName("power_supply"))
lightbulb.OutputByName("power_demand").PipeTo(battery.InputByName("power_demand"))

fm := fmesh.New("battery_and_lightbulb").
fm := fmesh.NewWithConfig("battery_and_lightbulb", &fmesh.Config{
ErrorHandlingStrategy: fmesh.StopOnFirstErrorOrPanic,
Debug: false,
}).

Check warning on line 148 in examples/stateful_electric_circuit/main.go

View check run for this annotation

Codecov / codecov/patch

examples/stateful_electric_circuit/main.go#L145-L148

Added lines #L145 - L148 were not covered by tests
WithDescription("simple electric simulation").
WithComponents(battery, lightbulb).
WithConfig(fmesh.Config{
ErrorHandlingStrategy: fmesh.StopOnFirstErrorOrPanic,
})
WithComponents(battery, lightbulb)

Check warning on line 150 in examples/stateful_electric_circuit/main.go

View check run for this annotation

Codecov / codecov/patch

examples/stateful_electric_circuit/main.go#L150

Added line #L150 was not covered by tests

// Turn on the lightbulb (yes you can init an output port)
lightbulb.InputByName("start_power_demand").PutSignals(signal.New("start"))
Expand Down
11 changes: 5 additions & 6 deletions examples/strings_processing/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import (

// This example is used in readme.md
func main() {
fm := fmesh.New("hello world").
fm := fmesh.NewWithConfig("hello world", &fmesh.Config{
ErrorHandlingStrategy: fmesh.StopOnFirstErrorOrPanic,
CyclesLimit: 10,
}).

Check warning on line 17 in examples/strings_processing/main.go

View check run for this annotation

Codecov / codecov/patch

examples/strings_processing/main.go#L14-L17

Added lines #L14 - L17 were not covered by tests
WithComponents(
component.New("concat").
WithInputs("i1", "i2").
Expand All @@ -31,11 +34,7 @@ func main() {

this.OutputByName("res").PutSignals(signal.New(strings.ToTitle(inputString)))
return nil
})).
WithConfig(fmesh.Config{
ErrorHandlingStrategy: fmesh.StopOnFirstErrorOrPanic,
CyclesLimit: 10,
})
}))

Check warning on line 37 in examples/strings_processing/main.go

View check run for this annotation

Codecov / codecov/patch

examples/strings_processing/main.go#L37

Added line #L37 was not covered by tests

fm.Components().ByName("concat").Outputs().ByName("res").PipeTo(
fm.Components().ByName("case").Inputs().ByName("i1"),
Expand Down
71 changes: 20 additions & 51 deletions fmesh.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,37 +6,20 @@ import (
"github.com/hovsep/fmesh/common"
"github.com/hovsep/fmesh/component"
"github.com/hovsep/fmesh/cycle"
"log"
"os"
"sync"
)

const UnlimitedCycles = 0

type Config struct {
// ErrorHandlingStrategy defines how f-mesh will handle errors and panics
ErrorHandlingStrategy ErrorHandlingStrategy
// CyclesLimit defines max number of activation cycles, 0 means no limit
CyclesLimit int
}

var defaultConfig = Config{
ErrorHandlingStrategy: StopOnFirstErrorOrPanic,
CyclesLimit: 1000,
}

// FMesh is the functional mesh
type FMesh struct {
common.NamedEntity
common.DescribedEntity
*common.Chainable
components *component.Collection
cycles *cycle.Group
config Config
logger *log.Logger
config *Config
}

// New creates a new f-mesh
// New creates a new f-mesh with default config
func New(name string) *FMesh {
return &FMesh{
NamedEntity: common.NewNamedEntity(name),
Expand All @@ -45,10 +28,14 @@ func New(name string) *FMesh {
components: component.NewCollection(),
cycles: cycle.NewGroup(),
config: defaultConfig,
logger: getDefaultLogger(),
}
}

// NewWithConfig creates a new f-mesh with custom config
func NewWithConfig(name string, config *Config) *FMesh {
return New(name).withConfig(config)
}

// Components getter
func (fm *FMesh) Components() *component.Collection {
if fm.HasErr() {
Expand All @@ -57,7 +44,10 @@ func (fm *FMesh) Components() *component.Collection {
return fm.components
}

//@TODO: add shortcut method: ComponentByName()
// ComponentByName shortcut method
func (fm *FMesh) ComponentByName(name string) *component.Component {
return fm.Components().ByName(name)

Check warning on line 49 in fmesh.go

View check run for this annotation

Codecov / codecov/patch

fmesh.go#L48-L49

Added lines #L48 - L49 were not covered by tests
}

// WithDescription sets a description
func (fm *FMesh) WithDescription(description string) *FMesh {
Expand All @@ -81,23 +71,17 @@ func (fm *FMesh) WithComponents(components ...*component.Component) *FMesh {
return fm.WithErr(c.Err())
}
}
return fm
}

// WithConfig sets the configuration and returns the f-mesh
func (fm *FMesh) WithConfig(config Config) *FMesh {
if fm.HasErr() {
return fm
}

fm.config = config
fm.LogDebug(fmt.Sprintf("%d components added to mesh", fm.Components().Len()))
return fm
}

// runCycle runs one activation cycle (tries to activate ready components)
func (fm *FMesh) runCycle() {
newCycle := cycle.New().WithNumber(fm.cycles.Len() + 1)

fm.LogDebug(fmt.Sprintf("starting activation cycle #%d", newCycle.Number()))

if fm.HasErr() {
newCycle.SetErr(fm.Err())
}
Expand Down Expand Up @@ -142,6 +126,12 @@ func (fm *FMesh) runCycle() {
fm.SetErr(newCycle.Err())
}

if fm.IsDebug() {
for _, ar := range newCycle.ActivationResults() {
fm.LogDebug(fmt.Sprintf("activation result for component %s : activated: %t, , code: %s, is error: %t, is panic: %t, error: %v", ar.ComponentName(), ar.Activated(), ar.Code(), ar.IsError(), ar.IsPanic(), ar.ActivationError()))
}

Check warning on line 132 in fmesh.go

View check run for this annotation

Codecov / codecov/patch

fmesh.go#L130-L132

Added lines #L130 - L132 were not covered by tests
}

fm.cycles = fm.cycles.With(newCycle)
}

Expand Down Expand Up @@ -186,7 +176,6 @@ func (fm *FMesh) drainComponents() {
}

c.FlushOutputs()

}
}

Expand Down Expand Up @@ -289,23 +278,3 @@ func (fm *FMesh) WithErr(err error) *FMesh {
fm.SetErr(err)
return fm
}

func (fm *FMesh) WithLogger(logger *log.Logger) *FMesh {
if fm.HasErr() {
return fm
}

fm.logger = logger
return fm
}

func (fm *FMesh) Logger() *log.Logger {
return fm.logger
}

func getDefaultLogger() *log.Logger {
logger := log.Default()
logger.SetOutput(os.Stdout)
logger.SetFlags(log.LstdFlags | log.Lmsgprefix)
return logger
}
41 changes: 17 additions & 24 deletions fmesh_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ func TestNew(t *testing.T) {
components: component.NewCollection(),
cycles: cycle.NewGroup(),
config: defaultConfig,
logger: getDefaultLogger(),
},
},
{
Expand All @@ -48,7 +47,6 @@ func TestNew(t *testing.T) {
components: component.NewCollection(),
cycles: cycle.NewGroup(),
config: defaultConfig,
logger: getDefaultLogger(),
},
},
}
Expand Down Expand Up @@ -82,7 +80,6 @@ func TestFMesh_WithDescription(t *testing.T) {
components: component.NewCollection(),
cycles: cycle.NewGroup(),
config: defaultConfig,
logger: getDefaultLogger(),
},
},
{
Expand All @@ -98,7 +95,6 @@ func TestFMesh_WithDescription(t *testing.T) {
components: component.NewCollection(),
cycles: cycle.NewGroup(),
config: defaultConfig,
logger: getDefaultLogger(),
},
},
}
Expand All @@ -111,7 +107,7 @@ func TestFMesh_WithDescription(t *testing.T) {

func TestFMesh_WithConfig(t *testing.T) {
type args struct {
config Config
config *Config
}
tests := []struct {
name string
Expand All @@ -123,7 +119,7 @@ func TestFMesh_WithConfig(t *testing.T) {
name: "custom config",
fm: New("fm1"),
args: args{
config: Config{
config: &Config{
ErrorHandlingStrategy: IgnoreAll,
CyclesLimit: 9999,
},
Expand All @@ -134,17 +130,17 @@ func TestFMesh_WithConfig(t *testing.T) {
Chainable: common.NewChainable(),
components: component.NewCollection(),
cycles: cycle.NewGroup(),
config: Config{
config: &Config{
ErrorHandlingStrategy: IgnoreAll,
CyclesLimit: 9999,
Logger: getDefaultLogger(),
},
logger: getDefaultLogger(),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.want, tt.fm.WithConfig(tt.args.config))
assert.Equal(t, tt.want, tt.fm.withConfig(tt.args.config))
})
}
}
Expand Down Expand Up @@ -243,7 +239,7 @@ func TestFMesh_Run(t *testing.T) {
},
{
name: "unsupported error handling strategy",
fm: New("fm").WithConfig(Config{
fm: NewWithConfig("fm", &Config{
ErrorHandlingStrategy: 100,
CyclesLimit: 0,
}).
Expand Down Expand Up @@ -271,10 +267,9 @@ func TestFMesh_Run(t *testing.T) {
},
{
name: "stop on first error on first cycle",
fm: New("fm").
WithConfig(Config{
ErrorHandlingStrategy: StopOnFirstErrorOrPanic,
}).
fm: NewWithConfig("fm", &Config{
ErrorHandlingStrategy: StopOnFirstErrorOrPanic,
}).
WithComponents(
component.New("c1").
WithDescription("This component just returns an unexpected error").
Expand All @@ -298,10 +293,9 @@ func TestFMesh_Run(t *testing.T) {
},
{
name: "stop on first panic on cycle 3",
fm: New("fm").
WithConfig(Config{
ErrorHandlingStrategy: StopOnFirstPanic,
}).
fm: NewWithConfig("fm", &Config{
ErrorHandlingStrategy: StopOnFirstPanic,
}).
WithComponents(
component.New("c1").
WithDescription("This component just sends a number to c2").
Expand Down Expand Up @@ -396,10 +390,9 @@ func TestFMesh_Run(t *testing.T) {
},
{
name: "all errors and panics are ignored",
fm: New("fm").
WithConfig(Config{
ErrorHandlingStrategy: IgnoreAll,
}).
fm: NewWithConfig("fm", &Config{
ErrorHandlingStrategy: IgnoreAll,
}).
WithComponents(
component.New("c1").
WithDescription("This component just sends a number to c2").
Expand Down Expand Up @@ -727,7 +720,7 @@ func TestFMesh_mustStop(t *testing.T) {
{
name: "mesh hit an error",
getFMesh: func() *FMesh {
fm := New("fm").WithConfig(Config{
fm := NewWithConfig("fm", &Config{
ErrorHandlingStrategy: StopOnFirstErrorOrPanic,
CyclesLimit: UnlimitedCycles,
})
Expand All @@ -746,7 +739,7 @@ func TestFMesh_mustStop(t *testing.T) {
{
name: "mesh hit a panic",
getFMesh: func() *FMesh {
fm := New("fm").WithConfig(Config{
fm := NewWithConfig("fm", &Config{
ErrorHandlingStrategy: StopOnFirstPanic,
})
c := cycle.New().WithActivationResults(
Expand Down
Loading

0 comments on commit 5888cf0

Please sign in to comment.