74 lines
1.6 KiB
Go
74 lines
1.6 KiB
Go
package inboxserver
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"path/filepath"
|
|
"sync"
|
|
|
|
"inbox/internal/app/leaderloop"
|
|
"inbox/internal/app/runtimeconfig"
|
|
"inbox/internal/app/workspaceprovision"
|
|
"inbox/internal/app/workspaceruntime"
|
|
"inbox/internal/base/timeutil"
|
|
httpapi "inbox/internal/httpapi"
|
|
"inbox/internal/inboxapp"
|
|
sqlitestore "inbox/internal/store/sqlite"
|
|
)
|
|
|
|
type App struct {
|
|
store *sqlitestore.Store
|
|
handler http.Handler
|
|
cancel context.CancelFunc
|
|
wg sync.WaitGroup
|
|
}
|
|
|
|
func Open(projectRoot, workspacesDir string, serverPort int, clock timeutil.Clock) (*App, error) {
|
|
store, err := sqlitestore.Open(filepath.Join(projectRoot, ".runtime", "inbox.db"), clock)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
runtime := workspaceruntime.NewService(store, projectRoot, workspacesDir, serverPort, clock, nil)
|
|
provision := workspaceprovision.NewService(store, workspacesDir, runtime)
|
|
handler := httpapi.NewHandlerWithServices(inboxapp.BuildServices(store, clock, inboxapp.Options{
|
|
WorkspaceProvision: provision,
|
|
WorkspaceRuntime: runtime,
|
|
}))
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
leader := leaderloop.NewService(store, runtimeconfig.NewService(store, store, clock), runtime, nil, clock, projectRoot)
|
|
|
|
app := &App{
|
|
store: store,
|
|
handler: handler,
|
|
cancel: cancel,
|
|
}
|
|
app.wg.Add(1)
|
|
go func() {
|
|
defer app.wg.Done()
|
|
_ = leader.Run(ctx)
|
|
}()
|
|
return app, nil
|
|
}
|
|
|
|
func (a *App) Handler() http.Handler {
|
|
if a == nil {
|
|
return nil
|
|
}
|
|
return a.handler
|
|
}
|
|
|
|
func (a *App) Close() error {
|
|
if a == nil {
|
|
return nil
|
|
}
|
|
if a.cancel != nil {
|
|
a.cancel()
|
|
}
|
|
a.wg.Wait()
|
|
if a.store == nil {
|
|
return nil
|
|
}
|
|
return a.store.Close()
|
|
}
|