Skip to content

Commit 6b842f6

Browse files
cstocktonChris Stockton
and
Chris Stockton
authored
feat: allow invalid config directories (#1969)
This change will prevent an invalid config directory from shutting down the auth server. To prevent spamming the logs we wait for the reloadInterval between each attempt to check the config dir. --------- Co-authored-by: Chris Stockton <[email protected]>
1 parent 5eec914 commit 6b842f6

File tree

3 files changed

+49
-5
lines changed

3 files changed

+49
-5
lines changed

cmd/serve_cmd.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ func serve(ctx context.Context) {
3434
}
3535

3636
if err := conf.LoadDirectory(watchDir); err != nil {
37-
logrus.WithError(err).Fatal("unable to load config from watch dir")
37+
logrus.WithError(err).Error("unable to load config from watch dir")
3838
}
3939

4040
config, err := conf.LoadGlobalFromEnv()

internal/reloader/reloader.go

+22-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ type Reloader struct {
3030
tickerIval time.Duration
3131
watchFn func() (watcher, error)
3232
reloadFn func(dir string) (*conf.GlobalConfiguration, error)
33+
addDirFn func(ctx context.Context, wr watcher, dir string, dur time.Duration) error
3334
}
3435

3536
func NewReloader(watchDir string) *Reloader {
@@ -39,6 +40,7 @@ func NewReloader(watchDir string) *Reloader {
3940
tickerIval: tickerInterval,
4041
watchFn: newFSWatcher,
4142
reloadFn: defaultReloadFn,
43+
addDirFn: defaultAddDirFn,
4244
}
4345
}
4446

@@ -74,7 +76,7 @@ func (rl *Reloader) Watch(ctx context.Context, fn ConfigFunc) error {
7476
defer tr.Stop()
7577

7678
// Ignore errors, if watch dir doesn't exist we can add it later.
77-
if err := wr.Add(rl.watchDir); err != nil {
79+
if err := rl.addDirFn(ctx, wr, rl.watchDir, reloadInterval); err != nil {
7880
logrus.WithError(err).Error("reloader: error watching config directory")
7981
}
8082

@@ -89,8 +91,8 @@ func (rl *Reloader) Watch(ctx context.Context, fn ConfigFunc) error {
8991
// being moved and then recreated. I've tested all of these basic
9092
// scenarios and wr.WatchList() does not grow which aligns with
9193
// the documented behavior.
92-
if err := wr.Add(rl.watchDir); err != nil {
93-
logrus.WithError(err).Error(err)
94+
if err := rl.addDirFn(ctx, wr, rl.watchDir, reloadInterval); err != nil {
95+
logrus.WithError(err).Error("reloader: error watching config directory")
9496
}
9597

9698
// Check to see if the config is ready to be relaoded.
@@ -141,6 +143,23 @@ func (rl *Reloader) Watch(ctx context.Context, fn ConfigFunc) error {
141143
}
142144
}
143145

146+
// defaultAddDirFn adds a dir to a watcher with a common error and sleep
147+
// duration if the directory doesn't exist.
148+
func defaultAddDirFn(ctx context.Context, wr watcher, dir string, dur time.Duration) error {
149+
if err := wr.Add(dir); err != nil {
150+
tr := time.NewTicker(dur)
151+
defer tr.Stop()
152+
153+
select {
154+
case <-ctx.Done():
155+
return ctx.Err()
156+
case <-tr.C:
157+
return err
158+
}
159+
}
160+
return nil
161+
}
162+
144163
func defaultReloadFn(dir string) (*conf.GlobalConfiguration, error) {
145164
if err := conf.LoadDirectory(dir); err != nil {
146165
return nil, err

internal/reloader/reloader_test.go

+26-1
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ import (
44
"bytes"
55
"context"
66
"errors"
7+
"fmt"
78
"os"
89
"path"
910
"path/filepath"
1011
"testing"
1112
"time"
1213

1314
"github.com/fsnotify/fsnotify"
15+
"github.com/sirupsen/logrus"
1416
"github.com/stretchr/testify/assert"
1517
"github.com/supabase/auth/internal/conf"
1618
"golang.org/x/sync/errgroup"
@@ -49,6 +51,20 @@ func TestWatch(t *testing.T) {
4951
}
5052
}
5153

54+
// test watch invalid dir in addDirFn
55+
{
56+
57+
sentinel := errors.New("sentinel")
58+
wr := newMockWatcher(sentinel)
59+
rl := NewReloader(path.Join(dir, "__not_found__"))
60+
rl.watchFn = func() (watcher, error) { return wr, nil }
61+
62+
err := rl.addDirFn(ctx, wr, "__not_found__", time.Millisecond)
63+
if exp, got := sentinel, err; exp != got {
64+
assert.Equal(t, exp, got)
65+
}
66+
}
67+
5268
// test watch error chan closed
5369
{
5470
rr := mockReloadRecorder()
@@ -138,6 +154,13 @@ func TestWatch(t *testing.T) {
138154
rl := NewReloader(dir)
139155
rl.watchFn = func() (watcher, error) { return wr, wr.getErr() }
140156
rl.reloadFn = rr.reloadFn
157+
rl.addDirFn = func(ctx context.Context, wr watcher, dir string, dur time.Duration) error {
158+
if err := wr.Add(dir); err != nil {
159+
logrus.WithError(err).Error("reloader: error watching config directory")
160+
return err
161+
}
162+
return nil
163+
}
141164

142165
// Need to lower reload ival to pickup config write quicker.
143166
rl.reloadIval = time.Second / 10
@@ -256,6 +279,7 @@ func TestWatch(t *testing.T) {
256279
Name: name,
257280
Op: fsnotify.Create,
258281
}
282+
259283
select {
260284
case <-egCtx.Done():
261285
assert.Nil(t, egCtx.Err())
@@ -411,7 +435,8 @@ func TestReloadCheckAt(t *testing.T) {
411435
}
412436

413437
func helpTestDir(t testing.TB) (dir string, cleanup func()) {
414-
dir = filepath.Join("testdata", t.Name())
438+
name := fmt.Sprintf("%v_%v", t.Name(), time.Now().Nanosecond())
439+
dir = filepath.Join("testdata", name)
415440
err := os.MkdirAll(dir, 0750)
416441
if err != nil && !os.IsExist(err) {
417442
assert.Nil(t, err)

0 commit comments

Comments
 (0)