Skip to content

PE-9129: Sync and login resiliency quick wins#2162

Open
vilenarios wants to merge 8 commits into
devfrom
fix/sync-quick-wins
Open

PE-9129: Sync and login resiliency quick wins#2162
vilenarios wants to merge 8 commits into
devfrom
fix/sync-quick-wins

Conversation

@vilenarios

Copy link
Copy Markdown
Collaborator

Summary

First pass of the sync/data-fetching remediation plan: the highest-impact, lowest-risk fixes identified in the end-to-end sync analysis. Each change is a separate commit with its own tests; none alters happy-path behavior.

Bug fixes

  • Login no longer fails or hangs when the balance endpoint is downgetUser awaited getWalletBalance with no retry/timeout, locking out users with valid passwords during gateway blips. Balance is now best-effort (5s timeout, falls back to 0); ArDriveAuth._updateBalance refreshes it asynchronously right after login as before.
  • Wallets with 200+ drives no longer crash every synctransactionParseBatchSize computed 200 ~/ drivesCount, which reaches 0 at 201 drives and makes BatchProcessor throw. Extracted calculateTransactionParseBatchSize clamped to ≥ 1.
  • BulkImportResult.importedFiles was always empty — WorkerPool discards the execute callback's return value; successful imports are now collected in the callback.

Performance

  • Drive syncs bounded to 5 concurrent (was: every drive at once) via a new runBoundedWorkers helper mirroring Future.wait(eagerError: false) semantics — per-drive error handling, cancellation, and progress reporting unchanged.
  • MetadataCache constructed once instead of rebuilt from SharedPreferences on every parsed batch of every drive.
  • Pin transaction info fetched 100 ids per request instead of 5 — added first: 100 to the InfoOfTransactionsToBePinned query (it previously relied on the gateway's default page size, which is why the batch had to stay tiny), matching the TransactionStatuses/LicenseAssertions pattern.

Test plan

  • 13 new unit tests (batch-size clamp edge cases, balance-fetch failure paths, worker-pool bounds/failure isolation)
  • flutter analyze: clean
  • Full main-app suite on Flutter 3.19.6: 709 passed / 3 skipped / 0 failed
  • Generated artemis code is gitignored; CI regenerates via scr setup

🤖 Generated with Claude Code

vilenarios and others added 7 commits July 2, 2026 23:52
…ches

- extract calculateTransactionParseBatchSize helper from syncAllDrives
- clamp result to at least 1: wallets with 200+ drives previously computed
  a batch size of 0, causing BatchProcessor to throw and every drive sync
  to fail
- guard the denominator so drivesSynced >= drivesCount cannot divide by zero
- add unit tests covering the budget split and both clamp edge cases

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- getUser previously awaited getWalletBalance with no retry, timeout, or
  error handling, so a transient gateway failure locked the user out even
  though the password was correct and the profile is stored locally
- balance fetch now falls back to zero on error or after a 5s timeout;
  ArDriveAuth._updateBalance already refreshes it asynchronously right
  after login and pushes the updated user to the auth stream
- healthy-gateway behavior is unchanged (fresh balance at login)
- deduplicate the double wallet.getAddress() call
- add tests covering sync and async balance-fetch failures

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- syncAllDrives previously started every drive's full sync pipeline at
  once via Future.wait; accounts with many drives fanned out dozens of
  concurrent snapshot/GraphQL/data-fetch pipelines and could trip gateway
  rate limits
- introduce runBoundedWorkers, a small worker-pool helper mirroring
  Future.wait(eagerError: false) semantics: all tasks run even if some
  fail, first error is reported after all complete
- per-drive error handling, cancellation, and progress reporting are
  unchanged (the per-drive closure body is untouched)
- add kMaxConcurrentDriveSyncs constant and unit tests for the pool
  (bounded in-flight count, failure isolation, edge cases)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- createDriveEntityHistoryFromTransactions rebuilt MetadataCache from a
  new SharedPreferences cache store on every parsed batch of every drive
  during sync; it now lazily constructs one instance and reuses it
- behavior is otherwise unchanged: same store, same put/get semantics

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- BulkImportResult.importedFiles was always empty: WorkerPool discards
  the execute callback's return value, so the FileEntry produced by each
  successful _importFile call was never collected
- successful imports are now added to importedFiles inside the worker
  callback; no current consumer reads the field (the bloc tracks progress
  via callbacks), so this only makes the result truthful

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- getInfoOfTxsToBePinned issued one GraphQL round-trip per 5 ids; bulk
  imports of large manifests paid 20x more sequential requests than
  needed
- add first: 100 to the InfoOfTransactionsToBePinned query (previously it
  relied on the gateway's default page size, which is why the batch size
  had to stay tiny) and raise the batch size to 100, matching the
  established pattern in TransactionStatuses and LicenseAssertions
  queries
- generated artemis code is gitignored and regenerated by scr setup

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@vilenarios, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 28 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7f114bf8-6324-4e1b-9b2c-1ed93d9fab3a

📥 Commits

Reviewing files that changed from the base of the PR and between 14623fa and a66fb87.

📒 Files selected for processing (11)
  • lib/core/arfs/use_cases/bulk_import_files.dart
  • lib/services/arweave/arweave_service.dart
  • lib/services/arweave/graphql/queries/InfoOfTransactionsToBePinned.graphql
  • lib/sync/constants.dart
  • lib/sync/domain/repositories/sync_repository.dart
  • lib/sync/utils/bounded_worker_pool.dart
  • lib/user/repositories/user_repository.dart
  • packages/ardrive_ui/pubspec.yaml
  • test/sync/domain/transaction_parse_batch_size_test.dart
  • test/sync/utils/bounded_worker_pool_test.dart
  • test/user/repositories/user_repository_test.dart
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/sync-quick-wins

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.

- equatable 2.1.0 (released after the last green dev build) deprecates
  EquatableMixin, which data_table.dart uses; package lockfiles are not
  committed, so CI's per-package pub get floated to 2.1.0 and scr test
  failed on the analyze step for every PR and dev push
- the main app's committed lockfile resolves equatable 2.0.7, where
  Equatable cannot be used as a mixin, so migrating the code instead of
  pinning would break the app build; pin until both contexts can move to
  2.1.x together

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 5, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit a66fb87):

https://ardrive-web--pr2162-fix-sync-quick-wins-rrf3ixga.web.app

(expires Sun, 12 Jul 2026 19:59:59 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: a224ebaee2f0939e7665e7630e7d3d6cd7d0f8b0

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