evdist: Publish next settings change

This commit is contained in:
nemunaire 2024-03-17 16:49:15 +01:00
parent 357944564b
commit 0db9e9b539
5 changed files with 76 additions and 21 deletions

View File

@ -78,7 +78,7 @@ func newDashboardFile(l *distList, raw_path string) {
Name: bpath,
Screen: s,
Date: activateTime,
})
}, nil)
} else {
log.Println("WARNING: Unknown file to treat: not a valid timestamp:", err.Error())
}

View File

@ -37,7 +37,7 @@ func (l *distList) TimerNextEvent() *time.Timer {
return time.NewTimer(time.Until(*min))
}
func (l *distList) AddEvent(nsf DistEvent) {
func (l *distList) AddEvent(nsf DistEvent, firstItemChanged func(DistEvent)) {
l.Lock.Lock()
istop := len(l.List)
@ -59,10 +59,13 @@ func (l *distList) AddEvent(nsf DistEvent) {
if istop == 0 {
l.ResetTimer()
if firstItemChanged != nil {
firstItemChanged(nsf)
}
}
}
func (l *distList) DelEvent(id int64) {
func (l *distList) DelEvent(id int64, firstItemChanged func(DistEvent)) {
l.Lock.Lock()
istop := len(l.List)
@ -83,6 +86,13 @@ func (l *distList) DelEvent(id int64) {
if istop == 0 {
l.ResetTimer()
if firstItemChanged != nil {
if len(l.List) == 0 {
firstItemChanged(nil)
} else {
firstItemChanged(l.List[0])
}
}
}
}

View File

@ -19,6 +19,7 @@ import (
var SettingsDistDir = "./SETTINGSDIST/"
var TmpSettingsDirectory string
var TmpSettingsDistDirectory string
var watchedNotify = fsnotify.Create
func watchsubdir(l *distList, watcher *fsnotify.Watcher, pathname string, treat func(l *distList, pathname string)) error {
log.Println("Watch new directory:", pathname)
@ -93,8 +94,6 @@ func main() {
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, syscall.SIGTERM)
watchedNotify := fsnotify.Create
treatNewFile := func(name string) {
if strings.HasPrefix(name, DashboardDir) {
newDashboardFile(lDashboard, name)
@ -139,16 +138,16 @@ loop:
log.Println("Treating deletion event:", ev, "for", ev.Name)
}
if strings.HasPrefix(ev.Name, DashboardDir) {
if ts, err := parseDashboardFilename(ev.Name); err == nil {
if ts, err := parseDashboardFilename(path.Base(ev.Name)); err != nil {
log.Println("Unable to parseint", ev.Name, err.Error())
} else {
lDashboard.DelEvent(ts)
lDashboard.DelEvent(ts, nil)
}
} else {
if ts, err := parseSettingsFilename(ev.Name); err == nil {
if ts, err := parseSettingsFilename(path.Base(ev.Name)); err != nil {
log.Println("Unable to parseint", ev.Name, err.Error())
} else {
lSettings.DelEvent(ts)
lSettings.DelEvent(ts, updateNextSettingsTime)
}
}
} else if err == nil && ev.Op&fsnotify.Write == fsnotify.Write {

View File

@ -12,8 +12,12 @@ import (
"time"
"srs.epita.fr/fic-server/settings"
"gopkg.in/fsnotify.v1"
)
var PublishNextChangeIndication = true
// NewDistList creates a distList from the given src directory
func NewSettingsDistList(src string) (*distList, error) {
list, err := settings.ListNextSettingsFiles()
@ -74,12 +78,33 @@ func newSettingsFile(l *distList, raw_path string) {
l.AddEvent(&settings.NextSettingsFile{
Id: ts,
Date: activateTime,
})
}, updateNextSettingsTime)
} else {
log.Println("WARNING: Unknown file to treat: not a valid timestamp:", err.Error())
}
}
func saveSettingsFile(cur_settings *settings.Settings) error {
if watchedNotify == fsnotify.Create {
err := settings.SaveSettings(path.Join(TmpSettingsDirectory, "settings.json"), cur_settings)
if err != nil {
return fmt.Errorf("Unable to save settings.json to tmp dir: %w", err)
}
err = os.Rename(path.Join(TmpSettingsDirectory, "settings.json"), path.Join(settings.SettingsDir, "settings.json"))
if err != nil {
return fmt.Errorf("Unable to move settings.json to dest dir: %w", err)
}
} else {
err := settings.SaveSettings(path.Join(settings.SettingsDir, "settings.json"), cur_settings)
if err != nil {
return fmt.Errorf("Unable to save settings.json to tmp dir: %w", err)
}
}
return nil
}
func treatSettingsFile(e DistEvent) {
v, err := settings.ReadNextSettingsFile(path.Join(settings.SettingsDir, fmt.Sprintf("%d.json", e.GetId())), e.GetId())
if err != nil {
@ -89,12 +114,38 @@ func treatSettingsFile(e DistEvent) {
} else {
cur_settings = settings.MergeSettings(*cur_settings, v.Values)
if err = settings.SaveSettings(path.Join(TmpSettingsDirectory, "settings.json"), cur_settings); err != nil {
log.Printf("Unable to save settings.json to tmp dir: %s", err.Error())
} else if err = os.Rename(path.Join(TmpSettingsDirectory, "settings.json"), path.Join(settings.SettingsDir, "settings.json")); err != nil {
log.Printf("Unable to move settings.json to dest dir: %s", err.Error())
if err := saveSettingsFile(cur_settings); err != nil {
log.Printf(err.Error())
} else if err = os.Remove(path.Join(settings.SettingsDir, fmt.Sprintf("%d.json", v.Id))); err != nil {
log.Printf("Unable to remove initial diff file (%d.json): %s", v.Id, err.Error())
}
}
}
func updateNextSettingsTime(e DistEvent) {
if !PublishNextChangeIndication {
return
}
log.Println("Updating settings.json to include next settings time")
cur_settings, err := settings.ReadSettings(path.Join(settings.SettingsDir, settings.SettingsFile))
if err != nil {
log.Printf("Unable to read settings.json: %s", err.Error())
return
}
if e == nil {
cur_settings = settings.MergeSettings(*cur_settings, map[string]interface{}{
"nextchangetime": nil,
})
} else {
cur_settings = settings.MergeSettings(*cur_settings, map[string]interface{}{
"nextchangetime": *e.GetDate(),
})
}
err = saveSettingsFile(cur_settings)
if err != nil {
log.Printf(err.Error())
}
}

View File

@ -29,8 +29,8 @@ type Settings struct {
Start time.Time `json:"start"`
// End is the expected end time (if empty their is no end-date).
End *time.Time `json:"end,omitempty"`
// ActivateTime is the time when the current file should be proceed.
ActivateTime time.Time `json:"activateTime"`
// NextChangeTime is the time of the next expected reload.
NextChangeTime *time.Time `json:"nextchangetime,omitempty"`
// FirstBlood is the coefficient applied to each first team who solve a challenge.
FirstBlood float64 `json:"firstBlood"`
@ -193,11 +193,6 @@ func LoadAndWatchSettings(settingsPath string, reload func(*Settings)) {
func tryReload(settingsPath string, reload func(*Settings)) {
if config, err := ReadSettings(settingsPath); err != nil {
log.Println("ERROR: Unable to read challenge settings:", err)
} else if time.Until(config.ActivateTime) > 0 {
log.Println("Configuration reloading postponed, activating at:", config.ActivateTime)
time.Sleep(time.Until(config.ActivateTime))
log.Println("Time to activate configuration...")
tryReload(settingsPath, reload)
} else {
reload(config)
}