-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- refactoring of the main runtime using CMD pattern - generarte UI config at runtime - lint code
- Loading branch information
Showing
33 changed files
with
442 additions
and
203 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -67,3 +67,6 @@ EXPOSE 8080 9090 | |
|
||
# Define entrypoint | ||
ENTRYPOINT [ "readflow" ] | ||
|
||
# Define command | ||
CMD [ "serve" ] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package all | ||
|
||
import ( | ||
// activate init-config command | ||
_ "github.com/ncarlier/readflow/cmd/init-config" | ||
// activate serve command | ||
_ "github.com/ncarlier/readflow/cmd/serve" | ||
// activate version command | ||
_ "github.com/ncarlier/readflow/cmd/version" | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package cmd | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
) | ||
|
||
var ( | ||
// ConfigFlag is the flag used to load the config file | ||
ConfigFlag string | ||
) | ||
|
||
func init() { | ||
defaultValue := "" | ||
if value, ok := os.LookupEnv("READFLOW_CONFIG"); ok { | ||
defaultValue = value | ||
} | ||
flag.StringVar(&ConfigFlag, "c", defaultValue, "Configuration file to load [ENV: READFLOW_CONFIG]") | ||
flag.Usage = func() { | ||
out := flag.CommandLine.Output() | ||
fmt.Fprintf(out, "readflow is a news-reading (or read-it-later) solution focused on versatility and simplicity.\n") | ||
fmt.Fprintf(out, "\nUsage:\n readflow [flags] [command]\n") | ||
fmt.Fprintf(out, "\nAvailable Commands:\n") | ||
for _, c := range Commands { | ||
c.Usage() | ||
} | ||
fmt.Fprintf(out, "\nFlags:\n") | ||
flag.PrintDefaults() | ||
fmt.Fprintf(out, "\nUse \"reaflow [command] --help\" for more information about a command.\n\n") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package cmd | ||
|
||
import "strings" | ||
|
||
// GetFirstCommand restun first command of argument list | ||
func GetFirstCommand(args []string) (name string, index int) { | ||
for idx, arg := range args { | ||
if strings.HasPrefix(arg, "-") { | ||
// ignore flags | ||
continue | ||
} | ||
return arg, idx | ||
} | ||
return "", -1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package initconfig | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
|
||
"github.com/ncarlier/readflow/cmd" | ||
"github.com/ncarlier/readflow/pkg/config" | ||
) | ||
|
||
const cmdName = "init-config" | ||
|
||
type InitConfigCmd struct { | ||
filename string | ||
flagSet *flag.FlagSet | ||
} | ||
|
||
func (c *InitConfigCmd) Exec(args []string, conf *config.Config) error { | ||
if err := c.flagSet.Parse(args); err != nil { | ||
return err | ||
} | ||
return conf.WriteDefaultConfigFile(c.filename) | ||
} | ||
|
||
func (c *InitConfigCmd) Usage() { | ||
fmt.Fprintf(c.flagSet.Output(), " %s\tInit configuration file\n", cmdName) | ||
} | ||
|
||
func newInitConfigCmd() cmd.Cmd { | ||
c := &InitConfigCmd{ | ||
flagSet: flag.NewFlagSet(cmdName, flag.ExitOnError), | ||
} | ||
c.flagSet.StringVar(&c.filename, "f", "config.toml", "Configuration file to create") | ||
return c | ||
} | ||
|
||
func init() { | ||
cmd.Add(cmdName, newInitConfigCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package cmd | ||
|
||
// Creator function for an output | ||
type Creator func() Cmd | ||
|
||
// Commands registry | ||
var Commands = map[string]Cmd{} | ||
|
||
// Add output to the registry | ||
func Add(name string, creator Creator) { | ||
Commands[name] = creator() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
package serve | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
|
||
"github.com/ncarlier/readflow/cmd" | ||
"github.com/ncarlier/readflow/pkg/config" | ||
) | ||
|
||
const cmdName = "serve" | ||
|
||
type ServeCmd struct { | ||
flagSet *flag.FlagSet | ||
} | ||
|
||
func (c *ServeCmd) Exec(args []string, conf *config.Config) error { | ||
// no args | ||
return startServer(conf) | ||
} | ||
|
||
func (c *ServeCmd) Usage() { | ||
fmt.Fprintf(c.flagSet.Output(), " %s\t\tStart readflow server\n", cmdName) | ||
} | ||
|
||
func newServeCmd() cmd.Cmd { | ||
c := &ServeCmd{ | ||
flagSet: flag.NewFlagSet(cmdName, flag.ExitOnError), | ||
} | ||
return c | ||
} | ||
|
||
func init() { | ||
cmd.Add("serve", newServeCmd) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
package serve | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/ncarlier/readflow/pkg/api" | ||
"github.com/ncarlier/readflow/pkg/cache" | ||
"github.com/ncarlier/readflow/pkg/config" | ||
"github.com/ncarlier/readflow/pkg/db" | ||
"github.com/ncarlier/readflow/pkg/exporter" | ||
"github.com/ncarlier/readflow/pkg/exporter/pdf" | ||
"github.com/ncarlier/readflow/pkg/metric" | ||
"github.com/ncarlier/readflow/pkg/server" | ||
"github.com/ncarlier/readflow/pkg/service" | ||
"github.com/rs/zerolog/log" | ||
) | ||
|
||
func startServer(conf *config.Config) error { | ||
log.Debug().Msg("starting readflow...") | ||
|
||
// configure the DB | ||
database, err := db.NewDB(conf.Database.URI) | ||
if err != nil { | ||
return fmt.Errorf("unable to configure the database: %w", err) | ||
} | ||
|
||
// configure download cache | ||
downloadCache, err := cache.NewDefault("readflow-downloads") | ||
if err != nil { | ||
return fmt.Errorf("unable to configure the downloader cache storage: %w", err) | ||
} | ||
|
||
// configure the service registry | ||
err = service.Configure(*conf, database, downloadCache) | ||
if err != nil { | ||
database.Close() | ||
return fmt.Errorf("unable to configure the service registry: %w", err) | ||
} | ||
|
||
// register external exporters... | ||
if conf.PDF.ServiceProvider != "" { | ||
log.Info().Str("provider", conf.PDF.ServiceProvider).Msg("using PDF generator service") | ||
exporter.Register("pdf", pdf.NewPDFExporter(conf.PDF.ServiceProvider)) | ||
} | ||
|
||
// create HTTP server | ||
httpServer := server.NewHTTPServer(conf) | ||
|
||
// create and start metrics server | ||
metricsServer := server.NewMetricsServer(conf) | ||
if metricsServer != nil { | ||
metric.StartCollectors(database) | ||
go metricsServer.ListenAndServe() | ||
} | ||
|
||
// create and start SMTP server | ||
smtpServer := server.NewSMTPHTTPServer(conf) | ||
if smtpServer != nil { | ||
go smtpServer.ListenAndServe() | ||
} | ||
|
||
done := make(chan bool) | ||
quit := make(chan os.Signal, 1) | ||
signal.Notify(quit, os.Interrupt, syscall.SIGTERM) | ||
|
||
go func() { | ||
<-quit | ||
log.Debug().Msg("shutting down readflow...") | ||
api.Shutdown() | ||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) | ||
defer cancel() | ||
|
||
if err := httpServer.Shutdown(ctx); err != nil { | ||
log.Fatal().Err(err).Msg("unable to gracefully shutdown the HTTP server") | ||
} | ||
if smtpServer != nil { | ||
if err := smtpServer.Shutdown(ctx); err != nil { | ||
log.Fatal().Err(err).Msg("unable to gracefully shutdown the SMTP server") | ||
} | ||
} | ||
if metricsServer != nil { | ||
metric.StopCollectors() | ||
if err := metricsServer.Shutdown(ctx); err != nil { | ||
log.Fatal().Err(err).Msg("unable to gracefully shutdown the metrics server") | ||
} | ||
} | ||
|
||
service.Shutdown() | ||
|
||
if err := downloadCache.Close(); err != nil { | ||
log.Error().Err(err).Msg("unable to gracefully shutdown the cache storage") | ||
} | ||
|
||
if err := database.Close(); err != nil { | ||
log.Fatal().Err(err).Msg("could not gracefully shutdown database connection") | ||
} | ||
|
||
close(done) | ||
}() | ||
|
||
// set API health check as started | ||
api.Start() | ||
|
||
// start HTTP server | ||
httpServer.ListenAndServe() | ||
|
||
<-done | ||
log.Debug().Msg("readflow stopped") | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package cmd | ||
|
||
import "github.com/ncarlier/readflow/pkg/config" | ||
|
||
type Cmd interface { | ||
Exec(args []string, conf *config.Config) error | ||
Usage() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package initconfig | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
|
||
"github.com/ncarlier/readflow/cmd" | ||
"github.com/ncarlier/readflow/pkg/config" | ||
"github.com/ncarlier/readflow/pkg/version" | ||
) | ||
|
||
const cmdName = "version" | ||
|
||
type VersionCmd struct { | ||
flagSet *flag.FlagSet | ||
} | ||
|
||
func (c *VersionCmd) Exec(args []string, conf *config.Config) error { | ||
// no args | ||
version.Print() | ||
return nil | ||
} | ||
|
||
func (c *VersionCmd) Usage() { | ||
fmt.Fprintf(c.flagSet.Output(), " %s\tDisplay version\n", cmdName) | ||
} | ||
|
||
func newVersionCmd() cmd.Cmd { | ||
c := &VersionCmd{ | ||
flagSet: flag.NewFlagSet(cmdName, flag.ExitOnError), | ||
} | ||
return c | ||
} | ||
|
||
func init() { | ||
cmd.Add("version", newVersionCmd) | ||
} |
Oops, something went wrong.