Presence - subset of online users from all online users. How to?

I have watched Chris’ youtube videos about new feature of 1.2 framework, which includes presence but I can’t figure out how to accomplish what the title of my post says.

A social website may have a 100K users logged on (on line) but I’m only interested in ones who live near me.

  1. does each client have to track all online users?
  2. how do I cross reference result(s) of my user searches with who’s on line?
1 Like

I don’t think you can do that with phoenix channels on their own, you need to think of a better solution. From top of my head, you can do the following:

  1. Use some spatial-aware database to store user’s location (lat,lng) in. Postgresql + PostGIS would be my first choice. You can also do it with MongoDB if you are adventurous and don’t mind occasional data disappearences ;).

  2. Once you have your user’s id, lat, lng in database, you write something listens to presence changes on your presence channel. Whenever user becomes online -> update it in the spatial database. Whenever user becomes offline -> update in spatial database. So you end up with a table with: id, lat, lng, is_online.

  3. Perform geospatial query to find nearest online users combining lat, lng and is_online fields.

You can probably do it other ways too. Like implement some sort of solution where you would have multiple channels, and user’s lat, lng gets rounded to some discrete value. Then you check presence for nearest channels, and merge the results.

But I think i’d go with first solution. The only important thing to check is if the database writes will be fast enough for the hundreds of thousands of users going online/offline, but I am sure you can find a solution to that too.

I think I might be misunderstanding how presence can or should be used. Seems to me like presence would be a very good choice for, say, a friends’ list where you have limited scope of 10 or 20 people who’s online status you wish to track. Searching for random users and their on/off line statuses should be handled differently. On the top of this, in my original post, I added fuel to fire by mixing details of geospatial searching, which is completely separate topic.

  1. online status is not really that important, it’s only serves informative purpose for other users, adding chat might be something we do later (obviously you can chat w/ online users only). Instead of rolling out custom solution I was wondering if I could leverage presence somehow.

  2. we are using RethinkDB (but that’s not important) and have already downloaded geospatial data from government site, so we are good on searching users w/in 25, 50 miles.

  3. since our app is 90% read it is therefore heavily cached, only actual writes (messages, profile creation/update etc) and detailed or rare requests go against the DB itself. We would never save online status in the DB itself. Once you log on to the site your details are moved up to the cache and other users will read your details from cache. Obviously when you update something about yourself it will be saved in the DB and then propagated back to cache.

  4. basically all communication will be over web sockets and I think we will go back to the original idea of having a key in cache which will indicate someone’s online status. This will expire in, say, 10 min of inactivity even though your web socket connection may still be open for a while when you walk away from your computer to have a beer with a friend.

  5. we are using Cachex for multilayer and distributed caching, works pretty well.

Thanks Hubert for taking the time to help me out with this. I appreciate it!

1 Like

I’m thinking the Presence structure should be structured a little different than how you are implying. If it were me I’d probably have the topic be the internal user id then on the fetch/2 callback I’d do the database/cache search to see who is near and add it to the return map. That way each user has a synchronized ‘online/nearby’ list between however many sessions that they have open, but each user has their own list.

So the use case you were describing was for a limited number of users (like my friends’ list), right? To my understanding, having a small list managed by presence would make sense. I would manage it from any device (or browser’s tab) that’s currently active.

I think I intended to use presence to query for on/off line statuses of all the users logged into the site, which could be a very large number and it doesn’t seem like that’s the right approach. I really don’t want to track 100K (currently logged on users) who are not my friends or I have no interest in them.
Presence, was not meant for this.

Precisely yeah, presence seems like it is meant for small amounts of ephemeral data for a given topic, though I could forsee a lot of topics…