Skip to content

Commit

Permalink
Merge pull request #18 from skoef/timeout-config
Browse files Browse the repository at this point in the history
parse service timeout as time.Duration
  • Loading branch information
skoef authored Jan 10, 2024
2 parents 5bdccd9 + 170268d commit 17dafeb
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 19 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ When I found out about anycast-healthchecker (sadly only recently on [HaproxyCon

It is written in Go because I like it and running multiple threads is easy.

## Upgrading

### Upgrading from 1.0.0-beta2 to 1.0.0-beta3

The notation of `timeout` for services changed from int (for number of seconds) to the format `time.ParseDuration` uses, such as "300ms", "-1.5h" or "2h45m".

For example: `10` should become `"10s"` in your config files.

## Example usage

This simple example configures a single service, runs `haproxy_check.sh` every second and manages 2 prefixes based on the exit code of the script:
Expand Down Expand Up @@ -92,7 +100,7 @@ Each service under this section can have the following settings:
| command | Command that will be periodically run to check if the service should be considered up or down. The result is based on the exit code: a non-zero exit codes makes birdwatcher decide the service is down, otherwise it's up. **Required** |
| functionname | Specify the name of the function birdwatcher will generate. You can use this function name to use in your protocol export filter in BIRD. Defaults to **match_route**. |
| interval | The interval in seconds at which birdwatcher will check the service. Defaults to **1** |
| timeout | Time in seconds in which the check command should complete. Afterwards it will be handled as if the check command failed. Defaults to **10** |
| timeout | Time in which the check command should complete. Afterwards it will be handled as if the check command failed. Defaults to **10s**, format following that of [`time.ParseDuration`](https://pkg.go.dev/time#ParseDuration). |
| fail | The amount of times the check command should fail before the service is considered to be down. Defaults to **1** |
| rise | The amount of times the check command should succeed before the service is considered to be up. Defaults to **1** |
| prefixes | Array of prefixes, mixed IPv4 and IPv6. At least 1 prefix is **required** per service |
3 changes: 2 additions & 1 deletion birdwatcher/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"net"
"os"
"time"

"github.com/BurntSushi/toml"
)
Expand All @@ -22,7 +23,7 @@ const (

defaultFunctionName = "match_route"
defaultCheckInterval = 1
defaultServiceTimeout = 10
defaultServiceTimeout = 10 * time.Second
defaultServiceFail = 1
defaultServiceRise = 1
)
Expand Down
21 changes: 12 additions & 9 deletions birdwatcher/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package birdwatcher
import (
"regexp"
"testing"
"time"

"github.com/stretchr/testify/assert"
)
Expand Down Expand Up @@ -135,15 +136,17 @@ func TestConfig(t *testing.T) {
svcs := testConf.GetServices()
if assert.Equal(t, 2, len(svcs)) {
// order of the services is not guaranteed
if svcs[0].name == "foo" {
assert.Equal(t, "foo", svcs[0].name)
} else {
assert.Equal(t, "bar", svcs[0].name)
}
if svcs[1].name == "bar" {
assert.Equal(t, "bar", svcs[1].name)
} else {
assert.Equal(t, "foo", svcs[1].name)
for _, svc := range svcs {
switch svc.name {
case "foo":
assert.Equal(t, 10, svc.Interval)
assert.Equal(t, 20, svc.Rise)
assert.Equal(t, 30, svc.Fail)
assert.Equal(t, time.Second*40, svc.Timeout)
case "bar":
default:
assert.Fail(t, "unexpected service name", "service name: %s", svc.name)
}
}
}
})
Expand Down
8 changes: 2 additions & 6 deletions birdwatcher/servicecheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type ServiceCheck struct {
FunctionName string
Command string
Interval int
Timeout int
Timeout time.Duration
Fail int
Rise int
Prefixes []string
Expand Down Expand Up @@ -159,12 +159,8 @@ func (s *ServiceCheck) performCheck() error {
})
sLog.Debug("performing check")

if s.Timeout <= 0 {
s.Timeout = 1
}

// create context that automatically times out
ctx, cancel := context.WithTimeout(context.Background(), time.Duration(s.Timeout)*time.Second)
ctx, cancel := context.WithTimeout(context.Background(), s.Timeout)
defer cancel()

// split reload command into command/args assuming the first part is the command
Expand Down
3 changes: 2 additions & 1 deletion birdwatcher/servicecheck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package birdwatcher
import (
"net"
"testing"
"time"

"github.com/stretchr/testify/assert"
)
Expand All @@ -16,7 +17,7 @@ func TestServiceCheckPushChannel(t *testing.T) {
Fail: 3,
Rise: 2,
Interval: 1,
Timeout: 2,
Timeout: 2 * time.Second,
prefixes: []net.IPNet{
{IP: net.IP{1, 2, 3, 4}, Mask: net.IPMask{255, 255, 255, 0}},
},
Expand Down
4 changes: 4 additions & 0 deletions birdwatcher/testdata/config/overridden
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ reloadcommand = "/sbin/birdc configure"
command = "/bin/true"
prefixes = ["192.168.0.0/24"]
functionname = "foo_bar"
interval = 10
rise = 20
fail = 30
timeout = "40s"
[services."bar"]
command = "/bin/false"
prefixes = ["192.168.1.0/24", "fc00::/7"]
2 changes: 1 addition & 1 deletion dist/birdwatcher.conf
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ reloadcommand = "/usr/sbin/birdc configure"
# command = "/usr/bin/my_check.sh"
# functionname = "match_route"
# interval = 1
# timeout = 10
# timeout = 10s
# fail = 1
# rise = 1
# prefixes = ["192.168.0.0/24", "fc00::/7"]

0 comments on commit 17dafeb

Please sign in to comment.