X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/959c24478e2c3a596a81cca359fd784c897f46a2..d8f3785bb69288663f4cc46bf4d609c6770452d5:/subagent.go?ds=sidebyside diff --git a/subagent.go b/subagent.go index 437aeb5..37e9b3a 100644 --- a/subagent.go +++ b/subagent.go @@ -95,39 +95,6 @@ func (s *Subagents) Create(ctx context.Context) (*Subagent, error) { return nil, fmt.Errorf("no free subagent name after %d draws", subagentNameDraws) } -// Reserve keeps a child name out of future subagent draws. An existing subagent -// directory or a reserved name is refused. -func (s *Subagents) Reserve(name string) error { - s.mutex.Lock() - defer s.mutex.Unlock() - - if s.reserved[name] { - return fmt.Errorf("name %q is already used", name) - } - - _, err := os.Lstat(filepath.Join(s.dir, name)) - if err == nil { - return fmt.Errorf("name %q is already used by a subagent", name) - } - - if !errors.Is(err, os.ErrNotExist) { - return fmt.Errorf("check subagent name: %w", err) - } - - s.reserved[name] = true - - return nil -} - -// Release frees a reservation after a child fails to publish. It does not -// remove a subagent directory or change an open log. -func (s *Subagents) Release(name string) { - s.mutex.Lock() - defer s.mutex.Unlock() - - delete(s.reserved, name) -} - // Get returns the subagent name with its log open. A name that is not valid or // that has no directory is an unknown agent. func (s *Subagents) Get(ctx context.Context, name string) (*Subagent, error) { @@ -180,6 +147,39 @@ func (s *Subagents) Get(ctx context.Context, name string) (*Subagent, error) { return subagent, nil } +// Reserve keeps a child name out of future subagent draws. An existing subagent +// directory or a reserved name is refused. +func (s *Subagents) Reserve(name string) error { + s.mutex.Lock() + defer s.mutex.Unlock() + + if s.reserved[name] { + return fmt.Errorf("name %q is already used", name) + } + + _, err := os.Lstat(filepath.Join(s.dir, name)) + if err == nil { + return fmt.Errorf("name %q is already used by a subagent", name) + } + + if !errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("check subagent name: %w", err) + } + + s.reserved[name] = true + + return nil +} + +// Release frees a reservation after a child fails to publish. It does not +// remove a subagent directory or change an open log. +func (s *Subagents) Release(name string) { + s.mutex.Lock() + defer s.mutex.Unlock() + + delete(s.reserved, name) +} + // Snapshot flushes and locks the open logs while snapshot reads the subagent // files. snapshot must not call Subagents or an open Subagent. func (s *Subagents) Snapshot(ctx context.Context, snapshot func() error) error { @@ -220,6 +220,19 @@ func (s *Subagents) Close() error { return err } +// Flush returns when every write before the call is durable. +func (a *Subagent) Flush(ctx context.Context) error { + return a.syncer.Flush(ctx) +} + +// close makes the writes durable and closes the log. +func (a *Subagent) close() error { + a.mutex.Lock() + defer a.mutex.Unlock() + + return errors.Join(a.syncer.Close(), a.log.Close()) +} + // Append logs a message of the subagent. func (a *Subagent) Append(kind, text string) (Message, error) { a.mutex.Lock() @@ -235,11 +248,6 @@ func (a *Subagent) Append(kind, text string) (Message, error) { return message, nil } -// Flush returns when every write before the call is durable. -func (a *Subagent) Flush(ctx context.Context) error { - return a.syncer.Flush(ctx) -} - // First returns the first message of the log. func (a *Subagent) First() (Message, error) { a.mutex.Lock() @@ -272,11 +280,3 @@ func (a *Subagent) Show() (string, error) { func (a *Subagent) WorkDir() string { return filepath.Join(a.dir, "work") } - -// close makes the writes durable and closes the log. -func (a *Subagent) close() error { - a.mutex.Lock() - defer a.mutex.Unlock() - - return errors.Join(a.syncer.Close(), a.log.Close()) -}