return nil, fmt.Errorf("create subagent directory: %w", err)
}
- return s.Get(ctx, name)
- }
-
- 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)
- }
+ subagent, err := s.Get(ctx, name)
+ if err != nil {
+ return subagent, fmt.Errorf("open created worker: %w", err)
+ }
- if !errors.Is(err, os.ErrNotExist) {
- return fmt.Errorf("check subagent name: %w", err)
+ return subagent, nil
}
- 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)
+ return nil, fmt.Errorf("no free subagent name after %d draws", subagentNameDraws)
}
// Get returns the subagent name with its log open. A name that is not valid or
log: log,
syncer: syncer,
}
+
s.open[name] = subagent
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 {
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()
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()
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())
-}