Skip to content

feat: Add push provider throttle and push priority processing #420

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

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

mtrezza
Copy link
Member

@mtrezza mtrezza commented Jul 2, 2025

New Pull Request Checklist

Issue Description

Pushes are sent out as fast as possible when calling Parse.Push.send() in Parse Server Cloud Code. A push provider may have API request limits that when exceeded cause requests being rejected.

Approach

Pushes can now be throttled per provider using a queue configuration to prevent exceeding rate limits imposed by services like APNS and FCM.

Example for parallel sending 5 pushes every 500ms, effectively allowing up to 10 pushes per second in 2 controlled bursts:

const parseServerOptions = {
  push: {
    adapter: new ParsePushAdapter({
      ios: {
        // ...
        queue: {
          concurrency: 5,
          intervalCapacity: 5,
          interval: 500,
        },
      }
    })
  }
};

Note

This feature has been implemented specifically in the push adapter, not in Parse Server where there is also a PushQueue. The push queue in Parse Server is responsible for gathering the push recipients' device tokens from the database in controlled batches, and then sending them off to the push adapter and tracking the push status. Since throttling is a push provider API topic, the feature of throttling is implemented as closely as possible to the push provider API, which is the push adapter.

TODOs before merging

  • Add tests
  • Add changes to documentation (guides, repository pages, in-code descriptions)

Summary by CodeRabbit

  • New Features
    • Added throttling and prioritization for push notifications, allowing control over sending rates and queue order per push type.
    • Introduced support for per-push time-to-live (TTL) and priority options.
  • Documentation
    • Extended README with detailed instructions and examples for configuring push queue throttling and options.
  • Tests
    • Added comprehensive tests for push queue throttling, TTL expiry, and priority handling.
    • Introduced a new test suite for the throttling queue.
  • Chores
    • Updated dependencies to include the p-queue package.

Copy link

parse-github-assistant bot commented Jul 2, 2025

🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review.

Copy link

coderabbitai bot commented Jul 2, 2025

📝 Walkthrough

Walkthrough

A throttling and prioritization mechanism for push notifications was introduced using a new ThrottleQueue class, integrated into the ParsePushAdapter. The system allows per-provider configuration of push sending rates, concurrency, task TTL, and priority. Documentation, tests, and supporting utilities were added or updated to reflect and verify these features.

Changes

File(s) Change Summary
README.md Added documentation for queue-based throttling and push options for the push adapter.
package.json Added p-queue@8.1.0 as a dependency.
spec/.eslintrc.json Adjusted indentation for the "jasmine" environment setting.
spec/helper.js Added and exported wait(ms) utility function; reordered import statements; increased Jasmine timeout.
src/ThrottleQueue.js Introduced new ThrottleQueue class for throttled, prioritized, and expiring task queuing.
src/ParsePushAdapter.js Integrated ThrottleQueue per push type; modified send logic to use queues with concurrency, rate limit, TTL, and priority.
spec/ParsePushAdapter.spec.js Added tests for throttling, TTL expiration, and priority ordering in push sending; reordered and added imports.
spec/ThrottleQueue.spec.js Added new test suite for ThrottleQueue, covering rate limit, TTL expiration, and priority.

Sequence Diagram(s)

Throttled and Prioritized Push Sending

sequenceDiagram
    participant Client
    participant ParsePushAdapter
    participant ThrottleQueue
    participant PushSender

    Client->>ParsePushAdapter: send(data, installations)
    alt Queue configured for push type
        ParsePushAdapter->>ThrottleQueue: enqueue({task, ttl, priority})
        ThrottleQueue-->>ParsePushAdapter: (waits for slot, respects TTL/priority)
        ThrottleQueue->>PushSender: send(data, installations)
        PushSender-->>ThrottleQueue: result
        ThrottleQueue-->>ParsePushAdapter: result
    else No queue configured
        ParsePushAdapter->>PushSender: send(data, installations)
        PushSender-->>ParsePushAdapter: result
    end
    ParsePushAdapter-->>Client: result
Loading

Task Dropped Due to TTL Expiry

sequenceDiagram
    participant ParsePushAdapter
    participant ThrottleQueue

    ParsePushAdapter->>ThrottleQueue: enqueue({task, ttl=short})
    ThrottleQueue-->>ParsePushAdapter: (waits in queue)
    alt TTL expired before execution
        ThrottleQueue-->>ParsePushAdapter: null (task skipped)
    else TTL valid
        ThrottleQueue->>PushSender: send()
        PushSender-->>ThrottleQueue: result
        ThrottleQueue-->>ParsePushAdapter: result
    end
Loading

Priority-based Task Execution

sequenceDiagram
    participant ParsePushAdapter
    participant ThrottleQueue

    ParsePushAdapter->>ThrottleQueue: enqueue({task1, priority=1})
    ParsePushAdapter->>ThrottleQueue: enqueue({task2, priority=10})
    ParsePushAdapter->>ThrottleQueue: enqueue({task3, priority=5})
    Note right of ThrottleQueue: Tasks are sorted by priority
    ThrottleQueue->>PushSender: send(task2)
    ThrottleQueue->>PushSender: send(task3)
    ThrottleQueue->>PushSender: send(task1)
Loading

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0bb3ec and c919e8d.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (1)
  • package.json (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • package.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Node.js 20
  • GitHub Check: Node.js 22
  • GitHub Check: Node.js 18

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@mtrezza mtrezza changed the title feat: Add push provider throttle and priority processing feat: Add push provider throttle and push priority processing Jul 2, 2025
@parseplatformorg
Copy link
Contributor

parseplatformorg commented Jul 2, 2025

🎉 Snyk checks have passed. No issues have been found so far.

security/snyk check is complete. No issues have been found. (View Details)

Copy link

codecov bot commented Jul 2, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (e608507) to head (c919e8d).

Additional details and impacted files
@@            Coverage Diff            @@
##            master      #420   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            9        10    +1     
  Lines         1351      1404   +53     
=========================================
+ Hits          1351      1404   +53     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
README.md (2)

239-239: Fix grammatical error in documentation

The sentence has a subject-verb agreement issue.

-In the example above, pushes will be sent in bursts of 5 at once, with max. 10 pushes within 1s. On a timeline that means at `t=0ms`, 5 pushes will be sent in parallel. If sending the pushes take less than 500ms, then `intervalCapacity` will still limit to 5 pushes within the first 500ms.
+In the example above, pushes will be sent in bursts of 5 at once, with max. 10 pushes within 1s. On a timeline that means at `t=0ms`, 5 pushes will be sent in parallel. If sending the pushes takes less than 500ms, then `intervalCapacity` will still limit to 5 pushes within the first 500ms.

247-247: Add missing article in documentation

Missing determiner before "Default".

-| `queue.ttl`      | `Infinity` | Yes      | The time-to-live of the push in the queue in seconds. If a queued push expires before it is sent to the push provider, it is discarded. Default is `Infinity`, meaning pushes never expire.  |
+| `queue.ttl`      | `Infinity` | Yes      | The time-to-live of the push in the queue in seconds. If a queued push expires before it is sent to the push provider, it is discarded. The default is `Infinity`, meaning pushes never expire.  |
src/ParsePushAdapter.js (1)

94-98: Consider alternatives to the delete operator for better performance.

The static analysis tool flags the delete operation as potentially performance-impacting. Consider using object destructuring to avoid mutation:

-        } else if (this.queues[pushType]) {
-          const { ttl, priority } = data?.queue || {};
-          delete data?.queue;
-          sendPromises.push(this.queues[pushType].enqueue({ task: () => sender.send(data, devices), ttl, priority }));
+        } else if (this.queues[pushType]) {
+          const { queue, ...dataWithoutQueue } = data || {};
+          const { ttl, priority } = queue || {};
+          sendPromises.push(this.queues[pushType].enqueue({ task: () => sender.send(dataWithoutQueue, devices), ttl, priority }));

This approach creates a new object without the queue property instead of mutating the original object.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bd219aa and 1712ccd.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (8)
  • README.md (2 hunks)
  • package.json (1 hunks)
  • spec/.eslintrc.json (1 hunks)
  • spec/ParsePushAdapter.spec.js (2 hunks)
  • spec/ThrottleQueue.spec.js (1 hunks)
  • spec/helper.js (1 hunks)
  • src/ParsePushAdapter.js (4 hunks)
  • src/ThrottleQueue.js (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
spec/ThrottleQueue.spec.js (2)
src/ThrottleQueue.js (1)
  • ThrottleQueue (3-42)
spec/helper.js (1)
  • wait (14-14)
spec/ParsePushAdapter.spec.js (2)
src/ParsePushAdapter.js (1)
  • ParsePushAdapter (14-108)
spec/helper.js (1)
  • wait (14-14)
🪛 GitHub Check: Lint
spec/helper.js

[warning] 14-14:
'setTimeout' is not defined

🪛 LanguageTool
README.md

[uncategorized] ~239-~239: This verb does not appear to agree with the subject. Consider using a different form.
Context: ...sent in parallel. If sending the pushes take less than 500ms, then `intervalCapacity...

(AI_EN_LECTOR_REPLACEMENT_VERB_AGREEMENT)


[uncategorized] ~247-~247: A determiner appears to be missing. Consider inserting it.
Context: ... to the push provider, it is discarded. Default is Infinity, meaning pushes never exp...

(AI_EN_LECTOR_MISSING_DETERMINER)

🪛 Biome (1.9.4)
src/ParsePushAdapter.js

[error] 96-96: Avoid the delete operator which can impact performance.

(lint/performance/noDelete)

🔇 Additional comments (10)
spec/helper.js (2)

9-9: LGTM: Increased timeout for throttling tests

The timeout increase to 50 seconds is appropriate for tests that verify throttling behavior and timing constraints.


14-18: LGTM: Clean utility function implementation

The wait function is a simple and effective utility for introducing delays in asynchronous tests. The static analysis warning about setTimeout being undefined is a false positive - setTimeout is a global function in Node.js environments.

package.json (1)

32-32: LGTM: Adding p-queue dependency

The p-queue@8.1.0 dependency is appropriately added to support the new ThrottleQueue functionality. This is a well-maintained library that provides the concurrency and priority queue capabilities needed for the throttling mechanism.

spec/.eslintrc.json (1)

3-3: LGTM: Consistent indentation

Minor formatting improvement that maintains consistent indentation throughout the ESLint configuration.

README.md (1)

187-262: Excellent documentation for the new push queue feature

The documentation comprehensively covers the new throttling and priority functionality with clear examples and parameter descriptions. The practical examples showing serial vs parallel configurations are particularly helpful.

spec/ThrottleQueue.spec.js (1)

1-67: Excellent comprehensive test suite for ThrottleQueue

The test suite thoroughly validates the core functionality of the ThrottleQueue class:

  1. Rate limiting test: Properly verifies that tasks respect the configured interval capacity by measuring execution timing with appropriate tolerance.

  2. TTL expiration test: Cleverly tests that expired tasks are dropped by using a blocking task and verifying the expired task doesn't execute.

  3. Priority ordering test: Well-designed test that blocks the queue to build up tasks, then verifies they execute in correct priority order.

The tests use appropriate async patterns, timing controls, and assertions. The use of the wait helper function from spec/helper.js is clean and effective.

src/ThrottleQueue.js (1)

1-42: LGTM! Clean implementation of throttling queue wrapper.

The ThrottleQueue class provides a well-designed wrapper around p-queue with additional TTL functionality. The implementation correctly:

  • Uses sensible defaults for throttling parameters
  • Converts TTL from seconds to milliseconds
  • Handles task expiration by returning null for expired tasks
  • Passes priority through to the underlying queue

The code is readable and follows good practices.

spec/ParsePushAdapter.spec.js (3)

647-673: Excellent test coverage for throttling functionality.

This test properly validates the throttling behavior by:

  • Configuring a queue with 1 task per second limit
  • Measuring timestamps of actual send calls
  • Asserting that the time difference is approximately 1 second

The timing assertions with tolerance (900-1100ms) account for potential execution delays, making the test robust.


675-698: Well-designed TTL expiration test.

This test effectively validates TTL functionality by:

  • Using a send method that takes longer than the TTL
  • Sending two pushes concurrently, one with a very short TTL
  • Asserting that only one send call actually occurs

The test correctly demonstrates that expired tasks are skipped.


700-736: Comprehensive priority ordering test.

This test excellently validates priority handling by:

  • Using a blocking task to control queue execution timing
  • Sending multiple pushes with different priorities
  • Asserting that execution order matches priority order (highest first)

The test design with the blocking task ensures that all priority tasks are enqueued before any are processed, making the priority comparison valid.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jul 2, 2025
@mtrezza mtrezza requested a review from dplewis July 2, 2025 21:55
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
spec/helper.js (1)

14-18: Address the setTimeout linting warning.

The wait function implementation is correct and serves a legitimate testing purpose for timing-dependent behaviors. However, the static analysis warning about 'setTimeout' not being defined should be addressed for better compatibility.

Consider importing setTimeout from the 'timers' module to resolve the linting warning:

+import { setTimeout } from 'timers';

Or if you prefer to keep it as a global, you can add a comment to disable the linting warning:

-const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms));
+const wait = (ms) => new Promise(resolve => setTimeout(resolve, ms)); // eslint-disable-line no-undef
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1712ccd and 1e45202.

📒 Files selected for processing (1)
  • spec/helper.js (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: mtrezza
PR: parse-community/parse-server-push-adapter#420
File: src/ParsePushAdapter.js:60-65
Timestamp: 2025-07-02T21:55:05.380Z
Learning: In ParsePushAdapter.js, the queue configuration intentionally uses `intervalCapacity` as the config parameter name, which is then mapped to `intervalCap` when passed to the ThrottleQueue constructor. This mapping is by design and should not be "fixed" to match parameter names.
🪛 GitHub Check: Lint
spec/helper.js

[warning] 14-14:
'setTimeout' is not defined

🔇 Additional comments (1)
spec/helper.js (1)

3-3: LGTM: Import reordering.

The import reordering is a minor code organization improvement with no functional impact.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/ParsePushAdapter.js (2)

61-61: Simplify the optional chain expression.

The current expression can be simplified using optional chaining for better readability.

-      const queue = Array.isArray(config) ? config.find(c => c && c.queue)?.queue : config.queue;
+      const queue = Array.isArray(config) ? config.find(c => c?.queue)?.queue : config?.queue;

97-97: Consider avoiding the delete operator for better performance.

The delete operator can impact performance. Consider using object destructuring or creating a new object without the queue property.

-          const { ttl, priority } = data?.queue || {};
-          delete data?.queue;
-          sendPromises.push(this.queues[pushType].enqueue({ task: () => sender.send(data, devices), ttl, priority }));
+          const { ttl, priority } = data?.queue || {};
+          const { queue, ...dataWithoutQueue } = data;
+          sendPromises.push(this.queues[pushType].enqueue({ task: () => sender.send(dataWithoutQueue, devices), ttl, priority }));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e45202 and 849e014.

📒 Files selected for processing (2)
  • spec/helper.js (1 hunks)
  • src/ParsePushAdapter.js (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • spec/helper.js
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: mtrezza
PR: parse-community/parse-server-push-adapter#420
File: src/ParsePushAdapter.js:60-65
Timestamp: 2025-07-02T21:55:05.380Z
Learning: In ParsePushAdapter.js, the queue configuration intentionally uses `intervalCapacity` as the config parameter name, which is then mapped to `intervalCap` when passed to the ThrottleQueue constructor. This mapping is by design and should not be "fixed" to match parameter names.
src/ParsePushAdapter.js (1)
Learnt from: mtrezza
PR: parse-community/parse-server-push-adapter#420
File: src/ParsePushAdapter.js:60-65
Timestamp: 2025-07-02T21:55:05.380Z
Learning: In ParsePushAdapter.js, the queue configuration intentionally uses `intervalCapacity` as the config parameter name, which is then mapped to `intervalCap` when passed to the ThrottleQueue constructor. This mapping is by design and should not be "fixed" to match parameter names.
🪛 Biome (1.9.4)
src/ParsePushAdapter.js

[error] 61-61: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 97-97: Avoid the delete operator which can impact performance.

(lint/performance/noDelete)

🔇 Additional comments (4)
src/ParsePushAdapter.js (4)

10-10: LGTM! Clean import addition.

The import statement is correctly added to support the new throttling functionality.


21-21: LGTM! Proper property initialization.

The queues property is correctly initialized to store ThrottleQueue instances per push type.


60-65: LGTM! Queue configuration parsing is well-implemented.

The queue configuration parsing correctly handles both array and object configurations, and the parameter name mapping from intervalCapacity to intervalCap is intentional as per the design.


95-98: LGTM! Queue integration is well-implemented.

The conditional logic correctly integrates the throttling queue when available, properly extracts TTL and priority parameters, and maintains backward compatibility when no queue is configured.

coderabbitai[bot]
coderabbitai bot previously approved these changes Jul 3, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/ParsePushAdapter.js (2)

60-66: Simplify the optional chaining and consider error handling.

The queue configuration logic is correct, but there are two potential improvements:

  1. The optional chaining can be simplified as suggested by static analysis
  2. Consider adding error handling for ThrottleQueue construction

Apply this diff to simplify the optional chaining:

-      const queue = Array.isArray(config) ? config.find(c => c && c.queue)?.queue : config.queue;
+      const queue = Array.isArray(config) ? config.find(c => c?.queue)?.queue : config.queue;

Consider adding error handling for ThrottleQueue construction:

       if (queue) {
         const { concurrency, intervalCapacity, interval } = queue || {};
-        this.queues[pushType] = new ThrottleQueue({ concurrency, intervalCap: intervalCapacity, interval });
+        try {
+          this.queues[pushType] = new ThrottleQueue({ concurrency, intervalCap: intervalCapacity, interval });
+        } catch (error) {
+          log.error(LOG_PREFIX, `Failed to create throttle queue for ${pushType}:`, error);
+        }
       }

95-98: Consider cleaning up queue metadata from data object.

The queue logic correctly handles conditional enqueueing, but the data.queue metadata is passed through to the sender. Consider whether this metadata should be removed before sending.

If the queue metadata should not be passed to the sender, apply this diff:

         } else if (this.queues[pushType]) {
           const { ttl, priority } = data?.queue || {};
+          const { queue, ...cleanData } = data || {};
-          sendPromises.push(this.queues[pushType].enqueue({ task: () => sender.send(data, devices), ttl, priority }));
+          sendPromises.push(this.queues[pushType].enqueue({ task: () => sender.send(cleanData, devices), ttl, priority }));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 849e014 and b0bb3ec.

📒 Files selected for processing (1)
  • src/ParsePushAdapter.js (4 hunks)
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: mtrezza
PR: parse-community/parse-server-push-adapter#420
File: src/ParsePushAdapter.js:60-65
Timestamp: 2025-07-02T21:55:05.380Z
Learning: In ParsePushAdapter.js, the queue configuration intentionally uses `intervalCapacity` as the config parameter name, which is then mapped to `intervalCap` when passed to the ThrottleQueue constructor. This mapping is by design and should not be "fixed" to match parameter names.
src/ParsePushAdapter.js (1)
Learnt from: mtrezza
PR: parse-community/parse-server-push-adapter#420
File: src/ParsePushAdapter.js:60-65
Timestamp: 2025-07-02T21:55:05.380Z
Learning: In ParsePushAdapter.js, the queue configuration intentionally uses `intervalCapacity` as the config parameter name, which is then mapped to `intervalCap` when passed to the ThrottleQueue constructor. This mapping is by design and should not be "fixed" to match parameter names.
🪛 Biome (1.9.4)
src/ParsePushAdapter.js

[error] 61-61: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (2)
src/ParsePushAdapter.js (2)

10-10: LGTM!

The ThrottleQueue import follows the existing import pattern and is correctly placed.


21-21: LGTM!

The queues property initialization is appropriate for storing ThrottleQueue instances per push type.

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