⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jk_lb_worker.c

📁 精通tomcat书籍原代码,希望大家共同学习
💻 C
📖 第 1 页 / 共 3 页
字号:
                        return JK_TRUE;
                    }
                    if (p->worker->lblock == JK_LB_LOCK_PESSIMISTIC)
                        jk_shm_unlock();
                }
                else {
                    /* If we can not get the endpoint
                     * mark the worker as busy rather then
                     * as in error if the attemp number is
                     * greater then the number of retries.
                     */
                    attempt++;
                    if (attempt > p->worker->s->retries) {
                        rec->s->is_busy = JK_TRUE;
                        num_of_workers = 0;
                    }
                    jk_log(l, JK_LOG_INFO,
                           "could not get free endpoint for worker %s (attempt %d)",
                           rec->s->name, attempt);
                    /* In case of attempt > num of workers sleep for 100 ms
                     * on each consequtive attempt.
                     */
                    if (attempt > (int)p->worker->num_of_workers)
                        jk_sleep_def();
                    continue;
                }
                if (service_stat == JK_FALSE) {
                    /*
                    * Service failed !!!
                    *
                    * Time for fault tolerance (if possible)...
                    */

                    rec->s->errors++;
                    rec->s->in_error_state = JK_TRUE;
                    rec->s->in_recovering = JK_FALSE;
                    rec->s->error_time = time(NULL);

                    if (is_service_error != JK_HTTP_SERVER_BUSY) {
                        /*
                        * Error is not recoverable - break with an error.
                        */
                        jk_log(l, JK_LOG_ERROR,
                            "unrecoverable error %d, request failed."
                            " Tomcat failed in the middle of request,"
                            " we can't recover to another instance.",
                            is_service_error);
                        *is_error = is_service_error;
                        JK_TRACE_EXIT(l);
                        return JK_FALSE;
                    }
                    jk_log(l, JK_LOG_INFO,
                           "service failed, worker %s is in error state",
                           rec->s->name);
                }
                else if (service_stat == JK_CLIENT_ERROR) {
                    /*
                    * Clent error !!!
                    * Since this is bad request do not fail over.
                    */
                    rec->s->errors++;
                    rec->s->in_error_state = JK_FALSE;
                    rec->s->in_recovering = JK_FALSE;
                    rec->s->error_time = 0;
                    *is_error = is_service_error;

                    jk_log(l, JK_LOG_INFO,
                           "unrecoverable error %d, request failed."
                           " Client failed in the middle of request,"
                           " we can't recover to another instance.",
                           is_service_error);
                    JK_TRACE_EXIT(l);
                    return JK_CLIENT_ERROR;
                }
                else {
                    /* If we can not get the endpoint from the worker
                     * that does not mean that the worker is in error
                     * state. It means that the worker is busy.
                     * We will try another worker.
                     * To prevent infinite loop decrement worker count;
                     */
                }
                /*
                 * Error is recoverable by submitting the request to
                 * another worker... Lets try to do that.
                 */
                if (JK_IS_DEBUG_LEVEL(l))
                    jk_log(l, JK_LOG_DEBUG,
                           "recoverable error... will try to recover on other host");
            }
#if 0
            else {
                /* NULL record, no more workers left ... */
                jk_log(l, JK_LOG_ERROR,
                       "All tomcat instances failed, no more workers left");
                JK_TRACE_EXIT(l);
                *is_error = JK_HTTP_SERVER_BUSY;
                return JK_FALSE;
            }
#endif
            --num_of_workers;
            prec = rec;
        }
        jk_log(l, JK_LOG_INFO,
               "All tomcat instances are busy or in error state");
        JK_TRACE_EXIT(l);
        /* Set error to Timeout */
        *is_error = JK_HTTP_SERVER_BUSY;
        return JK_FALSE;
    }
    if (is_error)
        *is_error = JK_HTTP_SERVER_ERROR;
    JK_LOG_NULL_PARAMS(l);
    JK_TRACE_EXIT(l);
    return JK_FALSE;
}

static int JK_METHOD done(jk_endpoint_t **e, jk_logger_t *l)
{
    JK_TRACE_ENTER(l);

    if (e && *e && (*e)->endpoint_private) {
        lb_endpoint_t *p = (*e)->endpoint_private;

        if (p->e) {
            p->e->done(&p->e, l);
        }

        free(p);
        *e = NULL;
        JK_TRACE_EXIT(l);
        return JK_TRUE;
    }

    JK_LOG_NULL_PARAMS(l);
    JK_TRACE_EXIT(l);
    return JK_FALSE;
}

static int JK_METHOD validate(jk_worker_t *pThis,
                              jk_map_t *props,
                              jk_worker_env_t *we, jk_logger_t *l)
{
    JK_TRACE_ENTER(l);

    if (pThis && pThis->worker_private) {
        lb_worker_t *p = pThis->worker_private;
        char **worker_names;
        unsigned int num_of_workers;
        const char *secret;

        p->s->sticky_session = jk_get_is_sticky_session(props, p->s->name);
        p->s->sticky_session_force = jk_get_is_sticky_session_force(props, p->s->name);
        secret = jk_get_worker_secret(props, p->s->name);

        if (jk_get_lb_worker_list(props,
                                  p->s->name,
                                  &worker_names,
                                  &num_of_workers) && num_of_workers) {
            unsigned int i = 0;

            p->lb_workers = jk_pool_alloc(&p->p,
                                          num_of_workers *
                                          sizeof(worker_record_t));
            if (!p->lb_workers) {
                JK_TRACE_EXIT(l);
                return JK_FALSE;
            }

            for (i = 0; i < num_of_workers; i++) {
                p->lb_workers[i].s = jk_shm_alloc_worker(&p->p);
                if (p->lb_workers[i].s == NULL) {
                    jk_log(l, JK_LOG_ERROR,
                           "allocating worker record from shared memory");
                    JK_TRACE_EXIT(l);
                    return JK_FALSE;
                }
            }
            for (i = 0; i < num_of_workers; i++) {
                const char *s;
                strncpy(p->lb_workers[i].s->name, worker_names[i],
                        JK_SHM_STR_SIZ);
                p->lb_workers[i].s->lb_factor =
                    jk_get_lb_factor(props, worker_names[i]);
                if (p->lb_workers[i].s->lb_factor < 1) {
                    p->lb_workers[i].s->lb_factor = 1;
                }
                if ((s = jk_get_worker_domain(props, worker_names[i], NULL)))
                    strncpy(p->lb_workers[i].s->domain, s, JK_SHM_STR_SIZ);
                if ((s = jk_get_worker_redirect(props, worker_names[i], NULL)))
                    strncpy(p->lb_workers[i].s->redirect, s, JK_SHM_STR_SIZ);

                p->lb_workers[i].s->lb_value = p->lb_workers[i].s->lb_factor;
                p->lb_workers[i].s->in_error_state = JK_FALSE;
                p->lb_workers[i].s->in_recovering = JK_FALSE;
                p->lb_workers[i].s->is_busy = JK_FALSE;
                p->lb_workers[i].s->error_time = 0;
                /* Worker can be initaly disabled as hot standby */
                p->lb_workers[i].s->is_disabled = jk_get_is_worker_disabled(props, worker_names[i]);
                /* Worker can be initaly deactive as cold standby */
                p->lb_workers[i].s->is_stopped = jk_get_is_worker_stopped(props, worker_names[i]);
                if (!wc_create_worker(p->lb_workers[i].s->name, 0,
                                      props,
                                      &(p->lb_workers[i].w),
                                      we, l) || !p->lb_workers[i].w) {
                    break;
                }
                if (secret && (p->lb_workers[i].w->type == JK_AJP13_WORKER_TYPE ||
                    p->lb_workers[i].w->type == JK_AJP14_WORKER_TYPE)) {
                    ajp_worker_t *aw = (ajp_worker_t *)p->lb_workers[i].w->worker_private;
                    if (!aw->secret)
                        aw->secret = secret;
                }
            }

            if (i != num_of_workers) {
                jk_log(l, JK_LOG_ERROR,
                       "Failed creating worker %s",
                       p->lb_workers[i].s->name);
                close_workers(p, i, l);
            }
            else {
                if (JK_IS_DEBUG_LEVEL(l)) {
                    for (i = 0; i < num_of_workers; i++) {
                        jk_log(l, JK_LOG_DEBUG,
                               "Balanced worker %i has name %s in domain %s",
                               i, p->lb_workers[i].s->name, p->lb_workers[i].s->domain);
                    }
                }
                p->num_of_workers = num_of_workers;
                JK_TRACE_EXIT(l);
                return JK_TRUE;
            }
        }
    }

    JK_LOG_NULL_PARAMS(l);
    JK_TRACE_EXIT(l);
    return JK_FALSE;
}

static int JK_METHOD init(jk_worker_t *pThis,
                          jk_map_t *props,
                          jk_worker_env_t *we, jk_logger_t *log)
{
    int i;

    lb_worker_t *p = (lb_worker_t *)pThis->worker_private;
    JK_TRACE_ENTER(log);

    pThis->retries = jk_get_worker_retries(props, p->s->name,
                                           JK_RETRIES);
    p->s->retries = pThis->retries;
    p->s->recover_wait_time = jk_get_worker_recover_timeout(props, p->s->name,
                                                            WAIT_BEFORE_RECOVER);
    if (p->s->recover_wait_time < WAIT_BEFORE_RECOVER)
        p->s->recover_wait_time = WAIT_BEFORE_RECOVER;

    p->lbmethod = jk_get_lb_method(props, p->s->name);
    p->lblock   = jk_get_lb_lock(props, p->s->name);

    JK_INIT_CS(&(p->cs), i);
    if (i == JK_FALSE) {
        jk_log(log, JK_LOG_ERROR,
               "creating thread lock errno=%d",
               errno);
        JK_TRACE_EXIT(log);
        return JK_FALSE;
    }

    JK_TRACE_EXIT(log);
    return JK_TRUE;
}

static int JK_METHOD get_endpoint(jk_worker_t *pThis,
                                  jk_endpoint_t **pend, jk_logger_t *l)
{
    JK_TRACE_ENTER(l);

    if (pThis && pThis->worker_private && pend) {
        lb_endpoint_t *p = (lb_endpoint_t *) malloc(sizeof(lb_endpoint_t));
        p->e = NULL;
        p->worker = pThis->worker_private;
        p->endpoint.endpoint_private = p;
        p->endpoint.service = service;
        p->endpoint.done = done;
        *pend = &p->endpoint;

        JK_TRACE_EXIT(l);
        return JK_TRUE;
    }
    else {
        JK_LOG_NULL_PARAMS(l);
    }

    JK_TRACE_EXIT(l);
    return JK_FALSE;
}

static int JK_METHOD destroy(jk_worker_t **pThis, jk_logger_t *l)
{
    JK_TRACE_ENTER(l);

    if (pThis && *pThis && (*pThis)->worker_private) {
        unsigned int i;
        lb_worker_t *private_data = (*pThis)->worker_private;

        close_workers(private_data, private_data->num_of_workers, l);
        JK_DELETE_CS(&(private_data->cs), i);
        jk_close_pool(&private_data->p);
        free(private_data);

        JK_TRACE_EXIT(l);
        return JK_TRUE;
    }

    JK_LOG_NULL_PARAMS(l);
    JK_TRACE_EXIT(l);
    return JK_FALSE;
}

int JK_METHOD lb_worker_factory(jk_worker_t **w,
                                const char *name, jk_logger_t *l)
{
    JK_TRACE_ENTER(l);

    if (NULL != name && NULL != w) {
        lb_worker_t *private_data =
            (lb_worker_t *) calloc(1, sizeof(lb_worker_t));


        jk_open_pool(&private_data->p,
                        private_data->buf,
                        sizeof(jk_pool_atom_t) * TINY_POOL_SIZE);

        private_data->s = jk_shm_alloc_worker(&private_data->p);
        if (!private_data->s) {
            free(private_data);
            JK_TRACE_EXIT(l);
            return 0;
        }
        strncpy(private_data->s->name, name, JK_SHM_STR_SIZ);
        private_data->lb_workers = NULL;
        private_data->num_of_workers = 0;
        private_data->worker.worker_private = private_data;
        private_data->worker.validate = validate;
        private_data->worker.init = init;
        private_data->worker.get_endpoint = get_endpoint;
        private_data->worker.destroy = destroy;
        private_data->worker.maintain = maintain_workers;
        private_data->worker.retries = JK_RETRIES;
        private_data->s->recover_wait_time = WAIT_BEFORE_RECOVER;
        *w = &private_data->worker;
        JK_TRACE_EXIT(l);
        return JK_LB_WORKER_TYPE;
    }
    else {
        JK_LOG_NULL_PARAMS(l);
    }

    JK_TRACE_EXIT(l);
    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -