)
const (
+ // whatsappContactLookupTimeout is the longest time of a read of names
+ // in the session.
+ whatsappContactLookupTimeout = 10 * time.Second
+
+ // whatsappImageDownloadTimeout is the longest time of an image
+ // download.
+ whatsappImageDownloadTimeout = 2 * time.Minute
+
// whatsappSource is the source of the work events of the batches.
whatsappSource = "whatsapp"
- // whatsappCatchupLimit is the longest wait for the end of the catch-up
- // after a connection.
- whatsappCatchupLimit = time.Minute
+ // whatsappCatchupTimeout is the longest wait for the end of the
+ // catch-up after a connection.
+ whatsappCatchupTimeout = time.Minute
)
// newWhatsAppInbox returns the inbox of the batches in state, with clock for
// holds shared images, and logger gets image failures.
func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *WhatsAppGroups, images *ImageStore, logger *slog.Logger) *WhatsAppInbox {
return &WhatsAppInbox{
- state: state,
- clock: clock,
- groups: groups,
- images: images,
- logger: logger,
- lookupTime: whatsappLookupTime,
- imageTime: whatsappImageTime,
- catchupLimit: whatsappCatchupLimit,
- wake: make(chan struct{}, 1),
- failures: make(chan error, 1),
+ state: state,
+ clock: clock,
+ groups: groups,
+ images: images,
+ logger: logger,
+ wake: make(chan struct{}, 1),
+ failures: make(chan error, 1),
}
}
//
// After each connection, the servers send the messages that came while the
// daemon was away, and then OfflineSyncCompleted. Until then, or until
-// catchupLimit passes, the closed batches wait in the state file. At the end of
-// the catch-up, deliver closes all batches and logs them. It wakes the root
-// once for its batches, so their catch-up gives one turn, not one for each
-// chat. The batches of the state file at the start wait for the first catch-up
-// in the same way. The event handler acknowledges a message only after the
-// state file holds it, so the servers send again a message that a crash lost. A
-// batch leaves the state file only after its work message is durable in the log
-// or agent queue. A crash between the two can repeat an unrouted batch once. A
-// routed batch enters the durable agent queue, which prevents a second log
-// entry and wakes only the child. A missing child uses the root.
+// whatsappCatchupTimeout passes, the closed batches wait in the state file. At
+// the end of the catch-up, deliver closes all batches and logs them. It wakes
+// the root once for its batches, so their catch-up gives one turn, not one for
+// each chat. The batches of the state file at the start wait for the first
+// catch-up in the same way. The event handler acknowledges a message only after
+// the state file holds it, so the servers send again a message that a crash
+// lost. A batch leaves the state file only after its work message is durable in
+// the log or agent queue. A crash between the two can repeat an unrouted batch
+// once. A routed batch enters the durable agent queue, which prevents a second
+// log entry and wakes only the child. A missing child uses the root.
//
// The state file is the one of WhatsApp, which keeps the send records in it
// too. groups gives the names of the groups. The mutex protects the state of
// goroutines. wake tells Run that a batch can be due or that a catch-up ended,
// and failures gives Run the error of a write of the state file.
type WhatsAppInbox struct {
- state *WhatsAppState
- clock func() time.Time
- groups *WhatsAppGroups
- images *ImageStore
- logger *slog.Logger
- lookupTime time.Duration
- imageTime time.Duration
- catchupLimit time.Duration
- wake chan struct{}
- failures chan error
+ state *WhatsAppState
+ clock func() time.Time
+ groups *WhatsAppGroups
+ images *ImageStore
+ logger *slog.Logger
+ wake chan struct{}
+ failures chan error
mutex sync.Mutex
catchingUp bool
}
// startCatchup starts the catch-up of a new connection, which ends at
-// endCatchup or after catchupLimit.
+// endCatchup or after whatsappCatchupTimeout.
func (i *WhatsAppInbox) startCatchup() {
i.mutex.Lock()
defer i.mutex.Unlock()
i.catchupTimer.Stop()
}
- i.catchupTimer = time.AfterFunc(i.catchupLimit, func() {
+ i.catchupTimer = time.AfterFunc(whatsappCatchupTimeout, func() {
i.caughtUpBy(catchups)
})
}
// message, so that the library does not acknowledge it, and Run stops the
// daemon. An image that cannot be downloaded or stored gets a text marker. A
// message that the batches do not take is handled with nothing to do.
-func (i *WhatsAppInbox) receive(link WhatsAppLink, event *events.Message) bool {
- ctx, cancel := context.WithTimeout(context.Background(), i.lookupTime)
+func (i *WhatsAppInbox) receive(ctx context.Context, link WhatsAppLink, event *events.Message) bool {
+ lookupCtx, cancel := context.WithTimeout(ctx, whatsappContactLookupTimeout)
defer cancel()
- chat, message, found := whatsappMessage(ctx, link.device, link.own, event)
+ chat, message, found := whatsappMessage(lookupCtx, link.device, link.own, event)
if !found {
return true
}
if event.Message.GetImageMessage() != nil {
- ctx, cancel := context.WithTimeout(context.Background(), i.imageTime)
+ ctx, cancel := context.WithTimeout(ctx, whatsappImageDownloadTimeout)
defer cancel()
message.Text = i.imageText(ctx, link, event, message.Text)