Skip to content

Commit

Permalink
Merge pull request #34 from hovsep/v.0.1.0
Browse files Browse the repository at this point in the history
V.0.1.0
  • Loading branch information
hovsep authored Sep 16, 2024
2 parents eda5416 + 9ea0e7d commit 07f1f82
Show file tree
Hide file tree
Showing 12 changed files with 1,208 additions and 202 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/qodana_code_quality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: Qodana
on:
workflow_dispatch:
pull_request:
push:
branches:
- main
- v.0.1.0

jobs:
qodana:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: 'Qodana Scan'
uses: JetBrains/[email protected]
env:
QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }}
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
.idea
.idea
qodana.*
129 changes: 78 additions & 51 deletions component/activation_result.go
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
package component

import "fmt"

// ActivationResult defines the result (possibly an error) of the activation of given component in given cycle
type ActivationResult struct {
activated bool
componentName string
code ActivationCode
activated bool
code ActivationResultCode
err error
}

// ActivationCode denotes a specific info about how a component been activated or why not activated at all
type ActivationCode int
// ActivationResults is a collection
type ActivationResults map[string]*ActivationResult

// ActivationResultCode denotes a specific info about how a component been activated or why not activated at all
type ActivationResultCode int

const (
// ActivationCodeOK ...: component is activated and did not return any errors
ActivationCodeOK ActivationCode = iota
ActivationCodeOK ActivationResultCode = iota

// ActivationCodeNoInput ...: component is not activated because it has no input set
ActivationCodeNoInput
Expand All @@ -31,68 +36,90 @@ const (
ActivationCodePanicked
)

func (ar ActivationResult) HasError() bool {
return ar.Error() != nil
// NewActivationResult creates a new activation result for given component
func NewActivationResult(componentName string) *ActivationResult {
return &ActivationResult{
componentName: componentName,
}
}

func (ar ActivationResult) ComponentName() string {
return ar.componentName
// SetActivated setter
func (ar *ActivationResult) SetActivated(activated bool) *ActivationResult {
ar.activated = activated
return ar
}

func (ar ActivationResult) Activated() bool {
return ar.activated
// WithActivationCode setter
func (ar *ActivationResult) WithActivationCode(code ActivationResultCode) *ActivationResult {
ar.code = code
return ar
}

func (ar ActivationResult) Error() error {
return ar.err
// WithError setter
func (ar *ActivationResult) WithError(err error) *ActivationResult {
ar.err = err
return ar
}

func (c *Component) newActivationResultOK() ActivationResult {
return ActivationResult{
activated: true,
componentName: c.Name(),
code: ActivationCodeOK,
}
// newActivationResultOK builds a specific activation result
func (c *Component) newActivationResultOK() *ActivationResult {
return NewActivationResult(c.Name()).SetActivated(true).WithActivationCode(ActivationCodeOK)
}

func (c *Component) newActivationCodeNoInput() ActivationResult {
return ActivationResult{
activated: false,
componentName: c.Name(),
code: ActivationCodeNoInput,
}
// newActivationCodeNoInput builds a specific activation result
func (c *Component) newActivationCodeNoInput() *ActivationResult {
return NewActivationResult(c.Name()).SetActivated(false).WithActivationCode(ActivationCodeNoInput)
}

func (c *Component) newActivationCodeNoFunction() ActivationResult {
return ActivationResult{
activated: false,
componentName: c.Name(),
code: ActivationCodeNoFunction,
}
// newActivationCodeNoFunction builds a specific activation result
func (c *Component) newActivationCodeNoFunction() *ActivationResult {
return NewActivationResult(c.Name()).SetActivated(false).WithActivationCode(ActivationCodeNoFunction)
}

func (c *Component) newActivationCodeWaitingForInput() ActivationResult {
return ActivationResult{
activated: false,
componentName: c.Name(),
code: ActivationCodeWaitingForInput,
}
// newActivationCodeWaitingForInput builds a specific activation result
func (c *Component) newActivationCodeWaitingForInput() *ActivationResult {
return NewActivationResult(c.Name()).SetActivated(false).WithActivationCode(ActivationCodeWaitingForInput)
}

func (c *Component) newActivationCodeReturnedError(err error) ActivationResult {
return ActivationResult{
activated: true,
componentName: c.Name(),
code: ActivationCodeReturnedError,
err: err,
}
// newActivationCodeReturnedError builds a specific activation result
func (c *Component) newActivationCodeReturnedError(err error) *ActivationResult {
return NewActivationResult(c.Name()).
SetActivated(true).
WithActivationCode(ActivationCodeReturnedError).
WithError(fmt.Errorf("component returned an error: %w", err))
}

func (c *Component) newActivationCodePanicked(err error) ActivationResult {
return ActivationResult{
activated: true,
componentName: c.Name(),
code: ActivationCodePanicked,
err: err,
}
// newActivationCodePanicked builds a specific activation result
func (c *Component) newActivationCodePanicked(err error) *ActivationResult {
return NewActivationResult(c.Name()).SetActivated(true).WithActivationCode(ActivationCodePanicked).WithError(err)
}

// ComponentName getter
func (ar *ActivationResult) ComponentName() string {
return ar.componentName
}

// Activated getter
func (ar *ActivationResult) Activated() bool {
return ar.activated
}

// Error getter
func (ar *ActivationResult) Error() error {
return ar.err
}

// Code getter
func (ar *ActivationResult) Code() ActivationResultCode {
return ar.code
}

// HasError returns true when activation result has an error
func (ar *ActivationResult) HasError() bool {
return ar.code == ActivationCodeReturnedError && ar.Error() != nil
}

// HasPanic returns true when activation result is derived from panic
func (ar *ActivationResult) HasPanic() bool {
return ar.code == ActivationCodePanicked && ar.Error() != nil
}
35 changes: 18 additions & 17 deletions component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"errors"
"fmt"
"github.com/hovsep/fmesh/port"
"runtime/debug"
)

type ActivationFunc func(inputs port.Ports, outputs port.Ports) error
Expand All @@ -22,12 +21,14 @@ type Component struct {
type Components map[string]*Component

// NewComponent creates a new empty component
// TODO: rename all constructors to New
func NewComponent(name string) *Component {
return &Component{name: name}
}

// NewComponents creates a collection of components
// names are optional and can be used to create multiple empty components in one call
// @TODO: rename all such constructors to NewCollection
func NewComponents(names ...string) Components {
components := make(Components, len(names))
for _, name := range names {
Expand Down Expand Up @@ -86,28 +87,26 @@ func (c *Component) hasActivationFunction() bool {
}

// MaybeActivate tries to run the activation function if all required conditions are met
func (c *Component) MaybeActivate() (activationResult ActivationResult) {
func (c *Component) MaybeActivate() (activationResult *ActivationResult) {
defer func() {
if r := recover(); r != nil {
errorFormat := "panicked with: %v, stacktrace: %s"
if _, ok := r.(error); ok {
errorFormat = "panicked with: %w, stacktrace: %s"
}
activationResult = c.newActivationCodePanicked(fmt.Errorf(errorFormat, r, debug.Stack()))
//Clear inputs and exit
c.inputs.ClearSignal()
activationResult = c.newActivationCodePanicked(fmt.Errorf("panicked with: %v", r))
}
}()

//@TODO:: https://github.com/hovsep/fmesh/issues/15
if !c.inputs.AnyHasSignal() {
//No inputs set, stop here
activationResult = c.newActivationCodeNoInput()
if !c.hasActivationFunction() {
//Activation function is not set (maybe useful while the mesh is under development)
activationResult = c.newActivationCodeNoFunction()

return
}

if !c.hasActivationFunction() {
//Activation function is not set (maybe useful while the mesh is under development)
activationResult = c.newActivationCodeNoFunction()
//@TODO:: https://github.com/hovsep/fmesh/issues/15
if !c.inputs.AnyHasSignal() {
//No inputs set, stop here
activationResult = c.newActivationCodeNoInput()

return
}
Expand Down Expand Up @@ -159,8 +158,10 @@ func (components Components) ByName(name string) *Component {
return components[name]
}

// Add adds a component to collection
func (components Components) Add(component *Component) Components {
components[component.Name()] = component
// Add adds new components to existing collection
func (components Components) Add(newComponents ...*Component) Components {
for _, component := range newComponents {
components[component.Name()] = component
}
return components
}
Loading

0 comments on commit 07f1f82

Please sign in to comment.