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

Subscribe to changes using logical replication #220

Merged
merged 2 commits into from
Sep 19, 2021
Merged

Subscribe to changes using logical replication #220

merged 2 commits into from
Sep 19, 2021

Conversation

porsager
Copy link
Owner

@porsager porsager commented Aug 29, 2021

I've just finished implementing realtime capability to Postgres.js through logical replication, so you can subscribe to changes as simple as this:

Create a publication (eg. in migration)

CREATE PUBLICATION alltables FOR ALL TABLES

Subscribe to updates

const sql = postgres({ publications: 'alltables' })

const { unsubscribe } = await sql.subscribe('insert:events', row =>
  // tell about new event row over eg. websockets or do something else
)

The pattern for subscribing is [command]:[schema.table]=[primary_key] where command is insert | update | delete | * and defaults to *. schema.table defaults to * and will prepend public. if schema is not defined. As the last thing primary_key can be used to only subscribe to a specific row. It's optimized to do the least amount of work depending on what you subscribe to, so I'm really excited to see what can be built with this.

Now I still have some tests and docs to write, but if anyone would like to take this branch for a spin I would love to hear what you think..

@alextes
Copy link
Contributor

alextes commented Aug 30, 2021

Yea this would be a bunch cleaner than the notify/listen I have going on now. The only challenge for our codebase is that we only have one notify/listen and it triggers after two tabels have updated. Maybe when I have some time I can change that insert/update to be a transaction, and then the subscribe to either of those tables would work well I think 🤔 .

@porsager
Copy link
Owner Author

porsager commented Sep 10, 2021

@alextes Maybe I misunderstand, but wouldn't this be equivalent?

const sql = postgres({ ... })

sql.subscribe('table1', notifyHandler)
sql.subscribe('table2', notifyHandler)

function notifyHandler() {
  // This is called when the two tables change.
}

@alextes
Copy link
Contributor

alextes commented Sep 13, 2021

@porsager my description was a bit imprecise. Some event A, causes an update to two tables, call those updates B and C, I need to call a handler when B && C have updated, or seen differently when we're done dealing with event A. Your code example results in the handler being called if B || C happens if I'm not mistaken. Now that I think about it, running B and C in a transaction would also solve this maybe at which point subscribing to either would work right?

@porsager
Copy link
Owner Author

Ah I see.

Yes, subscribing to either should be fine as well, but remember that if you do any kind of changes besides in that transaction it'll fire as well.

@porsager porsager merged commit 51d033c into master Sep 19, 2021
@porsager porsager deleted the subscribe branch September 19, 2021 20:23
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