Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

A fragment of the spawning mechanism has been rewritten. This new

version ought to behave better under high load.


git-svn-id: svn://cherokee-project.com/cherokee/trunk@3551 5dc97367-97f1-0310-9951-d761b3857238
  • Loading branch information...
commit 83990a07ebd6b464cdf118e59949baf3728342f2 1 parent a5017ea
@alobbs alobbs authored
View
4 cherokee/handler_fcgi.c
@@ -299,7 +299,6 @@ cherokee_handler_fcgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_
n->post_phase = fcgi_post_init;
n->post_len = 0;
n->src_ref = NULL;
- n->spawned = 0;
cherokee_socket_init (&n->socket);
cherokee_buffer_init (&n->write_buffer);
@@ -543,8 +542,7 @@ connect_to_server (cherokee_handler_fcgi_t *hdl)
}
} else {
ret = cherokee_source_interpreter_connect_polling (SOURCE_INT(hdl->src_ref),
- &hdl->socket, conn,
- &hdl->spawned);
+ &hdl->socket, conn);
}
return ret;
View
1  cherokee/handler_fcgi.h
@@ -46,7 +46,6 @@ typedef enum {
typedef struct {
cherokee_handler_cgi_base_t base;
cherokee_source_t *src_ref;
- time_t spawned;
cherokee_socket_t socket;
cherokee_handler_fcgi_post_t post_phase;
off_t post_len;
View
4 cherokee/handler_scgi.c
@@ -193,7 +193,6 @@ cherokee_handler_scgi_new (cherokee_handler_t **hdl, void *cnt, cherokee_module_
/* Properties
*/
n->post_len = 0;
- n->spawned = 0;
n->src_ref = NULL;
cherokee_buffer_init (&n->header);
@@ -289,8 +288,7 @@ connect_to_server (cherokee_handler_scgi_t *hdl)
}
} else {
ret = cherokee_source_interpreter_connect_polling (SOURCE_INT(hdl->src_ref),
- &hdl->socket, conn,
- &hdl->spawned);
+ &hdl->socket, conn);
}
return ret;
View
1  cherokee/handler_scgi.h
@@ -47,7 +47,6 @@ typedef struct {
cherokee_buffer_t header;
cherokee_socket_t socket;
cherokee_source_t *src_ref;
- time_t spawned;
off_t post_len;
} cherokee_handler_scgi_t;
View
3  cherokee/source.c
@@ -83,8 +83,9 @@ cherokee_source_connect (cherokee_source_t *src, cherokee_socket_t *sock)
/* Get required objects
*/
ret = cherokee_resolv_cache_get_default (&resolv);
- if (unlikely (ret!=ret_ok))
+ if (unlikely (ret!=ret_ok)) {
return ret;
+ }
/* UNIX socket
*/
View
153 cherokee/source_interpreter.c
@@ -37,12 +37,13 @@
#define ENTRIES "source,src,interpreter"
-#define DEFAULT_TIMEOUT 10
-#define GRNAM_BUF_LEN 8192
-#define SPAWNING_GRACE_TIME 5
+#define DEFAULT_TIMEOUT 10
+#define GRNAM_BUF_LEN 8192
static void interpreter_free (void *src);
+#define source_is_unresponsive(src) \
+ (cherokee_bogonow_now > (src)->spawning_since + (src)->timeout)
ret_t
cherokee_source_interpreter_new (cherokee_source_interpreter_t **src)
@@ -62,7 +63,8 @@ cherokee_source_interpreter_new (cherokee_source_interpreter_t **src)
n->change_user = -1;
n->change_group = -1;
n->spawn_type = spawn_unknown;
- n->last_spawn = cherokee_bogonow_now - (SPAWNING_GRACE_TIME + 1);
+ n->spawning_since = 0;
+ n->last_connect = 0;
SOURCE(n)->type = source_interpreter;
SOURCE(n)->free = (cherokee_func_free_t)interpreter_free;
@@ -536,12 +538,6 @@ cherokee_source_interpreter_spawn (cherokee_source_interpreter_t *src,
return ret_not_found;
}
- /* Check grace time
- */
- if ((src->last_spawn + SPAWNING_GRACE_TIME) < cherokee_bogonow_now) {
- return ret_ok;
- }
-
/* Try with SHM first
*/
#ifdef HAVE_POSIX_SHM
@@ -551,10 +547,9 @@ cherokee_source_interpreter_spawn (cherokee_source_interpreter_t *src,
ret = _spawn_shm (src, logger);
if (ret == ret_ok) {
if (src->spawn_type == spawn_unknown) {
- src->spawn_type == spawn_shm;
+ src->spawn_type = spawn_shm;
}
- src->last_spawn = cherokee_bogonow_now + SPAWNING_GRACE_TIME;
return ret_ok;
} else if (ret == ret_eagain) {
@@ -569,7 +564,7 @@ cherokee_source_interpreter_spawn (cherokee_source_interpreter_t *src,
/* No luck, go 'local' then..
*/
if (src->spawn_type == spawn_unknown) {
- src->spawn_type == spawn_local;
+ src->spawn_type = spawn_local;
}
ret = _spawn_local (src, logger);
@@ -577,7 +572,6 @@ cherokee_source_interpreter_spawn (cherokee_source_interpreter_t *src,
return ret;
}
- src->last_spawn = cherokee_bogonow_now + SPAWNING_GRACE_TIME;
return ret_ok;
}
@@ -585,99 +579,118 @@ cherokee_source_interpreter_spawn (cherokee_source_interpreter_t *src,
ret_t
cherokee_source_interpreter_connect_polling (cherokee_source_interpreter_t *src,
cherokee_socket_t *socket,
- cherokee_connection_t *conn,
- time_t *spawned)
+ cherokee_connection_t *conn)
{
+ int re;
ret_t ret;
-
- /* Try to connect
+ int unlocked;
+ int kill_prev;
+
+ /* Connect
*/
ret = cherokee_source_connect (SOURCE(src), socket);
switch (ret) {
case ret_ok:
+ /* connected */
+ if (src->spawning_since != 0) {
+ src->spawning_since = 0;
+ }
+ src->last_connect = cherokee_bogonow_now;
TRACE (ENTRIES, "Connected successfully fd=%d\n", socket->socket);
- goto out;
- case ret_deny:
- /* The connection has been refused:
- * Close the socket and try again.
- */
- TRACE (ENTRIES, "Connection refused (closing fd=%d)\n", socket->socket);
- cherokee_socket_close (socket);
- break;
+ return ret_ok;
+
case ret_eagain:
+ /* wait for the fd */
ret = cherokee_thread_deactive_to_polling (CONN_THREAD(conn),
- conn,
- SOCKET_FD(socket),
- FDPOLL_MODE_WRITE,
- false);
+ conn, SOCKET_FD(socket),
+ FDPOLL_MODE_WRITE, false);
if (ret != ret_ok) {
- ret = ret_deny;
- goto out;
+ return ret_error;
}
-
- /* Leave the mutex locked */
return ret_eagain;
+
+ case ret_deny:
case ret_error:
- ret = ret_error;
- goto out;
- default:
+ /* reset by peer: spawn process? */
+ TRACE (ENTRIES, "Connection refused (closing fd=%d)\n", socket->socket);
+ cherokee_socket_close (socket);
break;
+
+ default:
+ cherokee_socket_close (socket);
+ RET_UNKNOWN(ret);
+ return ret_error;
}
- /* In case it did not success, launch a interpreter
+ /* Spawn a new process
*/
- if (*spawned == 0) {
- int unlocked;
-
- /* Launch a new interpreter
- */
- unlocked = CHEROKEE_MUTEX_TRY_LOCK(&src->launching_mutex);
- if (unlocked)
- return ret_eagain;
+ unlocked = CHEROKEE_MUTEX_TRY_LOCK (&src->launching_mutex);
+ if (unlocked) {
+ cherokee_connection_sleep (conn, 1000);
+ return ret_eagain;
+ }
- src->launching = true;
+ if (src->spawning_since == 0) {
+ /* Kill prev (unresponsive) interpreter? */
+ kill_prev = ((src->pid > 0) && (source_is_unresponsive(src)));
+ if (! kill_prev) {
+ src->pid = -1;
+ }
+ /* Spawn */
ret = cherokee_source_interpreter_spawn (src, CONN_VSRV(conn)->logger);
switch (ret) {
case ret_ok:
- break;
+ src->spawning_since = cherokee_bogonow_now;
+ ret = ret_eagain;
+ goto out;
+
case ret_eagain:
- /* Spawner was busy.. */
- cherokee_connection_sleep (conn, 300);
+ cherokee_connection_sleep (conn, 1000);
ret = ret_eagain;
goto out;
+
default:
- if (src->interpreter.buf)
- TRACE (ENTRIES, "Couldn't spawn: %s\n",
- src->interpreter.buf);
- else
+ if (src->interpreter.buf) {
+ TRACE (ENTRIES, "Couldn't spawn: %s\n", src->interpreter.buf);
+ } else {
TRACE (ENTRIES, "No interpreter to be spawned %s", "\n");
-
+ }
ret = ret_error;
goto out;
}
- *spawned = cherokee_bogonow_now;
-
- /* Reset the internal socket */
- cherokee_socket_close (socket);
-
- } else if (cherokee_bogonow_now > *spawned + src->timeout) {
- TRACE (ENTRIES, "Giving up; spawned %d secs ago: %s\n",
- src->timeout, src->interpreter.buf);
-
+ SHOULDNT_HAPPEN;
ret = ret_error;
goto out;
}
- /* Leave the mutex locked */
- return ret_eagain;
+ /* Is the launching process death?
+ */
+ if (src->pid > 0) {
+ re = kill (src->pid, 0);
+ if (re != 0) {
+ /* It's death */
+ src->spawning_since = 0;
+ ret = ret_eagain;
+ goto out;
+ }
+ }
-out:
- if (src->launching) {
- CHEROKEE_MUTEX_UNLOCK (&src->launching_mutex);
- src->launching = false;
+ /* Is it unresponsive?
+ */
+ if (source_is_unresponsive(src)) {
+ src->spawning_since = 0;
+ ret = ret_eagain;
+ goto out;
}
+ /* Spawning on-going
+ */
+ cherokee_connection_sleep (conn, 1000);
+ ret = ret_eagain;
+
+out:
+ CHEROKEE_MUTEX_UNLOCK (&src->launching_mutex);
return ret;
}
View
6 cherokee/source_interpreter.h
@@ -47,7 +47,8 @@ typedef struct {
cuint_t timeout;
cherokee_boolean_t debug;
pid_t pid;
- time_t last_spawn;
+ time_t last_connect;
+ time_t spawning_since;
cherokee_buffer_t change_user_name;
uid_t change_user;
@@ -70,8 +71,7 @@ ret_t cherokee_source_interpreter_spawn (cherokee_source_interpreter_t *src,
ret_t cherokee_source_interpreter_connect_polling (cherokee_source_interpreter_t *src,
cherokee_socket_t *socket,
- cherokee_connection_t *conn,
- time_t *spawned);
+ cherokee_connection_t *conn);
CHEROKEE_END_DECLS
Please sign in to comment.
Something went wrong with that request. Please try again.