Connected clients count
yildizsc opened this issue · comments
Hi @boazsegev,
Thanks for this great work. You deserve the best I think. Very useful tool.
My question is can I get the connected clients count like the following.
Iodine.connections.count
I have a workaround but this is not reliable like the following using redis.
class SSECallback
CHANNEL_NAME = 'SSE'
def initialize(client_channel_name: CHANNEL_NAME)
@channel_name = client_channel_name
end
def on_open(client)
client.subscribe @channel_name
redis.incr 'connections_count'
end
def on_close(client)
redis.decr 'connections_count'
end
end
Hi @yildizsc ,
Thank you for your feedback and input! I might be able to do better on the 0.8.x version (if I ever get there), but currently even Iodine doesn't keep such a list.
The issue with implementing something like Iodine.connections.count
is that it is both unreliable and unclear when using the forking feature ... the feature could mean "how many connections in this process?" or "how many connections in the server instance?" or "how many connections globally?"... so it really depends on your use-case.
In addition, there are implementation hurdles that I simple circumvented by not keeping a list of active connections and using other connection access techniques.
For starters, when implementing this - even on a single multi-threaded process - the count might change between the count
method returning and the next line of code executing (which means that count
will be "fuzzy" at best...
... Theoretically the only reliable data will be on a single threaded server... and even that isn't really true, as there's an additional dedicated IO thread that makes sure that IO operations - such as data write
and connection closure - the could happen even when user threads are blocking.
Also, there's the issue of a potentially crushing worker. If some code causes a worker process to crush, Iodine
would normally automatically spawn a new worker. In such an instance, old data might persist if synchronizing the Iodine.connections.count
across multiple workers.
If I understood your specific use-case I might be able to help more.
If you're looking for a per-server-instance I would consider using Iodine
's internal pub/sub system rather than Redis, collecting the data in the root process (PUBLISH2ROOT
). You will avoid a lot of overhead by keeping the information in-house.
If you're looking on a per-worker solution, than the on_open
and on_close
could easily be used to atomically (or using a mutex) incrementing / decrementing a counter.
If fuzzy information is enough, you might be able to simply count the instances of the Connection class using Ruby's ObjectSpace
.
Good Luck!
Bo.