How does nginx_redis2_module achieve non-blocking operation? - nginx

I need a nginx server that receives HTTP request and sends back response from Redis-store and this should be non-blocking. After Googling and going through forums, i came across the nginx_redis2_module. I tried going through the code but was not able to understand how it works. How have they achieved non-blocking operation? Have they achieved this by adding events to nginx's event loop ? Is there any document or sample code how this is done ?
source : https://github.com/openresty/redis2-nginx-module

The essence of nginx is non blocking modules.
It is complex area.
Here you may found some starting points: how to write Nginx module?
FYI:
When used in conjunction with lua-nginx-module, it is recommended to
use the lua-resty-redis library instead of this module though, because
the former is much more flexible and memory-efficient.

Related

LDAP Proxy with inspection/modification of requests and responses

I need to build an LDAP proxy that I can program to inspect and modify the LDAP requests and responses - some of the LDAP requests/responses will simply be passed through, but for others I might want to send two different requests to the server and then combine the results (that's just one example - there will be other use cases).
I've looked at the proxying options documented for OpenLDAP's slapd, and I see that it has quite flexible configuration and 'overlays', but no capability to insert custom code.
So I think that's not a solution, unless slapd's source code is easy to modify, to insert my own modules plus hooks to/from the existing code (?)
An alternative would be to start with a friendly TCP/IP framework library (or even a complete TCP/IP proxy). Then I can link to an ASN.1 decoding/encoding library, and write the rest myself.
I'd prefer to avoid having to write (& learn) all the TCP/IP connection/message handling and event loop myself.
So I'm looking for the most complete starting point that does the hard work and gives me the flexibility to write what I need. Typical lazy/greedy approach :-)
Must be open source, ideally in C or C++, and I'll probably be targetting RHEL/CentOS 8 in a container.

Asynchronous HTTP(S) request in existing loop

I want to send a HTTPS request to a server but have a problem figuring out how. The best way for me to do it would be to initiate the request and regularly check back whether it has finished. How can I do this? It is even possible? What are the alternatives?
The best way to make asynchronous I/O is to use tokio.
You can find a example HTTP+TLS in doc : https://tokio.rs/docs/getting-started/tls/

Streaming stdout to a web page

This seems like it should be a really simple thing to achieve, unfortunately web development was never my strong point.
I have a bunch of scripts, and I would like to launch them from a webpage and see the realtime stdout text on the page. Some of the scripts take a long time to run so the normal single response isn't good enough (I have this working already).
As far as I can see, my options are
stdout to a file, and periodically (every couple of seconds) send a request from the client and respond with the contents of this file.
Chunked HTTP responses? I'm not sure if this is what they are used for- I tried to implement this already but I think I may be misunderstanding their purpose.
Websockets (I'm using a Luvit server so this isn't an option).
... Something else?
I'm sure there must be a standard way of achieving, I see other sites doing this all the time. Teamcity for example. Or chat rooms (vanilla TCP sockets?).
Any pointers in the right direction appreciated. Simplest method possible, if that's just sending lots of scheduled requests from the client then so be it.
That heavily reminds me of Common Gateway Interfaces.
Your own ideas sound all like the right direction. As you are using a shell script, and some potentially nontrivial interactions with the web server, I feel it could make sense to point out where to dig for examples of this kind of code, which was common a long time ago, and very error-prone, basically allways.
Practically, your script is a CGI script, doing typical things.
In the earlier days and years of the internet, that was the "normal way" to implement web page that are not just static files (HTML or others).
The page is basically implemented as a shell script (or any other programm reading from stdin and writing to stdout).
Part of what you are doing/proposing is very similar, and I think there are useful lessons to learn from old CGI code.
For example, getting buffering right with from inside the script over sdtout, whrough the web server onto the client's page can be tricky of course.
So digging out old examples could help a lot.
(Much of this may be obvious to you, the OP, personally, so take the "you" as potential reader)
The tricky part in general will be the buffering, I expect. If you are used to explicitly handling stdin/out buffers in shell, for programms that do not support it, the kind of things to expect can be imagined - but if not used to it: I remember CGI is worse, as you have to get the buffering of the HTTP server in sync too (let's hope it is handled automatically) - so maybe start to ask questions/dig for examples early.
The CGI style way would be exactly what you have implemented now - and it the buffering is right, that should be as real-time as it can get. But I understand that you get timeouts because of the long runtime? Or do you have strongly varying runtimes?
In terms of getting it as real-time as possible, there is nothing better than writing stdout to the http stream.
(I assume we accept the overhead of going through a HTTP server.)
Also, I'm thinking of line buffering, so not flushing every char - is that good enough for the use case? (i.e. no animated progress indicator lines/ ANSI escapes that you want to see in real time)
Then maybe the best is to work aroung the issues like timeouts, but to keep the concept. If real time is not that important, other ways may be better in many ways, of course. One point would be that other methods could be required for any scalability.

Does nginx block on long requests?

I've read a couple similar questions but haven't gotten the answer I'm looking for.
If Nginx is using an evented model, my understanding is that any work that happens in the event loop is blocking the event loop. So does it block, or does it use some other idea to avoid blocking the event loop if there's some slow request. Is it based on the idea that there are no slow requests in a typical http situation?

overhead of using local http calls

I'm developing a wrapper around an existent RESTful API. I basically have to do some preprocessing, calling the underlying API, and some preprocessing, with a little bit of cache in the middle. The API is specially designed for RESTful access via http.
My question is, should I refactor the API so I can invoke it via code, or should I make local http calls to it. This second option seems nice since it increases decoupling, but I'm afraid that creating the http requests / responses can seriously affect performance. I've heard though that couchDB does something like that (its api is RESTful and accessed via http).
No one can answer this for you, as it will depend hugely on how your current RESTful API is implemented. For example, you can write a relatively short C program that will listen on a socket and handle HTTP requests - if it does RESTful things in response to the different HTTP methods then it's an implementation of a RESTful API and can have very very little overhead over just calling the underlying functions directly (without HTTP). On the other hand, you can write your program as this bloated, heavy Java EE monster - in that case, the overhead may be quite large.
Thus, skaffman was correct to say "Measure it and see" - this really is the only way to get a meaningful answer.
All that said, if you are asking this question, odds are good that you're not really facing a Google-scale problem, so if the refactoring is going to be a lot of work and just intercepting HTTP requests is easy for you then I'd suggest you first get the functionality you need with the HTTP wrapper and only once you have a working product start worrying about performance optimization.
Look at section 5.1.6 in the REST Dissertation about layered systems. What you are actually describing fits very nicely into this idea of a layered architecture. Effectively you are building a HTTP proxy that will intercept the incoming requests, do some work and then and then pass it along to the next layer.
I'd refactor it. You used to have some set of functionality exposed by a RESTful API. You've now got a set of functionality exposed by a RESTful API and by your wrapper. You should refactor the code so that it can do both. It should be easy if your code is reasonably well organized.
When in doubt, err on the side of doing less work. Write the wrapper and test it. Refactor if you have to.

Resources