summaryrefslogtreecommitdiffhomepage
path: root/src/nxt_conf_validation.c
diff options
context:
space:
mode:
authorMax Romanov <max.romanov@nginx.com>2018-01-29 16:17:36 +0300
committerMax Romanov <max.romanov@nginx.com>2018-01-29 16:17:36 +0300
commit9cd4fdbdb78e035254e8094b5cff2155857ab764 (patch)
tree6de4ee721996740cbeda8647e11b8b2aa18e704f /src/nxt_conf_validation.c
parenta36babddef203d79dc37736661e1a042df4064f8 (diff)
downloadunit-9cd4fdbdb78e035254e8094b5cff2155857ab764.tar.gz
unit-9cd4fdbdb78e035254e8094b5cff2155857ab764.tar.bz2
Introducing extended app process management.
- Pre-fork 'processes.spare' application processes; - fork more processes to keep 'processes.spare' idle processes; - fork on-demand up to 'processes.max' count; - scale down idle application processes above 'processes.spare' after 'processes.idle_timeout'; - number of concurrently started application processes also limited by 'processes.spare' (or 1, if spare is 0).
Diffstat (limited to 'src/nxt_conf_validation.c')
-rw-r--r--src/nxt_conf_validation.c143
1 files changed, 139 insertions, 4 deletions
diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c
index cb17a62b..e4109b00 100644
--- a/src/nxt_conf_validation.c
+++ b/src/nxt_conf_validation.c
@@ -54,6 +54,8 @@ static nxt_int_t nxt_conf_vldt_app(nxt_conf_validation_t *vldt,
nxt_str_t *name, nxt_conf_value_t *value);
static nxt_int_t nxt_conf_vldt_object(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
+static nxt_int_t nxt_conf_vldt_processes(nxt_conf_validation_t *vldt,
+ nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data);
static nxt_int_t nxt_conf_vldt_system(nxt_conf_validation_t *vldt,
@@ -107,22 +109,42 @@ static nxt_conf_vldt_object_t nxt_conf_vldt_app_limits_members[] = {
};
-static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
- { nxt_string("type"),
- NXT_CONF_VLDT_STRING,
+static nxt_conf_vldt_object_t nxt_conf_vldt_app_processes_members[] = {
+ { nxt_string("spare"),
+ NXT_CONF_VLDT_INTEGER,
+ NULL,
+ NULL },
+
+ { nxt_string("max"),
+ NXT_CONF_VLDT_INTEGER,
NULL,
NULL },
- { nxt_string("workers"),
+ { nxt_string("idle_timeout"),
NXT_CONF_VLDT_INTEGER,
NULL,
NULL },
+ NXT_CONF_VLDT_END
+};
+
+
+static nxt_conf_vldt_object_t nxt_conf_vldt_common_members[] = {
+ { nxt_string("type"),
+ NXT_CONF_VLDT_STRING,
+ NULL,
+ NULL },
+
{ nxt_string("limits"),
NXT_CONF_VLDT_OBJECT,
&nxt_conf_vldt_object,
(void *) &nxt_conf_vldt_app_limits_members },
+ { nxt_string("processes"),
+ NXT_CONF_VLDT_INTEGER | NXT_CONF_VLDT_OBJECT,
+ &nxt_conf_vldt_processes,
+ (void *) &nxt_conf_vldt_app_processes_members },
+
{ nxt_string("user"),
NXT_CONF_VLDT_STRING,
nxt_conf_vldt_system,
@@ -475,6 +497,119 @@ nxt_conf_vldt_object(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
}
+typedef struct {
+ int64_t spare;
+ int64_t max;
+ int64_t idle_timeout;
+} nxt_conf_vldt_processes_conf_t;
+
+
+static nxt_conf_map_t nxt_conf_vldt_processes_conf_map[] = {
+ {
+ nxt_string("spare"),
+ NXT_CONF_MAP_INT64,
+ offsetof(nxt_conf_vldt_processes_conf_t, spare),
+ },
+
+ {
+ nxt_string("max"),
+ NXT_CONF_MAP_INT64,
+ offsetof(nxt_conf_vldt_processes_conf_t, max),
+ },
+
+ {
+ nxt_string("idle_timeout"),
+ NXT_CONF_MAP_INT64,
+ offsetof(nxt_conf_vldt_processes_conf_t, idle_timeout),
+ },
+};
+
+
+static nxt_int_t
+nxt_conf_vldt_processes(nxt_conf_validation_t *vldt, nxt_conf_value_t *value,
+ void *data)
+{
+ int64_t int_value;
+ nxt_int_t ret;
+ nxt_conf_vldt_processes_conf_t proc;
+
+ static nxt_str_t max_str = nxt_string("max");
+
+ if (nxt_conf_type(value) == NXT_CONF_INTEGER) {
+ int_value = nxt_conf_get_integer(value);
+
+ if (int_value < 1) {
+ return nxt_conf_vldt_error(vldt, "The \"processes\" number must be "
+ "equal to or greater than 1.");
+ }
+
+ if (int_value > NXT_INT32_T_MAX) {
+ return nxt_conf_vldt_error(vldt, "The \"processes\" number must "
+ "not exceed %d.", NXT_INT32_T_MAX);
+ }
+
+ return NXT_OK;
+ }
+
+ ret = nxt_conf_vldt_object(vldt, value, data);
+ if (ret != NXT_OK) {
+ return ret;
+ }
+
+ proc.spare = 1;
+ proc.max = 1;
+ proc.idle_timeout = 15;
+
+ ret = nxt_conf_map_object(vldt->pool, value,
+ nxt_conf_vldt_processes_conf_map,
+ nxt_nitems(nxt_conf_vldt_processes_conf_map),
+ &proc);
+ if (ret != NXT_OK) {
+ return ret;
+ }
+
+ if (proc.spare < 0) {
+ return nxt_conf_vldt_error(vldt, "The \"spare\" number must not be "
+ "negative.");
+ }
+
+ if (proc.spare > NXT_INT32_T_MAX) {
+ return nxt_conf_vldt_error(vldt, "The \"spare\" number must not "
+ "not exceed %d.", NXT_INT32_T_MAX);
+ }
+
+ if (nxt_conf_get_object_member(value, &max_str, NULL) != NULL) {
+
+ if (proc.max < 1) {
+ return nxt_conf_vldt_error(vldt, "The \"max\" number must be equal "
+ "to or greater than 1.");
+ }
+
+ if (proc.max > NXT_INT32_T_MAX) {
+ return nxt_conf_vldt_error(vldt, "The \"max\" number must not "
+ "not exceed %d.", NXT_INT32_T_MAX);
+ }
+
+ if (proc.max < proc.spare) {
+ return nxt_conf_vldt_error(vldt, "The \"spare\" number must be "
+ "lower than \"max\".");
+ }
+ }
+
+ if (proc.idle_timeout < 0) {
+ return nxt_conf_vldt_error(vldt, "The \"idle_timeout\" number must not "
+ "be negative.");
+ }
+
+ if (proc.idle_timeout > NXT_INT32_T_MAX / 1000) {
+ return nxt_conf_vldt_error(vldt, "The \"idle_timeout\" number must not "
+ "not exceed %d.", NXT_INT32_T_MAX / 1000);
+ }
+
+ return NXT_OK;
+}
+
+
static nxt_int_t
nxt_conf_vldt_object_iterator(nxt_conf_validation_t *vldt,
nxt_conf_value_t *value, void *data)