Changeset 1390:46656b52ae97 in freeDiameter
- Timestamp:
- Nov 15, 2019, 7:21:41 PM (4 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
extensions/rt_load_balance/rt_load_balance.c
r1284 r1390 31 31 32 32 #include <freeDiameter/extension.h> 33 #include <limits.h> 34 #include <time.h> 35 36 struct best_candidate_entry { 37 long load; 38 struct rtd_candidate *cand; 39 }; 40 41 static unsigned int seed; 42 43 #define MODULE_NAME "rt_load_balance" 33 44 34 45 /* 35 * Load balancing extension. Send request to least-loaded node. 46 * Load balancing extension. Send request to least-loaded node: Add a 47 * score of 1 to the least loaded candidates among those with highest 48 * score. 36 49 */ 37 50 … … 41 54 struct fd_list *lic; 42 55 struct msg * msg = *pmsg; 43 56 int max_score = -1; 57 int max_score_count = 0; 58 44 59 TRACE_ENTRY("%p %p %p", cbdata, msg, candidates); 45 60 46 61 CHECK_PARAMS(msg && candidates); 47 62 63 48 64 /* Check if it is worth processing the message */ 49 65 if (FD_IS_LIST_EMPTY(candidates)) 50 66 return 0; 51 67 52 /* load balancing*/68 /* find out maximal score and how many candidates have it */ 53 69 for (lic = candidates->next; lic != candidates; lic = lic->next) { 54 70 struct rtd_candidate * cand = (struct rtd_candidate *) lic; 55 struct peer_hdr *peer; 56 long to_receive, to_send, load; 57 int score; 58 CHECK_FCT(fd_peer_getbyid(cand->diamid, cand->diamidlen, 0, &peer)); 59 CHECK_FCT(fd_peer_get_load_pending(peer, &to_receive, &to_send)); 60 load = to_receive + to_send; 61 /* other routing mechanisms need to add to the 62 * appropriate entries so their base value is high 63 * enough that they are considered */ 71 if (max_score < cand->score) { 72 max_score = cand->score; 73 max_score_count = 1; 74 } 75 else if (cand->score == max_score) { 76 max_score_count++; 77 } 78 } 64 79 65 /* logarithmic scaling */ 66 int load_log = 0; 67 while (load > 0) { 68 load_log++; 69 load /= 2; 70 } 71 score = cand->score; 72 cand->score -= load_log; 73 TRACE_DEBUG(FULL, "evaluated peer `%.*s', score was %d, now %d", (int)cand->diamidlen, cand->diamid, score, cand->score); 80 if (max_score_count > 0) { 81 /* find out minimum load among those with maximal 82 * score, and how many candidates have it */ 83 struct best_candidate_entry best_candidates[max_score_count]; 84 long min_load = LONG_MAX; 85 int min_load_count = 0; 86 int j; 87 88 for (j = 0, lic = candidates->next; lic != candidates; lic = lic->next) { 89 struct rtd_candidate * cand = (struct rtd_candidate *) lic; 90 if (cand->score == max_score) { 91 long to_receive, to_send, load; 92 struct peer_hdr *peer; 93 CHECK_FCT(fd_peer_getbyid(cand->diamid, cand->diamidlen, 0, &peer)); 94 CHECK_FCT(fd_peer_get_load_pending(peer, &to_receive, &to_send)); 95 load = to_receive + to_send; 96 97 best_candidates[j].cand = cand; 98 best_candidates[j].load = load; 99 j++; 100 101 if (min_load > load) { 102 min_load = load; 103 min_load_count = 1; 104 } else if (min_load == load) { 105 min_load_count++; 106 } 107 } 108 } 109 110 /* increase score by 1 for all entries with minimum 111 * load, and further increase by 1 for one randomly 112 * chosen candidate */ 113 if (min_load_count > 0) { 114 int lucky_candidate = rand_r(&seed) % min_load_count; 115 int i; 116 for (j = 0, i = 0; j < max_score_count; j++) { 117 struct best_candidate_entry *entry = best_candidates+j; 118 if (entry->load == min_load) { 119 struct rtd_candidate *cand = entry->cand; 120 long old_score = cand->score; 121 cand->score++; 122 TRACE_DEBUG(FULL, "%s: boosting peer `%.*s', score was %d, now %d; load was %ld", MODULE_NAME, (int)cand->diamidlen, cand->diamid, old_score, cand->score, entry->load); 123 124 if (i == lucky_candidate) { 125 cand->score++; 126 TRACE_DEBUG(FULL, "%s: boosting lucky peer `%.*s', score was %d, now %d; load was %ld", MODULE_NAME, (int)cand->diamidlen, cand->diamid, old_score, cand->score, entry->load); 127 } 128 i++; 129 } 130 } 131 } 74 132 } 75 133 … … 86 144 CHECK_FCT(fd_rt_out_register(rt_load_balancing, NULL, 10, &rt_load_balancing_hdl)); 87 145 146 seed = (unsigned int)time(NULL); 147 88 148 TRACE_DEBUG(INFO, "Extension 'Load Balancing' initialized"); 89 149 return 0; … … 98 158 } 99 159 100 EXTENSION_ENTRY( "rt_load_balance", rt_load_balance_entry);160 EXTENSION_ENTRY(MODULE_NAME, rt_load_balance_entry);
Note: See TracChangeset
for help on using the changeset viewer.