M skelsprig/arbor/arbor.go => skelsprig/arbor/arbor.go +34 -18
@@ 4,6 4,7 @@ import (
"fmt"
"log"
"os"
+ "path/filepath"
"time"
"git.sr.ht/~athorp96/forest-ex/expiration"
@@ 14,30 15,32 @@ import (
"git.sr.ht/~whereswaldon/sprig/skelsprig/settings"
)
+// Service manages the storage for arbor chat history.
type Service struct {
- conn scheduler.Connection
- nodeStore store.ExtendedStore
- cl *ds.CommunityList
- done chan struct{}
- init, requested bool
- current settings.DataDirs
+ conn scheduler.Connection
+ nodeStore store.ExtendedStore
+ cl *ds.CommunityList
+ done chan struct{}
+ current settings.DataDirs
}
// New creates a new instance of the Arbor Service using
// the provided Settings within the app to acquire configuration.
func New(bus scheduler.Connection) (*Service, error) {
s := &Service{
+ conn: bus,
done: make(chan struct{}),
}
go s.run()
return s, nil
}
+// initialize loads the chat data from disk.
func (s *Service) initialize() error {
- if err := os.MkdirAll(s.current.GrovePath, 0770); err != nil {
+ if err := os.MkdirAll(filepath.Dir(s.current.OrchardPath), 0770); err != nil {
return fmt.Errorf("preparing data directory for store: %v", err)
}
- o, err := orchard.Open(s.current.GrovePath)
+ o, err := orchard.Open(s.current.OrchardPath)
if err != nil {
return fmt.Errorf("opening Orchard store: %v", err)
}
@@ 52,37 55,50 @@ func (s *Service) initialize() error {
ExtendedStore: s.nodeStore,
PurgeInterval: time.Hour,
}.Start(s.done)
+ log.Println("Arbor service initialized")
return nil
}
+// InitializeRequest asks the arbor service to initialize. This allows for
+// delayed initialization when a storage migration must occur before the
+// service starts.
type InitializeRequest struct{}
+// Request can be sent over the bus to ask for an Event to be sent over the bus.
type Request struct{}
+// Event provides a handle to the service over the bus. This allows other
+// parts of the application to invoke methods on the service.
type Event struct {
*Service
}
func (s *Service) run() {
+ var (
+ canInit, initRequested, requested, initialized bool
+ )
+ s.conn.Message(settings.Request{})
for event := range s.conn.Output() {
switch event := event.(type) {
case settings.Event:
s.current = event.Dirs
+ canInit = true
case InitializeRequest:
- // TODO: handle the case in which we don't yet have settings.
- if !s.init {
- s.initialize()
- if s.requested {
- s.conn.Message(Event{s})
- }
- }
+ initRequested = true
case Request:
- if !s.init {
- s.requested = true
+ requested = true
+ }
+ if canInit && initRequested && !initialized {
+ if err := s.initialize(); err != nil {
+ log.Printf("failed initializing arbor service: %v", err)
} else {
- s.conn.Message(Event{s})
+ initialized = true
}
}
+ if requested && initialized {
+ requested = false
+ s.conn.Message(Event{s})
+ }
}
}
M skelsprig/main.go => skelsprig/main.go +5 -0
@@ 10,6 10,7 @@ import (
"gioui.org/app"
"git.sr.ht/~gioverse/skel/scheduler"
"git.sr.ht/~gioverse/skel/window"
+ "git.sr.ht/~whereswaldon/sprig/skelsprig/arbor"
"git.sr.ht/~whereswaldon/sprig/skelsprig/pages"
"git.sr.ht/~whereswaldon/sprig/skelsprig/settings"
)
@@ 49,6 50,10 @@ func main() {
if err != nil {
log.Fatalf("Failed initializing settings: %v", err)
}
+ _, err = arbor.New(bus.Connect())
+ if err != nil {
+ log.Fatalf("Failed initializing arbor storage: %v", err)
+ }
w := window.NewWindower(bus)
go func() {
M skelsprig/pages/setup.go => skelsprig/pages/setup.go +2 -0
@@ 13,6 13,7 @@ import (
"git.sr.ht/~gioverse/skel/scheduler"
"git.sr.ht/~whereswaldon/forest-go/grove"
"git.sr.ht/~whereswaldon/forest-go/orchard"
+ "git.sr.ht/~whereswaldon/sprig/skelsprig/arbor"
"git.sr.ht/~whereswaldon/sprig/skelsprig/settings"
sprigWidget "git.sr.ht/~whereswaldon/sprig/widget"
sprigTheme "git.sr.ht/~whereswaldon/sprig/widget/theme"
@@ 72,6 73,7 @@ func (s *Setup) Update(event interface{}) bool {
s.gotSettings = true
case StorageMigrationCompleteEvent:
s.finishedStorageMigration = true
+ s.Conn.Message(arbor.InitializeRequest{})
default:
return false
}