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

Create multiple connections in separate threads (for multiple users) #126

Open
martinbarilik opened this issue Jun 1, 2020 · 1 comment

Comments

@martinbarilik
Copy link

martinbarilik commented Jun 1, 2020

Another problem we are facing is to create multiple websocket connections for separate users.

Every user has its own settings and has to be able to connect to its own websocket server with client.

What is the problem is the fact user's first thread is merged into second.

ws_logger.info "User##{user.id} started initialization"
threads << Thread.new {
  begin
    EM.run {
      ws = Faye::WebSocket::Client.new('wss://www.bitmex.com/realtime')
      ws.on :open do
        # ... some code
        ws_logger.info "Socket started in ##{Thread.current.object_id}"
      end
      ws.on :message ...
      ws.on :close

      # ...
    }
  ensure
    ws_logger.info "ensured close thread##{Thread.current.object_id}"
  end
}

threads.each do |thread|
  foo.thread_id = thread.object_id
  foo.save!
end

So far so good, output:

User#1 started initialization
Socket started in #76800

And foo.thread_id of user#1 is 76800. But if another user runs the method:

User#2 started initialization
ensured close thread#74500
Socket started in #76800

and user#2 foo.thread_id is 74500. Now both are running in the same thread and if terminate #76800, ws is closed for both users. What is the right way to do it? I even tried EM.defer, but it does the same.

Also, we experience this: #89 with passenger and nginx + postgresql.

@jcoglan
Copy link
Collaborator

jcoglan commented Jun 8, 2020

By setting up threads yourself, you're working against how EM is supposed to be used. It's a single-threaded reactor, just like JavaScript in the browser, and all I/O is asynchronous. So, if you want to start sockets for a set of users you should do something like this:

EM.run {
  users.each do |user|
    ws_logger.info "User##{user.id} started initialization"

    ws = Faye::WebSocket::Client.new('wss://www.bitmex.com/realtime')

    ws.on :open do
      # ... some code
      ws_logger.info "Socket started in ##{Thread.current.object_id}"
    end

    ws.on :message # ...
    ws.on :close # ...
  end
}

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

No branches or pull requests

2 participants