make application methods as a part of struct
This commit is contained in:
+31
-32
@@ -81,7 +81,7 @@ func main() {
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
|
||||
// graceful termination
|
||||
// catch signal and invoke graceful termination
|
||||
go func() {
|
||||
stop := make(chan os.Signal, 1)
|
||||
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
|
||||
@@ -90,34 +90,16 @@ func main() {
|
||||
cancel()
|
||||
}()
|
||||
|
||||
app, err := Setup(opts)
|
||||
app, err := New(opts)
|
||||
if err != nil {
|
||||
log.Fatalf("[ERROR] failed to setup application, %+v", err)
|
||||
}
|
||||
log.Printf("[INFO] remark terminated %s", Run(ctx, app))
|
||||
log.Printf("[INFO] remark terminated %s", app.Run(ctx))
|
||||
}
|
||||
|
||||
// Run all application objects
|
||||
func Run(ctx context.Context, a *Application) error {
|
||||
if a.DevPasswd != "" {
|
||||
log.Printf("[WARN] running in dev mode")
|
||||
}
|
||||
|
||||
activateBackup(ctx, a.exporter) // runs in goroutine for each site
|
||||
go a.importer.Run(a.Port + 1)
|
||||
go a.srv.Run(opts.Port)
|
||||
|
||||
// shutdown on context cancellation
|
||||
<-ctx.Done()
|
||||
a.srv.Shutdown()
|
||||
a.importer.Shutdown()
|
||||
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
// Setup prepares application and return all active parts
|
||||
// New prepares application and return it with all active parts
|
||||
// doesn't start anything
|
||||
func Setup(opts Opts) (*Application, error) {
|
||||
func New(opts Opts) (*Application, error) {
|
||||
setupLog(opts.Dbg)
|
||||
|
||||
if err := makeDirs(opts.BoltPath, opts.BackupLocation, opts.AvatarStore); err != nil {
|
||||
@@ -125,13 +107,13 @@ func Setup(opts Opts) (*Application, error) {
|
||||
}
|
||||
|
||||
dataService := service.DataStore{
|
||||
Interface: makeBoltStore(opts.Sites),
|
||||
Interface: makeBoltStore(opts.Sites, opts.BoltPath),
|
||||
EditDuration: 5 * time.Minute,
|
||||
Secret: opts.SecretKey,
|
||||
MaxCommentSize: opts.MaxCommentSize,
|
||||
}
|
||||
|
||||
cache := rest.NewLoadingCache(rest.MaxValueSize(opts.MaxCachedValue), rest.MaxKeys(opts.MaxCachedItems),
|
||||
cache := rest.NewLoadingCache(rest.MaxValSize(opts.MaxCachedValue), rest.MaxKeys(opts.MaxCachedItems),
|
||||
rest.PostFlushFn(postFlushFn))
|
||||
|
||||
jwtService := auth.NewJWT(opts.SecretKey, strings.HasPrefix(opts.RemarkURL, "https://"), 7*24*time.Hour)
|
||||
@@ -171,14 +153,31 @@ func Setup(opts Opts) (*Application, error) {
|
||||
return &Application{srv: srv, importer: importer, exporter: exporter, Opts: opts}, nil
|
||||
}
|
||||
|
||||
// Run all application objects
|
||||
func (a *Application) Run(ctx context.Context) error {
|
||||
if a.DevPasswd != "" {
|
||||
log.Printf("[WARN] running in dev mode")
|
||||
}
|
||||
|
||||
a.activateBackup(ctx) // runs in goroutine for each site
|
||||
go a.importer.Run(a.Port + 1)
|
||||
go a.srv.Run(opts.Port)
|
||||
|
||||
// shutdown on context cancellation
|
||||
<-ctx.Done()
|
||||
a.srv.Shutdown()
|
||||
a.importer.Shutdown()
|
||||
return ctx.Err()
|
||||
}
|
||||
|
||||
// activateBackup runs background backups for each site
|
||||
func activateBackup(ctx context.Context, exporter migrator.Exporter) {
|
||||
for _, siteID := range opts.Sites {
|
||||
func (a *Application) activateBackup(ctx context.Context) {
|
||||
for _, siteID := range a.Sites {
|
||||
backup := migrator.AutoBackup{
|
||||
Exporter: exporter,
|
||||
BackupLocation: opts.BackupLocation,
|
||||
Exporter: a.exporter,
|
||||
BackupLocation: a.BackupLocation,
|
||||
SiteID: siteID,
|
||||
KeepMax: opts.MaxBackupFiles,
|
||||
KeepMax: a.MaxBackupFiles,
|
||||
Duration: 24 * time.Hour,
|
||||
}
|
||||
go backup.Do(ctx)
|
||||
@@ -186,10 +185,10 @@ func activateBackup(ctx context.Context, exporter migrator.Exporter) {
|
||||
}
|
||||
|
||||
// makeBoltStore creates store for all sites
|
||||
func makeBoltStore(siteNames []string) engine.Interface {
|
||||
func makeBoltStore(siteNames []string, path string) engine.Interface {
|
||||
sites := []engine.BoltSite{}
|
||||
for _, site := range siteNames {
|
||||
sites = append(sites, engine.BoltSite{SiteID: site, FileName: fmt.Sprintf("%s/%s.db", opts.BoltPath, site)})
|
||||
sites = append(sites, engine.BoltSite{SiteID: site, FileName: fmt.Sprintf("%s/%s.db", path, site)})
|
||||
}
|
||||
result, err := engine.NewBoltDB(bolt.Options{Timeout: 30 * time.Second}, sites...)
|
||||
if err != nil {
|
||||
|
||||
+2
-2
@@ -82,9 +82,9 @@ func (lc *loadingCache) allowed(data []byte) bool {
|
||||
// CacheOption func type
|
||||
type CacheOption func(lc *loadingCache) error
|
||||
|
||||
// MaxValueSize functional option defines the largest value's size allowed to be cached
|
||||
// MaxValSize functional option defines the largest value's size allowed to be cached
|
||||
// By default it is 0, which means unlimited.
|
||||
func MaxValueSize(max int) CacheOption {
|
||||
func MaxValSize(max int) CacheOption {
|
||||
return func(lc *loadingCache) error {
|
||||
lc.maxValueSize = max
|
||||
return nil
|
||||
|
||||
@@ -43,7 +43,7 @@ func TestLoadingCache_Get(t *testing.T) {
|
||||
func TestLoadingCache_MaxKeys(t *testing.T) {
|
||||
var postFnCall, coldCalls int32
|
||||
lc := NewLoadingCache(CleanupInterval(200*time.Millisecond), PostFlushFn(func() { atomic.AddInt32(&postFnCall, 1) }),
|
||||
MaxKeys(5), MaxValueSize(10))
|
||||
MaxKeys(5), MaxValSize(10))
|
||||
|
||||
// put 5 keys to cache
|
||||
for i := 0; i < 5; i++ {
|
||||
@@ -97,7 +97,7 @@ func TestLoadingCache_MaxKeys(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestLoadingCache_MaxSize(t *testing.T) {
|
||||
lc := NewLoadingCache(CleanupInterval(200*time.Millisecond), MaxKeys(5), MaxValueSize(10))
|
||||
lc := NewLoadingCache(CleanupInterval(200*time.Millisecond), MaxKeys(5), MaxValSize(10))
|
||||
|
||||
// put good size value to cache and make sure it cached
|
||||
res, err := lc.Get("key-Z", time.Minute, func() ([]byte, error) {
|
||||
|
||||
Reference in New Issue
Block a user