Skip to content

feat: add getMaxMessageId() and getAllMessageIdsWithSizes() to spoole… - #45

Draft
saranyailla wants to merge 2 commits into
mainfrom
feat-queries
Draft

feat: add getMaxMessageId() and getAllMessageIdsWithSizes() to spoole…#45
saranyailla wants to merge 2 commits into
mainfrom
feat-queries

Conversation

@saranyailla

Copy link
Copy Markdown
Member

…r startup optimization

Implements getMaxMessageId() and getAllMessageIdsWithSizes() — default methods added to the CloudMessageSpool interface in Nucleus 2.18.3+ (aws-greengrass-nucleus#1834).

Context

At boot, the Nucleus reloads persisted message IDs into its in-memory dispatch queue. Today this calls getMessageById() per message — reading the full payload from SQLite — only to get payload.length for capacity tracking. On constrained hardware with ~26,500 queued messages, this blocks all component startup for ~5 minutes (nucleus #1832).

These two queries eliminate the per-message payload reads entirely.

Queries

getMaxMessageId()

SELECT MAX(message_id) AS max_id FROM spooler;

O(1) — message_id is INTEGER PRIMARY KEY, so SQLite resolves MAX() directly from the B-tree index. Returns -1 when the table is empty. Lets the Nucleus set its next-ID counter instantly without iterating all rows.

getAllMessageIdsWithPayloadSize()

SELECT message_id, LENGTH(payload) AS payload_size FROM spooler ORDER BY message_id ASC;

Single table scan. LENGTH() on a BLOB reads the size from the SQLite row header — no payload bytes are loaded into memory. ORDER BY message_id ASC is free since the primary key is already ordered in the B-tree. Lets the Nucleus populate its dispatch queue and enforce capacity in milliseconds regardless of queue depth.

Testing

Added 7 unit tests covering:

  • Empty table behavior for both methods
  • Non-sequential ID insertion with correct ordering and sizes
  • NULL payload returns size 0
  • State correctness after message removal

Compatibility

These methods are additive. On Nucleus versions older than 2.18.3 that don't call them, they exist on the class but are never invoked — no minimum Nucleus version required.

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.


@Override
protected PreparedStatement createStatement(Connection connection) throws SQLException {
return connection.prepareStatement(QUERY);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommendation generated by Amazon CodeGuru Reviewer. Leave feedback on this recommendation by replying to the comment or by reacting to the comment using emoji.

The code is not properly closing resources, which can lead to resource leaks. Unclosed resources may cause memory leaks or other system resource issues, potentially degrading application performance over time. If an exception occurs before the explicit close() call, the resource will not be closed, increasing the risk of leaks. To remediate this, use the try-with-resources statement to automatically close AutoCloseable resources.Alternatively, if try-with-resources cannot be used, ensure that close() is called in a finally block to guarantee proper resource cleanup even when exceptions occur.

Learn more


@Override
protected ResultSet doExecute(PreparedStatement statement) throws SQLException {
return statement.executeQuery();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommendation generated by Amazon CodeGuru Reviewer. Leave feedback on this recommendation by replying to the comment or by reacting to the comment using emoji.

The code is not properly closing resources, which can lead to resource leaks. Unclosed resources may cause memory leaks or other system resource issues, potentially degrading application performance over time. If an exception occurs before the explicit close() call, the resource will not be closed, increasing the risk of leaks. To remediate this, use the try-with-resources statement to automatically close AutoCloseable resources.Alternatively, if try-with-resources cannot be used, ensure that close() is called in a finally block to guarantee proper resource cleanup even when exceptions occur.

Learn more


@Override
protected ResultSet doExecute(PreparedStatement statement) throws SQLException {
return statement.executeQuery();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommendation generated by Amazon CodeGuru Reviewer. Leave feedback on this recommendation by replying to the comment or by reacting to the comment using emoji.

The code is not properly closing resources, which can lead to resource leaks. Unclosed resources may cause memory leaks or other system resource issues, potentially degrading application performance over time. If an exception occurs before the explicit close() call, the resource will not be closed, increasing the risk of leaks. To remediate this, use the try-with-resources statement to automatically close AutoCloseable resources.Alternatively, if try-with-resources cannot be used, ensure that close() is called in a finally block to guarantee proper resource cleanup even when exceptions occur.

Learn more


@Override
protected PreparedStatement createStatement(Connection connection) throws SQLException {
return connection.prepareStatement(QUERY);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Recommendation generated by Amazon CodeGuru Reviewer. Leave feedback on this recommendation by replying to the comment or by reacting to the comment using emoji.

The code is not properly closing resources, which can lead to resource leaks. Unclosed resources may cause memory leaks or other system resource issues, potentially degrading application performance over time. If an exception occurs before the explicit close() call, the resource will not be closed, increasing the risk of leaks. To remediate this, use the try-with-resources statement to automatically close AutoCloseable resources.Alternatively, if try-with-resources cannot be used, ensure that close() is called in a finally block to guarantee proper resource cleanup even when exceptions occur.

Learn more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants