Skip to content

Fix delivery behavior issues from code review - #580

Merged
excid3 merged 2 commits into
mainfrom
review-followups
Sep 30, 2026
Merged

excid3 merged 2 commits into
mainfrom
review-followups

Conversation

@excid3

@excid3 excid3 commented Sep 30, 2026

Copy link
Copy Markdown
Owner

Summary

Follow-up to #579 covering the review items that change delivery behavior.

  • EventJob loads notifications with find_in_batches and enqueues delivery jobs in bulk with ActiveJob.perform_all_later (falls back to per-job enqueue on Rails 7.0). Adds DeliverBy#job as the primitive; perform_later is now job(...).enqueue. Note: perform_all_later skips ActiveJob enqueue callbacks (documented Rails behavior); noted in the CHANGELOG.
  • iOS: one Apnotic::Connection per delivery, closed in ensure. The class-level pool's on(:error) closure captured the first job instance, so later notifications' error_handler ran against the wrong notification, and every notifier shared the first one's credentials. Since IOS Delivery Method error handling #503 already closed the connection after every push, the pool wasn't pooling anything. Removes pool_size.
  • FCM: a 400 only counts as an invalid token when the error body names message.token or mentions the registration token. Previously any 400 (e.g. a malformed payload) invoked invalid_token and could delete valid tokens. Access token fetched once per delivery rather than once per device token.
  • Logging: post_request no longer logs request/response bodies — Bluesky's createSession request contains the password and the response contains access/refresh JWTs.

Test plan

  • standardrb clean
  • rails test on main Gemfile, Rails main, 7.1, 8.1 — 147 runs, 0 failures
  • CI on Rails 7.0 exercises the jobs.each(&:enqueue) fallback

* EventJob loads notifications with find_in_batches and enqueues delivery
  jobs with ActiveJob.perform_all_later (per-job enqueue on Rails 7.0)
  via a new DeliverBy#job primitive
* iOS opens one Apnotic connection per delivery and closes it afterwards
  instead of a class-level pool whose on(:error) handler was bound to the
  first job instance and whose credentials were shared across notifiers.
  PR #503 already closed the connection after every push, so the pool
  was not pooling anything. Removes the pool_size option.
* FCM only treats a 400 as an invalid token when the error names
  message.token or mentions the registration token, so malformed payloads
  no longer trigger invalid_token cleanup. Access token fetched once per
  delivery instead of once per device token.
* post_request no longer logs request/response bodies (Bluesky's session
  request carries the password and its response carries JWTs)
* FCM bad_token? uses a single detection strategy (error message) with
  a token_error? explaining method, same shape as the iOS check
* EventJob pulls the per-notification job building into
  delivery_jobs_for so perform reads top to bottom
* iOS error_handler uses truthiness like invalid_token
* iOS test fakes Apnotic::Connection instead of reaching into @client
@excid3
excid3 merged commit b323c98 into main Sep 30, 2026
36 checks passed
@excid3
excid3 deleted the review-followups branch September 30, 2026 21:13
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.

1 participant