Skip to content

Commit

Permalink
add tracking and comparison of latest healthy content before loading …
Browse files Browse the repository at this point in the history
…a module (#5054)

* add tracking and comparison of latest healthy content before loading a module
* add tracking and check for arguments in module loaders

Signed-off-by: erikbaranowski <39704712+erikbaranowski@users.noreply.github.com>

---------

Signed-off-by: erikbaranowski <39704712+erikbaranowski@users.noreply.github.com>
(cherry picked from commit 597bb6b)
  • Loading branch information
erikbaranowski committed Sep 5, 2023
1 parent b4a47eb commit 7b8d8ce
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 3 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ changes that impact end-user behavior are listed; changes to documentation or
internal API changes are not present.


### Bugfixes

- Restart managed components of a module loader only on if module content
changes or the last load failed. This was specifically impacting `module.git`
each time it pulls. (@erikbaranowski)

v0.36.0 (2023-08-30)
--------------------

Expand Down
45 changes: 42 additions & 3 deletions component/module/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package module
import (
"context"
"fmt"
"reflect"
"sync"
"time"

Expand All @@ -14,8 +15,10 @@ type ModuleComponent struct {
opts component.Options
mod component.Module

mut sync.RWMutex
health component.Health
mut sync.RWMutex
health component.Health
latestContent string
latestArgs map[string]any
}

// Exports holds values which are exported from the run module.
Expand All @@ -38,8 +41,13 @@ func NewModuleComponent(o component.Options) (*ModuleComponent, error) {

// LoadFlowContent loads the flow controller with the current component content. It
// will set the component health in addition to return the error so that the consumer
// can rely on either or both.
// can rely on either or both. If the content is the same as the last time it was
// successfully loaded, it will not be reloaded.
func (c *ModuleComponent) LoadFlowContent(args map[string]any, contentValue string) error {
if reflect.DeepEqual(args, c.getLatestArgs()) && contentValue == c.getLatestContent() {
return nil
}

err := c.mod.LoadConfig([]byte(contentValue), args)
if err != nil {
c.setHealth(component.Health{
Expand All @@ -51,11 +59,14 @@ func (c *ModuleComponent) LoadFlowContent(args map[string]any, contentValue stri
return err
}

c.setLatestArgs(args)
c.setLatestContent(contentValue)
c.setHealth(component.Health{
Health: component.HealthTypeHealthy,
Message: "module content loaded",
UpdateTime: time.Now(),
})

return nil
}

Expand All @@ -77,3 +88,31 @@ func (c *ModuleComponent) setHealth(h component.Health) {
defer c.mut.Unlock()
c.health = h
}

func (c *ModuleComponent) setLatestContent(content string) {
c.mut.Lock()
defer c.mut.Unlock()
c.latestContent = content
}

func (c *ModuleComponent) getLatestContent() string {
c.mut.RLock()
defer c.mut.RUnlock()
return c.latestContent
}

func (c *ModuleComponent) setLatestArgs(args map[string]any) {
c.mut.Lock()
defer c.mut.Unlock()

c.latestArgs = make(map[string]any)
for key, value := range args {
c.latestArgs[key] = value
}
}

func (c *ModuleComponent) getLatestArgs() map[string]any {
c.mut.RLock()
defer c.mut.RUnlock()
return c.latestArgs
}

0 comments on commit 7b8d8ce

Please sign in to comment.