Skip to content
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

Update global event listeners to handle sync server and DB update sync events #4161

Merged
merged 3 commits into from
Jan 22, 2025

Conversation

joel-jeremy
Copy link
Contributor

@joel-jeremy joel-jeremy commented Jan 15, 2025

Fixes #4082

The global-listeners file listens to a bunch of events from the backend (i.e. service worker). One of these events is the sync-event this event is emitted whenever new messages are received from the sync server (type: 'success') or whenever a DB update is made (type: 'applied'). This change updates the sync-event handler so that it handles both success and applied sync event types - what this means is that whenever Actual received sync messages from the sync server or whenever a DB update is made, the payees, categories, and accounts in the redux state are automatically updated.

This will also help with performance by removing some of the duplicate sync-event listeners resulting in less DB calls

@actual-github-bot actual-github-bot bot changed the title Update global event listeners [WIP] Update global event listeners Jan 15, 2025
Copy link

netlify bot commented Jan 15, 2025

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit 41ffffa
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/678cb2d1bd72c40008d13ff9
😎 Deploy Preview https://deploy-preview-4161.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

github-actions bot commented Jan 15, 2025

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
15 6.67 MB → 6.67 MB (-303 B) -0.00%
Changeset
File Δ Size
src/redux/index.ts 📈 +41 B (+44.09%) 93 B → 134 B
src/global-events.ts 📈 +245 B (+7.42%) 3.22 kB → 3.46 kB
home/runner/work/actual/actual/packages/loot-core/src/client/shared-listeners.ts 📈 +549 B (+6.37%) 8.42 kB → 8.96 kB
src/components/App.tsx 📈 +104 B (+1.70%) 5.98 kB → 6.08 kB
node_modules/react-redux/dist/react-redux.mjs 📈 +4 B (+0.05%) 7.44 kB → 7.44 kB
src/components/payees/ManagePayeesWithData.tsx 📉 -35 B (-0.93%) 3.69 kB → 3.66 kB
src/components/mobile/accounts/AccountTransactions.tsx 📉 -120 B (-1.54%) 7.6 kB → 7.49 kB
src/index.tsx 📉 -27 B (-2.52%) 1.05 kB → 1.02 kB
src/components/mobile/budget/index.tsx 📉 -344 B (-2.84%) 11.83 kB → 11.5 kB
src/components/mobile/budget/CategoryTransactions.tsx 📉 -120 B (-3.98%) 2.94 kB → 2.83 kB
src/components/budget/index.tsx 📉 -600 B (-6.15%) 9.53 kB → 8.94 kB
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/index.js 4.27 MB → 4.27 MB (+161 B) +0.00%

Smaller

Asset File Size % Changed
static/js/narrow.js 84.83 kB → 84.38 kB (-464 B) -0.53%

Unchanged

Asset File Size % Changed
static/js/nl.js 50.6 kB 0%
static/js/en-GB.js 96.03 kB 0%
static/js/en.js 97.98 kB 0%
static/js/workbox-window.prod.es5.js 5.69 kB 0%
static/js/resize-observer.js 18.37 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.5 kB 0%
static/js/uk.js 118.39 kB 0%
static/js/pt-BR.js 106.65 kB 0%
static/js/AppliedFilters.js 10.21 kB 0%
static/js/useAccountPreviewTransactions.js 1.63 kB 0%
static/js/BackgroundImage.js 122.29 kB 0%
static/js/wide.js 101.22 kB 0%
static/js/ReportRouter.js 1.59 MB 0%

Copy link
Contributor

github-actions bot commented Jan 15, 2025

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
1 1.33 MB 0%

Changeset

No files were changed

View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.js 1.33 MB 0%

@@ -157,6 +158,10 @@ function ErrorFallback({ error }: FallbackProps) {
}

export function App() {
const store = useStore();

useEffect(() => handleGlobalEvents(store), [store]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved call to handleGlobalEvents here so that we can have proper cleanup of listeners

@@ -106,31 +102,6 @@ function BudgetInner(props: BudgetInnerProps) {
}

run();

const unlistens = [
Copy link
Contributor Author

@joel-jeremy joel-jeremy Jan 15, 2025

Choose a reason for hiding this comment

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

No need for this since this is already handled by the global sync-event listener

@@ -277,10 +276,6 @@ function TransactionListWithPreviews({
) {
reloadTransactions();
}

if (tables.includes('payees') || tables.includes('payee_mapping')) {
Copy link
Contributor Author

@joel-jeremy joel-jeremy Jan 15, 2025

Choose a reason for hiding this comment

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

No need for this since this is already handled by the global sync-event listener

@@ -72,10 +71,6 @@ export function CategoryTransactions({
) {
reloadTransactions();
}

if (tables.includes('payees') || tables.includes('payee_mapping')) {
Copy link
Contributor Author

@joel-jeremy joel-jeremy Jan 15, 2025

Choose a reason for hiding this comment

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

No need for this since this is already handled by the global sync-event listener

@@ -68,22 +67,6 @@ export function Budget() {
}

init();

const unlisten = listen('sync-event', event => {
Copy link
Contributor Author

@joel-jeremy joel-jeremy Jan 15, 2025

Choose a reason for hiding this comment

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

No need for this since this is already handled by the global sync-event listener

});

// TODO: Should this run on mobile too?
listen('sync-event', async ({ type }) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this to the shared-listeners.ts file


// This is experimental: we sync data locally automatically when
// data changes from the backend
listen('sync-event', async event => {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved this to the shared-listeners.ts file. That file has been updated to handle both success and applied events

@@ -37,9 +36,6 @@ const boundActions = bindActionCreators(
store.dispatch,
);

// Listen for global events from the server or main process
handleGlobalEvents(store);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved inside a useEffect in App.tsx

const prefs = store.getState().prefs.local;
if (!prefs || !prefs.id) {
// Do nothing if no budget is loaded
return;
}

if (event.type === 'success') {
if (event.type === 'success' || event.type === 'applied') {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refreshes the state whenever a server sync was made (i.e. success type) or a local change was made/applied (i.e. applied type)

if (tables.includes('payees') || tables.includes('payee_mapping')) {
if (
// Sync on accounts change because so that transfer payees are updated
tables.includes('accounts') ||
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Main fix for #4082

@joel-jeremy joel-jeremy changed the title [WIP] Update global event listeners \Update global event listeners Jan 15, 2025
@joel-jeremy joel-jeremy changed the title \Update global event listeners Update global event listeners Jan 15, 2025
Copy link
Contributor

coderabbitai bot commented Jan 15, 2025

Warning

Rate limit exceeded

@joel-jeremy has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 17 minutes and 48 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 25a8732 and 41ffffa.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/4161.md is excluded by !**/*.md
📒 Files selected for processing (11)
  • eslint.config.mjs (1 hunks)
  • packages/desktop-client/src/components/App.tsx (2 hunks)
  • packages/desktop-client/src/components/budget/index.tsx (2 hunks)
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (0 hunks)
  • packages/desktop-client/src/components/mobile/budget/CategoryTransactions.tsx (0 hunks)
  • packages/desktop-client/src/components/mobile/budget/index.tsx (1 hunks)
  • packages/desktop-client/src/components/payees/ManagePayeesWithData.tsx (0 hunks)
  • packages/desktop-client/src/global-events.ts (4 hunks)
  • packages/desktop-client/src/index.tsx (0 hunks)
  • packages/desktop-client/src/redux/index.ts (1 hunks)
  • packages/loot-core/src/client/shared-listeners.ts (3 hunks)

Walkthrough

The pull request introduces several changes across multiple files in the packages/desktop-client and packages/loot-core directories. The primary modifications involve restructuring global event handling, removing specific sync event listeners, and updating the Redux-related imports and configurations. A new ESLint rule is added to restrict the import of useStore from react-redux, encouraging the use of a custom useStore() hook. The changes simplify event listening mechanisms, remove some automatic data fetching triggered by sync events, and modify how global events are managed within the application.

Assessment against linked issues

Objective Addressed Explanation
Resolve payee name autocomplete issue [#4082] Unable to definitively determine if the changes directly address the payee name autocomplete problem

Possibly related PRs

Suggested labels

sparkles: Merged

Suggested reviewers

  • joel-jeremy
  • MikesGlitch

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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 docstrings to generate docstrings for this PR. (Beta)
  • @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.

Copy link
Contributor

@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 (3)
packages/desktop-client/src/redux/index.ts (1)

4-4: LGTM! Consider adding JSDoc comments.

The addition of type-safe Redux hooks improves type safety. Consider adding JSDoc comments to document the purpose and usage of these hooks.

+/**
+ * Type-safe hook for accessing the Redux store.
+ * @returns The Redux store with proper type inference.
+ */
 export const useStore = useReduxStore.withTypes<AppStore>();

Also applies to: 7-11, 13-13

packages/desktop-client/src/global-events.ts (1)

26-37: Consider adding error handling for server errors.

The server error notification is generic. Consider providing more specific error information to help users troubleshoot issues.

 store.dispatch(
   addNotification({
     type: 'warning',
-    message: 'Unable to authenticate with server',
+    message: `Unable to authenticate with server: ${error?.message || 'Unknown error'}`,
     sticky: true,
     id: 'auth-issue',
+    button: {
+      title: 'Retry',
+      action: () => store.dispatch(sync())
+    }
   }),
 );
packages/loot-core/src/client/shared-listeners.ts (1)

23-35: Good addition of unauthorized event handling.

The unauthorized event handling is well implemented. Consider adding a retry mechanism with exponential backoff for transient authentication issues.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 97b28ca and 25a8732.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/4161.md is excluded by !**/*.md
📒 Files selected for processing (11)
  • eslint.config.mjs (1 hunks)
  • packages/desktop-client/src/components/App.tsx (2 hunks)
  • packages/desktop-client/src/components/budget/index.tsx (2 hunks)
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx (0 hunks)
  • packages/desktop-client/src/components/mobile/budget/CategoryTransactions.tsx (0 hunks)
  • packages/desktop-client/src/components/mobile/budget/index.tsx (1 hunks)
  • packages/desktop-client/src/components/payees/ManagePayeesWithData.tsx (0 hunks)
  • packages/desktop-client/src/global-events.ts (4 hunks)
  • packages/desktop-client/src/index.tsx (0 hunks)
  • packages/desktop-client/src/redux/index.ts (1 hunks)
  • packages/loot-core/src/client/shared-listeners.ts (3 hunks)
💤 Files with no reviewable changes (4)
  • packages/desktop-client/src/index.tsx
  • packages/desktop-client/src/components/mobile/accounts/AccountTransactions.tsx
  • packages/desktop-client/src/components/payees/ManagePayeesWithData.tsx
  • packages/desktop-client/src/components/mobile/budget/CategoryTransactions.tsx
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Visual regression
  • GitHub Check: Functional
  • GitHub Check: build (windows-latest)
  • GitHub Check: build (ubuntu-latest)
🔇 Additional comments (7)
packages/desktop-client/src/global-events.ts (1)

22-37: Great improvement in event listener management!

The cleanup pattern implementation is excellent. Each listener is properly stored and cleaned up, preventing memory leaks.

Also applies to: 39-40, 43-43, 147-160

packages/desktop-client/src/components/App.tsx (1)

161-163: LGTM! Good placement of global event handling.

Moving the global event handling to the App component level and using useEffect for cleanup is a good architectural decision.

packages/loot-core/src/client/shared-listeners.ts (2)

344-347: LGTM! Proper cleanup implementation.

The cleanup function ensures proper removal of event listeners.


46-46: Verify the impact of payee updates on transfer payees.

The comment indicates that payees are updated when accounts change to handle transfer payees. Ensure this doesn't cause unnecessary updates.

Also applies to: 73-78

✅ Verification successful

Transfer payee updates are necessary and correctly implemented.

The sync is required to maintain data consistency when accounts change, as transfer payees are directly linked to accounts. The implementation includes proper safeguards and only updates when necessary.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for transfer payee usage in the codebase
rg -A 5 "transfer.*payee" 

Length of output: 11193

packages/desktop-client/src/components/budget/index.tsx (1)

89-89: LGTM! Category fetching simplified.

The direct approach to fetching categories aligns well with the global event listener pattern, making the code more maintainable.

packages/desktop-client/src/components/mobile/budget/index.tsx (1)

19-19: LGTM! Consistent with desktop implementation.

The removal of sync event listeners aligns with the global event handling pattern, maintaining consistency across desktop and mobile components.

eslint.config.mjs (1)

664-669: LGTM! Consistent Redux hook restrictions.

The new ESLint rule for useStore follows the established pattern for Redux hooks, ensuring consistent usage of custom store implementations across the application.

@joel-jeremy joel-jeremy changed the title Update global event listeners Update global event listeners to handle sync events Jan 15, 2025
@joel-jeremy
Copy link
Contributor Author

joel-jeremy commented Jan 16, 2025

I did some more digging and there are a lot of other calls to getPayees, getAccounts, getCategories that are being dispatched whenever a new entity is created. These can be removed because it is already being handled by this global event handler but I'll just separate that change to another PR.

@joel-jeremy joel-jeremy changed the title Update global event listeners to handle sync events Update global event listeners to handle sync server and DB update sync events Jan 16, 2025
@joel-jeremy joel-jeremy force-pushed the update-global-event-listeners branch from 25a8732 to 1b8cf86 Compare January 19, 2025 08:02
@joel-jeremy joel-jeremy merged commit f0c81ee into master Jan 22, 2025
20 checks passed
@joel-jeremy joel-jeremy deleted the update-global-event-listeners branch January 22, 2025 06:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: After change account name, payee name autocompletes with old name instead of updated name
2 participants