static int get_most_suitable_worker()

in native/common/jk_lb_worker.c [1035:1150]


static int get_most_suitable_worker(jk_ws_service_t *s,
                                    lb_worker_t *p,
                                    char *sessionid,
                                    int *states,
                                    jk_log_context_t *l)
{
    int rc = -1;

    JK_TRACE_ENTER(l);
    s->sticky = JK_FALSE;
    if (p->num_of_workers == 1) {
        /* No need to find the best worker
         * if there is a single one
         */
        int activation = s->extension.activation ?
                         s->extension.activation[0] :
                         JK_LB_ACTIVATION_UNSET;
        if (activation == JK_LB_ACTIVATION_UNSET)
            activation = p->lb_workers[0].activation;
        if (JK_WORKER_USABLE_STICKY(states[0], activation)) {
            if (activation != JK_LB_ACTIVATION_DISABLED) {
                s->sticky = JK_TRUE;
                JK_TRACE_EXIT(l);
                return 0;
            }
        }
        else {
            JK_TRACE_EXIT(l);
            return -1;
        }
    }
    if (p->lblock == JK_LB_LOCK_PESSIMISTIC) {
        if (!jk_shm_lock()) {
            jk_log(l, JK_LOG_ERROR, "locking failed (errno=%d)", errno);
            JK_TRACE_EXIT(l);
            return -1;
        }
    }
    else {
        JK_ENTER_CS(&p->cs);
    }
    if (sessionid) {
        char *session = sessionid;
        while (sessionid) {
            char *next = strchr(sessionid, ';');
            char *session_route = NULL;
            if (next)
               *next++ = '\0';
            if (JK_IS_DEBUG_LEVEL(l))
                jk_log(l, JK_LOG_DEBUG,
                       "searching worker for partial sessionid %s",
                       sessionid);
            session_route = strchr(sessionid, '.');
            if (session_route) {
                ++session_route;

                if (JK_IS_DEBUG_LEVEL(l))
                    jk_log(l, JK_LOG_DEBUG,
                           "searching worker for session route %s",
                           session_route);

                /* We have a session route. Whow! */
                rc = find_bysession_route(s, p, session_route, states, l);
                if (rc >= 0) {
                    lb_sub_worker_t *wr = &(p->lb_workers[rc]);
                    if (p->lblock == JK_LB_LOCK_PESSIMISTIC) {
                        jk_shm_unlock();
                    }
                    else {
                        JK_LEAVE_CS(&p->cs);
                    }
                    if (JK_IS_DEBUG_LEVEL(l))
                        jk_log(l, JK_LOG_DEBUG,
                               "found worker %s (%s) for route %s and partial sessionid %s",
                               wr->name, wr->route, session_route, sessionid);
                    JK_TRACE_EXIT(l);
                    return rc;
                }
            }
            /* Try next partial sessionid if present */
            sessionid = next;
            rc = -1;
        }
        if (rc < 0 && p->sticky_session_force) {
            if (p->lblock == JK_LB_LOCK_PESSIMISTIC) {
                jk_shm_unlock();
            }
            else {
                JK_LEAVE_CS(&p->cs);
            }
            jk_log(l, JK_LOG_INFO,
                   "all workers are in error state for session %s",
                   session);
            JK_TRACE_EXIT(l);
            return -1;
        }
    }
    rc = find_best_worker(s, p, states, l);
    if (p->lblock == JK_LB_LOCK_PESSIMISTIC) {
        jk_shm_unlock();
    }
    else {
        JK_LEAVE_CS(&p->cs);
    }
    if (rc >= 0) {
        lb_sub_worker_t *wr = &(p->lb_workers[rc]);
        if (JK_IS_DEBUG_LEVEL(l))
            jk_log(l, JK_LOG_DEBUG,
                   "found best worker %s (%s) using method '%s'",
                   wr->name, wr->route, jk_lb_get_method(p, l));
        JK_TRACE_EXIT(l);
        return rc;
    }
    JK_TRACE_EXIT(l);
    return -1;
}