Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connected clients count #121

Open
yildizsc opened this issue May 3, 2022 · 1 comment
Open

Connected clients count #121

yildizsc opened this issue May 3, 2022 · 1 comment

Comments

@yildizsc
Copy link

yildizsc commented May 3, 2022

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
@boazsegev
Copy link
Owner

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants