The Python support is not good! In theory you just write a WSGI app, and it will work under a FastCGI wrapper.
But I had to revive the old "flup" wrapper, since Dreamhost has Python 2. I downloaded an older tarball and build it myself.
Use case: I parse thousands of shell scripts on every release and upload the results as a ".wwz" file, which is just a zip file served by a FastCGI script.
https://www.oilshell.org/release/0.8.1/test/wild.wwz/
So whenever there's a URL with .wwz in it, you're hitting a FastCGI script!
This technique makes backing up a website a lot easier, as you can sync a single 50 MB zip file, rather than 10,000 tiny files, which takes forever to stat() the file system metadata.
It's more rsync-friendly, in other words.
I also use it for logs in my continuous build: http://travis-ci.oilshell.org/jobs/
-----
Does anyone know of any other web hosts that support FastCGI well? I like having my site portable and host independent. I think FastCGI is a good open standard for dynamic content, and it works well on shared hosting (which has a lot of the benefits of the cloud, and not many of the downsides).
I keep wishing we had webhosts that supported WSGI as 'shared hosting' with all the other benefits of a shared webhost.
It works on Dreamhost, but it takes some effort.
FastCGI provides that but the Python libraries are not that well documented, and sometimes unmaintained. For some reason this appears to be a "cultural" thing and not a technical issue.
I wrote a whole bunch of comments about my plans to work on that here (andyc):
https://lobste.rs/s/xl63ah/fastcgi_forgotten_treasure#c_65gp...
I'm probably going to share my .wwz Python WSGI/FastCGI script. And show the hacks I did to deploy it on Dreamhost.
Long term I want to build FastCGI support into https://www.oilshell.org/ so the same problem doesn't exist there! i.e. the fact that you CAN deploy Python on many shared hosts, but nobody does because the ecosystem doesn't support it. Whereas the PHP ecosystem does support it, but the language is hard to learn.
I believe Dreamhost is the only larger host that does so. But there are a few that support WSGI directly either via mod_wsgi or uWSGI.
I contemplated using nodejs or something else, but the ability to bang out a script that answers on a URL on nginx is so much easier, python or otherwise.
This was not nostalgia either : the reason for doing that is because I was writing webapps for my pinephone. Toying with the phone, I decided I wanted my apps to be webapps rather than GTK apps, so that I can access them either from mobile or laptop (through local network), but I didn't want to have the apps running all the time, in order for them to consume less energy (which directly translates to battery lifetime on a mobile). Turns out that CGI is perfect for that : the only process always running are nginx and fcgiwrap, then all my apps are started only on demand, for the lifetime of the request.
I did expect a big performance hit, but I was surprised it was not so bad. I guess that's because they are C app rather than written in languages which require loading an interpreter before running anything. One app that I rewrote from libmicrohttpd had actually better perfs (although it was the first time I used libmicrohttpd, so it was probably something I didn't do correctly).
This is a really nice idea. It almost makes me wish browsers could just make a local CGI request directly, without a webserver at all. A quick search turns up an extension for ye olde Firefox: https://github.com/RufusHamade/lcgi. I suppose with native messaging APIs it's probably possible with new extension APIs too, if a bit more convoluted.
Isn't this what most people use their phone for? What exactly are you compromising on in this list? You might as well say you just need a fully-functional smartphone, not a hacking project.
I don't remember if there was any other option on the server we had, but I had to write that sucker in C! Reading and parsing a .csv file, handling search options, working as a CGI program, what a pain, especially for a dumb high schooler like me!
Although, now that I understand fastcgi better, I guess fcgiwrap could be adapted for lighttpd, if it doesn't work for it as is (my package manager's description mentions explicitly it's for nginx).
Thanks for the advice, I'll dig that.
The thing that fastcgi brought over cgi-bin was that an application process could be left open to communicate with the server, where-as cgi-bin model required spawning a new process for each request.
If one reads the AWS Lambda docs, they'll see the execution context[1] has a similar behavior. AWS will spin up new instances, but these instances will serve multiple requests, via a fairly custom "function" interface defined for various runtimes (but which is actually, typically an http interface). There is a standard HTTP api for runtimes to use to retrieve function invocations[2].
With FastCGI the front end server uses a socket to push request messages to app servers, which replies in order. Where-as with Lambda & it's above mentioned runtime API, the runtime is retrieving requests from Amazon at it's pacing, & fulfilling them as it can. So there's a push vs pull model, but in both cases, the application server is talking a fairly custom protocol to the front-end server.
Also though, there are some cgi-bin like behaviors seen in some serverless systems. Serverless is a big umbrella with a lot of different implementation strategies. One optimization is use of checkpoint-restore. With checkpoint restore, an app server is brought up to a "ready to serve" state, then the host operating system takes a "snapshot" of the process. When new instances of the process are needed, the serverless system can "restore" this memory mapped process & the resources it was using, bringing it up in a ready-to-serve state quickly. This behavior is more cgi-bin like, in that it's a technique for spawning new serving processes quickly, although few serverless systems go as far as cgi-bin went with a per-request process. None-the-less, openwhisk for example has was showing off start times decreasing from 0.9-0.5s for node, python, java app servers down to .09s-0.7s startup times using these checkpoint restore capabilities of the OS.
[1] https://docs.aws.amazon.com/lambda/latest/dg/runtimes-contex...
[2] https://docs.aws.amazon.com/en_us/lambda/latest/dg/runtimes-...
[3] https://events19.linuxfoundation.org/wp-content/uploads/2017...
> The thing that fastcgi brought over cgi-bin was that an application process could be left open to communicate with the server, where-as cgi-bin model required spawning a new process for each request.
Absolutely (I read/skimmed the article, and this was brought up) -- serverless functions are the same here, because it also allows for machines to stay running for some indefinite
> If one reads the AWS Lambda docs, they'll see the execution context[1] has a similar behavior. AWS will spin up new instances, but these instances will serve multiple requests, via a fairly custom "function" interface defined for various runtimes (but which is actually, typically an http interface). There is a standard HTTP api for runtimes to use to retrieve function invocations[2].
> With FastCGI the front end server uses a socket to push request messages to app servers, which replies in order. Where-as with Lambda & it's above mentioned runtime API, the runtime is retrieving requests from Amazon at it's pacing, & fulfilling them as it can. So there's a push vs pull model, but in both cases, the application server is talking a fairly custom protocol to the front-end server.
This is one of the reasons I said "serverless functions" instead of Lambda. While AWS happens to specify their operational semantics that way, there is no need for anyone else to. While improvements are necessary I still think this is fairly close to FCGI, and FCGI could absolutely serve as a "serverless" provider implementation.
Needless to say, how long you keep around the process, or how you checkpoint restore (criu[1] is very interesting, for anyone who's never seen it) and move processes are all implementation-specific in my mind.
[0]: https://gitlab.com/mrman/talks/raw/master/dist/2019/04/merca...
Edit: oh lol, this was written in 2002, alright, that confirms that.
hard disagree, but I'd love to learn more of the things that PHP is good at when compared to other frameworks and languages. Rails & Django are the frameworks to beat in terms of completeness and productivity, Flask/Sinatra for python/ruby flavored micro frameworks, NodeJS for massive concurrency and parallelism (Node does support threads as well as subprocesses) and large (sometimes sketchy) ecosystem and ease of contributions. There are the compiled languages as well with various advantages -- single binary deploy, speed, error avoidance with compile time type declaration/inference, etc.
What does modern PHP and a framework (like Laravel? what is popular in the space these days?) do better than it's contemporaries do? IIRC HHVM which seemed to be a bright spot (?) was abandoned by FB... Would love to hear about PHP's bright spots from a PHP enthusiast.
HHVM as you mentioned lost momentum when PHP7 largely met or surpassed its performance. That’s not a bad thing though, it just wasn’t hugely necessary anymore. The major upside is everyone gets the boost now, whereas HHVM was a nightmare to setup if you were not Facebook.
Beyond that, I truly believe the stateless nature of PHP requests is by far the easiest mental model to work with. As cross-request state is held exclusively and explicitly elsewhere (Redis, Memcache, SQL), it’s remarkably easy to reason about at scale.
This makes it easy to scale! Just throw another server on the load balancer and everything works. I work on a relatively large educational product, and we auto-balance up to 30+ servers during the week to handle a couple million users sending continuous streams of data, down to a minimum of 2 on weekends. It’s taken almost no consideration on the developers parts because of PHPs naturally stateless clean slate per page load model.
We also have a fair bit of Go in production, largely for CPU intensive operations. I love Go and use it for the majority of my newer personal projects. The major advantage to PHP that keeps it our primary language is the speed at which I can develop and iterate. The difference save/refresh vs save/recompile/restart/refresh makes in speed is not to be underestimated.
Myself as well as our lead dev have been using Go since before 1.x and we both still agree that PHP is better for rapid prototyping as well as just generally getting things out the door quickly.
https://golang.org/pkg/net/http/fcgi/
Underlying code:
https://golang.org/src/net/http/fcgi/
Edit:
They also link to a 'unofficial' spec they referenced it seems https://fast-cgi.github.io/
Or if you're running PHP, this shortcut usually does the right thing: https://caddyserver.com/docs/caddyfile/directives/php_fastcg...
This server isn't directly exposed, only valid requests are proxied to it.
I have no reason to think this is the best approach, it's a near forgotten foundational layer of an application that has been stable and reliable for a decade, that is under constant attack and regularly pen-tested.
1. Configure webserver (apache, lighttpd, etc) to forward certain routes to a particular unix socket (i.e. `/tmp/fcgi.sock`)
2. Create and launch a C/C++ process that links in libfcgi.so (or similar) and has an event loop reading from the same socket (i.e. `/tmp/fcgi.sock`)
After that the webserver will forward incoming requests that match to the C/C++ process over socket.
where you will be able to find FastCGI Developer's Kit sources and documentations
In the late 90s I used FastCGI with Perl to basically do everything... personal sites, the local Lee Newspaper, even a math expert system funded by a NSF grant that interfaced with MatLab. Nowadays, http server extensions and cloud services easily match FastCGI performance, while providing many scaling and logging and denial of service protections and features built in. It's hard to argue for FastCGI anymore, but everyone wants to reinvent the wheel, and some of those wheels are nice. Who needs EDI when we have SOAP? Who needs either when we have REST.
You also have less control over buffering and since you don't see the actual connection, you have to rely on special headers to get things like remote ip and remote protocol. Not a big deal, but still nice.
[1]: https://en.wikipedia.org/wiki/Simple_Common_Gateway_Interfac...
It wasn't as fast as something like mod_perl [1], but much easier to integrate with quickly hacked scripts, as long as you were lexically scoping everything with my() and not screwing up your globals. Fun times.
Wprth mentioning that Openbsd does have fastcgi support in it's httpd server, but only supports the responder role
> Kapow! is being developed by BBVA-Labs Security team members.
BBVA is one of Spain's/the world's largest banks.
Performance-wise I don't know how it would compare to other options, but I think it's a great way to expose C/C++ code to the web.
Or how about using http/2 for multiplexing?
One advantage of FastCGI is that it's inherently easy to scale horizontally and load balance because it basically forces the apps to have no state. This is one of the big benefits that PHP happens to have for that reason.
fastcgi applications can "scale to 0" and cost nothing when they are not used. An application server must always have at least one open socket on a running machine.
fastcgi would probably do better over http/2 than other protocols not designed for multiplexing.
https://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html https://tomcat.apache.org/connectors-doc/miscellaneous/faq.h...
But that said, I do use https://reactphp.org/ occasionally for certain types of tasks (like running a websocket server) and that works great too, but it takes extra care to make sure not to use blocking IO and to take more care of memory management.
Apache's FastCGI support was atrocious until mod_proxy_fcgi arrived only a few years ago. This severely limited FastCGI adoption in Apache territory. But sometime in the mid-00s lighttpd came along, and then nginx. Both of them not only supported but required FastCGI to interface with PHP. So the lighttpd guys developed spawn-fcgi, which was a huge step ahead of Apache's mod_fastcgi/mod_fcgid. With the increasing popularity of nginx, PHP itself adopted FPM (FastCGI Process Manager), which went yet another step ahead of spawn-fcgi. The performance gains were unbelievable! That was sometime between 2006 and 2008 IIRC, just when PHP was starting to clean up after itself.
PHP-FPM is now the preferred way to run PHP no matter what webserver you use (perhaps with the exception of IIS). It keeps things running fast and smooth without giving up PHP's straightforward, CGI-like execution model.
Some fcgi libraries may convert the headers into Env Vars to make it "easier" for code, but it is not strictly necessary.
For example, the HTTP header Proxy may be converted to "HTTP_PROXY" and some application servers may interpret it as the environment variable HTTP_PROXY (I seem to remember HHVM did it). Good servers have measures in place to handle that header, but it can bite you if you are implementing a new server.
oh, whoops.
Does anyone know how FastCGI compares to performance with fast VM languages that self host like Go, C#, Java? I remember it being fast compared to CGI with Perl... But thats a pretty low bar
HTTP/2 and newer are basically the same.