Skip to content
Snippets Groups Projects
Verified Commit b81a2b5f authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

feat: new function StopWatching

parent 1d5bac6c
No related branches found
No related tags found
No related merge requests found
......@@ -29,9 +29,30 @@ func (e WatcherNotActiveError) Error() string {
return "Watcher is not active"
}
// WatcherNotActiveError represents an error when trying to add a path that is already being watched.
type WatcherNotRunningError struct{}
func (e WatcherNotRunningError) Error() string {
return "Watcher is not active"
}
// WatcherAlreadyRunningError represents an error when trying to add a path that is already being watched.
type WatcherAlreadyRunningError struct{}
func (e WatcherAlreadyRunningError) Error() string {
return "Watcher is already running"
}
// LighthouseNotActiveError represents an error when trying to add a path that is already being watched.
type LighthouseNotActiveError struct{}
func (e LighthouseNotActiveError) Error() string {
return "lighthouse is not active"
}
// WatcherNotActiveError represents an error when trying to add a path that is already being watched.
type WatcherAlreadyActiveError struct{}
func (e WatcherAlreadyActiveError) Error() string {
return "Watcher is already active"
}
......@@ -23,8 +23,10 @@ type lighthouse struct {
fsnotify *fsnotify.Watcher
mutex sync.Mutex
active bool
running bool
onError EventErrorCallback
debounce time.Duration
quit chan struct{}
}
// SetOnError Methode, um onError zu setzen
......@@ -47,7 +49,11 @@ type Lighthouse interface {
IsActiveWatched(path string) bool
IsWatched(path string) bool
IsRunning() bool
StartWatching()
IsActive() bool
StartWatching() error
StopWatching() error
SetOnError(callback EventErrorCallback)
SetDebounce(duration time.Duration)
......@@ -56,6 +62,7 @@ type Lighthouse interface {
// NewLighthouse creates a new lighthouse instance.
func NewLighthouse() Lighthouse {
l := &lighthouse{}
l.debounce = 500 * time.Millisecond
l.checkAndInit()
return l
......@@ -63,30 +70,49 @@ func NewLighthouse() Lighthouse {
func (l *lighthouse) checkAndInit() {
var err error
if l.active {
return
}
l.debounce = 500 * time.Millisecond
if l.watchers == nil {
l.watchers = make(map[string]*Watch)
}
if l.fsnotify == nil {
var err error
l.fsnotify, err = fsnotify.NewWatcher()
if err != nil {
return
}
}
// test if fsnotify is running
err = l.fsnotify.Add("/undefined-path-123456789")
if err != nil {
if err.Error() == "inotify instance already closed" {
l.fsnotify, err = fsnotify.NewWatcher()
if err != nil {
return
}
}
}
l.active = true
}
// IsRunning returns true if the watcher is active, false otherwise.
func (l *lighthouse) IsRunning() bool {
l.mutex.Lock()
defer l.mutex.Unlock()
return l.running
}
// IsActive returns true if the watcher is active, false otherwise.
func (l *lighthouse) IsActive() bool {
l.mutex.Lock()
defer l.mutex.Unlock()
return l.active
}
......
......@@ -48,7 +48,7 @@ func TestRemoveWatch(t *testing.T) {
func TestNewLighthouse(t *testing.T) {
l := NewLighthouse()
assert.NotNil(t, l)
assert.True(t, l.IsRunning())
assert.True(t, l.IsActive())
}
func TestIsWatched(t *testing.T) {
......
......@@ -7,7 +7,34 @@ import (
"time"
)
func (l *lighthouse) StartWatching() {
// StopWatching stops watching the given file for changes
// If the watcher is not running, an error WatcherNotRunningError is returned.
func (l *lighthouse) StopWatching() error {
if !l.IsRunning() {
return WatcherNotRunningError{}
}
l.mutex.Lock()
defer l.mutex.Unlock()
close(l.quit)
l.running = false
return nil
}
// StartWatching starts watching the given file for changes
func (l *lighthouse) StartWatching() error {
if l.IsRunning() {
return WatcherAlreadyRunningError{}
}
l.mutex.Lock()
defer l.mutex.Unlock()
l.quit = make(chan struct{})
l.running = true
l.checkAndInit()
go func() {
eventChannel := make(chan fsnotify.Event, 100)
errorChannel := make(chan error, 100)
......@@ -17,7 +44,14 @@ func (l *lighthouse) StartWatching() {
go func() {
for {
l.mutex.Lock()
quit := l.quit
l.mutex.Unlock()
select {
case <-quit:
return
case event := <-l.fsnotify.Events:
eventChannel <- event
case err := <-l.fsnotify.Errors:
......@@ -27,7 +61,14 @@ func (l *lighthouse) StartWatching() {
}()
for {
l.mutex.Lock()
quit := l.quit
l.mutex.Unlock()
select {
case <-quit:
return
case event := <-eventChannel:
debounceMutex.Lock()
......@@ -123,8 +164,12 @@ func (l *lighthouse) StartWatching() {
debounceMutex.Unlock()
case err := <-errorChannel:
go l.onError(err)
if l.onError != nil {
go l.onError(err)
}
}
}
}()
return nil
}
......@@ -143,3 +143,31 @@ func TestRecreateEvent(t *testing.T) {
t.Fail()
}
}
func TestStopWatching(t *testing.T) {
l := NewLighthouse() // Erstellen Sie eine neue Instanz der `lighthouse`-Struktur.
// Start Watching
_ = l.StartWatching()
// Erlauben Sie dem System etwas Zeit, um den Watch-Prozess zu starten.
time.Sleep(time.Second * 1)
if !l.IsRunning() {
t.Fatal("l.active is false, but should be true after StartWatching")
}
// Stop Watching
err := l.StopWatching()
if err != nil {
t.Fatalf("StopWatching failed: %v", err)
}
// Überprüfen Sie, ob die Goroutine und der Watcher gestoppt wurden.
if l.IsRunning() {
t.Fatal("l.active is true, but should be false after StopWatching")
}
_ = l.StartWatching()
assert.True(t, l.IsRunning())
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment