From 72dc2fe4fd82508ee9720c4437e685a9a17d8310 Mon Sep 17 00:00:00 2001 From: hovsep Date: Tue, 24 Sep 2024 23:45:27 +0300 Subject: [PATCH 1/3] Comments fixed --- component/activation_result.go | 12 ++++++------ component/collection.go | 2 +- component/component.go | 4 ++-- component/state_snapshot.go | 4 ++-- port/port.go | 28 ++++++++++++++-------------- signal/group.go | 4 +++- 6 files changed, 28 insertions(+), 26 deletions(-) diff --git a/component/activation_result.go b/component/activation_result.go index bea6f33..e74aa58 100644 --- a/component/activation_result.go +++ b/component/activation_result.go @@ -19,22 +19,22 @@ type ActivationResult struct { type ActivationResultCode int const ( - // ActivationCodeOK ...: component is activated and did not return any errors + // ActivationCodeOK : component is activated and did not return any errors ActivationCodeOK ActivationResultCode = iota - // ActivationCodeNoInput ...: component is not activated because it has no input set + // ActivationCodeNoInput : component is not activated because it has no input set ActivationCodeNoInput - // ActivationCodeNoFunction ...: component activation function is not set, so we can not activate it + // ActivationCodeNoFunction : component activation function is not set, so we can not activate it ActivationCodeNoFunction - // ActivationCodeWaitingForInput ...: component is waiting for more inputs on some ports + // ActivationCodeWaitingForInput : component is waiting for more inputs on some ports ActivationCodeWaitingForInput - // ActivationCodeReturnedError ...: component is activated, but returned an error + // ActivationCodeReturnedError : component is activated, but returned an error ActivationCodeReturnedError - // ActivationCodePanicked ...: component is activated, but panicked + // ActivationCodePanicked : component is activated, but panicked ActivationCodePanicked ) diff --git a/component/collection.go b/component/collection.go index 3ba87b1..53514f5 100644 --- a/component/collection.go +++ b/component/collection.go @@ -1,6 +1,6 @@ package component -// ComponentCollection is a collection of components with useful methods +// Collection is a collection of components with useful methods type Collection map[string]*Component // NewComponentCollection creates empty collection diff --git a/component/component.go b/component/component.go index 3064bc6..19f6f35 100644 --- a/component/component.go +++ b/component/component.go @@ -143,7 +143,7 @@ func (c *Component) MaybeActivate() (activationResult *ActivationResult) { return } -// FlushInputs ... +// FlushInputs flushes and clears (when needed) input ports // @TODO: hide this method from user func (c *Component) FlushInputs(activationResult *ActivationResult, keepInputSignals bool) { c.Inputs().Flush() @@ -157,7 +157,7 @@ func (c *Component) FlushInputs(activationResult *ActivationResult, keepInputSig } } -// FlushOutputs ... +// FlushOutputs flushes output ports and disposes processed signals // @TODO: hide this method from user func (c *Component) FlushOutputs(activationResult *ActivationResult) { for portName, p := range c.Outputs() { diff --git a/component/state_snapshot.go b/component/state_snapshot.go index 3a2731f..46816a2 100644 --- a/component/state_snapshot.go +++ b/component/state_snapshot.go @@ -16,12 +16,12 @@ func NewStateSnapshot() *StateSnapshot { } } -// InputPortsMetadata ... getter +// InputPortsMetadata getter func (s *StateSnapshot) InputPortsMetadata() port.MetadataMap { return s.inputPortsMetadata } -// OutputPortsMetadata ... getter +// OutputPortsMetadata getter func (s *StateSnapshot) OutputPortsMetadata() port.MetadataMap { return s.outputPortsMetadata } diff --git a/port/port.go b/port/port.go index 8f15441..3a5279f 100644 --- a/port/port.go +++ b/port/port.go @@ -77,6 +77,20 @@ func (p *Port) FlushAndDispose(n int) { p.DisposeSignals(n) } +// Flush pushes signals to pipes and returns true when flushed +// @TODO: hide this method from user +func (p *Port) Flush() bool { + if !p.HasSignals() || !p.HasPipes() { + return false + } + + for _, outboundPort := range p.pipes { + //Fan-Out + ForwardSignals(p, outboundPort) + } + return true +} + // HasSignals says whether port signals is set or not func (p *Port) HasSignals() bool { return len(p.Signals()) > 0 @@ -98,20 +112,6 @@ func (p *Port) PipeTo(toPorts ...*Port) { } } -// Flush pushes signals to pipes, clears the port if needed and returns true when flushed -// @TODO: hide this method from user -func (p *Port) Flush() bool { - if !p.HasSignals() || !p.HasPipes() { - return false - } - - for _, outboundPort := range p.pipes { - //Fan-Out - ForwardSignals(p, outboundPort) - } - return true -} - // ForwardSignals copies all signals from source port to destination port, without clearing the source port func ForwardSignals(source *Port, dest *Port) { dest.PutSignals(source.Signals()...) diff --git a/signal/group.go b/signal/group.go index cb09937..05b7770 100644 --- a/signal/group.go +++ b/signal/group.go @@ -1,5 +1,6 @@ package signal +// Group represents a list of signals type Group []*Signal // NewGroup creates empty group @@ -14,7 +15,7 @@ func NewGroup(payloads ...any) Group { // FirstPayload returns the first signal payload func (group Group) FirstPayload() any { //Intentionally not checking the group len - //as the method does not have returning error (api is simpler) + //as the method does not have returning error (chaining api) //and we can not just return nil, as nil may be a valid payload. //Just letting the runtime panic return group[0].Payload() @@ -41,6 +42,7 @@ func (group Group) With(signals ...*Signal) Group { return group } +// WithPayloads allows to add new signals into the group providing only their payloads func (group Group) WithPayloads(payloads ...any) Group { for _, p := range payloads { group = append(group, New(p)) From 2e84b8d7abf1a71fc4f5d689cff5ec898a88cae7 Mon Sep 17 00:00:00 2001 From: hovsep Date: Wed, 25 Sep 2024 00:17:25 +0300 Subject: [PATCH 2/3] Groups & collections addition optimized --- component/collection.go | 6 +-- cycle/collection.go | 12 +++--- cycle/collection_test.go | 2 +- fmesh.go | 2 +- fmesh_test.go | 10 ++--- .../piping/piping_from_inputs_test.go | 10 ++--- port/collection.go | 3 +- port/group.go | 11 +++--- signal/group.go | 37 +++++++++++-------- 9 files changed, 50 insertions(+), 43 deletions(-) diff --git a/component/collection.go b/component/collection.go index 53514f5..cde1f62 100644 --- a/component/collection.go +++ b/component/collection.go @@ -13,9 +13,9 @@ func (collection Collection) ByName(name string) *Component { return collection[name] } -// Add adds new components to existing collection -func (collection Collection) Add(newComponents ...*Component) Collection { - for _, component := range newComponents { +// Add adds components to existing collection +func (collection Collection) Add(components ...*Component) Collection { + for _, component := range components { collection[component.Name()] = component } return collection diff --git a/cycle/collection.go b/cycle/collection.go index 70edd58..1008d8f 100644 --- a/cycle/collection.go +++ b/cycle/collection.go @@ -8,10 +8,12 @@ func NewCollection() Collection { return make(Collection, 0) } -// Add adds cycle results to existing collection -func (collection Collection) Add(newCycleResults ...*Cycle) Collection { - for _, cycleResult := range newCycleResults { - collection = append(collection, cycleResult) +// With adds cycle results to existing collection +func (collection Collection) With(cycleResults ...*Cycle) Collection { + newCollection := make(Collection, len(collection)+len(cycleResults)) + copy(newCollection, collection) + for i, cycleResult := range cycleResults { + newCollection[len(collection)+i] = cycleResult } - return collection + return newCollection } diff --git a/cycle/collection_test.go b/cycle/collection_test.go index 5c7e0ea..2f4f580 100644 --- a/cycle/collection_test.go +++ b/cycle/collection_test.go @@ -58,7 +58,7 @@ func TestCollection_Add(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - assert.Equal(t, tt.want, tt.cycleResults.Add(tt.args.cycleResults...)) + assert.Equal(t, tt.want, tt.cycleResults.With(tt.args.cycleResults...)) }) } } diff --git a/fmesh.go b/fmesh.go index 4572c9d..af43acd 100644 --- a/fmesh.go +++ b/fmesh.go @@ -102,7 +102,7 @@ func (fm *FMesh) Run() (cycle.Collection, error) { allCycles := cycle.NewCollection() for { cycleResult := fm.runCycle() - allCycles = allCycles.Add(cycleResult) + allCycles = allCycles.With(cycleResult) mustStop, err := fm.mustStop(cycleResult, len(allCycles)) if mustStop { diff --git a/fmesh_test.go b/fmesh_test.go index 2f50674..e09efb7 100644 --- a/fmesh_test.go +++ b/fmesh_test.go @@ -274,7 +274,7 @@ func TestFMesh_Run(t *testing.T) { { name: "empty mesh stops after first cycle", fm: New("fm"), - want: cycle.NewCollection().Add(cycle.New()), + want: cycle.NewCollection().With(cycle.New()), wantErr: false, }, { @@ -294,7 +294,7 @@ func TestFMesh_Run(t *testing.T) { //Fire the mesh fm.Components().ByName("c1").Inputs().ByName("i1").PutSignals(signal.New("start c1")) }, - want: cycle.NewCollection().Add( + want: cycle.NewCollection().With( cycle.New(). WithActivationResults(component.NewActivationResult("c1"). SetActivated(true). @@ -316,7 +316,7 @@ func TestFMesh_Run(t *testing.T) { initFM: func(fm *FMesh) { fm.Components().ByName("c1").Inputs().ByName("i1").PutSignals(signal.New("start")) }, - want: cycle.NewCollection().Add( + want: cycle.NewCollection().With( cycle.New(). WithActivationResults( component.NewActivationResult("c1"). @@ -374,7 +374,7 @@ func TestFMesh_Run(t *testing.T) { c1.Inputs().ByName("i1").PutSignals(signal.New("start c1")) c3.Inputs().ByName("i1").PutSignals(signal.New("start c3")) }, - want: cycle.NewCollection().Add( + want: cycle.NewCollection().With( cycle.New(). WithActivationResults( component.NewActivationResult("c1"). @@ -485,7 +485,7 @@ func TestFMesh_Run(t *testing.T) { c1.Inputs().ByName("i1").PutSignals(signal.New("start c1")) c3.Inputs().ByName("i1").PutSignals(signal.New("start c3")) }, - want: cycle.NewCollection().Add( + want: cycle.NewCollection().With( //c1 and c3 activated, c3 finishes with error cycle.New(). WithActivationResults( diff --git a/integration_tests/piping/piping_from_inputs_test.go b/integration_tests/piping/piping_from_inputs_test.go index 1932581..65d1277 100644 --- a/integration_tests/piping/piping_from_inputs_test.go +++ b/integration_tests/piping/piping_from_inputs_test.go @@ -88,7 +88,7 @@ func Test_PipingFromInput(t *testing.T) { WithOutputsIndexed("o", 1, 2). WithActivationFunc(func(inputs port.Collection, outputs port.Collection) error { //Activate downstream components - outputs.PutSignals(inputs.AllSignals()[0]) + outputs.PutSignals(inputs.ByName("start").Signals().First()) return nil }) @@ -97,7 +97,7 @@ func Test_PipingFromInput(t *testing.T) { WithInputs("i1"). WithOutputs("o1"). WithActivationFunc(func(inputs port.Collection, outputs port.Collection) error { - outputs.PutSignals(signal.New(1 + inputs.AllSignals().FirstPayload().(int))) + outputs.PutSignals(signal.New(1 + inputs.ByName("i1").Signals().FirstPayload().(int))) return nil }) @@ -106,7 +106,7 @@ func Test_PipingFromInput(t *testing.T) { WithInputs("i1"). WithOutputs("o1"). WithActivationFunc(func(inputs port.Collection, outputs port.Collection) error { - outputs.PutSignals(signal.New(1 + inputs.AllSignals().FirstPayload().(int))) + outputs.PutSignals(signal.New(1 + inputs.ByName("i1").Signals().FirstPayload().(int))) return nil }) @@ -115,7 +115,7 @@ func Test_PipingFromInput(t *testing.T) { WithInputs("i1"). WithOutputs("o1"). WithActivationFunc(func(inputs port.Collection, outputs port.Collection) error { - outputs.PutSignals(signal.New(2 * inputs.AllSignals().FirstPayload().(int))) + outputs.PutSignals(signal.New(2 * inputs.ByName("i1").Signals().FirstPayload().(int))) return nil }) @@ -138,7 +138,7 @@ func Test_PipingFromInput(t *testing.T) { WithInputsIndexed("i", 1, 2). WithOutputs("log"). WithActivationFunc(func(inputs port.Collection, outputs port.Collection) error { - outputs.ByName("log").PutSignals(inputs.AllSignals()...) + outputs.ByName("log").PutSignals(inputs.ByNames("i1", "i2").Signals()...) return nil }) diff --git a/port/collection.go b/port/collection.go index 128cc72..e404bfe 100644 --- a/port/collection.go +++ b/port/collection.go @@ -103,7 +103,8 @@ func (collection Collection) AddIndexed(prefix string, startIndex int, endIndex return collection.Add(NewIndexedGroup(prefix, startIndex, endIndex)...) } -func (collection Collection) AllSignals() signal.Group { +// Signals returns all signals of all ports in the group +func (collection Collection) Signals() signal.Group { group := signal.NewGroup() for _, p := range collection { group = append(group, p.Signals()...) diff --git a/port/group.go b/port/group.go index fd598db..7caf63b 100644 --- a/port/group.go +++ b/port/group.go @@ -35,12 +35,11 @@ func NewIndexedGroup(prefix string, startIndex int, endIndex int) Group { // With adds ports to group func (group Group) With(ports ...*Port) Group { - for _, port := range ports { - if port == nil { - continue - } - group = append(group, port) + newGroup := make(Group, len(group)+len(ports)) + copy(newGroup, group) + for i, port := range ports { + newGroup[len(group)+i] = port } - return group + return newGroup } diff --git a/signal/group.go b/signal/group.go index 05b7770..af85347 100644 --- a/signal/group.go +++ b/signal/group.go @@ -12,40 +12,45 @@ func NewGroup(payloads ...any) Group { return group } +// First returns the first signal in the group +func (group Group) First() *Signal { + return group[0] +} + // FirstPayload returns the first signal payload func (group Group) FirstPayload() any { - //Intentionally not checking the group len - //as the method does not have returning error (chaining api) - //and we can not just return nil, as nil may be a valid payload. - //Just letting the runtime panic - return group[0].Payload() + return group.First().Payload() } // AllPayloads returns a slice with all payloads of the all signals in the group func (group Group) AllPayloads() []any { - all := make([]any, 0, len(group)) - for _, s := range group { - all = append(all, s.Payload()) + all := make([]any, len(group), len(group)) + for i, sig := range group { + all[i] = sig.Payload() } return all } -// With adds signals to group +// With returns the group with added signals func (group Group) With(signals ...*Signal) Group { - for _, sig := range signals { + newGroup := make(Group, len(group)+len(signals)) + copy(newGroup, group) + for i, sig := range signals { if sig == nil { continue } - group = append(group, sig) + newGroup[len(group)+i] = sig } - return group + return newGroup } -// WithPayloads allows to add new signals into the group providing only their payloads +// WithPayloads returns a group with added signals created from provided payloads func (group Group) WithPayloads(payloads ...any) Group { - for _, p := range payloads { - group = append(group, New(p)) + newGroup := make(Group, len(group)+len(payloads)) + copy(newGroup, group) + for i, p := range payloads { + newGroup[len(group)+i] = New(p) } - return group + return newGroup } From 46bb386b89a48f946ea000a9f9adb3834674e43a Mon Sep 17 00:00:00 2001 From: hovsep Date: Wed, 25 Sep 2024 00:21:12 +0300 Subject: [PATCH 3/3] Try to fix Qodana action --- .github/workflows/qodana_code_quality.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/qodana_code_quality.yml b/.github/workflows/qodana_code_quality.yml index f4305a4..9700004 100644 --- a/.github/workflows/qodana_code_quality.yml +++ b/.github/workflows/qodana_code_quality.yml @@ -15,6 +15,6 @@ jobs: with: fetch-depth: 0 - name: 'Qodana Scan' - uses: JetBrains/qodana-action@v2024.3 + uses: JetBrains/qodana-action@v2024.2 env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} \ No newline at end of file