roadrunner-server / roadrunner

🤯 High-performance PHP application server, process manager written in Go and powered with plugins
https://docs.roadrunner.dev
MIT License
7.83k stars 407 forks source link

[💡 FEATURE REQUEST]: RR as a Caddy module #1120

Closed rustatian closed 1 year ago

rustatian commented 2 years ago

Plugin

No response

I have an idea!

Implement a RR as a Caddy module.

Draft notes: Implement a RoundTripper to have a RR as a Caddy transport (http). Since this is good for the HTTP, other plugins, such as rr-temporal or those, that don't use an HTTP as a transport can't be easily integrated (for example, the whole queues bundle (jobs, sqs, beanstalk, etc.), rr-temporal integration. So, basically, we should find a way to use the RR plugins inside the Caddy. OR: Just use a classic approach, like, reverse_proxy to the RR endpoint.


config:

{
    # the roadrunner app
    roadrunner {
        rpc tcp://127.0.0.1:6001 # remove ??
        server {
                        on_init: # Do we need that inside the Caddy ???
                        pool: # we need a pool config inside the server
                            debug: false
                            command php psr-worker.php
                            num_workers: 0
                            max_jobs: 64
                            allocate_timeout: 60s
                            destroy_timeout: 60s
                                supervisor:
                                    watch_tick: 1s
                                    ttl: 0s
                                    idle_ttl: 10s
                                    max_worker_memory: 128
                                    exec_ttl: 60s
        }
        ...
    }
}

app.example.com {
    root * /srv
    encode gzip
    mercure {
        ...
    }
    php_fastcgi roadrunner {
        transport roadrunner
    }
    file_server
}
  1. We can't use RR plugins (at least in the initial implementation), until we properly cover all plugin's functionality by tests.
  2. We should use a pool configuration inside the server section (this is not the same as the RR configuration server section).
  3. We don't need to use a roadrunner repository. I guess, we only need to use a RR SDK, especially: link
  4. I guess, we also don't need an RPC plugin, since we don't use RPC.

Part of the discussion is here: https://github.com/roadrunner-server/roadrunner/issues/917

mholt commented 2 years ago

Following. Let me know if you have any questions!

rustatian commented 1 year ago

Hey guys 👋🏻

I investigated the possibility of adding RR and the module to the Caddy web server, and unfortunately, this is not possible because RR will lose almost all its features. I mean, no Queues support, temporal, gRPC, etc. Using the fCGI/http2/h2c/http reverse proxy is better to pass the request to the RR.

mholt commented 1 year ago

@rustatian Are you sure? Why would it have to lose all its features?

francislavoie commented 1 year ago

@rustatian The suggestion was that it should run as an App Module, see https://caddyserver.com/docs/extending-caddy#app-modules. That would have Caddy start up RR as a dependency (i.e. the whole thing, not just one part), then you'd also have an HTTP handler module that would send the request through RR's pipeline.

rustatian commented 1 year ago

RR is a little bit more than an HTTP handler 😃 HTTP is only one of the various ways to deliver the payload. Others are: temporal server handlers, various jobs handlers (RPC): Kafka, rabbitmq, etc, gRPC handlers. Many of the plugins have their own RPC bridges (via our goridge protocol to communicate via IPC with PHP processes). So, as far as I understand, the Caddy server use case is for the HTTP(2,3,S) only? So, for example, if the user uses only RPC with, let's say, the SQS queue, there is no need for Caddy (for such users). And because of that reason, if we integrate an HTTP part of the RR into the Caddy, all other RR's features would be lost.

mholt commented 1 year ago

@rustatian

So, as far as I understand, the Caddy server use case is for the HTTP(2,3,S) only?

No, the HTTP server is itself just a plugin to Caddy. It's an app module. RR would probably be an app module as well, not just an HTTP handler.

For example, here's a layer4 (TCP/UDP) server for Caddy: https://github.com/mholt/caddy-l4

Don't limit yourself to just HTTP!

rustatian commented 1 year ago

I used the wrong terminology. Yeah, RR also has a TCP plugin. But by HTTP, I meant the whole transport layer (that was my mistake, I wanted to use fewer words).

Do you mean, that the app module can be fully independent with its own configuration, lifetime, http/grpc/tcp/temporal/jobs endpoints?

mholt commented 1 year ago

@rustatian

Do you mean, that the app module can be fully independent with its own configuration, lifetime, http/grpc/tcp/temporal/jobs endpoints?

Exactly. 🎯

Well, Caddy manages the config including reloads, but your app can manage state that persists through reloads, etc. It can definitely open its own sockets, etc.

francislavoie commented 1 year ago

I suggest you read through https://caddyserver.com/docs/architecture to get an idea of the architecture.

rustatian commented 1 year ago

Yeah, I saw this doc earlier, thanks @francislavoie.

I'll discuss this case with the team, but I'm worried about the use cases.

  1. Since we might have an independent module, users will send their payloads directly to the RR, bypassing the Caddy server. In this case, we will lose the advantages of the web-server.
  2. For the other cases, RR doesn't need a web server, since all communications are done via the gRCP directly to the RR (like Queues payloads, TCP, etc). Users architecture, in this case provides only a load balancer.

So, to have a nice integration for the Caddy web-server, would be nice to have a RR module, but not the app. In this case, users will benefit from the Caddy, but RR should be significantly reworked with only the HTTP PHP processes pool.