-
Notifications
You must be signed in to change notification settings - Fork 189
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Detect network interface change and restart the service when detected
- Loading branch information
Showing
2 changed files
with
96 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
package netstatus | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"reflect" | ||
"sync" | ||
"time" | ||
) | ||
|
||
type Change struct{} | ||
|
||
var handlers struct { | ||
sync.Mutex | ||
c []chan<- Change | ||
} | ||
|
||
var cancel context.CancelFunc | ||
var lastInterfaces []net.Interface | ||
|
||
// Notify sends a Change to c any time the network interfaces status change. | ||
func Notify(c chan<- Change) { | ||
handlers.Lock() | ||
defer handlers.Unlock() | ||
if handlers.c == nil { | ||
go startChecker() | ||
} | ||
handlers.c = append(handlers.c, c) | ||
} | ||
|
||
// Stop unsubscribes from network interfaces change notification. | ||
func Stop(c chan<- Change) { | ||
handlers.Lock() | ||
defer handlers.Unlock() | ||
var newC = make([]chan<- Change, 0, len(handlers.c)-1) | ||
for _, ch := range handlers.c { | ||
if ch != c { | ||
newC = append(newC, c) | ||
} | ||
} | ||
handlers.c = newC | ||
if len(handlers.c) == 0 && cancel != nil { | ||
cancel() | ||
cancel = nil | ||
} | ||
} | ||
|
||
func broadcast(c Change) { | ||
handlers.Lock() | ||
defer handlers.Unlock() | ||
for _, ch := range handlers.c { | ||
ch <- c | ||
} | ||
} | ||
|
||
func startChecker() { | ||
tick := time.NewTicker(30 * time.Second) | ||
defer tick.Stop() | ||
var ctx context.Context | ||
ctx, cancel = context.WithCancel(context.Background()) | ||
defer cancel() | ||
changed() // init | ||
for { | ||
select { | ||
case <-tick.C: | ||
if changed() { | ||
broadcast(Change{}) | ||
} | ||
case <-ctx.Done(): | ||
break | ||
} | ||
} | ||
} | ||
|
||
func changed() bool { | ||
interfaces, _ := net.Interfaces() | ||
changed := !reflect.DeepEqual(lastInterfaces, interfaces) | ||
lastInterfaces = interfaces | ||
return changed | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters