# Nginx Module Concurrency Query

**URL:** <https://www.ruby-forum.com/t/nginx-module-concurrency-query/208975>\
**Category:** NGINX\
**Created:** [July 1, 2011, 3:40pm UTC](https://www.ruby-forum.com/t/nginx-module-concurrency-query/208975 "2011-07-01T15:40:45Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![luislavena](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/0ea827/32.png) [@luislavena](https://www.ruby-forum.com/u/luislavena)\
**Post date:** [July 1, 2011, 3:40pm UTC](https://www.ruby-forum.com/t/nginx-module-concurrency-query/208975/1 "2011-07-01T15:40:45Z")

</div>

Hello,

I have been trying to get a simple nginx\_module working. I referred  
[Emiller’s Guide to Nginx Module Development – Evan Miller](http://www.evanmiller.org/nginx-modules-guide.html) and found it very  
useful.

The module takes “[http://10.90.50.31:1257/hello?w=lelj&ljd=22112](http://10.90.50.31:1257/hello?w=lelj&ljd=22112)” and  
sleeps for few sec and simply prints the URI.

## Here is the code :-

#include \<ngx\_config.h\>  
#include \<ngx\_core.h\>  
#include \<ngx\_http.h\>  
#include \<unistd.h\>

static char \*ngx\_http\_hello\_world(ngx\_conf\_t \*cf, ngx\_command\_t \*cmd,  
void \*conf);

static ngx\_command\_t ngx\_http\_hello\_world\_commands[] = {

{ ngx\_string(“hello\_world”),  
NGX\_HTTP\_LOC\_CONF|NGX\_CONF\_NOARGS,  
ngx\_http\_hello\_world,  
0,  
0,  
NULL },

```
ngx_null_command

```

};

//static u\_char ngx\_hello\_world[] = “elcome world”;

static ngx\_http\_module\_t ngx\_http\_hello\_world\_module\_ctx = {  
NULL, /\* preconfiguration _/  
NULL, /_ postconfiguration \*/

NULL, /\* create main configuration _/  
NULL, /_ init main configuration \*/

NULL, /\* create server configuration _/  
NULL, /_ merge server configuration \*/

NULL, /\* create location configuration _/  
NULL /_ merge location configuration \*/  
};

ngx\_module\_t ngx\_http\_hello\_world\_module = {  
NGX\_MODULE\_V1,  
&ngx\_http\_hello\_world\_module\_ctx, /\* module context _/  
ngx\_http\_hello\_world\_commands, /_ module directives _/  
NGX\_HTTP\_MODULE, /_ module type _/  
NULL, /_ init master _/  
NULL, /_ init module _/  
NULL, /_ init process _/  
NULL, /_ init thread _/  
NULL, /_ exit thread _/  
NULL, /_ exit process _/  
NULL, /_ exit master \*/  
NGX\_MODULE\_V1\_PADDING  
};

int sum(int a, int b)  
{  
return a+b;  
}

static ngx\_int\_t ngx\_http\_hello\_world\_handler(ngx\_http\_request\_t \*r)  
{  
ngx\_buf\_t \*b;  
ngx\_chain\_t out;

r-\>headers\_out.content\_type.len = sizeof(“text/html”) - 1;  
r-\>headers\_out.content\_type.data = (u\_char \*) “text/html”;

b = ngx\_pcalloc(r-\>pool, sizeof(ngx\_buf\_t));

out.buf = b;  
out.next = NULL;

b-\>pos = (r-\>args).data;  
b-\>last = (r-\>args).data + (r-\>args).len;  
b-\>memory = 1;  
b-\>last\_buf = 1;

usleep(1500000);

r-\>headers\_out.status = NGX\_HTTP\_OK;  
r-\>headers\_out.content\_length\_n = (r-\>args).len;  
ngx\_http\_send\_header(r);

return ngx\_http\_output\_filter(r, &out);  
}

static char \*ngx\_http\_hello\_world(ngx\_conf\_t \*cf, ngx\_command\_t \*cmd,  
void \*conf)  
{  
ngx\_http\_core\_loc\_conf\_t \*clcf;

clcf = ngx\_http\_conf\_get\_module\_loc\_conf(cf, ngx\_http\_core\_module);  
clcf-\>handler = ngx\_http\_hello\_world\_handler;

## return NGX\_CONF\_OK; }

nginx.conf  
###########  
worker\_processes 4;  
events {  
worker\_connections 1024;  
}  
… # … #

```
            location = /hello {
                    hello_world ;
            }

```

#########

But I guess, I am missing something here.

I tried ab (Apache benchmarking) on it, and I found that response time  
degrades on increasing concurrency.

# ab -c 10 -n 100 “[http://10.90.50.31:1257/hello?w=lelj&ljd=22112](http://10.90.50.31:1257/hello?w=lelj&ljd=22112)”

…  
Time per request: 3804.810 [ms] (mean)  
…

# ab -c 20 -n 100 “[http://10.90.50.31:1257/hello?w=lelj&ljd=22112](http://10.90.50.31:1257/hello?w=lelj&ljd=22112)”

…  
Time per request: 7587.228 [ms] (mean)  
…

# ab -c 30 -n 100 “[http://10.90.50.31:1257/hello?w=lelj&ljd=22112](http://10.90.50.31:1257/hello?w=lelj&ljd=22112)”

…  
Time per request: 11376.207 [ms] (mean)  
…

The response time was 11376ms, 7587ms, 3804ms for 30, 20, 10 concurrency  
respectively.  
I am not sure what I am missing.

Can someone please guide me on how do I make this module scale?

- Danny

Posted at Nginx Forum:

> **[Nginx Module Concurrency Query](https://forum.nginx.org/read.php?2,211552,211552#msg-211552)**
>
> Hello, I have been trying to get a simple nginx\_module working. I referred http://www.evanmiller.org/nginx-modules-guide.html and found it very useful. The module takes "http://10.90.50.31:1257/hello?w=lelj&ljd=22112" and sleeps for few...

---

<div class="post-metadata">

**Author:** ![Danny\_Glover](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3bc359/32.png) [@Danny\_Glover](https://www.ruby-forum.com/u/Danny_Glover)\
**Post date:** [July 1, 2011, 4:08pm UTC](https://www.ruby-forum.com/t/nginx-module-concurrency-query/208975/2 "2011-07-01T16:08:33Z")

</div>

Hello!

On Fri, Jul 01, 2011 at 09:40:20AM -0400, Danny Glover wrote:

> I have been trying to get a simple nginx\_module working. I referred  
> [Emiller’s Guide to Nginx Module Development – Evan Miller](http://www.evanmiller.org/nginx-modules-guide.html) and found it very  
> useful.
> 
> The module takes “[http://10.90.50.31:1257/hello?w=lelj&ljd=22112](http://10.90.50.31:1257/hello?w=lelj&ljd=22112)” and  
> sleeps for few sec and simply prints the URI.
> 
> Here is the code :-

[…]

> usleep(1500000);

[…]

> The response time was 11376ms, 7587ms, 3804ms for 30, 20, 10 concurrency  
> respectively.  
> I am not sure what I am missing.
> 
> Can someone please guide me on how do I make this module scale?

The behaviour you see is expected: you can’t sleep as it will  
block all requests in a worker process. Welcome to event-based  
programming. 🙂

You have to arm timer and return back to event loop, then continue  
processing once event fires. You may take a look how to do this  
in standard limit\_req module, though it will require some adaption  
for handler module. In particular, you’ll have to return NGX\_DONE  
and then finalize request yourself, much like it’s done when  
reading request body.

Maxim D.

---

<div class="post-metadata">

**Author:** ![Danny\_Glover](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/d/3bc359/32.png) [@Danny\_Glover](https://www.ruby-forum.com/u/Danny_Glover)\
**Post date:** [July 5, 2011, 9:29am UTC](https://www.ruby-forum.com/t/nginx-module-concurrency-query/208975/3 "2011-07-05T09:29:47Z")

</div>

Hi Maxim,

Thank you for the details.  
I will read through.

- Danny

Posted at Nginx Forum:

> **[Re: Nginx Module Concurrency Query](https://forum.nginx.org/read.php?2,211552,211950#msg-211950)**
>
> Hello, I have been trying to get a simple nginx\_module working. I referred http://www.evanmiller.org/nginx-modules-guide.html and found it very useful. The module takes "http://10.90.50.31:1257/hello?w=lelj&ljd=22112" and sleeps for few...
