How to setup a phoenix channel for say hundreds of topics?

Suppose there are some users, say 100. Each user has, say 100 items and a percentage of which are shared to the users by other users. Each item has a name.

So… What I want is, if I edit the name of item1 of user1, it should update all the users who have item1.

I have already setup the permissions necessary and REST api is working over controllers.

Now I want to implement real time updates and channels in phoenix are the right fit. If I have a channel with topic item:*, I can account for all the items of all the users.

So, if there is a user1 with item1, item2, item3…, item100. How will I setup the listeners on javascript side?

APPROACH 1

I can have a channel with topic “items:*”, and subscribe to individual items on client side.

var channels = {}
forEach(function(items, val) {

    var topic = "item:" + val
    // Join the topic
    channels[topic] = socket.channel(topic, {})

    channels[topic].join()
        .receive("ok", data => {
            console.log("Joined topic", topic)
        })
        .receive("error", resp => {
            console.log("Unable to join topic", topic)
        })

    channels[topic].on("name_changed", resp => {
        console.log("name was changed of this item", resp);
    })
});

APPROACH 2

(By @schrockwell on #phoenix channel of Slack)
Make a single “item_updates” channel, and then push messages to it like {item_id: 1, changes: …}
And then on the server-end, register an outgoing handler on that channel so the user only gets updates for items they have permission to know about.

THOUGHTS

I think approach 2 is minimal and seems like a nice solution. But wont this be a problem with thousands of users as every broadcast to “item_updates” will trigger an update for every user and that item might be only shared to 1 or 2 users or none. So for every update I will have to check for every user if that user has access to that item.

Instead in approach 1 there will be a big initial setup cost during client side attaching of event listeners. But after that any item update will tunnel to their respective owner and shared to users.

So attaching event listeners to hundreds of items will be a problem? Am I thinking right?

1 Like

you could also have the user connect to a “user:#{user_id}” channel…

and then if an item updates that is shared by users say: 1, 57, 189 - you broadcast the “item_update” to those three users’ “user:#{user_id}” channel…

I would definitely not go with approach 1, approach 2 seems prone to backing up and being slow, but it all depends…

1 Like

I think your solution should work. I will check and update here. Thank you.

3 Likes