dunglas / mercure

🪽 An open, easy, fast, reliable and battery-efficient solution for real-time communications
https://mercure.rocks
GNU Affero General Public License v3.0
3.98k stars 296 forks source link

How mercure handle multiple hub subscription? #622

Closed Lenny4 closed 2 years ago

Lenny4 commented 2 years ago

I was wondering how Mercure will handle subscription when multiple instance of a hub are launch with Kubernetes.

Here we can read:

To subscribe to updates, the client opens an HTTPS connection following the Server-Sent Events specification to the hub's subscription URL advertised by the publisher

But let's say we have:

If ClientA send an HTTP request which result that HubA send to all his subscribers an event, then ClientB will not receive an event (if I anderstand how Mercure works).

I'm planning to deploy my application as the documentation say (Deploying to a Kubernetes Cluster).

But i'm afraid that some clients will not be able to received all the events as they won't be listening to the "right" hub.

Question:

Thank you.

ingfdoaguirre commented 2 years ago

Hi as I can understand you need to share the same transport db with your containers, lets say: mercure container 1 mercure container 2 redis container transport -> This transport will be shared, and in your configuration files just put in transport_url the url of the exposed redis container.

So, when an update comes to HubA will be saved to the shared transport, and HubB will know about this new update.

This is a theory of how I think this would work. @dunglas needs to confirm this.

dunglas commented 2 years ago

The free and open source version of Mercure only supports single-node/pod setups. If you want to create a cluster, you need the managed or the on prem version or to write your own transport: https://mercure.rocks/docs/hub/cluster

Lenny4 commented 2 years ago

Hi @dunglas , Thanks for the answer, after reading the doc it is more clear to me how mercure works.

Especially now I know about Transports.

So by default mercure use BoltDB which can run on a single node. In the caddyfile we can clearly see how it configured transport_url {$MERCURE_TRANSPORT_URL:bolt:///data/mercure.db}

Now I'm trying to change the transport to PostgreSQL. So in my .env I simply add these 2 vars:

MERCURE_TRANSPORT_URL=postgresql://api-platform:toor@5432/api?serverVersion=13&charset=utf8
MERCURE_LICENSE=snip

When I launch my mercure (and postgre bdd with docker), I got this error message:

caddy_1          | run: loading initial config: loading new config: loading http app module: provision http: server srv0: setting up route handlers: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 0: loading handler modules: position 0: loading module 'subroute': provision http.handlers.subroute: setting up subroutes: route 1: loading handler modules: position 0: loading module 'mercure': provision http.handlers.mercure: "postgresql://api-platform:xxxxx@db:5432/api?serverVersion=13&charset=utf8": invalid transport: no such transport available

It says that invalid transport: no such transport available while I'm sure that there is no error in the connections parameters.

In transport.go we can read that this error occur when:

// TransportError is returned when the Transport's DSN is invalid.

But I'm sure that there is no error, as I use the same env var in my php code to connect to my database. Event tought my php code is in another container as all my services are in the same docker-compose file it shouldn't be a problem.

What am I missing here ? Do I need to configure my api database a certain way to work as a transport ?

Thank you.

dunglas commented 2 years ago

You need the on premise (paid) version to use the Postgres transport. It isn't included in the open source version.