Add flags and more robust functionality than "until" provided

This commit is contained in:
Neale Pickett 2019-11-24 15:58:43 -07:00
parent 309432d05c
commit 65f810539a
4 changed files with 96 additions and 33 deletions

View File

@ -25,4 +25,4 @@ func (c *Component) path(parts ...string) string {
func (c *Component) Run(updateInterval time.Duration) {
// Stub!
}
}

View File

@ -1,24 +1,50 @@
package main
import (
"time"
"github.com/namsral/flag"
"log"
"time"
)
func main() {
log.Print("Started")
theme := NewTheme("../../theme")
state := NewState("../../state")
puzzles := NewMothballs("../../mothballs")
interval := 2 * time.Second
go theme.Run(interval)
go state.Run(interval)
go puzzles.Run(interval)
themePath := flag.String(
"theme",
"theme",
"Path to theme files",
)
statePath := flag.String(
"state",
"state",
"Path to state files",
)
puzzlePath := flag.String(
"mothballs",
"mothballs",
"Path to mothballs to host",
)
refreshInterval := flag.Duration(
"refresh",
2*time.Second,
"Duration between maintenance tasks",
)
bindStr := flag.String(
"bind",
":8000",
"Bind [host]:port for HTTP service",
)
theme := NewTheme(*themePath)
state := NewState(*statePath)
puzzles := NewMothballs(*puzzlePath)
go theme.Run(*refreshInterval)
go state.Run(*refreshInterval)
go puzzles.Run(*refreshInterval)
log.Println("I would be binding to", *bindStr)
time.Sleep(1 * time.Second)
log.Print(state.Export(""))
time.Sleep(19 * time.Second)
}
}

View File

@ -1,10 +1,10 @@
package main
import (
"time"
"io/ioutil"
"strings"
"log"
"strings"
"time"
)
type Mothballs struct {

View File

@ -34,6 +34,7 @@ type StateExport struct {
// The only thing State methods need to know is the path to the state directory.
type State struct {
Component
Enabled bool
update chan bool
}
@ -42,32 +43,60 @@ func NewState(baseDir string) *State {
Component: Component{
baseDir: baseDir,
},
Enabled: true,
update: make(chan bool, 10),
}
}
// Check a few things to see if this state directory is "enabled".
func (s *State) Enabled() bool {
func (s *State) UpdateEnabled() {
if _, err := os.Stat(s.path("enabled")); os.IsNotExist(err) {
s.Enabled = false
log.Print("Suspended: enabled file missing")
return false
return
}
untilspec, err := ioutil.ReadFile(s.path("until"))
if err == nil {
untilspecs := strings.TrimSpace(string(untilspec))
until, err := time.Parse(time.RFC3339, untilspecs)
nextEnabled := true
untilFile, err := os.Open(s.path("hours"))
if err != nil {
return
}
defer untilFile.Close()
scanner := bufio.NewScanner(untilFile)
for scanner.Scan() {
line := scanner.Text()
if len(line) < 1 {
continue
}
thisEnabled := true
switch line[0] {
case '+':
thisEnabled = true
line = line[1:]
case '-':
thisEnabled = false
line = line[1:]
case '#':
continue
default:
log.Printf("Misformatted line in hours file")
}
line = strings.TrimSpace(line)
until, err := time.Parse(time.RFC3339, line)
if err != nil {
log.Printf("Suspended: Unparseable until date: %s", untilspec)
return false
log.Printf("Suspended: Unparseable until date: %s", line)
continue
}
if until.Before(time.Now()) {
log.Print("Suspended: until time reached, suspending maintenance")
return false
nextEnabled = thisEnabled
}
}
return true
if nextEnabled != s.Enabled {
s.Enabled = nextEnabled
log.Println("Setting enabled to", s.Enabled, "based on hours file")
}
}
// Returns team name given a team ID.
@ -291,17 +320,23 @@ func (s *State) maybeInitialize() {
// Create some files
ioutil.WriteFile(
s.path("initialized"),
[]byte("Remove this file to re-initialized the contest\n"),
[]byte("state/initialized: remove to re-initialize the contest\n"),
0644,
)
ioutil.WriteFile(
s.path("enabled"),
[]byte("Remove this file to suspend the contest\n"),
[]byte("state/enabled: remove to suspend the contest\n"),
0644,
)
ioutil.WriteFile(
s.path("until"),
[]byte("3009-10-31T00:00:00Z\n"),
s.path("hours"),
[]byte(
"# state/hours: when the contest is enabled\n"+
"# Lines starting with + enable, with - disable.\n"+
"\n"+
"+ 1970-01-01T00:00:00Z\n"+
"- 3019-10-31T00:00:00Z\n",
),
0644,
)
ioutil.WriteFile(
@ -319,10 +354,12 @@ func (s *State) maybeInitialize() {
func (s *State) Run(updateInterval time.Duration) {
for {
s.maybeInitialize()
if s.Enabled() {
s.UpdateEnabled()
if s.Enabled {
s.collectPoints()
}
// Wait for something to happen
select {
case <-s.update:
case <-time.After(updateInterval):