Skip to content

fix: Dispatch save success callbacks on callbackQueue#473

Open
Mieruko wants to merge 1 commit into
parse-community:mainfrom
Mieruko:bounty-callback-queue-save
Open

fix: Dispatch save success callbacks on callbackQueue#473
Mieruko wants to merge 1 commit into
parse-community:mainfrom
Mieruko:bounty-callback-queue-save

Conversation

@Mieruko

@Mieruko Mieruko commented May 13, 2026

Copy link
Copy Markdown

Fixes #431

Summary:

  • Dispatch callback-style save/create/replace/update success completions on the provided callbackQueue.
  • Applies the fix to ParseObject, ParseUser, and ParseInstallation paths.
  • Adds regression tests for ParseObject.save and ParseUser.save success callbacks.

Validation:

  • git diff --check
  • Swift tests not run locally: Swift toolchain is not installed on this Windows machine.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed completion handler dispatch behavior in async save, create, replace, and update operations. Success callbacks now properly execute on the specified callback queue, ensuring consistent thread behavior across all operations.
  • Tests

    • Added comprehensive test coverage validating proper callback queue execution in async operations.

Review Change Stack

@parse-github-assistant

parse-github-assistant Bot commented May 13, 2026

Copy link
Copy Markdown

🚀 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.

Tip

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

Note

Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect.

Caution

Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code.

@coderabbitai

coderabbitai Bot commented May 13, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Three core Parse model classes now consistently dispatch async CRUD operation success completions to the provided callbackQueue. Previously, success paths invoked completion handlers directly while error paths were dispatched to the queue. Updates apply to single-object methods (save, create, replace, update) and batch methods across ParseObject, ParseInstallation, and ParseUser. New tests validate the queue dispatch behavior.

Changes

Async CRUD Callback Queue Dispatch Fix

Layer / File(s) Summary
ParseObject async CRUD queue dispatch
Sources/ParseSwift/Objects/ParseObject.swift
save, create, replace, update and batch saveAll, createAll, replaceAll, updateAll methods now wrap success completion calls with callbackQueue.async in the _Concurrency code path, ensuring consistent queue dispatch for all outcomes.
ParseInstallation async CRUD queue dispatch
Sources/ParseSwift/Objects/ParseInstallation.swift
save, create, replace, update and batch saveAll, createAll, replaceAll, updateAll methods apply the same queue dispatch pattern to their async implementations.
ParseUser async CRUD queue dispatch
Sources/ParseSwift/Objects/ParseUser.swift
save, create, replace, update and batch saveAll, createAll, replaceAll, updateAll methods apply the same queue dispatch pattern to their async implementations.
Queue dispatch validation tests
Tests/ParseSwiftTests/ParseObjectTests.swift, Tests/ParseSwiftTests/ParseUserTests.swift
New tests verify completion handlers execute on the provided callbackQueue for successful async operations using DispatchQueue.getSpecific to validate queue context.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Engage In Review Feedback ❓ Inconclusive PR was just created (2026-05-13) with no review comments yet. Cannot assess engagement with review feedback when no feedback exists. This check requires review feedback to exist. Monitor for review comments and re-evaluate once reviewers engage with the PR.
✅ Passed checks (6 passed)
Check name Status Explanation
Description check ✅ Passed PR description covers main aspects but is incomplete; checklist items are not checked off and changelog/documentation TODOs are not addressed.
Linked Issues check ✅ Passed Changes correctly address issue #431: all callback-style save/create/replace/update success completions are dispatched on callbackQueue across ParseObject, ParseUser, and ParseInstallation, with regression tests added.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the callback queue dispatching issue; no unrelated modifications detected in the altered files.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Security Check ✅ Passed No security vulnerabilities detected. The PR wraps success callbacks in callbackQueue.async for threading consistency. No self-references, deadlock risks, race conditions, or data exposure issues.
Title check ✅ Passed The pull request title 'fix: Dispatch save success callbacks on callbackQueue' follows the required prefix 'fix:' and clearly describes the main change: ensuring success callbacks are dispatched on the provided callbackQueue for save operations.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
Tests/ParseSwiftTests/ParseUserTests.swift (1)

1010-1054: ⚡ Quick win

Optional: Consider adding error path test for completeness.

The test validates that success callbacks execute on the provided callbackQueue. While issue #431 reported that error callbacks were already correctly dispatched, adding a test for the error path would prevent future regressions and provide complete coverage of queue dispatch behavior.

Example pattern:

// Mock an error response and verify error callback runs on callbackQueue
MockURLProtocol.mockRequests { _ in
    let parseError = ParseError(code: .objectNotFound, message: "Not found")
    let encoded = try! ParseCoding.jsonEncoder().encode(parseError)
    return MockURLResponse(data: encoded, statusCode: 404, delay: 0.0)
}
user.save(options: [], callbackQueue: callbackQueue) { result in
    XCTAssertEqual(DispatchQueue.getSpecific(key: callbackKey), callbackValue)
    // validate error...
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/ParseSwiftTests/ParseUserTests.swift` around lines 1010 - 1054, Add a
companion test to testSaveAsyncCallbackQueueOnSuccess that verifies the error
callback is dispatched to the provided callbackQueue: mock an error response via
MockURLProtocol.mockRequests (returning a ParseError payload and 404 status),
call user.save(options:[], callbackQueue: callbackQueue) and inside the
completion assert DispatchQueue.getSpecific(key: callbackKey) == callbackValue
and that the result is a failure with the expected ParseError; mirror the
existing test's setup (callbackKey, callbackValue, callbackQueue, expectation)
and fulfill/wait the expectation just like in
testSaveAsyncCallbackQueueOnSuccess.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Tests/ParseSwiftTests/ParseUserTests.swift`:
- Around line 1010-1054: Add a companion test to
testSaveAsyncCallbackQueueOnSuccess that verifies the error callback is
dispatched to the provided callbackQueue: mock an error response via
MockURLProtocol.mockRequests (returning a ParseError payload and 404 status),
call user.save(options:[], callbackQueue: callbackQueue) and inside the
completion assert DispatchQueue.getSpecific(key: callbackKey) == callbackValue
and that the result is a failure with the expected ParseError; mirror the
existing test's setup (callbackKey, callbackValue, callbackQueue, expectation)
and fulfill/wait the expectation just like in
testSaveAsyncCallbackQueueOnSuccess.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 14a308a1-1088-44c0-8e1e-e3adb0545d6c

📥 Commits

Reviewing files that changed from the base of the PR and between 645180e and ebc669b.

📒 Files selected for processing (5)
  • Sources/ParseSwift/Objects/ParseInstallation.swift
  • Sources/ParseSwift/Objects/ParseObject.swift
  • Sources/ParseSwift/Objects/ParseUser.swift
  • Tests/ParseSwiftTests/ParseObjectTests.swift
  • Tests/ParseSwiftTests/ParseUserTests.swift

@Mieruko Mieruko changed the title Dispatch save success callbacks on callbackQueue fix: dispatch save success callbacks on callbackQueue May 13, 2026
@parse-github-assistant

Copy link
Copy Markdown

I will reformat the title to use the proper commit message syntax.

@parse-github-assistant parse-github-assistant Bot changed the title fix: dispatch save success callbacks on callbackQueue fix: Dispatch save success callbacks on callbackQueue May 13, 2026
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.

Parse.User save not dispatching back to callback queue when result is success

1 participant