X-Git-Url: https://git.giacomolli.uk/onechat/blobdiff_plain/c781f79f3c8cb9a7577ee1574d196988da2719b3..e86df5fad9aa2f280aad845adeefd239b0e944ae:/daemon_message.go diff --git a/daemon_message.go b/daemon_message.go index eade727..7665678 100644 --- a/daemon_message.go +++ b/daemon_message.go @@ -278,6 +278,20 @@ func (m *DaemonMessages) SnapshotAgents(ctx context.Context, snapshot func() err }) } +// Snapshot holds the queue lock while snapshot locks and copies agent files. +// Its callback must take the memory locks after this lock, as delivery does. +func (m *DaemonMessages) Snapshot(snapshot func() error) error { + m.mutex.Lock() + defer m.mutex.Unlock() + + err := snapshot() + if err != nil { + return fmt.Errorf("copy agent message snapshot: %w", err) + } + + return nil +} + // Tell queues a user message from parent to its own child, then wakes the // child. It is the daemon entry point for parent-to-child messages. func (m *DaemonMessages) Tell(parent, child, text string) error { @@ -308,6 +322,29 @@ func (m *DaemonMessages) Tell(parent, child, text string) error { return nil } +// add appends a queue entry under the mutex. Its ID is never reused. +func (m *DaemonMessages) add(source, target, kind, text string) { + m.state.Next++ + m.state.Pending = append(m.state.Pending, DaemonMessage{ + ID: m.state.Next, + Source: source, + Target: target, + Kind: kind, + Text: text, + }) +} + +// failed stops all loops after a queue failure. Further sends must not change +// the queue, because the outcome of the failed write is not known. +func (m *DaemonMessages) failed(err error) error { + m.failure = err + for _, loop := range m.loops { + loop.fail(err) + } + + return err +} + // RouteWhatsApp queues a routed batch as work and wakes its child. It returns // false for an unrouted source or a missing child. A saved receipt survives // turn acknowledgement until the inbox removes the batch. A repeat after a stop @@ -385,43 +422,6 @@ func (m *DaemonMessages) PruneWhatsApp(batches []WhatsAppBatch) error { return nil } -// add appends a queue entry under the mutex. Its ID is never reused. -func (m *DaemonMessages) add(source, target, kind, text string) { - m.state.Next++ - m.state.Pending = append(m.state.Pending, DaemonMessage{ - ID: m.state.Next, - Source: source, - Target: target, - Kind: kind, - Text: text, - }) -} - -// failed stops all loops after a queue failure. Further sends must not change -// the queue, because the outcome of the failed write is not known. -func (m *DaemonMessages) failed(err error) error { - m.failure = err - for _, loop := range m.loops { - loop.fail(err) - } - - return err -} - -// Snapshot holds the queue lock while snapshot locks and copies agent files. -// Its callback must take the memory locks after this lock, as delivery does. -func (m *DaemonMessages) Snapshot(snapshot func() error) error { - m.mutex.Lock() - defer m.mutex.Unlock() - - err := snapshot() - if err != nil { - return fmt.Errorf("copy agent message snapshot: %w", err) - } - - return nil -} - // Finish acknowledges the queued messages taken by a turn and queues its final // report in the same file replacement. A child with no final text sends // nothing. Call after a final reply, a failure, or a user interrupt, but not