Use singleton in other places as well

This commit is contained in:
Deluan 2021-06-21 18:41:11 -04:00
parent 1f997357a9
commit 743e469795
7 changed files with 39 additions and 104 deletions

View file

@ -10,6 +10,7 @@ import (
"github.com/navidrome/navidrome/consts" "github.com/navidrome/navidrome/consts"
"github.com/navidrome/navidrome/db" "github.com/navidrome/navidrome/db"
"github.com/navidrome/navidrome/log" "github.com/navidrome/navidrome/log"
"github.com/navidrome/navidrome/scheduler"
"github.com/oklog/run" "github.com/oklog/run"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
@ -121,10 +122,10 @@ func startSignaler() (func() error, func(err error)) {
func schedulePeriodicScan(schedule string) { func schedulePeriodicScan(schedule string) {
scanner := GetScanner() scanner := GetScanner()
scheduler := GetScheduler() schedulerInstance := scheduler.GetInstance()
log.Info("Scheduling periodic scan", "schedule", schedule) log.Info("Scheduling periodic scan", "schedule", schedule)
err := scheduler.Add(schedule, func() { err := schedulerInstance.Add(schedule, func() {
_ = scanner.RescanAll(context.Background(), false) _ = scanner.RescanAll(context.Background(), false)
}) })
if err != nil { if err != nil {
@ -140,11 +141,11 @@ func schedulePeriodicScan(schedule string) {
func startScheduler() (func() error, func(err error)) { func startScheduler() (func() error, func(err error)) {
log.Info("Starting scheduler") log.Info("Starting scheduler")
scheduler := GetScheduler() schedulerInstance := scheduler.GetInstance()
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
return func() error { return func() error {
scheduler.Run(ctx) schedulerInstance.Run(ctx)
return nil return nil
}, func(err error) { }, func(err error) {

View file

@ -13,7 +13,6 @@ import (
"github.com/navidrome/navidrome/core/transcoder" "github.com/navidrome/navidrome/core/transcoder"
"github.com/navidrome/navidrome/persistence" "github.com/navidrome/navidrome/persistence"
"github.com/navidrome/navidrome/scanner" "github.com/navidrome/navidrome/scanner"
"github.com/navidrome/navidrome/scheduler"
"github.com/navidrome/navidrome/server" "github.com/navidrome/navidrome/server"
"github.com/navidrome/navidrome/server/events" "github.com/navidrome/navidrome/server/events"
"github.com/navidrome/navidrome/server/nativeapi" "github.com/navidrome/navidrome/server/nativeapi"
@ -31,7 +30,7 @@ func CreateServer(musicFolder string) *server.Server {
func CreateNativeAPIRouter() *nativeapi.Router { func CreateNativeAPIRouter() *nativeapi.Router {
dataStore := persistence.New() dataStore := persistence.New()
broker := GetBroker() broker := events.GetBroker()
share := core.NewShare(dataStore) share := core.NewShare(dataStore)
router := nativeapi.New(dataStore, broker, share) router := nativeapi.New(dataStore, broker, share)
return router return router
@ -48,8 +47,8 @@ func CreateSubsonicAPIRouter() *subsonic.Router {
players := core.NewPlayers(dataStore) players := core.NewPlayers(dataStore)
externalMetadata := core.NewExternalMetadata(dataStore) externalMetadata := core.NewExternalMetadata(dataStore)
scanner := GetScanner() scanner := GetScanner()
broker := GetBroker() broker := events.GetBroker()
scrobblerScrobbler := scrobbler.New(dataStore) scrobblerScrobbler := scrobbler.GetInstance(dataStore)
router := subsonic.New(dataStore, artwork, mediaStreamer, archiver, players, externalMetadata, scanner, broker, scrobblerScrobbler) router := subsonic.New(dataStore, artwork, mediaStreamer, archiver, players, externalMetadata, scanner, broker, scrobblerScrobbler)
return router return router
} }
@ -65,24 +64,14 @@ func createScanner() scanner.Scanner {
artworkCache := core.GetImageCache() artworkCache := core.GetImageCache()
artwork := core.NewArtwork(dataStore, artworkCache) artwork := core.NewArtwork(dataStore, artworkCache)
cacheWarmer := core.NewCacheWarmer(artwork, artworkCache) cacheWarmer := core.NewCacheWarmer(artwork, artworkCache)
broker := GetBroker() broker := events.GetBroker()
scannerScanner := scanner.New(dataStore, cacheWarmer, broker) scannerScanner := scanner.New(dataStore, cacheWarmer, broker)
return scannerScanner return scannerScanner
} }
func createBroker() events.Broker {
broker := events.NewBroker()
return broker
}
func createScheduler() scheduler.Scheduler {
schedulerScheduler := scheduler.New()
return schedulerScheduler
}
// wire_injectors.go: // wire_injectors.go:
var allProviders = wire.NewSet(core.Set, subsonic.New, nativeapi.New, persistence.New, lastfm.NewRouter, GetBroker) var allProviders = wire.NewSet(core.Set, subsonic.New, nativeapi.New, persistence.New, lastfm.NewRouter, events.GetBroker)
// Scanner must be a Singleton // Scanner must be a Singleton
var ( var (
@ -96,29 +85,3 @@ func GetScanner() scanner.Scanner {
}) })
return scannerInstance return scannerInstance
} }
// Broker must be a Singleton
var (
onceBroker sync.Once
brokerInstance events.Broker
)
func GetBroker() events.Broker {
onceBroker.Do(func() {
brokerInstance = createBroker()
})
return brokerInstance
}
// Scheduler must be a Singleton
var (
onceScheduler sync.Once
schedulerInstance scheduler.Scheduler
)
func GetScheduler() scheduler.Scheduler {
onceScheduler.Do(func() {
schedulerInstance = createScheduler()
})
return schedulerInstance
}

View file

@ -5,14 +5,14 @@ package cmd
import ( import (
"sync" "sync"
"github.com/navidrome/navidrome/server/events"
"github.com/google/wire" "github.com/google/wire"
"github.com/navidrome/navidrome/core" "github.com/navidrome/navidrome/core"
"github.com/navidrome/navidrome/core/agents/lastfm" "github.com/navidrome/navidrome/core/agents/lastfm"
"github.com/navidrome/navidrome/persistence" "github.com/navidrome/navidrome/persistence"
"github.com/navidrome/navidrome/scanner" "github.com/navidrome/navidrome/scanner"
"github.com/navidrome/navidrome/scheduler"
"github.com/navidrome/navidrome/server" "github.com/navidrome/navidrome/server"
"github.com/navidrome/navidrome/server/events"
"github.com/navidrome/navidrome/server/nativeapi" "github.com/navidrome/navidrome/server/nativeapi"
"github.com/navidrome/navidrome/server/subsonic" "github.com/navidrome/navidrome/server/subsonic"
) )
@ -23,7 +23,7 @@ var allProviders = wire.NewSet(
nativeapi.New, nativeapi.New,
persistence.New, persistence.New,
lastfm.NewRouter, lastfm.NewRouter,
GetBroker, events.GetBroker,
) )
func CreateServer(musicFolder string) *server.Server { func CreateServer(musicFolder string) *server.Server {
@ -71,41 +71,3 @@ func createScanner() scanner.Scanner {
scanner.New, scanner.New,
)) ))
} }
// Broker must be a Singleton
var (
onceBroker sync.Once
brokerInstance events.Broker
)
func GetBroker() events.Broker {
onceBroker.Do(func() {
brokerInstance = createBroker()
})
return brokerInstance
}
func createBroker() events.Broker {
panic(wire.Build(
events.NewBroker,
))
}
// Scheduler must be a Singleton
var (
onceScheduler sync.Once
schedulerInstance scheduler.Scheduler
)
func GetScheduler() scheduler.Scheduler {
onceScheduler.Do(func() {
schedulerInstance = createScheduler()
})
return schedulerInstance
}
func createScheduler() scheduler.Scheduler {
panic(wire.Build(
scheduler.New,
))
}

View file

@ -32,7 +32,7 @@ type scrobbler struct {
playMap *ttlcache.Cache playMap *ttlcache.Cache
} }
func New(ds model.DataStore) Scrobbler { func GetInstance(ds model.DataStore) Scrobbler {
instance := singleton.Get(scrobbler{}, func() interface{} { instance := singleton.Get(scrobbler{}, func() interface{} {
m := ttlcache.NewCache() m := ttlcache.NewCache()
m.SkipTTLExtensionOnHit(true) m.SkipTTLExtensionOnHit(true)

View file

@ -16,6 +16,6 @@ var Set = wire.NewSet(
NewCacheWarmer, NewCacheWarmer,
NewPlayers, NewPlayers,
transcoder.New, transcoder.New,
scrobbler.New, scrobbler.GetInstance,
NewShare, NewShare,
) )

View file

@ -3,6 +3,7 @@ package scheduler
import ( import (
"context" "context"
"github.com/navidrome/navidrome/utils/singleton"
"github.com/robfig/cron/v3" "github.com/robfig/cron/v3"
) )
@ -11,11 +12,14 @@ type Scheduler interface {
Add(crontab string, cmd func()) error Add(crontab string, cmd func()) error
} }
func New() Scheduler { func GetInstance() Scheduler {
c := cron.New(cron.WithLogger(&logger{})) instance := singleton.Get(&scheduler{}, func() interface{} {
return &scheduler{ c := cron.New(cron.WithLogger(&logger{}))
c: c, return &scheduler{
} c: c,
}
})
return instance.(*scheduler)
} }
type scheduler struct { type scheduler struct {

View file

@ -10,6 +10,8 @@ import (
"sync/atomic" "sync/atomic"
"time" "time"
"github.com/navidrome/navidrome/utils/singleton"
"code.cloudfoundry.org/go-diodes" "code.cloudfoundry.org/go-diodes"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/navidrome/navidrome/consts" "github.com/navidrome/navidrome/consts"
@ -69,18 +71,21 @@ type broker struct {
unsubscribing clientsChan unsubscribing clientsChan
} }
func NewBroker() Broker { func GetBroker() Broker {
// Instantiate a broker instance := singleton.Get(&broker{}, func() interface{} {
broker := &broker{ // Instantiate a broker
publish: make(messageChan, 100), broker := &broker{
subscribing: make(clientsChan, 1), publish: make(messageChan, 100),
unsubscribing: make(clientsChan, 1), subscribing: make(clientsChan, 1),
} unsubscribing: make(clientsChan, 1),
}
// Set it running - listening and broadcasting events // Set it running - listening and broadcasting events
go broker.listen() go broker.listen()
return broker
})
return broker return instance.(*broker)
} }
func (b *broker) SendMessage(ctx context.Context, evt Event) { func (b *broker) SendMessage(ctx context.Context, evt Event) {