Skip to content

Add missing SQS operations and fix message lifecycle#15

Open
codesoda wants to merge 3 commits intooneslash:mainfrom
TeamCadenceAI:main
Open

Add missing SQS operations and fix message lifecycle#15
codesoda wants to merge 3 commits intooneslash:mainfrom
TeamCadenceAI:main

Conversation

@codesoda
Copy link
Copy Markdown

Summary

  • Add 5 new SQS API operations: DeleteMessage, ChangeMessageVisibility, GetQueueUrl, GetQueueAttributes, SetQueueAttributes
  • Fix message lifecycle: receive_message now properly marks messages with a visibility timeout instead of immediately deleting them, matching real SQS behavior
  • Housekeeping: add .gitignore entries for SQLite DB files, compiled test binaries, and misc artifacts; remove accidentally committed binary/DB files

Details

New Operations

  • DeleteMessage — deletes a message by receipt handle
  • ChangeMessageVisibility — updates the visibility timeout of an in-flight message
  • GetQueueUrl — resolves a queue name to its URL
  • GetQueueAttributes — returns queue attributes (message counts, delays, visibility timeout, timestamps, ARN, etc.)
  • SetQueueAttributes — updates queue attributes (visibility timeout, delay, max message size, retention period)

Message Lifecycle Fix

Previously, ReceiveMessage deleted messages from the database on read. Now messages follow the standard SQS lifecycle:

  1. Message is sent → stored with visible status
  2. Message is received → marked as in_flight with a visibility timeout
  3. Message is deleted → explicitly removed via DeleteMessage
  4. If not deleted before timeout → message becomes visible again

Other Changes

  • Added .gitignore rules for *.db, *.db-shm, *.db-wal, test binaries, and attributes.json
  • Removed accidentally committed database.db*, attributes.json, and test-app/test_kafka_app binary

Test plan

  • Run cargo build to verify compilation
  • Test SendMessageReceiveMessageDeleteMessage lifecycle
  • Test ChangeMessageVisibility extends timeout on in-flight messages
  • Test GetQueueUrl / GetQueueAttributes / SetQueueAttributes
  • Verify messages reappear after visibility timeout expires

Implement DeleteMessage, ChangeMessageVisibility, GetQueueUrl,
GetQueueAttributes, and SetQueueAttributes endpoints. Replace
destructive pop with visibility-timeout-based receive semantics.
Route SendMessage/ReceiveMessage dynamically via QueueUrl instead
of hardcoded "myqueue". Add long polling support to ReceiveMessage.

Remove tracked binaries and database files from repo, update .gitignore.
@oneslash
Copy link
Copy Markdown
Owner

Hi @codesoda, wow thank you :) It was my small Rust learning project, I will merge after the codex review

@oneslash
Copy link
Copy Markdown
Owner

@codex review

@oneslash oneslash self-requested a review February 24, 2026 07:46
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ece834c2b0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

README.md Outdated

```bash
$ git clone git@github.com:oneslash/sqs-navbat.git
$ git clone git@github.com:TeamCadenceAI/sqs-navbat.git
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Repository has been changed, could you revert it please?

Review fixes (from oneslash and Codex review):
- Revert README git clone URL back to oneslash/sqs-navbat
- GetQueueUrl: resolve queue existence from DB instead of in-memory map
  so queues are discoverable after process restarts (P1)
- ReceiveMessage: use stored first_received_at timestamp for
  ApproximateFirstReceiveTimestamp instead of current time (P2)
- GetQueueAttributes: surface DB errors as 500 responses instead of
  silently returning empty attributes via unwrap_or_default() (P2)

Also fix clippy warnings across modified files (needless returns,
dead_code annotations, manual clamp, empty string comparison).
@codesoda
Copy link
Copy Markdown
Author

@oneslash I addressed your feedback and updated the PR.

Btw, you should consider using my x-agent skills for running cargo toolchains, uses less tokens and helps make sure clippy warnings and test errors are handled which a coding agent is doing it's thing.

https://github.com/codesoda/x-agent

@oneslash
Copy link
Copy Markdown
Owner

@codex review

@oneslash
Copy link
Copy Markdown
Owner

thank you @codesoda!

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e312473c98

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +63 to +64
let reader = app_state.queues.lock().await;
if !reader.contains_key(&queue_name) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Check queue existence in DB before rejecting attributes update

This endpoint treats a queue as non-existent if it is missing from app_state.queues, but queue metadata is persisted in SQLite while the in-memory map starts empty on process boot. That means after a restart, persisted queues can still exist in the DB yet SetQueueAttributes will always return AWS.SimpleQueueService.NonExistentQueue for them, blocking attribute updates for valid queues. The existence check should come from persistent storage (or the map should be hydrated at startup) instead of only contains_key.

Useful? React with 👍 / 👎.

Comment on lines +73 to +77
if let Some(vt) = attrs.get("VisibilityTimeout") {
if let Ok(timeout) = vt.parse::<u32>() {
let mut writer = app_state.queues.lock().await;
if let Some(queue) = writer.get_mut(&queue_name) {
queue.default_visibility_timeout = timeout;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Persist queue attributes before mutating runtime visibility

The handler updates queue.default_visibility_timeout in memory before attempting service.set_queue_attributes(...). If the DB upsert fails, the API returns 500 but the runtime queue has already changed, so subsequent receives use a timeout that was never durably stored. This creates inconsistent state after a failed request; defer the in-memory mutation until after persistence succeeds (or roll it back on error).

Useful? React with 👍 / 👎.

if let Some(pos) = self
.messages
.iter()
.position(|m| m.receipt_handle.as_deref() == Some(handle))
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Invalidate stale receipt handles after visibility timeout

Message deletion accepts any matching receipt_handle without checking whether the message is still in-flight. When visibility expires, the old handle remains attached to the now-visible message, so a stale consumer can still delete it later and lose work that should have been eligible for redelivery. Handle matching should require visible_at > now (and similarly for visibility changes), or handles should be cleared when messages become visible again.

Useful? React with 👍 / 👎.

@oneslash
Copy link
Copy Markdown
Owner

I will fix later :)

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