Skip to content

Add ability to make the FE trigger automatic dashboard refresh#6442

Merged
RobertJoonas merged 19 commits into
masterfrom
automatic-dashboard-refresh
Jun 16, 2026
Merged

Add ability to make the FE trigger automatic dashboard refresh#6442
RobertJoonas merged 19 commits into
masterfrom
automatic-dashboard-refresh

Conversation

@RobertJoonas

@RobertJoonas RobertJoonas commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Changes

Resurrecting what was started in #5362.

Adds a new plug in the :internal_stats_api pipeline that adds an x-api-version response header. Incrementing the value will trigger an automatic dashboard refresh.

In order to not trigger repeated dashboard reloads during deployments, the x-api-version header gets the value of the minimum version across the cluster. Each node has @api_version compiled in. That same value gets passed into the FE via a <meta> tag. Without the meta tag in the DOM, the frontend defaults to EXPECTED_API_VERSION = 0, which:

  • keeps the FE test suite working without having to worry about the api version
  • makes sure that dashboard does not refresh when this PR itself is deployed

Whenever the FE version gets ahead of the BE (i.e. load the dashboard from a freshly deployed node while some app servers are still on the old version), we do not refresh the dashboard. Done by comparing version integers.

Tests

  • Automated tests have been added

Changelog

  • This PR does not make a user-facing change

Documentation

  • This change does not need a documentation update

Dark mode

  • This PR does not change the UI

- extract fetchSuggestions into a separate module to break circular dependency
- handle headers not existing in API response (no headers in tests)
@github-actions

Copy link
Copy Markdown
Preview environment👷🏼‍♀️🏗️
PR-6442

@RobertJoonas RobertJoonas changed the title Add ability to trigger automatic dashboard refresh when api version gets outdated Add ability to make the FE trigger automatic dashboard refresh Jun 10, 2026
Comment thread lib/plausible_web/plugs/internal_stats_api_version.ex Outdated
Comment thread lib/plausible_web/plugs/internal_stats_api_version.ex Outdated
Comment thread assets/js/dashboard/api.ts Outdated
Comment thread assets/js/dashboard/api.ts Outdated
Comment thread assets/js/dashboard/util/url-search-params.ts Outdated
Comment thread assets/js/dashboard/api.ts Outdated
Comment thread assets/js/dashboard/api.ts Outdated
Comment thread assets/js/dashboard/stats/modals/filter-modal-row.js
*
* BE: lib/plausible_web/plugs/internal_stats_api_version.ex
*/
export function maybeReloadForApiVersion(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

issue, blocking: I think this must be unit tested quite extensively.

The FE makes multiple requests for data concurrently. The requests may hit different instances of the BE. During rolling deploys, the BE instances may report different API versions. What should happen?

I suggest we spec it out with a jest test suite that includes the concurrent requests during rolling deploys scenario.

I suspect we may need to set a flag that we're about to update to have deterministic behavior, e.g. at module level, let reloadingDueToApiVersionChange

@RobertJoonas RobertJoonas Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

During rolling deploys, the BE instances may report different API versions. What should happen?

Uff, yeah good catch! I feel like this is now turning into an infrastructure problem. So basically, a dashboard reload is useless until there's old code still around on at least one app server. We definitely don't want the dashboard to keep reloading itself until our deployment finishes.

I guess the version bump should happen separate from the code change then. I'm now thinking about storing the version in Postgres and bumping it via remote shell once all deployments have finished, maybe?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've landed on :rpc.multicall to get the effective API version as the minimum across the cluster, falling back to the current node version on non-cluster setups or when the multicall fails. the "effective version" value is cached for 30s.

Basically, the idea is that when we start rolling out new code, the effective version will be the old one for as long as there's at least one app node still at that version. This guarantees that all nodes have updated once we trigger the automatic refresh.

However, the client can still (re)load the dashboard manually while deployment is in progress, meaning they'd get the new FE code with requests served by the old BE. Although there's a version mismatch there, we don't reload the page because the frontend API version is ahead. Basically the frontend is in the correct state, and just waiting for the backend to update.

Comment thread assets/js/dashboard/util/url-search-params.ts Outdated
@RobertJoonas RobertJoonas requested a review from zoldar June 15, 2026 08:29

@spec effective_version() :: non_neg_integer()
def effective_version() do
GenServer.call(__MODULE__, :get)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Although it's highly unlikely this process might go bad or become a bottleneck, I'd consider persisting the effective version in ETS instead and attempting to fetch it here with a graceful fallback, just in case. It could be done in a way similar to Salts https://github.com/plausible/analytics/blob/master/lib/plausible/session/salts.ex#L10-L27

@zoldar zoldar left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Comment thread test/test_helper.exs Outdated
@RobertJoonas RobertJoonas added this pull request to the merge queue Jun 16, 2026
Merged via the queue into master with commit 1662eae Jun 16, 2026
22 checks passed
@RobertJoonas RobertJoonas deleted the automatic-dashboard-refresh branch June 16, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants