Skip to content

Conversation

@IcedTea2K
Copy link
Contributor

@IcedTea2K IcedTea2K commented Jun 11, 2024

What kind of change does this PR introduce?

This PR is part one of many parts to the issue #2. It implements the following few functionalities:

  • RealtimeClient.Channel() - create a channel with a specific topic. It will fail if the channel with the same topic name already exists.
  • RealtimeChannel.On() - register an event with a user's callback. This currently only handles postgres_changes events. It validates event configurations such as schema, table, event type (i.e., * | INSERT | UPDATE | DELETE), and event filter (such as age=eq.200).
  • RealtimeChannel.Subscribe() - send a connection message to the phoenix server, and waits for a response. It then maps the received IDs to the appropriate callbacks. It also validates that the number and configurations of the subscribed events. Upon any error, it will rollback and unsubscribe from the server. After the initial call, a goroutine will be kicked off to listen to the server's upcoming events in realtime! The received event will be processed and sent to the correct callback. Currently, only postgres events are being handled. Broadcast and presence features are yet implemented.
  • RealtimeChannel.Unsubscribe()- send a phx_leave message to the phoenix server to leave the topic. As such, events will no longer be triggered. Though, the client still doesn't disconnect from the server.

What is the current behavior?

None. The RealtimeClient is only able to establish and maintain the connection with the server.

What is the new behavior?

The following demo shows a simple program listening to the 4 types of events: * | UPDATE | INSERT | DELETE. After 20 seconds or so, the program unsubscribes, and stop receiving events.
Demo

This is a sample response of the payload passed into the callback.

{
	"data": {
		"schema": "public",
		"table": "sample",
		"commit_timestamp": "2024-06-14T23:17:00.348Z",
		"record": {
			"age": 200,
			"created_at": "2024-06-11T03:23:28.851861+00:00",
			"id": 22
		},
		"columns": [
			{
				"name": "id",
				"type": "int8"
			},
			{
				"name": "created_at",
				"type": "timestamptz"
			},
			{
				"name": "age",
				"type": "int8"
			}
		],
		"type": "UPDATE",
		"old_record": {
			"id": 22
		},
		"errors": ""
	},
	"ids": [
		17277040,
		49337105,
		7548478,
		24028530
	]
}

Additional context

Apologies for a massive of a PR. A lot of these components have to come with each other before we could have a working code :(

A small comparison with the JavaScript counterpart:

  • Go Realtime.Client disallow channels with the same name, while that of JS overwrites the channel and create a new fresh one. (this was discussed in the issue Server Event Income Handling #2 (comment))
  • To stick with the true spirit of Go, functions like On(), Subscribe(), and Unsubscribe() return an error indicating if the action is successful or not. Unfortunately, that prevents the function chaining similar to realtime-js.
  • realtime-js sends the connection message and joins the topics upon the creation of a channel. This might be a waste of resources since the client is forced to make and maintain a connection. realtime-go, however, will only make a connection and join the topic upon subscribing. Though, if the user wants to perform the overhead beforehand, they could use RealtimeClient.Connect() to perform the connection early on, then join the topic later with RealtimeClient.Subscribe().

@IcedTea2K IcedTea2K marked this pull request as ready for review June 14, 2024 22:30
@groud
Copy link

groud commented Aug 29, 2024

Hey! Thanks a lot for this PR, it helps us a lot!

We are creating a micro-service that would greatly benefit from realtime-go being actually usable in production. So, as it seems that this PR goes a huge step towards this goal, I'd like to know if it is currently in a working / mergeable state, and if so, whether there's a chance it gets merged soon-ish or not. In any case, I'll check the PR and see if I manage to make it work. I'll leave an approval/review here once I'm done.

@muratmirgun I see you are the maintainer the project. Pinging you to know if you still wish / have the time to work on it. No pressure, it just allows us to decide if it is worth maintaining our own fork or not.

@wade-liwei
Copy link

wade-liwei commented Nov 22, 2024

do you have the problem?

2024/11/22 20:15:34 Unexpected error while listening: failed to read JSON message: failed to get reader: use of closed network connection
2024/11/22 20:15:34 Unexpected error while listening: failed to read JSON message: failed to get reader: use of closed network connection
2024/11/22 20:15:34 Unexpected error while listening: failed to read JSON message: failed to get reader: use of closed network connection

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.

3 participants