]> git.giacomolli.uk - onechat/commitdiff
Name timeouts for the operations they limit master
authorAnderson A. Giacomolli <redacted>
Tue, 10 Nov 2026 18:09:23 +0000 (15:09 -0300)
committerAnderson A. Giacomolli <redacted>
Tue, 10 Nov 2026 18:30:10 +0000 (15:30 -0300)
Each operation limit ends in Timeout and names its operation. Telegram
file lookup, image download, and typing have separate names from message
sends. All wait values stay the same, including the server wait for
updates and the memory build wait.

14 files changed:
build_run.go
schedule.go
schedule_test.go
telegram_api.go
telegram_api_test.go
tools.go
whatsapp.go
whatsapp_groups.go
whatsapp_image_test.go
whatsapp_inbox.go
whatsapp_inbox_test.go
whatsapp_send.go
whatsapp_state.go
whatsapp_test.go

index 9c27ff2146b7451a9d7c5c0a5e08864575a69a3e..cc12cf26d2d66542bbab2216a96350079e32d422 100644 (file)
@@ -19,6 +19,9 @@ import (
 // buildLineBytes is the most bytes of one line in a build input or usage log.
 const buildLineBytes = 1 << 20
 
 // buildLineBytes is the most bytes of one line in a build input or usage log.
 const buildLineBytes = 1 << 20
 
+// buildWaitTimeout is the longest wait for pending memory builds.
+const buildWaitTimeout = time.Second
+
 // buildQuotaLimit is the largest increase in used quota points of a run.
 const buildQuotaLimit = 15.0
 
 // buildQuotaLimit is the largest increase in used quota points of a run.
 const buildQuotaLimit = 15.0
 
@@ -113,7 +116,7 @@ func (r *BuildRun) check() string {
 
 // waitBuilds waits up to one second without leaving a child context open.
 func (r *BuildRun) waitBuilds(ctx context.Context) error {
 
 // waitBuilds waits up to one second without leaving a child context open.
 func (r *BuildRun) waitBuilds(ctx context.Context) error {
-       ctx, cancel := context.WithTimeout(ctx, time.Second)
+       ctx, cancel := context.WithTimeout(ctx, buildWaitTimeout)
        defer cancel()
 
        return r.memory.Wait(ctx)
        defer cancel()
 
        return r.memory.Wait(ctx)
index a1eba1c1665f11e35cb800a71a25978dd30f6fa6..28a5a767777bd341e880b046dde2fac9e8d7f675 100644 (file)
@@ -33,10 +33,10 @@ const (
        // scheduleSource is the source of the work events of the runs.
        scheduleSource = "schedule"
 
        // scheduleSource is the source of the work events of the runs.
        scheduleSource = "schedule"
 
-       // scheduleCheck is the longest wait of Run before it looks at the times
-       // again, so that it sees a suspend of the machine or a change of the
-       // clock.
-       scheduleCheck = time.Minute
+       // scheduleClockWaitTimeout is the longest wait of Run before it looks
+       // at the times again, so that it sees a suspend of the machine or a
+       // change of the clock.
+       scheduleClockWaitTimeout = time.Minute
 
        // scheduleLate is how long after its time a run is late.
        scheduleLate = time.Minute
 
        // scheduleLate is how long after its time a run is late.
        scheduleLate = time.Minute
@@ -124,9 +124,10 @@ type Schedules struct {
 }
 
 // Run starts the runs of the due schedules in l until ctx ends. It waits until
 }
 
 // Run starts the runs of the due schedules in l until ctx ends. It waits until
-// the first due time, at most scheduleCheck at a time, and also wakes at a set
-// or a remove. So a schedule that came due while the daemon was stopped runs at
-// the start. It returns the error of a write of the log or of the file.
+// the first due time, at most scheduleClockWaitTimeout at a time, and also
+// wakes at a set or a remove. So a schedule that came due while the daemon was
+// stopped runs at the start. It returns the error of a write of the log or of
+// the file.
 func (s *Schedules) Run(ctx context.Context, l *TurnLoop) error {
        for {
                err := s.deliver(ctx, l)
 func (s *Schedules) Run(ctx context.Context, l *TurnLoop) error {
        for {
                err := s.deliver(ctx, l)
@@ -141,7 +142,7 @@ func (s *Schedules) Run(ctx context.Context, l *TurnLoop) error {
 
                wait, found := s.Wait(s.clock())
                if found {
 
                wait, found := s.Wait(s.clock())
                if found {
-                       timer = time.NewTimer(min(wait, scheduleCheck))
+                       timer = time.NewTimer(min(wait, scheduleClockWaitTimeout))
                        timeout = timer.C
                }
 
                        timeout = timer.C
                }
 
index 5743a22bb3fdae5fd18289a348a58b0ead9fb4cd..cb839d5f95351d810c38a344319da5f3e8424bd6 100644 (file)
@@ -336,7 +336,7 @@ func TestSchedulesCheckTheClockAfterItsWaitLimit(t *testing.T) {
                synctest.Wait()
                require.Zero(t, loop.memory.Len())
                clock.Set(clock.Now().Add(5 * time.Minute))
                synctest.Wait()
                require.Zero(t, loop.memory.Len())
                clock.Set(clock.Now().Add(5 * time.Minute))
-               time.Sleep(scheduleCheck)
+               time.Sleep(scheduleClockWaitTimeout)
                synctest.Wait()
                require.Equal(t, 1, loop.memory.Len())
                require.Contains(t, events.Last("work"), "Check the clock.")
                synctest.Wait()
                require.Equal(t, 1, loop.memory.Len())
                require.Contains(t, events.Last("work"), "Check the clock.")
index a04b2fa56e88af4aca8480d0dc29bbad964846af..8f78387d096b3215de9a0246ec7213f338d1f601 100644 (file)
@@ -15,25 +15,33 @@ import (
 )
 
 const (
 )
 
 const (
-       // telegramPollSeconds is how long one getUpdates call waits for an
-       // update.
-       telegramPollSeconds = 50
+       // telegramUpdateWaitTimeout is how long one getUpdates call waits for
+       // an update.
+       telegramUpdateWaitTimeout = 50 * time.Second
 
 
-       // telegramPollSlack is how much longer than telegramPollSeconds a
+       // telegramPollSlack is how much longer than telegramUpdateWaitTimeout a
        // getUpdates call can take before the bot gives it up.
        telegramPollSlack = 20 * time.Second
 
        // telegramPollTimeout is how long one getUpdates call can take.
        // getUpdates call can take before the bot gives it up.
        telegramPollSlack = 20 * time.Second
 
        // telegramPollTimeout is how long one getUpdates call can take.
-       telegramPollTimeout = telegramPollSeconds*time.Second + telegramPollSlack
-
-       // telegramSendTimeout is how long a sendMessage, sendRichMessage, or
-       // sendChatAction call can take. A connection that stops without a
-       // close, such as after a network change, then fails the call, and the
-       // sender tries again, instead of a wait until TCP gives up. The client
-       // has no timeout of its own, because the long poll of getUpdates needs
-       // a longer limit.
+       telegramPollTimeout = telegramUpdateWaitTimeout + telegramPollSlack
+
+       // telegramSendTimeout is how long a sendMessage or sendRichMessage call
+       // can take. A connection that stops without a close, such as after a
+       // network change, then fails the call, and the sender tries again,
+       // instead of a wait until TCP gives up. The client has no timeout of
+       // its own, because the long poll of getUpdates needs a longer limit.
        telegramSendTimeout = 30 * time.Second
 
        telegramSendTimeout = 30 * time.Second
 
+       // telegramFileLookupTimeout is the longest wait for image file details.
+       telegramFileLookupTimeout = 30 * time.Second
+
+       // telegramImageDownloadTimeout is the longest wait for image bytes.
+       telegramImageDownloadTimeout = 30 * time.Second
+
+       // telegramTypingTimeout is the longest wait to show the typing action.
+       telegramTypingTimeout = 30 * time.Second
+
        // telegramAnswerBytes is the most bytes of one answer of the Bot API.
        telegramAnswerBytes = 16 << 20
 )
        // telegramAnswerBytes is the most bytes of one answer of the Bot API.
        telegramAnswerBytes = 16 << 20
 )
@@ -84,15 +92,15 @@ type TelegramAPI struct {
        http  *http.Client
 }
 
        http  *http.Client
 }
 
-// GetUpdates waits for the updates from offset on, up to telegramPollSeconds,
-// and returns them. Telegram forgets each update before offset. Only new
-// messages are asked for.
+// GetUpdates waits for the updates from offset on, up to
+// telegramUpdateWaitTimeout, and returns them. Telegram forgets each update
+// before offset. Only new messages are asked for.
 func (b *TelegramAPI) GetUpdates(ctx context.Context, offset int64) ([]TelegramUpdate, error) {
        var updates []TelegramUpdate
 
        err := b.call(ctx, telegramPollTimeout, "getUpdates", map[string]any{
                "offset":          offset,
 func (b *TelegramAPI) GetUpdates(ctx context.Context, offset int64) ([]TelegramUpdate, error) {
        var updates []TelegramUpdate
 
        err := b.call(ctx, telegramPollTimeout, "getUpdates", map[string]any{
                "offset":          offset,
-               "timeout":         telegramPollSeconds,
+               "timeout":         int(telegramUpdateWaitTimeout / time.Second),
                "allowed_updates": []string{"message"},
        }, &updates)
 
                "allowed_updates": []string{"message"},
        }, &updates)
 
@@ -107,7 +115,7 @@ func (b *TelegramAPI) GetImage(ctx context.Context, id string) (data []byte, err
                Size int64  `json:"file_size"`
        }
 
                Size int64  `json:"file_size"`
        }
 
-       err = b.call(ctx, telegramSendTimeout, "getFile", map[string]any{"file_id": id}, &file)
+       err = b.call(ctx, telegramFileLookupTimeout, "getFile", map[string]any{"file_id": id}, &file)
        if err != nil {
                return nil, fmt.Errorf("get image file: %w", err)
        }
        if err != nil {
                return nil, fmt.Errorf("get image file: %w", err)
        }
@@ -120,7 +128,7 @@ func (b *TelegramAPI) GetImage(ctx context.Context, id string) (data []byte, err
                return nil, errors.New("invalid image file path")
        }
 
                return nil, errors.New("invalid image file path")
        }
 
-       ctx, cancel := context.WithTimeout(ctx, telegramSendTimeout)
+       ctx, cancel := context.WithTimeout(ctx, telegramImageDownloadTimeout)
        defer cancel()
 
        request, err := http.NewRequestWithContext(ctx, http.MethodGet, b.base+"/file/bot"+b.token+"/"+file.Path, nil)
        defer cancel()
 
        request, err := http.NewRequestWithContext(ctx, http.MethodGet, b.base+"/file/bot"+b.token+"/"+file.Path, nil)
@@ -130,13 +138,13 @@ func (b *TelegramAPI) GetImage(ctx context.Context, id string) (data []byte, err
 
        response, err := b.http.Do(request)
        if err != nil {
 
        response, err := b.http.Do(request)
        if err != nil {
-               return nil, b.networkError("image download failed", err, telegramSendTimeout)
+               return nil, b.networkError("image download failed", err, telegramImageDownloadTimeout)
        }
 
        defer func() {
                closeErr := response.Body.Close()
                if closeErr != nil {
        }
 
        defer func() {
                closeErr := response.Body.Close()
                if closeErr != nil {
-                       err = errors.Join(err, b.networkError("close image download", closeErr, telegramSendTimeout))
+                       err = errors.Join(err, b.networkError("close image download", closeErr, telegramImageDownloadTimeout))
                }
        }()
 
                }
        }()
 
@@ -149,7 +157,7 @@ func (b *TelegramAPI) GetImage(ctx context.Context, id string) (data []byte, err
 
        data, err = io.ReadAll(io.LimitReader(response.Body, imageMaxBytes+1))
        if err != nil {
 
        data, err = io.ReadAll(io.LimitReader(response.Body, imageMaxBytes+1))
        if err != nil {
-               return nil, b.networkError("image cut off", err, telegramSendTimeout)
+               return nil, b.networkError("image cut off", err, telegramImageDownloadTimeout)
        }
 
        if len(data) > imageMaxBytes {
        }
 
        if len(data) > imageMaxBytes {
@@ -189,9 +197,10 @@ func (b *TelegramAPI) SendRichMessage(ctx context.Context, chat int64, markdown
 }
 
 // SendTyping shows the typing action in chat for about five seconds. A call
 }
 
 // SendTyping shows the typing action in chat for about five seconds. A call
-// that takes longer than telegramSendTimeout fails with a TelegramNetworkError.
+// that takes longer than telegramTypingTimeout fails with a
+// TelegramNetworkError.
 func (b *TelegramAPI) SendTyping(ctx context.Context, chat int64) error {
 func (b *TelegramAPI) SendTyping(ctx context.Context, chat int64) error {
-       return b.call(ctx, telegramSendTimeout, "sendChatAction", map[string]any{
+       return b.call(ctx, telegramTypingTimeout, "sendChatAction", map[string]any{
                "chat_id": chat,
                "action":  "typing",
        }, nil)
                "chat_id": chat,
                "action":  "typing",
        }, nil)
index 6fa4cba18179bd048ba21c45961cae910e22b9f4..ca112743c478b64691eaf177c79a96665402e3a4 100644 (file)
@@ -29,7 +29,7 @@ func TestGetUpdatesAsksForMessagesFromTheOffset(t *testing.T) {
        require.Equal(t, "getUpdates", call.method)
        require.Equal(t, map[string]any{
                "offset":          float64(7),
        require.Equal(t, "getUpdates", call.method)
        require.Equal(t, map[string]any{
                "offset":          float64(7),
-               "timeout":         float64(telegramPollSeconds),
+               "timeout":         float64(telegramUpdateWaitTimeout / time.Second),
                "allowed_updates": []any{"message"},
        }, call.params)
 }
                "allowed_updates": []any{"message"},
        }, call.params)
 }
index 96cbb97d38010e9d6e53871b7bef0c471dba5dcf..bbd34cf67a7c82389e35aca4944bab7e33024fff 100644 (file)
--- a/tools.go
+++ b/tools.go
@@ -27,9 +27,9 @@ const (
        // output, enough for toolClipCharacters/2 characters of 4 bytes.
        toolClipBytes = 4 * toolClipCharacters / 2
 
        // output, enough for toolClipCharacters/2 characters of 4 bytes.
        toolClipBytes = 4 * toolClipCharacters / 2
 
-       // toolShellWaitDelay is how long a command can keep its output open
+       // toolShellOutputTimeout is how long a command can keep its output open
        // after it ends or after its kill.
        // after it ends or after its kill.
-       toolShellWaitDelay = 2 * time.Second
+       toolShellOutputTimeout = 2 * time.Second
 )
 
 // ToolLog is the log that the tools write their calls and results to.
 )
 
 // ToolLog is the log that the tools write their calls and results to.
@@ -379,7 +379,7 @@ func (b *Toolbox) shell(ctx context.Context, command string) string {
        cmd.Cancel = func() error {
                return syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
        }
        cmd.Cancel = func() error {
                return syscall.Kill(-cmd.Process.Pid, syscall.SIGKILL)
        }
-       cmd.WaitDelay = toolShellWaitDelay
+       cmd.WaitDelay = toolShellOutputTimeout
 
        output := &ToolHeadTail{}
        cmd.Stdout = output
 
        output := &ToolHeadTail{}
        cmd.Stdout = output
index 93651736c5285c885f3656a814a8056f2108977f..97b1e857d50cebcf45a59f1d08251cfd76bbcb76 100644 (file)
@@ -54,17 +54,17 @@ const (
        // whatsappTimeLayout is the layout of the times in the answers.
        whatsappTimeLayout = "2006-01-02 15:04"
 
        // whatsappTimeLayout is the layout of the times in the answers.
        whatsappTimeLayout = "2006-01-02 15:04"
 
-       // whatsappPairTime is the longest time of a pairing. The library closes
-       // the pairing connection after about 160 seconds.
-       whatsappPairTime = 3 * time.Minute
+       // whatsappPairTimeout is the longest time of a pairing. The library
+       // closes the pairing connection after about 160 seconds.
+       whatsappPairTimeout = 3 * time.Minute
 
 
-       // whatsappLogoutTime is the longest time of the logout call of an
+       // whatsappLogoutTimeout is the longest time of the logout call of an
        // unlink.
        // unlink.
-       whatsappLogoutTime = 30 * time.Second
+       whatsappLogoutTimeout = 30 * time.Second
 
 
-       // whatsappNoticeDelay is how long a disconnection lasts before the user
-       // gets a notice.
-       whatsappNoticeDelay = 10 * time.Minute
+       // whatsappOutageNoticeDelay is the delay from a disconnection to its
+       // notice to the user.
+       whatsappOutageNoticeDelay = 10 * time.Minute
 
        // whatsappRetryDelay is the first wait after a failed starting
        // connection.
 
        // whatsappRetryDelay is the first wait after a failed starting
        // connection.
@@ -309,7 +309,7 @@ func (w *WhatsApp) Run(ctx context.Context, l *TurnLoop, notify func(Event)) err
                        case w.isLinked():
                                request.answer("WhatsApp is linked already. Run /whatsapp unlink first.")
                        default:
                        case w.isLinked():
                                request.answer("WhatsApp is linked already. Run /whatsapp unlink first.")
                        default:
-                               pairCtx, cancelPair := context.WithTimeout(ctx, whatsappPairTime)
+                               pairCtx, cancelPair := context.WithTimeout(ctx, whatsappPairTimeout)
                                cancel = cancelPair
                                pairing.Go(func() {
                                        defer cancelPair()
                                cancel = cancelPair
                                pairing.Go(func() {
                                        defer cancelPair()
@@ -569,7 +569,7 @@ func (w *WhatsApp) startOutage() bool {
                w.disconnectedAt = w.clock()
                w.disconnections++
                disconnections := w.disconnections
                w.disconnectedAt = w.clock()
                w.disconnections++
                disconnections := w.disconnections
-               w.timer = time.AfterFunc(whatsappNoticeDelay, func() {
+               w.timer = time.AfterFunc(whatsappOutageNoticeDelay, func() {
                        w.disconnectedLong(disconnections)
                })
        }
                        w.disconnectedLong(disconnections)
                })
        }
@@ -654,7 +654,7 @@ func (w *WhatsApp) unlink(ctx context.Context, l *TurnLoop, answer func(text str
        var logoutErr error
 
        if client != nil {
        var logoutErr error
 
        if client != nil {
-               ctx, cancel := context.WithTimeout(ctx, whatsappLogoutTime)
+               ctx, cancel := context.WithTimeout(ctx, whatsappLogoutTimeout)
                defer cancel()
 
                logoutErr = client.Logout(ctx)
                defer cancel()
 
                logoutErr = client.Logout(ctx)
@@ -890,8 +890,8 @@ func (w *WhatsApp) linkedBy(client WhatsAppClient) {
 // handle takes one event of the library and tells if it was handled. A message
 // goes to the inbox. The names of the groups follow the events of the groups. A
 // connection starts a catch-up of the inbox, which ends at OfflineSyncCompleted
 // handle takes one event of the library and tells if it was handled. A message
 // goes to the inbox. The names of the groups follow the events of the groups. A
 // connection starts a catch-up of the inbox, which ends at OfflineSyncCompleted
-// or after whatsappCatchupLimit. A disconnection keeps the time of its start
-// while Run or the library tries again. After whatsappNoticeDelay of a
+// or after whatsappCatchupTimeout. A disconnection keeps the time of its start
+// while Run or the library tries again. After whatsappOutageNoticeDelay of a
 // disconnection, all clients get one notice, and they get one more when the
 // connection comes back. A disconnection that the library does not try again
 // gives a notice at once.
 // disconnection, all clients get one notice, and they get one more when the
 // connection comes back. A disconnection that the library does not try again
 // gives a notice at once.
index 4d6c7e588be6501bb4c7e06745ba2fb6a427e892..6e9bed3eae9c27c80af78543b5bf4cf15326d939 100644 (file)
@@ -9,9 +9,9 @@ import (
 )
 
 const (
 )
 
 const (
-       // whatsappGroupsLookupTime is the longest time of a read of group
+       // whatsappGroupLookupTimeout is the longest time of a read of group
        // names.
        // names.
-       whatsappGroupsLookupTime = 10 * time.Second
+       whatsappGroupLookupTimeout = 10 * time.Second
 
        // whatsappGroupsRefresh is the shortest time between two reads of the
        // groups from WhatsApp for a group with no name.
 
        // whatsappGroupsRefresh is the shortest time between two reads of the
        // groups from WhatsApp for a group with no name.
@@ -81,7 +81,7 @@ func (g *WhatsAppGroups) read(ctx context.Context, link WhatsAppLink) bool {
                return false
        }
 
                return false
        }
 
-       ctx, cancel := context.WithTimeout(ctx, whatsappGroupsLookupTime)
+       ctx, cancel := context.WithTimeout(ctx, whatsappGroupLookupTimeout)
        defer cancel()
 
        groups, err := link.client.GetJoinedGroups(ctx)
        defer cancel()
 
        groups, err := link.client.GetJoinedGroups(ctx)
index 91af70a921e64cbd63e26e88111527d14d29df10..75a95dc88d23deebd4f095b12adae39e93b25703 100644 (file)
@@ -83,7 +83,7 @@ func TestWhatsAppImageDownloadCanOutlastNameLookup(t *testing.T) {
        synctest.Test(t, func(t *testing.T) {
                whatsapp, fake := whatsappStartTestLinked(t)
                whatsapp.client = fake
        synctest.Test(t, func(t *testing.T) {
                whatsapp, fake := whatsappStartTestLinked(t)
                whatsapp.client = fake
-               fake.downloadWait = whatsappLookupTime + time.Second
+               fake.downloadWait = whatsappContactLookupTimeout + time.Second
                data := imageTestPNG(t, 3, 2)
                fake.downloadData = data
 
                data := imageTestPNG(t, 3, 2)
                fake.downloadData = data
 
index 392593fda5109d1f4ba9f921b9baa6eb1d169562..9d2183e7d5e282a96442f35ba13d0a7cf58ec1a1 100644 (file)
@@ -16,19 +16,20 @@ import (
 )
 
 const (
 )
 
 const (
-       // whatsappLookupTime is the longest time of a read of names in the
-       // session.
-       whatsappLookupTime = 10 * time.Second
+       // whatsappContactLookupTimeout is the longest time of a read of names
+       // in the session.
+       whatsappContactLookupTimeout = 10 * time.Second
 
 
-       // whatsappImageTime is the longest time of an image download.
-       whatsappImageTime = 2 * time.Minute
+       // 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"
 
 
        // 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
 )
 
 // newWhatsAppInbox returns the inbox of the batches in state, with clock for
@@ -52,7 +53,7 @@ func newWhatsAppInbox(state *WhatsAppState, clock func() time.Time, groups *What
 //
 // After each connection, the servers send the messages that came while the
 // daemon was away, and then OfflineSyncCompleted. Until then, or until
 //
 // After each connection, the servers send the messages that came while the
 // daemon was away, and then OfflineSyncCompleted. Until then, or until
-// whatsappCatchupLimit passes, the closed batches wait in the state file. At
+// 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
 // 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
@@ -207,7 +208,7 @@ func (i *WhatsAppInbox) waitForCatchup() {
 }
 
 // startCatchup starts the catch-up of a new connection, which ends at
 }
 
 // startCatchup starts the catch-up of a new connection, which ends at
-// endCatchup or after whatsappCatchupLimit.
+// endCatchup or after whatsappCatchupTimeout.
 func (i *WhatsAppInbox) startCatchup() {
        i.mutex.Lock()
        defer i.mutex.Unlock()
 func (i *WhatsAppInbox) startCatchup() {
        i.mutex.Lock()
        defer i.mutex.Unlock()
@@ -219,7 +220,7 @@ func (i *WhatsAppInbox) startCatchup() {
                i.catchupTimer.Stop()
        }
 
                i.catchupTimer.Stop()
        }
 
-       i.catchupTimer = time.AfterFunc(whatsappCatchupLimit, func() {
+       i.catchupTimer = time.AfterFunc(whatsappCatchupTimeout, func() {
                i.caughtUpBy(catchups)
        })
 }
                i.caughtUpBy(catchups)
        })
 }
@@ -230,7 +231,7 @@ func (i *WhatsAppInbox) startCatchup() {
 // 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(ctx context.Context, link WhatsAppLink, event *events.Message) bool {
 // 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(ctx context.Context, link WhatsAppLink, event *events.Message) bool {
-       lookupCtx, cancel := context.WithTimeout(ctx, whatsappLookupTime)
+       lookupCtx, cancel := context.WithTimeout(ctx, whatsappContactLookupTimeout)
        defer cancel()
 
        chat, message, found := whatsappMessage(lookupCtx, link.device, link.own, event)
        defer cancel()
 
        chat, message, found := whatsappMessage(lookupCtx, link.device, link.own, event)
@@ -239,7 +240,7 @@ func (i *WhatsAppInbox) receive(ctx context.Context, link WhatsAppLink, event *e
        }
 
        if event.Message.GetImageMessage() != nil {
        }
 
        if event.Message.GetImageMessage() != nil {
-               ctx, cancel := context.WithTimeout(ctx, whatsappImageTime)
+               ctx, cancel := context.WithTimeout(ctx, whatsappImageDownloadTimeout)
                defer cancel()
 
                message.Text = i.imageText(ctx, link, event, message.Text)
                defer cancel()
 
                message.Text = i.imageText(ctx, link, event, message.Text)
index a0a0f9dfc4e61cd53139907edb994acf3f124799..1ce9a72da56d66c0af5891b1aac8a40f00d13bb3 100644 (file)
@@ -147,7 +147,7 @@ func TestWhatsAppRunClosesABatchAfterQuietTime(t *testing.T) {
                synctest.Wait()
                require.True(t, test.fake.Emit(whatsappTestMessage(whatsappTestAna, whatsappTestOwn, "m1", "On my way.", time.Now())))
                synctest.Wait()
                synctest.Wait()
                require.True(t, test.fake.Emit(whatsappTestMessage(whatsappTestAna, whatsappTestOwn, "m1", "On my way.", time.Now())))
                synctest.Wait()
-               time.Sleep(whatsappBatchQuiet - time.Nanosecond)
+               time.Sleep(whatsappBatchIdleTimeout - time.Nanosecond)
                synctest.Wait()
                require.Zero(t, test.loop.memory.Len())
 
                synctest.Wait()
                require.Zero(t, test.loop.memory.Len())
 
@@ -268,7 +268,7 @@ func TestWhatsAppCatchupEndsAfterItsLimit(t *testing.T) {
                require.NoError(t, test.whatsapp.inbox.deliver(t.Context(), test.loop, test.whatsapp.link(), false))
                require.Zero(t, test.loop.memory.Len())
 
                require.NoError(t, test.whatsapp.inbox.deliver(t.Context(), test.loop, test.whatsapp.link(), false))
                require.Zero(t, test.loop.memory.Len())
 
-               time.Sleep(whatsappCatchupLimit)
+               time.Sleep(whatsappCatchupTimeout)
                synctest.Wait()
                require.NoError(t, test.whatsapp.inbox.deliver(t.Context(), test.loop, test.whatsapp.link(), false))
                require.Equal(t, 1, test.loop.memory.Len())
                synctest.Wait()
                require.NoError(t, test.whatsapp.inbox.deliver(t.Context(), test.loop, test.whatsapp.link(), false))
                require.Equal(t, 1, test.loop.memory.Len())
index ce3f70b997d41a2e0fd55562a40634f8dfad94c6..d5995df4a0eb0996787c3443f4d2d3414393bcd7 100644 (file)
@@ -16,8 +16,8 @@ import (
 )
 
 const (
 )
 
 const (
-       // whatsappSendTime is the longest time of a send.
-       whatsappSendTime = 30 * time.Second
+       // whatsappSendTimeout is the longest time of a send.
+       whatsappSendTimeout = 30 * time.Second
 
        // whatsappSendBytes is the most bytes of the text of a send.
        whatsappSendBytes = 65536
 
        // whatsappSendBytes is the most bytes of the text of a send.
        whatsappSendBytes = 65536
@@ -77,7 +77,7 @@ func whatsappSend(ctx context.Context, link WhatsAppLink, groups *WhatsAppGroups
                return "", err
        }
 
                return "", err
        }
 
-       sendCtx, cancel := context.WithTimeout(ctx, whatsappSendTime)
+       sendCtx, cancel := context.WithTimeout(ctx, whatsappSendTimeout)
        defer cancel()
 
        response, err := link.client.SendMessage(sendCtx, jid, &waE2E.Message{
        defer cancel()
 
        response, err := link.client.SendMessage(sendCtx, jid, &waE2E.Message{
index 41bd2f0b50b81e7bc90a812fc6d7947f07fb58ae..b1b5935c7536833728bea6a06230998b1ae605af 100644 (file)
@@ -16,12 +16,12 @@ const (
        // the batches that are not in the log yet and the records of the sends.
        whatsappStateFileName = "state.json"
 
        // the batches that are not in the log yet and the records of the sends.
        whatsappStateFileName = "state.json"
 
-       // whatsappBatchQuiet is how long a chat is quiet before its batch
+       // whatsappBatchIdleTimeout is how long a chat is quiet before its batch
        // closes.
        // closes.
-       whatsappBatchQuiet = 20 * time.Second
+       whatsappBatchIdleTimeout = 20 * time.Second
 
 
-       // whatsappBatchWindow is the longest time of a batch.
-       whatsappBatchWindow = 2 * time.Minute
+       // whatsappBatchTimeout is the longest time of a batch.
+       whatsappBatchTimeout = 2 * time.Minute
 
        // whatsappBatchMessages is the most messages of a batch.
        whatsappBatchMessages = 50
 
        // whatsappBatchMessages is the most messages of a batch.
        whatsappBatchMessages = 50
@@ -32,8 +32,9 @@ const (
 )
 
 // openWhatsAppState reads the batches and the send records of the state file at
 )
 
 // openWhatsAppState reads the batches and the send records of the state file at
-// path. A missing file holds none. A batch closes after whatsappBatchQuiet with
-// no message, or after whatsappBatchWindow at the latest.
+// path. A missing file holds none. A batch closes after
+// whatsappBatchIdleTimeout with no message, or after whatsappBatchTimeout at
+// the latest.
 func openWhatsAppState(path string) (*WhatsAppState, error) {
        s := &WhatsAppState{
                path: path,
 func openWhatsAppState(path string) (*WhatsAppState, error) {
        s := &WhatsAppState{
                path: path,
@@ -59,12 +60,13 @@ func openWhatsAppState(path string) (*WhatsAppState, error) {
 // WhatsAppState holds the state file: the send records, and the batches of the
 // WhatsApp messages that are not in the log yet, open and closed, in the order
 // of their first message. The messages of one chat form one batch while the
 // WhatsAppState holds the state file: the send records, and the batches of the
 // WhatsApp messages that are not in the log yet, open and closed, in the order
 // of their first message. The messages of one chat form one batch while the
-// times of the messages are at most whatsappBatchQuiet apart, at most
-// whatsappBatchWindow after the first, and the batch has fewer than
+// times of the messages are at most whatsappBatchIdleTimeout apart, at most
+// whatsappBatchTimeout after the first, and the batch has fewer than
 // whatsappBatchMessages messages. The times are the WhatsApp times, so a
 // catch-up after a stop gives the same batches as live messages. A batch also
 // whatsappBatchMessages messages. The times are the WhatsApp times, so a
 // catch-up after a stop gives the same batches as live messages. A batch also
-// closes when whatsappBatchQuiet passes after the arrival of its last message,
-// or whatsappBatchWindow after the arrival of its first message, in real time.
+// closes when whatsappBatchIdleTimeout passes after the arrival of its last
+// message, or whatsappBatchTimeout after the arrival of its first message, in
+// real time.
 //
 // A send record keeps the result of a send by its ID, so that a repeated call
 // of the send tool does not send again. The state file keeps the last
 //
 // A send record keeps the result of a send by its ID, so that a repeated call
 // of the send tool does not send again. The state file keeps the last
@@ -99,7 +101,7 @@ func (s *WhatsAppState) Add(chat WhatsAppChat, message WhatsAppMessage, arrival
                        return false, nil
                }
 
                        return false, nil
                }
 
-               if message.Time.Sub(batch.Messages[len(batch.Messages)-1].Time) > whatsappBatchQuiet || message.Time.Sub(batch.Messages[0].Time) > whatsappBatchWindow {
+               if message.Time.Sub(batch.Messages[len(batch.Messages)-1].Time) > whatsappBatchIdleTimeout || message.Time.Sub(batch.Messages[0].Time) > whatsappBatchTimeout {
                        batch.Closed = true
                        closed = true
                        index = -1
                        batch.Closed = true
                        closed = true
                        index = -1
@@ -258,8 +260,8 @@ func (s *WhatsAppState) open(chat string) int {
 
 // deadline returns when batch closes in real time.
 func (s *WhatsAppState) deadline(batch WhatsAppBatch) time.Time {
 
 // deadline returns when batch closes in real time.
 func (s *WhatsAppState) deadline(batch WhatsAppBatch) time.Time {
-       quiet := batch.Last.Add(whatsappBatchQuiet)
-       window := batch.First.Add(whatsappBatchWindow)
+       quiet := batch.Last.Add(whatsappBatchIdleTimeout)
+       window := batch.First.Add(whatsappBatchTimeout)
        if window.Before(quiet) {
                return window
        }
        if window.Before(quiet) {
                return window
        }
index f098c908012013298260094afa083c716ea4217b..c1471e98e8f3c3aa2ad97daa69cd13795be3bd59 100644 (file)
@@ -249,12 +249,12 @@ func TestWhatsAppLongFirstConnectionOutageGivesOneNotice(t *testing.T) {
 
                since := time.Now().Format(whatsappTimeLayout)
 
 
                since := time.Now().Format(whatsappTimeLayout)
 
-               time.Sleep(whatsappNoticeDelay)
+               time.Sleep(whatsappOutageNoticeDelay)
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))
                require.Equal(t, "WhatsApp is disconnected since "+since+". OneChat tries again.", test.events.Last("notice"))
 
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))
                require.Equal(t, "WhatsApp is disconnected since "+since+". OneChat tries again.", test.events.Last("notice"))
 
-               time.Sleep(whatsappNoticeDelay)
+               time.Sleep(whatsappOutageNoticeDelay)
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))
                test.fake.mutex.Lock()
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))
                test.fake.mutex.Lock()
@@ -613,18 +613,18 @@ func TestWhatsAppLongDisconnectionGivesOneNotice(t *testing.T) {
                require.True(t, test.fake.Emit(&events.Connected{}))
                require.True(t, test.fake.Emit(&events.Disconnected{}))
                require.True(t, test.fake.Emit(&events.Connected{}))
                require.True(t, test.fake.Emit(&events.Connected{}))
                require.True(t, test.fake.Emit(&events.Disconnected{}))
                require.True(t, test.fake.Emit(&events.Connected{}))
-               time.Sleep(whatsappNoticeDelay + time.Second)
+               time.Sleep(whatsappOutageNoticeDelay + time.Second)
                synctest.Wait()
                require.Zero(t, test.events.Count("notice"))
 
                require.True(t, test.fake.Emit(&events.Disconnected{}))
                require.True(t, test.fake.Emit(&events.Disconnected{}))
                synctest.Wait()
                require.Zero(t, test.events.Count("notice"))
 
                require.True(t, test.fake.Emit(&events.Disconnected{}))
                require.True(t, test.fake.Emit(&events.Disconnected{}))
-               time.Sleep(whatsappNoticeDelay)
+               time.Sleep(whatsappOutageNoticeDelay)
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))
                require.Contains(t, test.events.Last("notice"), "OneChat tries again.")
                require.True(t, test.fake.Emit(&events.Disconnected{}))
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))
                require.Contains(t, test.events.Last("notice"), "OneChat tries again.")
                require.True(t, test.fake.Emit(&events.Disconnected{}))
-               time.Sleep(whatsappNoticeDelay)
+               time.Sleep(whatsappOutageNoticeDelay)
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))
 
                synctest.Wait()
                require.Equal(t, 1, test.events.Count("notice"))