Skip to content

Commit

Permalink
Background process check callback
Browse files Browse the repository at this point in the history
  • Loading branch information
atterpac committed Jan 18, 2024
1 parent 96a74d7 commit 4d1aeef
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 35 deletions.
39 changes: 28 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,15 @@ Using refresh as a library also opens the ability to add a [Callback](https://gi
### Structs
```go
type Config struct {
RootPath string `toml:"root_path"`
BackgroundExec string `toml:"background_exec"` // Execute that stays running and is unaffected by any reloads npm run dev for example
Ignore Ignore `toml:"ignore"`
ExecList []string `toml:"exec_list"` // See [Execute Lifecycle](https://github.com/atterpac/refresh#execute-lifecycle)
LogLevel string `toml:"log_level"`
Debounce int `toml:"debounce"`
Callback func(*EventCallback) EventHandle
Slog *slog.Logger
RootPath string `toml:"root_path"`
BackgroundExec string `toml:"background_exec"` // Execute that stays running and is unaffected by any reloads npm run dev for example
BackgroundCheck bool `toml:"background_check"`
Ignore Ignore `toml:"ignore"`
ExecList []string `toml:"exec_list"` // See [Execute Lifecycle](https://github.com/atterpac/refresh#execute-lifecycle)
LogLevel string `toml:"log_level"`
Debounce int `toml:"debounce"`
Callback func(*EventCallback) EventHandle
Slog *slog.Logger
}

type Ignore struct {
Expand All @@ -64,9 +65,11 @@ type Ignore struct {
}

type Execute struct {
Cmd string
IsBlocking bool // Should the next command wait for this command to finish
IsPrimary bool // Only one primary command can be run at a time
Cmd string `toml:"cmd" yaml:"cmd"` // Execute command
ChangeDir string `toml:"dir" yaml:"dir"` // If directory needs to be changed to call this command relative to the root path
IsBlocking bool `toml:"blocking" yaml:"blocking"` // Should the following executes wait for this one to complete
IsPrimary bool `toml:"primary" yaml:"primary"` // Only one primary command can be run at a time
DelayNext int `toml:"delay_next" yaml:"delay_next"` // Delay in milliseconds before running command
}
```

Expand Down Expand Up @@ -256,6 +259,8 @@ log_level = "info"
# Debounce setting for ignoring reptitive file system notifications
debounce = 1000 # Milliseconds
# Sets what files the watcher should ignore
background_check = true

[config.ignore]
# Ignore follows normal pattern matching including /**/
# Directories to ignore
Expand All @@ -268,6 +273,8 @@ watched_extensions = ["*.go"]
git_ignore = true

# Runs process in the background and doesnt restart when a refresh is triggered
# Vite dev and other processes take varying durations and the following commands might rely on them being "complete"
# This is where setting background_check = true and using a callback in golang library to confirm its state
[config.background]
cmd="vite dev"

Expand Down Expand Up @@ -295,6 +302,16 @@ cmd="./app"
primary=true
```

### Background Check Callback
There are instances where you want to wait for the "build" steps for something like vite or a server connection that could take a varying amount
of time to reach a ready state. Refresh adds `engine.AttachBackgroundCallback()` which will hault the execute commands until the callback returns
true (or false for error and shutting down). This could be used along side a ping to the vite port for example to ensure it is reached before
running commands that rely on it. This requires 3 things

- `background_check = true` in your config.toml or setting the equivalent in golang structs
- A callback function that is `func() bool` and returns true when ready and false when errored or exited
- Attaching the callback via `engine.AttachBackgroundCallback()` prior to running `engine.Start()`

#### Flags
This method is possible but not the most verbose and controlled way to use refresh

Expand Down
Binary file removed cmd/refresh/app.exe
Binary file not shown.
2 changes: 1 addition & 1 deletion cmd/refresh/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

func main() {
var version string = "0.4.3"
var version string = "0.4.4"

var rootPath string
var execCommand string
Expand Down
27 changes: 14 additions & 13 deletions engine/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,22 @@ import (
)

type Config struct {
RootPath string `toml:"root_path" yaml:"root_path"`
BackgroundStruct Execute `toml:"background" yaml:"background"`
Ignore Ignore `toml:"ignore" yaml:"ignore"`
ExecStruct []Execute `toml:"executes" yaml:"executes"`
ExecList []string `toml:"exec_list" yaml:"exec_list"`
LogLevel string `toml:"log_level" yaml:"log_level"`
Debounce int `toml:"debounce" yaml:"debounce"`
Callback func(*EventCallback) EventHandle
Slog *slog.Logger
ignoreMap ignoreMap
externalSlog bool
RootPath string `toml:"root_path" yaml:"root_path"`
BackgroundStruct Execute `toml:"background" yaml:"background"`
BackgroundCallback func() bool `toml:"-" yaml:"-"`
Ignore Ignore `toml:"ignore" yaml:"ignore"`
ExecStruct []Execute `toml:"executes" yaml:"executes"`
ExecList []string `toml:"exec_list" yaml:"exec_list"`
LogLevel string `toml:"log_level" yaml:"log_level"`
Debounce int `toml:"debounce" yaml:"debounce"`
Callback func(*EventCallback) EventHandle
Slog *slog.Logger
ignoreMap ignoreMap
externalSlog bool
}

// Reads a config.toml file and returns the engine
func (engine *Engine) readConfigFile(path string) *Engine{
func (engine *Engine) readConfigFile(path string) *Engine {
if _, err := toml.DecodeFile(path, &engine); err != nil {
slog.Error("Error reading config file")
slog.Error(err.Error())
Expand All @@ -48,7 +49,6 @@ func (engine *Engine) readConfigYaml(path string) *Engine {
}
return engine
}


// Verify required data is present in config
func (engine *Engine) verifyConfig() {
Expand Down Expand Up @@ -161,3 +161,4 @@ func changeWorkingDirectory(path string) {
slog.Error("Setting new directory", "dir", path)
}
}

20 changes: 18 additions & 2 deletions engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,27 @@ func (engine *Engine) Start() error {
engine.Config.ignoreMap.git = readGitIgnore(engine.Config.RootPath)
}
go backgroundExec(engine.Config.BackgroundStruct.Cmd)
if engine.Config.BackgroundStruct.BackgroundCheck {
if engine.Config.BackgroundCallback == nil {
slog.Error("Background Callback not set")
return errors.New("Background Callback not set")
}
ok := engine.Config.BackgroundCallback()
if !ok {
slog.Error("Background Callback Failed")
return errors.New("Background Callback Failed")
}
}
waitTime := time.Duration(engine.Config.BackgroundStruct.DelayNext) * time.Millisecond
time.Sleep(waitTime)
go engine.reloadProcess()
trapChan := make(chan error)
go engine.SigTrap(trapChan)
go engine.sigTrap(trapChan)
go engine.watch()
return <-trapChan
}

func (engine *Engine) SigTrap(ch chan error) {
func (engine *Engine) sigTrap(ch chan error) {
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, os.Interrupt)
go func() {
Expand Down Expand Up @@ -98,3 +109,8 @@ func NewEngineFromYAML(confPath string) *Engine {
engine.verifyConfig()
return &engine
}

func (engine *Engine) AttachBackgroundCallback(callback func() bool) *Engine {
engine.Config.BackgroundCallback = callback
return engine
}
13 changes: 7 additions & 6 deletions engine/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ import (
)

type Execute struct {
Cmd string `toml:"cmd" yaml:"cmd"` // Execute command
ChangeDir string `toml:"dir" yaml:"dir"` // If directory needs to be changed to call this command relative to the root path
IsBlocking bool `toml:"blocking" yaml:"blocking"` // Should the following executes wait for this one to complete
IsPrimary bool `toml:"primary" yaml:"primary"` // Only one primary command can be run at a time
DelayNext int `toml:"delay_next" yaml:"delay_next"` // Delay in milliseconds before running command
process *os.Process // Stores the Exec.Start() process
Cmd string `toml:"cmd" yaml:"cmd"` // Execute command
ChangeDir string `toml:"dir" yaml:"dir"` // If directory needs to be changed to call this command relative to the root path
IsBlocking bool `toml:"blocking" yaml:"blocking"` // Should the following executes wait for this one to complete
IsPrimary bool `toml:"primary" yaml:"primary"` // Only one primary command can be run at a time
DelayNext int `toml:"delay_next" yaml:"delay_next"` // Delay in milliseconds before running command
BackgroundCheck bool `toml:"background_check" yaml:"background_check"` // Should the background callback be run
process *os.Process // Stores the Exec.Start() process
}

var KILL_STALE = Execute{
Expand Down
3 changes: 3 additions & 0 deletions example/example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ root_path = "./test"
log_level = "debug"
# Debounce setting for ignoring reptitive file system notifications
debounce = 1000 # Milliseconds

# Sets what files the watcher should ignore
[config.ignore]
# Directories to ignore
Expand All @@ -21,6 +22,8 @@ watched_extension = ["*.go"]
# Background commands are run in the background and are not affected by any file changes
[config.background]
cmd="pwd"
# Engine will check for a callback that has to be added in golang to verify if the background process was successful before starting the next command
background_check=true
# Executes are run in order
# cmd is the command to run
# blocking will block the next command from running until it is complete
Expand Down
1 change: 1 addition & 0 deletions example/example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ config:
- '*.go'
background:
cmd: pwd
background_check: true
executes:
- cmd: go mod tidy
blocking: true
Expand Down
1 change: 1 addition & 0 deletions example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ require github.com/atterpac/refresh v0.1.0

require (
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/alexbrainman/ps v0.0.0-20171229230509-b3e1b4a15894 // indirect
github.com/lmittmann/tint v1.0.3 // indirect
github.com/rjeczalik/notify v0.9.3 // indirect
golang.org/x/sys v0.14.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions example/go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/alexbrainman/ps v0.0.0-20171229230509-b3e1b4a15894 h1:A6LgNoQeWttVPnIRYzKsbex/HePFxYT9ygCZvgVJDU0=
github.com/alexbrainman/ps v0.0.0-20171229230509-b3e1b4a15894/go.mod h1:Wgrp3f69GNEJz6CdHKtBqKAWdmYTd1K9IlOV+uuv4Uw=
github.com/lmittmann/tint v1.0.3 h1:W5PHeA2D8bBJVvabNfQD/XW9HPLZK1XoPZH0cq8NouQ=
github.com/lmittmann/tint v1.0.3/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE=
github.com/rjeczalik/notify v0.9.3 h1:6rJAzHTGKXGj76sbRgDiDcYj/HniypXmSJo1SWakZeY=
Expand Down
13 changes: 11 additions & 2 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"time"

refresh "github.com/atterpac/refresh/engine"
)

Expand Down Expand Up @@ -43,9 +45,16 @@ func main() {
}

// watch := refresh.NewEngineFromConfig(config)
watch := refresh.NewEngineFromYAML("./example.yaml")
watch := refresh.NewEngineFromTOML("./example.toml")

watch.Start()
watch.AttachBackgroundCallback(func() bool {
time.Sleep(5000 * time.Millisecond)
return true
})
err := watch.Start()
if err != nil {
panic(err)
}

<-make(chan struct{})
}
Expand Down
Binary file modified example/test/app
Binary file not shown.

0 comments on commit 4d1aeef

Please sign in to comment.