]> git.giacomolli.uk - onechat/blobdiff - whatsapp.go
Pass caller contexts through WhatsApp callbacks
[onechat] / whatsapp.go
index f225756e1efb64643a5cfbecf95d6a9ead54f3e5..be1acc65b8e763b131f107513b3efd9c2e71af0f 100644 (file)
@@ -107,6 +107,7 @@ type WhatsAppClient interface {
 // the client of a device with its event handler.
 func openWhatsApp(ctx context.Context, dir string, clock func() time.Time, logger *slog.Logger, newClient func(device *store.Device, handle func(event any) bool) WhatsAppClient) (*WhatsApp, error) {
        w := &WhatsApp{
+               ctx:         ctx,
                dir:         filepath.Join(dir, whatsappDirName),
                clock:       clock,
                logger:      logger,
@@ -169,6 +170,9 @@ func openWhatsApp(ctx context.Context, dir string, clock func() time.Time, logge
 // creation, close, removal, and snapshots. It is held before mutex, and stays
 // held when removal releases mutex for client callbacks.
 //
+// ctx is the caller context until Run sets its context for library callbacks.
+// The mutex protects it, so callbacks follow daemon cancellation.
+//
 // The inbox puts messages into batches and logs them, and groups holds the
 // names of the groups. Both get a WhatsAppLink from link for each call, so they
 // use the current device and client.
@@ -181,6 +185,7 @@ func openWhatsApp(ctx context.Context, dir string, clock func() time.Time, logge
 // log, and those of private chats hold phone numbers, because the agent needs
 // them to send.
 type WhatsApp struct {
+       ctx         context.Context
        dir         string
        clock       func() time.Time
        logger      *slog.Logger
@@ -224,6 +229,7 @@ type WhatsApp struct {
 func (w *WhatsApp) Run(ctx context.Context, l *TurnLoop, notify func(Event)) error {
        w.mutex.Lock()
 
+       w.ctx = ctx
        w.notify = notify
        linked := w.linked
        w.retrying = linked
@@ -900,9 +906,14 @@ func (w *WhatsApp) linkedBy(client WhatsAppClient) {
 // connected again with the length of the outage. The retries of the library and
 // Run between them log nothing.
 func (w *WhatsApp) handle(event any) bool {
+       w.mutex.Lock()
+
+       ctx := w.ctx
+       w.mutex.Unlock()
+
        switch event := event.(type) {
        case *events.Message:
-               return w.inbox.receive(w.link(), event)
+               return w.inbox.receive(ctx, w.link(), event)
        case *events.GroupInfo:
                if event.Name != nil {
                        w.groups.set(event.JID.String(), event.Name.Name)
@@ -987,7 +998,7 @@ func (w *WhatsApp) handle(event any) bool {
        w.mutex.Unlock()
 
        if line != "" {
-               w.logger.Log(context.Background(), level, line, attrs...)
+               w.logger.Log(ctx, level, line, attrs...)
        }
 
        if notice != "" {