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

Synchronizes database events between multiple clients #66

Merged
merged 4 commits into from
Apr 14, 2021

Conversation

kettanaito
Copy link
Member

@kettanaito kettanaito commented Apr 14, 2021

GitHub

Changes

  • Adds a synchronization middleware that syncs database events (create/update/delete) between multiple open tabs.
  • Each Database instance (internal) now has a unique reproducible MD5 hash to identify this instance among multiple database instances. This way a single broadcast channel applies events to proper databases based on the database ID of the source event.
    • MD5 hash is generated based on the following data:
      • Database invocation order.
      • Database invocation location (a stack trace to where factory() is called. Factory creates an internal Database instance).

Motivation

Client-side sync allows the database to feel like an actual external database you're working with, as its updates you provision in one tab are synced with the other tabs as if they are requesting the same database. In reality, each tab has its own runtime and creates its own database from a clean slate.

Roadmap

  • Ensure that multiple db instances sync their updates independently.

@kettanaito kettanaito force-pushed the extensions/sync branch 4 times, most recently from 7c906ca to 60813bc Compare April 14, 2021 09:35
private generateId() {
const { stack } = new Error()
const callFrame = stack?.split('\n')[4]
const salt = `${callOrder}-${callFrame?.trim()}`
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm using an invocation order and database location to identify a single database instance.
The order of factory() calls is unlikely to change on runtime. Two first-created databases across clients aren't necessarily the same instances, as each client may load a different module, while the same BroadcastChannel controls the entire host. To account for that, I'm adding a module location to the hash salt.

Two database instances on multiple pages are equal if:

  1. They were called in the same order.
  2. They were created in the same module.

@kettanaito
Copy link
Member Author

kettanaito commented Apr 14, 2021

Ignoring unrelated events

It's possible to have multiple factory() calls (and thus, Database instances) on a single page. The sync extension should understand that db has issued an update, and apply that update to the respective db in another client. This comes down to two possible solutions:

  1. Create a unique BroadcastChannel per db instance.
  2. Assign a unique reproducible ID to each db instance.

Unfortunately, BroadcastChannel is applied to the entire host and is discerned by channel name, not reference. Even if each db creates its own channel, it must still assign it a unique name, which is, effectively, a unique ID.

Copy link
Member

@marcosvega91 marcosvega91 left a comment

Choose a reason for hiding this comment

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

it looks very good :) nice 💯

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.

2 participants