treasure-data / serverengine

A framework to implement robust multiprocess servers like Unicorn
Apache License 2.0
756 stars 85 forks source link

Windows: Apply excluded port range to SocketManager #140

Closed daipom closed 1 year ago

daipom commented 1 year ago

On Windows, SocketManager selects an available port from the dynamic port range.

But shouldn't we need to exclude excludedportrange from this?

When I installed Docker for Windows, some ports are excluded as follows. This disables 49152 port, but SocketManager tries to bind 49152 and fails.

$ netsh int ipv4 show excludedportrange TCP
Protocol tcp Port Exclusion Ranges

Start Port    End Port
----------    --------
      5357        5357
     49152       49251
     50000       50059     *
     57095       57194
     64975       65074
     65075       65174
     65175       65274
     65275       65374
     65375       65474

* - Administered port exclusions.
2023-02-07 11:08:42 +0900 [info]: init supervisor logger path=nil rotate_age=nil rotate_size=nil
Unexpected error Permission denied - bind(2) for "127.0.0.1" port 49152
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/socket_manager_win.rb:113:in `initialize'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/socket_manager_win.rb:113:in `new'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/socket_manager_win.rb:113:in `start_server'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/socket_manager.rb:99:in `initialize'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/socket_manager.rb:92:in `new'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/socket_manager.rb:92:in `open'
  C:/Users/reang/Documents/work/fluentd/fluentd/lib/fluent/supervisor.rb:70:in `before_run'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/server.rb:125:in `main'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/daemon.rb:119:in `main'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/gems/serverengine-2.3.1/lib/serverengine/daemon.rb:68:in `run'
  C:/Users/reang/Documents/work/fluentd/fluentd/lib/fluent/supervisor.rb:902:in `supervise'
  C:/Users/reang/Documents/work/fluentd/fluentd/lib/fluent/supervisor.rb:742:in `run_supervisor'
  C:/Users/reang/Documents/work/fluentd/fluentd/lib/fluent/command/fluentd.rb:350:in `<top (required)>'
  C:/Users/reang/Documents/work/fluentd/fluentd/bin/fluentd:15:in `require'
  C:/Users/reang/Documents/work/fluentd/fluentd/bin/fluentd:15:in `<top (required)>'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/bin/fluentd:23:in `load'
  C:/Ruby26-x64/lib/ruby/gems/2.6.0/bin/fluentd:23:in `<main>'

I understand I can use the environmental variable SERVERENGINE_SOCKETMANAGER_PORT to avoid the excluded range.

If it looks like we should improve this feature, I will make a PR.

ashie commented 1 year ago

Ah, I've not been aware it. We need to fix it.

daipom commented 1 year ago

I create a PR #142 for now, but we need to discuss how to fix this more fundamentally.

ashie commented 1 year ago

We discussed about it in private chat.

For Fluentd, we should fix it more radically. For example:

Here is one of idea to fix it: https://github.com/fluent/fluentd/blob/a5bf404134f98f32c5cbcbc2f0989d9f88542853/lib/fluent/supervisor.rb#L69-L71

-        socket_manager_path = ServerEngine::SocketManager::Server.generate_path
-        ServerEngine::SocketManager::Server.open(socket_manager_path)
-        ENV['SERVERENGINE_SOCKETMANAGER_PATH'] = socket_manager_path.to_s
+       server = ServerEngine::SocketManager::Server.open
+       ENV['SERVERENGINE_SOCKETMANAGER_PATH'] =  server.path.to_s

(Modify ServerEngine::SocketManager::Server.open without argument to choose path or port automatically)

daipom commented 1 year ago

Thanks for the summary!

I will continue to work on that.