WIP: Component changes revert when multiple users edit components concurrently

Environment

  • Browser: Arc 1.170.0 (89123)
  • Chromium engine: 156.0.8078.48
  • OS: macOS

Summary
Two users edit different components on different pages at the same time and both save. One user’s component changes are lost. Components created during that window can also be deleted. Global classes have conflict detection for this situation, but components don’t.

Impact
High. Our team loses work unpredictably, and edits can’t be trusted to persist while more than one person is editing components.

Observed behavior

  • The reversion shows up on the front-end first, even though the builder still displays the current, unreverted changes.
  • After a reversion has occurred on the front-end, refreshing the builder loads the reverted version.

Steps to reproduce

  • Have components X and Y in the site.
  • User A opens Page 1 in the builder. User B opens Page 2 in the builder.
  • User A edits component X and saves.
  • User B, without reloading, edits component Y and saves.
  • Reload the builder.

Expected: Both edits are kept. X has A’s change and Y has B’s change.

Actual: Only B’s edit to Y is kept. X is back to its state before A’s edit.

Possible cause

  • Client: When components is in unsavedChanges, the builder sends the whole components array from its in-memory state. That’s the copy loaded when the builder opened, plus that user’s own edits.
  • Server: Ajax::save_post() in ajax.php treats that array as a complete replacement:
  • It compares incoming and stored components only for permission checks and sanitization.
  • Stored IDs missing from the payload are treated as deletions. The only check is the delete_components permission
  • It then calls update_option( BRICKS_DB_COMPONENTS, $components ) with the full client array.

Hello @tilla,

thank you for the report. I have good news for you. The fix for this will be implemented in the next bigger update. Up until then, please be careful when you edit the same component at the same time.

Best regards,
Matej

Awesome, thank you for the update!