package main import ( "fmt" "os" "os/signal" "syscall" "time" _ "time/tzdata" "git.fjla.uk/owlboard/timetable-mgr/background" "git.fjla.uk/owlboard/timetable-mgr/cif" "git.fjla.uk/owlboard/timetable-mgr/corpus" "git.fjla.uk/owlboard/timetable-mgr/dbAccess" "git.fjla.uk/owlboard/timetable-mgr/helpers" "git.fjla.uk/owlboard/timetable-mgr/log" "git.fjla.uk/owlboard/timetable-mgr/messaging" "git.fjla.uk/owlboard/timetable-mgr/vstp" ) func main() { cfg, err := helpers.LoadConfig() if err != nil { fmt.Println("Error loading configuration", err) return } cfg.PrintConfig() log.Msg.Info("Initialised OwlBoard timetable-mgr " + helpers.Version) dbAccess.InitDataAccess(cfg) dbAccess.PushVersionToDb() // Initialise a `stop` channel to signal goroutines to cleanup stop := make(chan struct{}) // Start CIF Task Ticker background.InitTicker(cfg, stop) // Handle signals from the OS go handleSignals(cfg, stop) // Manually call CIF and CORPUS checks to ensure that they are // not delayed until the first ticker event. go cif.CheckCif(cfg) go corpus.CheckCorpus(cfg) if cfg.VstpOn { messaging.StompInit(cfg) vstp.Subscribe() } <-stop } // Traps SIGINT and SIGTERM signals and ensures cleanup() is run func handleSignals(cfg *helpers.Configuration, stop chan<- struct{}) { sigChan := make(chan os.Signal, 1) signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) sig := <-sigChan log.Msg.Warn("Signal received: " + sig.String()) cleanup(cfg, stop) } // Cleans up open connections ready for a clean exit of the program func cleanup(cfg *helpers.Configuration, stop chan<- struct{}) { log.Msg.Debug("Cleaning up open connections") if cfg.VstpOn { if messaging.Client != nil { log.Msg.Info("Closing STOMP Client") messaging.Disconnect(messaging.Client) } } if dbAccess.MongoClient != nil { log.Msg.Info("Closing MongoDB Client") dbAccess.CloseMongoClient() } log.Msg.Info("Signalling to other goroutines") close(stop) log.Msg.Info("Program ready to exit") if log.Msg != nil { log.Msg.Sync() } time.Sleep(500 * time.Millisecond) os.Exit(0) }