feat(publicip): PUBLICIP_ENABLED replaces PUBLICIP_PERIOD

- No point periodically fetch the public IP address. Could not find anything mentioning why this was added.
- Simplification of the publicip loop code
- `PUBLICIP_ENABLED` (on, off) can be set to enable or not public ip data fetching on VPN connection
- `PUBLICIP_PERIOD=0` still works to indicate to disable public ip fetching
- `PUBLICIP_PERIOD` != 0 means to enable public ip fetching
- Warnings logged when using `PUBLICIP_PERIOD`
This commit is contained in:
Quentin McGaw
2024-10-07 19:49:25 +00:00
parent cbdd1a933c
commit 03deb9aed0
8 changed files with 59 additions and 109 deletions

View File

@@ -76,14 +76,8 @@ func (l *Loop) run(runCtx context.Context, runDone chan<- struct{},
updateTrigger <-chan settings.PublicIP, updatedResult chan<- error) {
defer close(runDone)
timer := time.NewTimer(time.Hour)
defer timer.Stop()
_ = timer.Stop()
timerIsReadyToReset := true
lastFetch := time.Unix(0, 0)
for {
singleRunCtx := runCtx
var singleRunCtx context.Context
var singleRunResult chan<- error
select {
case <-runCtx.Done():
@@ -91,26 +85,17 @@ func (l *Loop) run(runCtx context.Context, runDone chan<- struct{},
case singleRunCtx = <-runTrigger:
// Note singleRunCtx is canceled if runCtx is canceled.
singleRunResult = runResult
case <-timer.C:
timerIsReadyToReset = true
case partialUpdate := <-updateTrigger:
var err error
timerIsReadyToReset, err = l.update(partialUpdate, lastFetch, timer, timerIsReadyToReset)
err = l.update(partialUpdate)
updatedResult <- err
continue
}
lastFetch = l.timeNow()
timerIsReadyToReset = l.updateTimer(*l.settings.Period, lastFetch, timer, timerIsReadyToReset)
result, err := l.fetcher.FetchInfo(singleRunCtx, netip.Addr{})
if err != nil {
err = fmt.Errorf("fetching information: %w", err)
if singleRunResult != nil {
singleRunResult <- err
} else {
l.logger.Error(err.Error())
}
singleRunResult <- err
continue
}
@@ -128,11 +113,7 @@ func (l *Loop) run(runCtx context.Context, runDone chan<- struct{},
err = fmt.Errorf("persisting public ip address: %w", err)
}
if singleRunResult != nil {
singleRunResult <- err
} else if err != nil {
l.logger.Error(err.Error())
}
singleRunResult <- err
}
}

View File

@@ -3,25 +3,16 @@ package publicip
import (
"fmt"
"os"
"time"
"github.com/qdm12/gluetun/internal/configuration/settings"
)
func (l *Loop) update(partialUpdate settings.PublicIP,
lastTick time.Time, timer *time.Timer, timerIsReadyToReset bool) (
newTimerIsReadyToReset bool, err error) {
newTimerIsReadyToReset = timerIsReadyToReset
func (l *Loop) update(partialUpdate settings.PublicIP) (err error) {
// No need to lock the mutex since it can only be written
// in the code below in this goroutine.
updatedSettings, err := l.settings.UpdateWith(partialUpdate)
if err != nil {
return newTimerIsReadyToReset, err
}
if *l.settings.Period != *updatedSettings.Period {
newTimerIsReadyToReset = l.updateTimer(*updatedSettings.Period, lastTick,
timer, timerIsReadyToReset)
return err
}
if *l.settings.IPFilepath != *updatedSettings.IPFilepath {
@@ -30,17 +21,17 @@ func (l *Loop) update(partialUpdate settings.PublicIP,
err = persistPublicIP(*updatedSettings.IPFilepath,
l.ipData.IP.String(), l.puid, l.pgid)
if err != nil {
return newTimerIsReadyToReset, fmt.Errorf("persisting ip data: %w", err)
return fmt.Errorf("persisting ip data: %w", err)
}
case *updatedSettings.IPFilepath == "":
err = os.Remove(*l.settings.IPFilepath)
if err != nil {
return newTimerIsReadyToReset, fmt.Errorf("removing ip data file path: %w", err)
return fmt.Errorf("removing ip data file path: %w", err)
}
default:
err = os.Rename(*l.settings.IPFilepath, *updatedSettings.IPFilepath)
if err != nil {
return newTimerIsReadyToReset, fmt.Errorf("renaming ip data file path: %w", err)
return fmt.Errorf("renaming ip data file path: %w", err)
}
}
}
@@ -49,34 +40,5 @@ func (l *Loop) update(partialUpdate settings.PublicIP,
l.settings = updatedSettings
l.settingsMutex.Unlock()
return newTimerIsReadyToReset, nil
}
func (l *Loop) updateTimer(period time.Duration, lastFetch time.Time,
timer *time.Timer, timerIsReadyToReset bool) (newTimerIsReadyToReset bool) {
disableTimer := period == 0
if disableTimer {
if !timer.Stop() {
<-timer.C
}
return true
}
if !timerIsReadyToReset {
if !timer.Stop() {
<-timer.C
}
}
var waited time.Duration
if lastFetch.UnixNano() > 0 {
waited = l.timeNow().Sub(lastFetch)
}
leftToWait := period - waited
if leftToWait <= 0 {
leftToWait = time.Nanosecond
}
timer.Reset(leftToWait)
return false
return nil
}