Repository navigation
perf(courier): read and write attachments with the store free - #82
Merged
Merged
Conversation
The courier held the store for its whole cycle, including reading each inline image (up to 5 MB) and base64-encoding it, and messages.send decoded and wrote the owner's files (up to the attachment limit) under the store lock. Every chat item, tool call and request waited. The courier now locks per step and renders a delivery between them; claiming still checks the delivery is waiting. messages.send saves the files first and checks the bot again before storing the message.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second performance round, slice 3.
What
Two places held the single store mutex while doing file I/O:
render, which reads each image the message inlines (up to 5 MB), base64-encodes it, and builds the stream-json line.messages.send. It decoded the owner's base64 uploads and wrote them to the bot'sattachments\folder while holding the store.Meanwhile every chat item from a working bot, every MCP tool call and every app request waited for the lock. As #81 showed, a tokio worker blocked on that mutex also stalls the runtime's timers.
Now:
preparenow returns aDraftwith the data it read, instead of the rendered line.claim_deliverystill refuses a delivery that something else changed meanwhile.messages.sendchecks the bot, saves the files with the store free, then checks the bot again before storing the message. A bot archived or deleted in that gap gives the same error as before; the saved files stay in its folder.No behavior changes, and the spec stays true. The full suite, clippy and fmt pass; the existing courier, attachment and inline-image tests cover these paths.
Manual check (real Claude)
Send a bot a message with two large photos (3–5 MB each) while another bot in the crew is streaming a long answer. The answer keeps streaming, and the photo reaches the bot as before (it describes the image).