nginx-clojure / nginx-clojure

Nginx module for embedding Clojure or Java or Groovy programs, typically those Ring based handlers.

Home Page:http://nginx-clojure.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Achieve simple async tasks like reading from DB or local file or some local long running process

mcaap opened this issue · comments

commented

Hi,

Thanks for the nice library. We use it in production!
I have read the literature multiple times, but not sure how to achieve a simple async task.

NginxJavaRequest r = request;
		NginxHttpServerChannel channel = r.hijack(true);
		channel.addListener(channel, new ChannelCloseAdapter<NginxHttpServerChannel>() {
			@Override
			public void onClose(NginxHttpServerChannel serverChannel) throws IOException {
				logger.info("client closed");
			}
		});
		Thread t = new Thread() {
			@Override
			public void run() {
				logger.info("Run thread");
				try {
					Thread.sleep(5000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				logger.info("Done sleeping 5s");
				try {
					channel.sendResponse(new Object[] {200, ArrayMap.create("Content-Type", "text/plain"), "hello"});
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
		t.start();

You have mentioned co-routine & async channel/socket as two options.
I dont want to get into co-routine with wave configuration etc.
How do I achieve the above using async channel/socket?

  1. DB

If your DB has async client API it will be easy because you can call channel.sendResponse after you get result from the DB.

If your DB has HTTP or simple socket interface you can use async channel API from nginx-clojure, this is an example to read HTTP content from remote server (https://github.com/nginx-clojure/nginx-clojure/blob/master/test/java/nginx/clojure/net/SimpleHandler4TestNginxClojureAsynChannel.java)

and the doc can be found at #37

Otherwise you need to use thread , e.g, use thread pool created by yourself or use thread pool mode from nginx-clojure.

  1. Local File

It is quite simple because you can return a File object from you response, e.g.

return new Object[] {200, ArrayMap.create("content-type", "text/html"), new File("myfile.txt") }

or

channel.sendResponse(new Object[] {200, ArrayMap.create("Content-Type", "text/plain"), new File("myfile.txt") });

Then nginx will send the static file by non-blocking way.

commented

Thanks. And if I had to run some local shell script as part of the incoming request and send back the response after few seconds, will the channel api be the way to go or thread pool?

@mcaap
There are two kinds of channels: client channel and server channel. A server channel can be used to send message later. A client channel can be used to read/write message from/to the remote server.
A client channel can not be used to work with local shell script. For this case you can use server channel and thread pool created by your code. BTW for this case you can use thread pool mode from nginx-clojure too.

commented

Thank you for patiently answering my noob questions!