View | Details | Raw Unified | Return to bug 32317
Collapse All | Expand All

(-)jk_lb_worker.h.orig (+1 lines)
Lines 32-37 Link Here
32
#endif                          /* __cplusplus */
32
#endif                          /* __cplusplus */
33
33
34
#define JK_LB_WORKER_NAME ("lb")
34
#define JK_LB_WORKER_NAME ("lb")
35
#define JK_LB_DEF_DOMAIN_NAME ("unknown")
35
36
36
int JK_METHOD lb_worker_factory(jk_worker_t **w,
37
int JK_METHOD lb_worker_factory(jk_worker_t **w,
37
                                const char *name, jk_logger_t *l);
38
                                const char *name, jk_logger_t *l);
(-)jk_lb_worker.c.orig (-43 / +250 lines)
Lines 40-45 Link Here
40
#define WAIT_BEFORE_RECOVER (60*1)
40
#define WAIT_BEFORE_RECOVER (60*1)
41
#define WORKER_RECOVER_TIME ("recover_time")
41
#define WORKER_RECOVER_TIME ("recover_time")
42
42
43
int search_id_max = 5;
44
const char *search_types[] = {
45
    "none",
46
    "sticky",
47
    "sticky domain",
48
    "local",
49
    "local domain",
50
    "any"
51
};
52
43
/** 
53
/** 
44
 * Worker record should be inside shared
54
 * Worker record should be inside shared
45
 * memory for correct behavior.
55
 * memory for correct behavior.
Lines 49-57 Link Here
49
struct worker_record
59
struct worker_record
50
{
60
{
51
    char *name;
61
    char *name;
62
    char    *domain;
52
    int lb_factor;
63
    int lb_factor;
53
    int lb_value;
64
    int lb_value;
54
    int is_local_worker;
65
    int is_local_worker;
66
    int is_local_domain;
55
    int in_error_state;
67
    int in_error_state;
56
    int in_recovering;
68
    int in_recovering;
57
    time_t error_time;
69
    time_t error_time;
Lines 63-68 Link Here
63
{
75
{
64
    worker_record_t *lb_workers;
76
    worker_record_t *lb_workers;
65
    unsigned num_of_workers;
77
    unsigned num_of_workers;
78
    unsigned num_of_local_workers;
66
79
67
    jk_pool_t p;
80
    jk_pool_t p;
68
    jk_pool_atom_t buf[TINY_POOL_SIZE];
81
    jk_pool_atom_t buf[TINY_POOL_SIZE];
Lines 198-274 Link Here
198
    }
211
    }
199
}
212
}
200
213
214
const char *lookup_search_type(int search_id,
215
                        jk_logger_t *l)
216
{
217
    if ( ( search_id > 0 ) && ( search_id <= search_id_max ) ) {
218
	return search_types[search_id];
219
    }
220
    jk_log(l, JK_LOG_ERROR,
221
        "search id %d does not lie between 1 and %d\n",
222
        search_id, search_id_max);
223
    return search_types[0];
224
}
225
226
int is_worker_candidate(worker_record_t *wr,
227
                        int search_id,
228
                        const char *search_string,
229
                        jk_logger_t *l)
230
{
231
    switch(search_id) {
232
        case 1:
233
            if(0 == strcmp(search_string, wr->name)) {
234
                return JK_TRUE;
235
            }
236
            return JK_FALSE;
237
        case 2:
238
            if(0 == strcmp(search_string, wr->domain)) {
239
                return JK_TRUE;
240
            }
241
            return JK_FALSE;
242
        case 3:
243
            if(wr->is_local_worker) {
244
                return JK_TRUE;
245
            }
246
            return JK_FALSE;
247
        case 4:
248
            if(wr->is_local_domain) {
249
                return JK_TRUE;
250
            }
251
            return JK_FALSE;
252
        case 5:
253
            return JK_TRUE;
254
    }
255
    jk_log(l, JK_LOG_ERROR,
256
        "search id %d does not lie between 1 and %d\n",
257
        search_id, search_id_max);
258
    return JK_FALSE;
259
}
260
261
static worker_record_t *get_suitable_worker(lb_worker_t *p, 
262
                                            int search_id,
263
                                            const char *search_string,
264
                                            int start,
265
                                            int stop,
266
                                            int use_lb_factor,
267
                                            int *domain_id,
268
                                            jk_logger_t *l)
269
{
270
271
    worker_record_t *rc = NULL;
272
    int lb_max = 0;
273
    int total_factor = 0;
274
    const char *search_type;
275
    int i;
276
277
    *domain_id = -1;
278
    if ( JK_IS_DEBUG_LEVEL(l) ) {
279
        search_type = lookup_search_type(search_id, l);
280
    }
281
282
    if ( JK_IS_DEBUG_LEVEL(l) ) {
283
        jk_log(l, JK_LOG_TRACE,
284
            "searching for %s worker (%s)\n",
285
            search_type, search_string);
286
    }
287
    for(i = start ; i < stop ; i++) {
288
        if ( JK_IS_DEBUG_LEVEL(l) ) {
289
            jk_log(l, JK_LOG_TRACE,
290
                "testing worker %s (%d) for match with %s (%s)\n",
291
                p->lb_workers[i].name, i, search_type, search_string);
292
        }
293
        if(is_worker_candidate(&(p->lb_workers[i]), search_id, search_string, l)) {
294
            if(search_id == 1) {
295
                *domain_id = i;
296
            }
297
            if(!p->lb_workers[i].in_error_state || !p->lb_workers[i].in_recovering) {
298
                if ( JK_IS_DEBUG_LEVEL(l) ) {
299
                    jk_log(l, JK_LOG_TRACE,
300
                        "found candidate worker %s (%d) with previous load %d in search with %s (%s)\n",
301
                        p->lb_workers[i].name, i, p->lb_workers[i].lb_value, search_type, search_string);
302
                }
303
304
                if(p->lb_workers[i].in_error_state) {
305
306
                    time_t now = time(0);
307
                    if ((now - p->lb_workers[i].error_time) <=
308
                        p->recover_wait_time) {
309
                        if ( JK_IS_DEBUG_LEVEL(l) ) {
310
                            jk_log(l, JK_LOG_TRACE,
311
                                "worker candidate %s (%d) is in error state - will not yet recover (%u < %d)\n",
312
                                p->lb_workers[i].name, i, elapsed, p->recover_wait_time);
313
                        }
314
                        continue;
315
                    }
316
                }
317
318
                if(use_lb_factor) {
319
                    p->lb_workers[i].lb_value += p->lb_workers[i].lb_factor;
320
                    total_factor += p->lb_workers[i].lb_factor;
321
                    if(p->lb_workers[i].lb_value > lb_max || !rc) {
322
                        lb_max = p->lb_workers[i].lb_value;
323
                        rc = &(p->lb_workers[i]);
324
                        if ( JK_IS_DEBUG_LEVEL(l) ) {
325
                            jk_log(l, JK_LOG_TRACE,
326
                                "new maximal worker %s (%d) with previous load %d in search with %s (%s)\n",
327
                                rc->name, i, rc->lb_value, search_type, search_string);
328
                        }
329
                    }
330
                } else {
331
                    rc = &(p->lb_workers[i]);
332
                    break;
333
                }
334
            } else if ( JK_IS_DEBUG_LEVEL(l) ) {
335
                jk_log(l, JK_LOG_TRACE,
336
                    "worker candidate %s (%d) is in error state - already recovers\n",
337
                    p->lb_workers[i].name, i);
338
            }
339
        }
340
    }
341
342
    if(rc) {
343
        if(rc->in_error_state) {
344
            time_t now = time(0);
345
            rc->in_recovering  = JK_TRUE;
346
            rc->error_time     = now;
347
            if ( JK_IS_DEBUG_LEVEL(l) ) {
348
                jk_log(l, JK_LOG_TRACE,
349
                    "found worker %s is in error state - will recover\n",
350
                    rc->name);
351
            }
352
        }
353
        rc->lb_value -= total_factor;
354
        if ( JK_IS_DEBUG_LEVEL(l) ) {
355
            jk_log(l, JK_LOG_TRACE,
356
                "found worker %s with new load %d in search with %s (%s)\n",
357
                rc->name, rc->lb_value, search_type, search_string);
358
        }
359
        return rc;
360
    }
361
    if ( JK_IS_DEBUG_LEVEL(l) ) {
362
        jk_log(l, JK_LOG_TRACE,
363
            "found no %s (%s) worker\n",
364
            search_type, search_string);
365
    }
366
    return rc;
367
}
368
201
static worker_record_t *get_most_suitable_worker(lb_worker_t * p,
369
static worker_record_t *get_most_suitable_worker(lb_worker_t * p,
202
                                                 jk_ws_service_t *s,
370
                                                 jk_ws_service_t *s,
203
                                                 int attempt)
371
                                                 int attempt,
372
                                                 jk_logger_t *l)
204
{
373
{
205
    worker_record_t *rc = NULL;
374
    worker_record_t *rc = NULL;
206
    unsigned i;
375
    unsigned i;
207
    char *sessionid = NULL;
376
    char *sessionid = NULL;
208
    int total_factor = 0;
377
    int total_factor = 0;
378
    int domain_id =-1;
209
379
380
    JK_TRACE_ENTER(l);
210
    if (p->sticky_session) {
381
    if (p->sticky_session) {
211
        sessionid = get_sessionid(s);
382
        sessionid = get_sessionid(s);
212
    }
383
    }
213
384
385
    if ( JK_IS_DEBUG_LEVEL(l) ) {
386
        jk_log(l, JK_LOG_TRACE,
387
            "total sessionid is %s.\n",
388
            sessionid ? sessionid : "empty");
389
    }
390
214
    while (sessionid) {
391
    while (sessionid) {
215
        char *next = strchr(sessionid, ';');
392
        char *next = strchr(sessionid, ';');
216
        char *session_route;
393
        char *session_route;
394
        char *session_domain;
217
        if (next) {
395
        if (next) {
218
            *next++ = '\0';
396
            *next++ = '\0';
219
        }
397
        }
398
        if ( JK_IS_DEBUG_LEVEL(l) ) {
399
            jk_log(l, JK_LOG_TRACE,
400
                "searching worker for partial sessionid %s.\n",
401
                sessionid);
402
        }
220
        session_route = strchr(sessionid, '.');
403
        session_route = strchr(sessionid, '.');
221
        if (session_route) {
404
        if (session_route) {
222
            ++session_route;
405
            ++session_route;
223
            for (i = 0; i < p->num_of_workers; i++) {
406
224
                if (0 == strcmp(session_route, p->lb_workers[i].name)) {
407
            rc = get_suitable_worker(p, 1, session_route, 0, p->num_of_workers, 0, &domain_id, l);
225
                    /* First attempt will allways be to the
408
            if ( rc ) {
226
                       correct host. If this is indeed down and no
409
                JK_TRACE_EXIT(l);
227
                       hope of recovery, we'll go to fail-over
410
                return rc;
228
                     */
411
            }
229
                    if (attempt > 0 && p->lb_workers[i].in_error_state) {
412
230
                        next = NULL;    /* Double break; */
413
            if(domain_id>=0 && domain_id<p->num_of_workers) {
231
                        break;
414
                session_domain = p->lb_workers[domain_id].domain;
232
                    }
415
            } else {
233
                    else {
416
                session_domain = JK_LB_DEF_DOMAIN_NAME;
234
                        return &(p->lb_workers[i]);
235
                    }
236
                }
237
            }
417
            }
418
            if ( JK_IS_DEBUG_LEVEL(l) ) {
419
                jk_log(l, JK_LOG_TRACE,
420
                    "found domain %s in route %s\n",
421
                    session_domain, session_route);
422
            }
423
424
            rc = get_suitable_worker(p, 2, session_domain, 0, p->num_of_workers, 1, &domain_id, l);
425
            if ( rc ) {
426
                JK_TRACE_EXIT(l);
427
                return rc;
428
            }
429
238
        }
430
        }
239
        sessionid = next;
431
        sessionid = next;
240
    }
432
    }
241
433
242
    for (i = 0; i < p->num_of_workers; i++) {
243
        if (!p->in_local_worker_mode || p->lb_workers[i].is_local_worker
244
            || !p->local_worker_only) {
245
            if (p->lb_workers[i].in_error_state) {
246
                if (!p->lb_workers[i].in_recovering) {
247
                    time_t now = time(0);
248
                    if ((now - p->lb_workers[i].error_time) >
249
                        p->recover_wait_time) {
250
                        p->lb_workers[i].in_recovering = JK_TRUE;
251
                        p->lb_workers[i].error_time = now;
252
                        rc = &(p->lb_workers[i]);
253
434
254
                        break;
435
255
                    }
436
    rc = get_suitable_worker(p, 3, "any", 0, p->num_of_local_workers, 1, &domain_id, l);
256
                }
437
    if ( rc ) {
257
            }
438
        JK_TRACE_EXIT(l);
258
            else {
439
        return rc;
259
                p->lb_workers[i].lb_value += p->lb_workers[i].lb_factor;
260
                total_factor += p->lb_workers[i].lb_factor;
261
                if (!rc || p->lb_workers[i].lb_value > rc->lb_value)
262
                    rc = &(p->lb_workers[i]);
263
            }
264
        }
265
    }
440
    }
266
441
267
    if (rc) {
442
    if(p->local_worker_only) {
268
        rc->lb_value -= total_factor;
443
        JK_TRACE_EXIT(l);
444
        return NULL;
445
    }
446
447
    rc = get_suitable_worker(p, 4, "any", p->num_of_local_workers, p->num_of_workers, 1, &domain_id, l);
448
    if ( rc ) {
449
        JK_TRACE_EXIT(l);
450
        return rc;
269
    }
451
    }
270
452
271
    
453
    rc = get_suitable_worker(p, 5, "any", p->num_of_local_workers, p->num_of_workers, 1, &domain_id, l);
454
    JK_TRACE_EXIT(l);
272
    return rc;
455
    return rc;
273
}
456
}
274
457
Lines 297-303 Link Here
297
480
298
        while (1) {
481
        while (1) {
299
            worker_record_t *rec =
482
            worker_record_t *rec =
300
                get_most_suitable_worker(p->worker, s, attempt++);
483
                get_most_suitable_worker(p->worker, s, attempt++, l);
301
            int rc;
484
            int rc;
302
485
303
            if (rec) {
486
            if (rec) {
Lines 397-405 Link Here
397
        lb_worker_t *p = pThis->worker_private;
580
        lb_worker_t *p = pThis->worker_private;
398
        char **worker_names;
581
        char **worker_names;
399
        unsigned num_of_workers;
582
        unsigned num_of_workers;
583
        unsigned num_of_local_workers;
400
        p->in_local_worker_mode = JK_FALSE;
584
        p->in_local_worker_mode = JK_FALSE;
401
        p->local_worker_only = jk_get_local_worker_only_flag(props, p->name);
585
        p->local_worker_only = jk_get_local_worker_only_flag(props, p->name);
402
        p->sticky_session = jk_get_is_sticky_session(props, p->name);
586
        p->sticky_session = jk_get_is_sticky_session(props, p->name);
587
        p->num_of_local_workers = 0;
403
588
404
        if (jk_get_lb_worker_list(props,
589
        if (jk_get_lb_worker_list(props,
405
                                  p->name,
590
                                  p->name,
Lines 425-430 Link Here
425
                if (p->lb_workers[i].lb_factor < 1) {
610
                if (p->lb_workers[i].lb_factor < 1) {
426
                    p->lb_workers[i].lb_factor = 1;
611
                    p->lb_workers[i].lb_factor = 1;
427
                }
612
                }
613
                p->lb_workers[i].domain = jk_get_worker_domain(props,
614
                                                               worker_names[i],
615
                                                               JK_LB_DEF_DOMAIN_NAME);
616
                if ( !p->lb_workers[i].domain ) {
617
                    p->lb_workers[i].domain = JK_LB_DEF_DOMAIN_NAME;
428
618
429
                p->lb_workers[i].is_local_worker =
619
                p->lb_workers[i].is_local_worker =
430
                    jk_get_is_local_worker(props, worker_names[i]);
620
                    jk_get_is_local_worker(props, worker_names[i]);
Lines 457-462 Link Here
457
                    j++;
647
                    j++;
458
                }
648
                }
459
            }
649
            }
650
            num_of_local_workers = j;
460
651
461
            if (!p->in_local_worker_mode) {
652
            if (!p->in_local_worker_mode) {
462
                p->local_worker_only = JK_FALSE;
653
                p->local_worker_only = JK_FALSE;
Lines 470-479 Link Here
470
661
471
            }
662
            }
472
            else {
663
            else {
664
                for (i = 0; i < num_of_local_workers; i++) {
665
                    p->lb_workers[i].is_local_domain=1;
666
                }
667
                for (i = num_of_local_workers; i < num_of_workers; i++) {
668
                    p->lb_workers[i].is_local_domain=0;
669
                    for (j = 0; j < num_of_local_workers; j++) {
670
                        if(0 == strcmp(p->lb_workers[i].domain, p->lb_workers[j].domain)) {
671
                            p->lb_workers[i].is_local_domain=1;
672
                            break;
673
                        }
674
                    }
675
                }
676
473
                for (i = 0; i < num_of_workers; i++) {
677
                for (i = 0; i < num_of_workers; i++) {
474
                    jk_log(l, JK_LOG_DEBUG,
678
                    jk_log(l, JK_LOG_DEBUG,
475
                           "Balanced worker %i has name %s\n",
679
                           "Balanced worker %i has name %s in domain %s and has local=%d and local_domain=%d\n",
476
                           i, p->lb_workers[i].name);
680
                           i, p->lb_workers[i].name, p->lb_workers[i].domain,
681
                           p->lb_workers[i].is_local_worker, p->lb_workers[i].is_local_domain);
477
                }
682
                }
478
                jk_log(l, JK_LOG_DEBUG,
683
                jk_log(l, JK_LOG_DEBUG,
479
                       "in_local_worker_mode: %s\n",
684
                       "in_local_worker_mode: %s\n",
Lines 482-487 Link Here
482
                       "local_worker_only: %s\n",
687
                       "local_worker_only: %s\n",
483
                       (p->local_worker_only ? "true" : "false"));
688
                       (p->local_worker_only ? "true" : "false"));
484
                p->num_of_workers = num_of_workers;
689
                p->num_of_workers = num_of_workers;
690
                p->num_of_local_workers = num_of_local_workers;
485
                JK_TRACE_EXIT(l);
691
                JK_TRACE_EXIT(l);
486
                return JK_TRUE;
692
                return JK_TRUE;
487
            }
693
            }
Lines 576-581 Link Here
576
782
577
        private_data->lb_workers = NULL;
783
        private_data->lb_workers = NULL;
578
        private_data->num_of_workers = 0;
784
        private_data->num_of_workers = 0;
785
        private_data->num_of_local_workers = 0;
579
        private_data->worker.worker_private = private_data;
786
        private_data->worker.worker_private = private_data;
580
        private_data->worker.validate = validate;
787
        private_data->worker.validate = validate;
581
        private_data->worker.init = init;
788
        private_data->worker.init = init;
(-)jk_util.h.orig (+2 lines)
Lines 70-75 Link Here
70
70
71
int jk_get_worker_recycle_timeout(jk_map_t *m, const char *wname, int def);
71
int jk_get_worker_recycle_timeout(jk_map_t *m, const char *wname, int def);
72
72
73
char *jk_get_worker_domain(jk_map_t *m, const char *wname, const char *def);
74
73
char *jk_get_worker_secret_key(jk_map_t *m, const char *wname);
75
char *jk_get_worker_secret_key(jk_map_t *m, const char *wname);
74
76
75
int jk_get_worker_retries(jk_map_t *m, const char *wname, int def);
77
int jk_get_worker_retries(jk_map_t *m, const char *wname, int def);
(-)jk_util.c.orig (+11 lines)
Lines 59-64 Link Here
59
#define STICKY_SESSION              ("sticky_session")
59
#define STICKY_SESSION              ("sticky_session")
60
#define LOCAL_WORKER_ONLY_FLAG      ("local_worker_only")
60
#define LOCAL_WORKER_ONLY_FLAG      ("local_worker_only")
61
#define LOCAL_WORKER_FLAG           ("local_worker")
61
#define LOCAL_WORKER_FLAG           ("local_worker")
62
#define DOMAIN_OF_WORKER            ("domain")
62
63
63
#define DEFAULT_WORKER_TYPE         JK_AJP13_WORKER_NAME
64
#define DEFAULT_WORKER_TYPE         JK_AJP13_WORKER_NAME
64
#define SECRET_KEY_OF_WORKER        ("secretkey")
65
#define SECRET_KEY_OF_WORKER        ("secretkey")
Lines 334-339 Link Here
334
    sprintf(buf, "%s.%s.%s", PREFIX_OF_WORKER, wname, TYPE_OF_WORKER);
335
    sprintf(buf, "%s.%s.%s", PREFIX_OF_WORKER, wname, TYPE_OF_WORKER);
335
336
336
    return jk_map_get_string(m, buf, DEFAULT_WORKER_TYPE);
337
    return jk_map_get_string(m, buf, DEFAULT_WORKER_TYPE);
338
}
339
340
char *jk_get_worker_domain(jk_map_t *m, const char *wname, const char *def)
341
{
342
    char buf[1024];
343
    if (!m || !wname) {
344
        return NULL;
345
    }
346
    sprintf(buf, "%s.%s.%s", PREFIX_OF_WORKER, wname, DOMAIN_OF_WORKER);
347
    return map_get_string(m, buf, def);
337
}
348
}
338
349
339
char *jk_get_worker_secret(jk_map_t *m, const char *wname)
350
char *jk_get_worker_secret(jk_map_t *m, const char *wname)

Return to bug 32317