// StartModule sets up the module with the given name. func StartModule(name string, setup func(context *ModuleContext) error) { logger := log.New(os.Stderr, name+" ", log.LstdFlags) // Load configuration flag.Parse() if flag.NArg() != 1 { logger.Fatal("Expecting configuration path.") } cfgPath := util.GetConfigPath(flag.Arg(0)) settings, err := util.LoadMonstiSettings(cfgPath) if err != nil { logger.Fatal("Could not load settings: ", err) } gettext.DefaultLocales.Domain = "monsti-" + name gettext.DefaultLocales.LocaleDir = settings.Directories.Locale renderer := mtemplate.Renderer{ Root: settings.GetTemplatesPath()} monstiPath := settings.GetServicePath(service.MonstiService.String()) sessions := service.NewSessionPool(1, monstiPath) session, err := sessions.New() if err != nil { logger.Fatalf("Could not get session: %v", err) } defer sessions.Free(session) if err := setup(&ModuleContext{ settings, sessions, session, logger, &renderer, }); err != nil { logger.Fatalf("Could not setup module: %v", err) } if err := session.Monsti().ModuleInitDone("example-module"); err != nil { logger.Fatalf("Could not finish initialization: %v", err) } for { if err := session.Monsti().WaitSignal(); err != nil { logger.Printf("Could not wait for signal: %v", err) } } }
func main() { useSyslog := flag.Bool("syslog", false, "use syslog") flag.Parse() var logger *log.Logger if *useSyslog { var err error logger, err = syslog.NewLogger(syslog.LOG_INFO|syslog.LOG_DAEMON, 0) if err != nil { fmt.Fprintf(os.Stderr, "Could not setup syslog logger: %v\n", err) os.Exit(1) } } else { logger = log.New(os.Stderr, "monsti ", log.LstdFlags) } // Load configuration if flag.NArg() != 1 { logger.Fatalf("Usage: %v <config_directory>\n", filepath.Base(os.Args[0])) } cfgPath := msettings.GetConfigPath(flag.Arg(0)) var settings settings if err := msettings.LoadModuleSettings("daemon", cfgPath, &settings); err != nil { logger.Fatal("Could not load settings: ", err) } gettext.DefaultLocales.Domain = "monsti-daemon" gettext.DefaultLocales.LocaleDir = settings.Monsti.Directories.Locale var waitGroup sync.WaitGroup // Start service handler monstiPath := settings.Monsti.GetServicePath(service.MonstiService.String()) monsti := new(MonstiService) monsti.Settings = &settings monsti.Logger = logger provider := service.NewProvider("Monsti", monsti) provider.Logger = logger if err := provider.Listen(monstiPath); err != nil { logger.Fatalf("service: Could not start service: %v", err) } waitGroup.Add(1) go func() { defer waitGroup.Done() if err := provider.Accept(); err != nil { logger.Fatalf("Could not accept at service: %v", err) } }() sessions := service.NewSessionPool(1, monstiPath) renderer := template.Renderer{Root: settings.Monsti.GetTemplatesPath()} // Init core functionality session, err := sessions.New() if err != nil { logger.Fatalf("Could not get session: %v", err) } if err := initNodeTypes(&settings, session, logger); err != nil { logger.Fatalf("Could not init node types: %v", err) } if err := initBlog(&settings, session, sessions, logger, &renderer); err != nil { logger.Fatalf("Could not init blog: %v", err) } // Wait for signals go func() { for { if err := session.Monsti().WaitSignal(); err != nil { logger.Fatalf("Could not wait for signal: %v", err) } } }() // Start modules monsti.moduleInit = make(map[string]chan bool) for _, module := range settings.Modules { monsti.moduleInit[module] = make(chan bool, 1) } for _, module := range settings.Modules { executable := "monsti-" + module cmd := exec.Command(executable, cfgPath) cmd.Stderr = moduleLog{module, logger} go func(module string) { if err := cmd.Run(); err != nil { logger.Fatalf("Module %q failed: %v", module, err) } }(module) } logger.Println("Waiting for modules to finish initialization...") for _, module := range settings.Modules { logger.Printf("Waiting for %q...", module) <-monsti.moduleInit[module] } // Setup up httpd handler := nodeHandler{ Renderer: renderer, Settings: &settings, Log: logger, Sessions: sessions, } monsti.Handler = &handler monsti.siteMutexes = make(map[string]*sync.RWMutex) http.Handle("/static/", http.FileServer(http.Dir( filepath.Dir(settings.Monsti.GetStaticsPath())))) handler.InitializedSites = make(map[string]bool) http.Handle("/", &handler) waitGroup.Add(1) go func() { if err := http.ListenAndServe(settings.Listen, nil); err != nil { logger.Fatal("HTTP Listener failed: ", err) } waitGroup.Done() }() logger.Printf("Monsti is up and running, listening on %q.", settings.Listen) waitGroup.Wait() logger.Println("Monsti is shutting down.") }