diff options
| author | Ophestra <cat@gensokyo.uk> | 2025-08-28 01:07:51 +0900 |
|---|---|---|
| committer | Ophestra <cat@gensokyo.uk> | 2025-08-28 01:07:51 +0900 |
| commit | b14690aa77b3d5f86c4d1b1965675d6d82789e32 (patch) | |
| tree | 5765f705fd69dae7a65a0666451ac71a729a6aa8 /internal/app/app.go | |
| parent | d0b6852cd7db2bb1214c3267719d3ac108c0a53e (diff) | |
internal/app: remove seal interface
This further cleans up the package for the restructure.
Signed-off-by: Ophestra <cat@gensokyo.uk>
Diffstat (limited to 'internal/app/app.go')
| -rw-r--r-- | internal/app/app.go | 92 |
1 files changed, 69 insertions, 23 deletions
diff --git a/internal/app/app.go b/internal/app/app.go index d59b145d..17b4103d 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -2,35 +2,81 @@ package app import ( - "syscall" - "time" + "context" + "fmt" + "log" + "sync" + + "hakurei.app/hst" + "hakurei.app/internal/app/state" + "hakurei.app/internal/sys" ) -type SealedApp interface { - // Run commits sealed system setup and starts the app process. - Run(rs *RunState) error +func New(ctx context.Context, os sys.State) (*App, error) { + a := new(App) + a.sys = os + a.ctx = ctx + + id := new(state.ID) + err := state.NewAppID(id) + a.id = newID(id) + + return a, err } -// RunState stores the outcome of a call to [SealedApp.Run]. -type RunState struct { - // Time is the exact point in time where the process was created. - // Location must be set to UTC. - // - // Time is nil if no process was ever created. - Time *time.Time - // RevertErr is stored by the deferred revert call. - RevertErr error - // WaitErr is the generic error value created by the standard library. - WaitErr error +func MustNew(ctx context.Context, os sys.State) *App { + a, err := New(ctx, os) + if err != nil { + log.Fatalf("cannot create app: %v", err) + } + return a +} - syscall.WaitStatus +type App struct { + outcome *Outcome + + id *stringPair[state.ID] + sys sys.State + ctx context.Context + mu sync.RWMutex } -// SetStart stores the current time in [RunState] once. -func (rs *RunState) SetStart() { - if rs.Time != nil { - panic("attempted to store time twice") +// ID returns a copy of [state.ID] held by App. +func (a *App) ID() state.ID { a.mu.RLock(); defer a.mu.RUnlock(); return a.id.unwrap() } + +func (a *App) String() string { + if a == nil { + return "(invalid app)" + } + + a.mu.RLock() + defer a.mu.RUnlock() + + if a.outcome != nil { + if a.outcome.user.uid == nil { + return fmt.Sprintf("(sealed app %s with invalid uid)", a.id) + } + return fmt.Sprintf("(sealed app %s as uid %s)", a.id, a.outcome.user.uid) + } + + return fmt.Sprintf("(unsealed app %s)", a.id) +} + +// Seal determines the outcome of [hst.Config] as a [SealedApp]. +// Values stored in and referred to by [hst.Config] might be overwritten and must not be used again. +func (a *App) Seal(config *hst.Config) (*Outcome, error) { + a.mu.Lock() + defer a.mu.Unlock() + + if a.outcome != nil { + panic("app sealed twice") + } + + seal := new(Outcome) + seal.id = a.id + err := seal.finalise(a.ctx, a.sys, config) + if err == nil { + a.outcome = seal } - now := time.Now().UTC() - rs.Time = &now + return seal, err } |
