roadrunner icon indicating copy to clipboard operation
roadrunner copied to clipboard

[💡 FEATURE REQUEST]: upgrade TCP plugin

Open roxblnfk opened this issue 3 years ago • 3 comments

Plugin

TCP

I have an idea!

I think the TCP plugin needs to be reworked.

The way the RR-TCP plugin works now: RR cuts off data by separator and sends it to different workers. This approach works well when writing an SMTP server, but it's not enough for a true TCP server. For example we can't handle HTTP protocol, binary protocol or any custom protocol.


I propose to make the plugin so that a PHP-worker works with RR-TCP-plugin like with a stream.

When RR accepts a connection from a user, it tells the free PHP worker about it and attaches the connection to it.

The worker in this case can:

  • ask how many bytes to read
    • with specifying the max length
    • with specifying the separator
    • with specifying the min length (for blocking reading mode)
  • which data to write (using a buffer or with an immediate error if the connection is not ready to write)
  • when to pass the connection to another worker (detach the worker from the connection)
  • when to disconnect the client

roxblnfk avatar Jan 13 '22 12:01 roxblnfk

Hey @roxblnfk 😃

For example we can't handle HTTP protocol, binary protocol, or any custom protocol.

Actually, you can easily handle HTTP or any binary protocol, since they have delimiters that you can specify in the configuration. From the practical POV, there is no sense to handle an http frame via this plugin since we have a dedicated HTTP plugin.

When RR accepts a connection from a user, it tells the free PHP worker about it and attaches the connection to it

RR can't bind a worker to a connection, because in the case of 1000 simultaneous connections you'll have 1000 workers. Imagine, all of them occupy a minimum of 25MB RSS memory...then you should have 25GB of RAM (minimum) to handle a 1000 connection. Thus, we have a pool of workers and don't bind connections in such way.

ask how many bytes to read with specifying the max length with specifying the separator with specifying the min length (for blocking reading mode)

What you're saying here, is an addition to the existing commands. So, not READ like in the existing implementation, but READ 10 bytes, READ 10 bytes WITH '/n'.

Also, I'm not sure, what's true TCP server ?

rustatian avatar Jan 13 '22 20:01 rustatian

Actually, you can easily handle HTTP or any binary protocol, since they have delimiters that you can specify in the configuration.

Could you provide examples of configs for handling HTTP requests and packages from the Goridge plugin?

From the practical POV, there is no sense to handle an http frame via this plugin since we have a dedicated HTTP plugin.

The TCP plugin can provide more flexible handling of the HTTP protocol. It just needs to be refined.

RR can't bind a worker to a connection, because in the case of 1000 simultaneous connections you'll have 1000 workers. Imagine, all of them occupy a minimum of 25MB RSS memory...then you should have 25GB of RAM (minimum) to handle a 1000 connection. Thus, we have a pool of workers and don't bind connections in such way.

I'm sure that RR has a queuing mechanism and there is no need to create a separate worker for each request. It is enough to have several workers and a functioning pool.

roxblnfk avatar Jan 14 '22 14:01 roxblnfk

packages from the Goridge plugin

Goridge3 protocol behaves more like TCP/IP itself so, to handle transport protocols, we need to have the second part of your proposal - additional command (to read a particular number of bytes for example), there is no problem to extend existing commands. To handle application protocols, like HTTP it's enough to know the frames delimiter, in the case of HTTP it's CLRF (also you'll need to implement 2616 RFC)

From your proposal, If I understand correctly, we need to add additional commands to the existing set, they are:

  1. ask how many bytes to read
  2. how many bytes to read with specifying the max length
  3. how many bytes to read with specifying the separator
  4. ask how many bytes to read with specifying the min length
  5. which data to write (using a buffer or with an immediate error if the connection is not ready to write) - what type of buffer do you mean?
  6. when to disconnect the client -> CLOSEcommand, already exists.

when to pass the connection to another worker (detach the worker from the connection) The worker is not attached to the connection, so, there is nothing to detach.

rustatian avatar Jan 14 '22 19:01 rustatian

Since no one commented on this and there is no clarification on what particular protocols needs to be handled, closing the FR. Discussion is not closed anyway, so, feel free to create a new ticket or comment here.

rustatian avatar Mar 24 '23 01:03 rustatian