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

Falcon fails under websocket-bench #1

Open
jpcamara opened this issue Oct 2, 2024 · 8 comments
Open

Falcon fails under websocket-bench #1

jpcamara opened this issue Oct 2, 2024 · 8 comments

Comments

@jpcamara
Copy link

jpcamara commented Oct 2, 2024

Running falcon using

bundle exec bento --falcon

If you run websocket bench, it misses almost every broadcast:

./websocket-bench broadcast ws://localhost:8080/cable \
                --concurrent 8 \
                --sample-size 100 \
                --step-size 200 \
                --payload-padding 200 \
                --total-steps 10 \
                --origin http://0.0.0.0 \
                --server-type=actioncable
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:35-04:00] clients:   200    95per-rtt:   7ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   8ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:35-04:00] clients:   400    95per-rtt:   7ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   7ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:35-04:00] clients:   600    95per-rtt:   7ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   7ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:35-04:00] clients:   800    95per-rtt:   7ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   8ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:36-04:00] clients:  1000    95per-rtt:   8ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   8ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:36-04:00] clients:  1200    95per-rtt:   1ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   1ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:36-04:00] clients:  1400    95per-rtt:  13ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:  13ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:36-04:00] clients:  1600    95per-rtt:  17ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:  17ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:51:36-04:00] clients:  1800    95per-rtt:   1ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   1ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
Missing received broadcasts: expected 1100000, got 22982
[2024-10-01T22:51:38-04:00] clients:  2000    95per-rtt:   1ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt:   1ms

If you modify Async::Executor to run an async reactor in a separate thread, things get a little better:

module Async
    class Executor
      class Timer < Data.define(:task)
        def shutdown = task.stop
      end

      private attr_reader :semaphore

      def initialize(max_size: 10)
        # @semaphore = ::Async::Semaphore.new(max_size)
        @queue = Queue.new
        Thread.new do
          Async do
            loop do
              block = @queue.pop
              Async do
                block.call
              end
            end
          end
        end
      end

      def post(task = nil, &block)
        task ||= block
        # semaphore.async(&task)
        @queue.push(task)
      end

It takes longer to run (like a minute instead of the seconds everything else takes), but the numbers are better:

200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:52:47-04:00] clients:   200    95per-rtt:  82ms    min-rtt:   1ms    median-rtt:   1ms    max-rtt: 108ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:52:48-04:00] clients:   400    95per-rtt:   6ms    min-rtt:   1ms    median-rtt:   2ms    max-rtt:   6ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:52:51-04:00] clients:   600    95per-rtt:  10ms    min-rtt:   1ms    median-rtt:   2ms    max-rtt:  10ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:52:56-04:00] clients:   800    95per-rtt:  27ms    min-rtt:   1ms    median-rtt:   2ms    max-rtt:  27ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:53:02-04:00] clients:  1000    95per-rtt:  30ms    min-rtt:   1ms    median-rtt:   3ms    max-rtt:  31ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:53:10-04:00] clients:  1200    95per-rtt:  37ms    min-rtt:   1ms    median-rtt:   3ms    max-rtt:  37ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:53:20-04:00] clients:  1400    95per-rtt:  45ms    min-rtt:   1ms    median-rtt:   3ms    max-rtt:  65ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-10-01T22:53:35-04:00] clients:  1600    95per-rtt:  39ms    min-rtt:   1ms    median-rtt:   4ms    max-rtt:  39ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [-----------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 2302 p/s
[2024-10-01T22:53:48-04:00] clients:  1800    95per-rtt: 129ms    min-rtt:   1ms    median-rtt:   4ms    max-rtt: 129ms
200 / 200 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [-----------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 1382 p/s
Missing received broadcasts: expected 1100000, got 920988
[2024-10-01T22:54:07-04:00] clients:  2000    95per-rtt: 201ms    min-rtt:   1ms    median-rtt:   4ms    max-rtt: 201ms

Not saying this is correct per se, but definitely seem to be some issues with how it's currently setup. I'm still looking at it a bit as is @ioquatix but I wanted to post it here in the meantime.

@palkan
Copy link
Member

palkan commented Oct 4, 2024

Thanks for sharing!

Yeah, the Falcon version is not really optimized; it's just a reference implementation for Samuel to build a proper thing 🙂. My goal was only to make conformance tests pass.

@jpcamara
Copy link
Author

jpcamara commented Oct 8, 2024

Sounds good. Is there a sense of how much runway is left before this needs to be in and finalized?

@ioquatix
Copy link

ioquatix commented Oct 9, 2024

I haven't had a lot of time to look into this yet, but I will.

@jpcamara
Copy link
Author

jpcamara commented Oct 22, 2024

Circling back on this - I notice that the results also get better with no other changes than forking:

require "async/container"
class BenchmarkServer
  def self.run!
    container = Async::Container.new
    websocket_endpoint = Async::HTTP::Endpoint.parse("http://127.0.0.1:8080/cable").with(reuse_address: true)
    bound_endpoint = Sync { websocket_endpoint.bound }

    container.run(count: 32) do |instance|
      Async do |task|
        action_cable_server = ActionCable.server
        action_cable_server.instance_variable_set(:@executor, ActionCable::Async::Executor.new)

        app = Falcon::Server.middleware(ActionCable::Async::App.new(server: action_cable_server))
        server = Falcon::Server.new(app, bound_endpoint, protocol: websocket_endpoint.protocol, scheme: websocket_endpoint.scheme)

        server.run
        instance.ready!
        puts "Server is ready and listening on #{bound_endpoint.inspect}"

        task.children.each(&:wait)
      end
    end
  end
end

Which results in:

Missing received broadcasts: expected 1100000, got 693771
[2024-10-22T18:56:53-04:00] clients:  2000    95per-rtt:  89ms    min-rtt:   1ms    median-rtt:  19ms    max-rtt: 158ms

This doesn't seem like it should be necessary. But just more information to look at.

It should be based on processor count but this is a more accurate comparison with everything else since they're all forked by default. Still shouldn't be dropping requests, but it'll be more apples to apples once it's fully working.

@ioquatix
Copy link

I've been investigating the issues.

Puma also fails if you start it with a single process.

There is something odd about the benchmark. I don't know what yet, but I'll continue to investigate.

@ioquatix
Copy link

Okay, one issue is the ulimit -n - without ulimit -n 100000 (just a big number chosen arbitrarily), the test fails.

Using my current implementation of async-cable, I got these numbers:

Falcon

> PATH=websocket-bench/:$PATH make websocket-bench
websocket-bench broadcast ws://localhost:8080/cable \
	--concurrent 8 \
	--sample-size 100 \
	--step-size 200 \
	--payload-padding 200 \
	--total-steps 10 \
	--origin http://0.0.0.0 \
	--server-type=actioncable
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-11-18T14:09:22+13:00] clients:   200    95per-rtt:  10ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:  14ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 321 p/s
[2024-11-18T14:09:23+13:00] clients:   400    95per-rtt: 506ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt: 506ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 524 p/s
[2024-11-18T14:09:24+13:00] clients:   600    95per-rtt: 382ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt: 384ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 94 p/s
[2024-11-18T14:09:26+13:00] clients:   800    95per-rtt: 1244ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt: 1245ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-11-18T14:09:27+13:00] clients:  1000    95per-rtt:   2ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:   3ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-11-18T14:09:31+13:00] clients:  1200    95per-rtt:  12ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:  12ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 59 p/s
[2024-11-18T14:09:37+13:00] clients:  1400    95per-rtt: 1849ms    min-rtt:   0ms    median-rtt:   3ms    max-rtt: 1852ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-11-18T14:09:39+13:00] clients:  1600    95per-rtt:  15ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:  16ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
[2024-11-18T14:09:45+13:00] clients:  1800    95per-rtt:   4ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:   5ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% ? p/s
Missing received broadcasts: expected 1100000, got 916962
[2024-11-18T14:09:54+13:00] clients:  2000    95per-rtt:   2ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:   2ms

The number of broadcasts seems to fluctuate on every server I tested... is that expected?

Puma

> PATH=websocket-bench/:$PATH make websocket-bench
websocket-bench broadcast ws://localhost:8080/cable \
	--concurrent 8 \
	--sample-size 100 \
	--step-size 200 \
	--payload-padding 200 \
	--total-steps 10 \
	--origin http://0.0.0.0 \
	--server-type=actioncable
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 158 p/s
[2024-11-18T14:10:44+13:00] clients:   200    95per-rtt: 210ms    min-rtt:   1ms    median-rtt:  47ms    max-rtt: 417ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 68 p/s
[2024-11-18T14:10:46+13:00] clients:   400    95per-rtt: 123ms    min-rtt:   1ms    median-rtt:  71ms    max-rtt: 1672ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 40 p/s
[2024-11-18T14:10:49+13:00] clients:   600    95per-rtt: 183ms    min-rtt:   1ms    median-rtt: 132ms    max-rtt: 2727ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 31 p/s
[2024-11-18T14:10:53+13:00] clients:   800    95per-rtt: 236ms    min-rtt:   1ms    median-rtt: 167ms    max-rtt: 3478ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 21 p/s
[2024-11-18T14:10:58+13:00] clients:  1000    95per-rtt: 1597ms    min-rtt:   0ms    median-rtt: 231ms    max-rtt: 3993ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 16 p/s
[2024-11-18T14:11:05+13:00] clients:  1200    95per-rtt: 868ms    min-rtt:   1ms    median-rtt: 323ms    max-rtt: 2008ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 15 p/s
[2024-11-18T14:11:12+13:00] clients:  1400    95per-rtt: 973ms    min-rtt:   2ms    median-rtt: 347ms    max-rtt: 3774ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 13 p/s
[2024-11-18T14:11:20+13:00] clients:  1600    95per-rtt: 1172ms    min-rtt:   0ms    median-rtt: 419ms    max-rtt: 2208ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 11 p/s
[2024-11-18T14:11:30+13:00] clients:  1800    95per-rtt: 1166ms    min-rtt:   1ms    median-rtt: 565ms    max-rtt: 6412ms
200 / 200 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00%
100 / 100 [---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------] 100.00% 9 p/s
Missing received broadcasts: expected 1100000, got 1099991
[2024-11-18T14:11:43+13:00] clients:  2000    95per-rtt: 1367ms    min-rtt:   1ms    median-rtt: 736ms    max-rtt: 5066ms

Not sure if this is a fair comparison yet.

@ioquatix
Copy link

For both of these, I was running a single process for the server. In fact, I'm not sure it should matter that much, but I suppose for fairness, we should just use whatever is the default multi-process and max out all CPU cores (e.g. maximum connections/core).

@palkan
Copy link
Member

palkan commented Nov 25, 2024

The number of broadcasts seems to fluctuate on every server I tested... is that expected?

Maybe, some clients dropped during benchmark (though there must be some error logs in this case).

What looks more interesting is the difference between consecutive steps:

[2024-11-18T14:09:26+13:00] clients:   800    95per-rtt: 1244ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt: 1245ms
[2024-11-18T14:09:27+13:00] clients:  1000    95per-rtt:   2ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:   3ms
[2024-11-18T14:09:31+13:00] clients:  1200    95per-rtt:  12ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:  12ms
[2024-11-18T14:09:37+13:00] clients:  1400    95per-rtt: 1849ms    min-rtt:   0ms    median-rtt:   3ms    max-rtt: 1852ms
[2024-11-18T14:09:39+13:00] clients:  1600    95per-rtt:  15ms    min-rtt:   0ms    median-rtt:   1ms    max-rtt:  16ms

From ~1s to ~10ms 🤔

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

3 participants