-
Notifications
You must be signed in to change notification settings - Fork 107
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Limited sqs size #3620
base: master
Are you sure you want to change the base?
Limited sqs size #3620
Changes from 10 commits
127e6a6
2f08fac
b5fb5f1
d97fcee
f9a0e2f
5b4c3d2
1b060d1
e390f1b
b7c78a2
3966ac5
7ff89f2
847ec0f
4a3881f
a18310d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/). | |
|
||
### Changed | ||
|
||
- **CUMULUS-3678** | ||
- sqs messages truncated to max sqs length if necessary | ||
- **CUMULUS-3928** | ||
- updated publish scripting to use [email protected] for user email | ||
- updated publish scripting to use esm over common import of latest-version | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ const { | |
sqsQueueExists, | ||
sendSQSMessage, | ||
isSQSRecordLike, | ||
receiveSQSMessages, | ||
} = require('../SQS'); | ||
|
||
const randomString = () => cryptoRandomString({ length: 10 }); | ||
|
@@ -100,3 +101,29 @@ test('isSQSRecordLike filters correctly for sqs record shape', (t) => { | |
body *should* be a string form json object, | ||
but strictly checking is not compatible with the current use-case*/ | ||
}); | ||
|
||
test('sendSQSMessage truncates oversized messages safely', async (t) => { | ||
const queueName = randomString(); | ||
const queueUrl = await createQueue(queueName); | ||
const maxLength = 262144; | ||
const overflowMessage = '0'.repeat(maxLength + 2); | ||
await sendSQSMessage(queueUrl, overflowMessage); | ||
|
||
let recievedMessage = await receiveSQSMessages(queueUrl, {}); | ||
let messageBody = recievedMessage[0].Body; | ||
t.true(messageBody.endsWith('...TruncatedForLength')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you normally add negative test cases? Like if the message is under the max size, then verify the '...TruncatedForLength' message does not appear. In the event it adds it to all the messages regardless of size. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. that's a good point, I'll add it There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh wait, the lower part of this test is doing exactly that. it could be separated though to be clear that that's wha's being tested There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe at the end add: t.false(messageBody.endsWith('...TruncatedForLength')); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, we're checking implicitly just by checking that "it's unchanged", but verbosity==good in testing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you! |
||
t.is(messageBody.length, maxLength); | ||
}); | ||
|
||
test('sendSQSMessage does not alter objects of normal size', async (t) => { | ||
const queueName = randomString(); | ||
const queueUrl = await createQueue(queueName); | ||
const maxLength = 262144; | ||
const underflowMessage = '0'.repeat(maxLength); | ||
await sendSQSMessage(queueUrl, underflowMessage); | ||
recievedMessage = await receiveSQSMessages(queueUrl, {}); | ||
messageBody = recievedMessage[0].Body; | ||
|
||
t.deepEqual(messageBody, underflowMessage); | ||
t.false(messageBody.endsWith('...TruncatedForLength')); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How'd we come to this size?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that is the max size of an sqs message as documented here https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/quotas-messages.html#:~:text=The%20maximum%20is%20262%2C144%20bytes,message%20payload%20in%20Amazon%20S3.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm so that's in bytes
262,144 bytes
. JS'slength
returns UTF-16 "units".Is there a better way to determine the message size? If I'm thinking about this correctly (big if), the
length
JS would return is roughly twice as large as the max size SQS allows:If
length
returns e.g. 262144 units, which are each 16 bits long, and a byte is 8 bits...It seems like 'length' may not be appropriate here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it seems like you're right. I've tested this with 262144 length vs 262144, but I think they're using the standard ascii/unicode split where most characters are 1 byte, but bytes >=128 are interpreted as the first of two in a unicode. I'll do some testing here to be sure and figure out how to correctly measure this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
a fix for this is up now, thanks for that great catch!
there's an additional caveat that if a unicode character gets bifurcated, javascript encoding adds two more padding bytes that need to be dealt with. this latest change accounts for those things and tests them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm is there another way to handle this besides inspecting the character length of the message? It's starting to feel like an anti-pattern if we have to continue to use string.length and accommodate for the difference between units.
I'm also a little concerned about not storing the original, untruncated message anywhere.
We handle similar limitations with messages via the CMA by dumping the full message to S3 and referencing it in the message passed between functions in a step function. Is there something similar we could do here with SQS messages?
How was the issue initially encountered? Did a user report it?