package process import "os" import "time" import "github.com/jinzhu/gorm" import _ "github.com/jinzhu/gorm/dialects/sqlite" // required for orm import "github.com/rs/zerolog" import "github.com/rs/zerolog/log" import "github.com/mattn/go-isatty" import "github.com/sneak/feta/ingester" import "github.com/sneak/feta/storage" import "github.com/sneak/feta/locator" import "github.com/sneak/feta/manager" import "github.com/sneak/feta/instance" // CLIEntry is the main entrypoint for the feta process from the cli func CLIEntry(version string, buildarch string) int { f := new(Feta) f.version = version f.buildarch = buildarch f.setupLogging() return f.runForever() } // Feta is the main structure/process of this app type Feta struct { version string buildarch string locator *locator.InstanceLocator manager *manager.InstanceManager ingester *ingester.TootIngester api *Server db *gorm.DB startup time.Time } func (f *Feta) identify() { log.Info(). Str("version", f.version). Str("buildarch", f.buildarch). Msg("starting") } func (f *Feta) setupLogging() { log.Logger = log.With().Caller().Logger() tty := isatty.IsTerminal(os.Stdin.Fd()) || isatty.IsCygwinTerminal(os.Stdin.Fd()) if tty { out := zerolog.NewConsoleWriter( func(w *zerolog.ConsoleWriter) { // Customize time format w.TimeFormat = time.RFC3339 }, ) log.Logger = log.Output(out) } // always log in UTC zerolog.TimestampFunc = func() time.Time { return time.Now().UTC() } zerolog.SetGlobalLevel(zerolog.InfoLevel) if os.Getenv("DEBUG") != "" { zerolog.SetGlobalLevel(zerolog.DebugLevel) } f.identify() } func (f *Feta) uptime() time.Duration { return time.Since(f.startup) } /* func (f *Feta) setupDatabase() { var err error f.db, err = gorm.Open("sqlite3", "feta.sqlite") if err != nil { panic(err) } //f.databaseMigrations() } */ func (f *Feta) runForever() int { f.startup = time.Now() //f.setupDatabase() // FIXME move this channel creation into the manager's constructor // and add getters/setters on the manager/locator newInstanceHostnameNotifications := make(chan instance.Hostname) f.locator = locator.New() f.manager = manager.New() f.ingester = ingester.NewTootIngester() home := os.Getenv("HOME") if home == "" { panic("can't find home directory") } diskBackend := storage.NewTootFSStorage(home + "/.local/feta") f.ingester.SetStorageBackend(diskBackend) f.api = new(Server) f.api.SetFeta(f) // api needs to get to us to access data f.locator.SetInstanceNotificationChannel(newInstanceHostnameNotifications) f.manager.SetInstanceNotificationChannel(newInstanceHostnameNotifications) f.manager.SetTootDestination(f.ingester.GetDeliveryChannel()) // ingester goroutine: go f.ingester.Ingest() // locator goroutine: go f.locator.Locate() // manager goroutine: go f.manager.Manage() go f.api.Serve() // this goroutine (main) does nothing until we handle signals // FIXME(sneak) for { time.Sleep(1 * time.Second) } return 0 }