Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature - Load Balancer Round Robin Queue for Destination Selection #1036

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Adding Virtual Queue Implementation and Associated Flag to Load Balan…
…cing Selction Algorithm
ryleyd committed Jan 30, 2017
commit e7385cc23384669763253c6010142119d1a9e85b
40 changes: 36 additions & 4 deletions modules/load_balancer/lb_data.c
Original file line number Diff line number Diff line change
@@ -330,6 +330,7 @@ int add_lb_dsturi( struct lb_data *data, int id, int group, char *uri,
data->last_dst = dst;
}
data->dst_no++;
dst->queue_loc = data->dst_no;

pkg_free(lb_rl);
return 0;
@@ -459,7 +460,7 @@ int lb_route(struct sip_msg *req, int group, struct lb_res_str_list *rl,
struct lb_dst *it_d;
struct lb_resource *it_r;
int load, it_l;
int i, j, cond, cnt_aval_dst;
int i, j, cond, cnt_aval_dst, q_lowest;


/* init control vars state */
@@ -666,7 +667,7 @@ int lb_route(struct sip_msg *req, int group, struct lb_res_str_list *rl,

/* init selected destinations buff */
dsts_cur = NULL;
dsts_size_max = (flags & LB_FLAGS_RANDOM) ? data->dst_no : 1;
dsts_size_max = (flags & (LB_FLAGS_RANDOM||LB_FLAGS_QUEUE)) ? data->dst_no : 1;
if( dsts_size_max > 1 ) {
if( dsts_size_max > dsts_size ) {
dsts = (struct lb_dst **)pkg_realloc
@@ -778,7 +779,16 @@ int lb_route(struct sip_msg *req, int group, struct lb_res_str_list *rl,
}
/* choose one destination among selected */
if( dsts_size_cur > 0 ) {
if( (dsts_size_cur > 1) && (flags & LB_FLAGS_RANDOM) ) {
if((dsts_size_cur > 1) && (flags & LB_FLAGS_QUEUE)){
//Find lowest queue number in virtual queue
q_lowest = data->dst_no;
for( i=0 ; i<dsts_size_cur; i++){
if (dsts[i]->queue_loc < q_lowest){
Copy link
Member

@liviuchircu liviuchircu Aug 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Harmless in this case, but for code consistency, this should be dsts_cur[i]->queue_loc, as below.

q_lowest = dsts_cur[i]->queue_loc;
dst = dsts_cur[i];
}
}
}else if( (dsts_size_cur > 1) && (flags & LB_FLAGS_RANDOM) ) {
dst = dsts_cur[rand() % dsts_size_cur];
} else {
dst = dsts_cur[0];
@@ -812,6 +822,13 @@ int lb_route(struct sip_msg *req, int group, struct lb_res_str_list *rl,
(reuse ? "sequential" : "initial"));
}

//Move members around in virtual queue
for( it_d=data->dsts; it_d; it_d=it_d->next){
if(it_d->queue_loc > dst->queue_loc){it_d->queue_loc--;}
}
//Move chosen dst to end of virtual queue
dst->queue_loc = data->dst_no;

/* unlock resources */
for( i=0 ; i<res_cur_n ; i++ )
lock_release(res_cur[i]->lock);
@@ -905,6 +922,7 @@ int do_lb_reset(struct sip_msg *req, struct lb_data *data)
struct usr_avp *res_avp, *del_res_avp;
int_str id_val;
int_str res_val;
int i;

struct dlg_cell *dlg;
struct lb_dst *it_d, *last_dst;
@@ -961,6 +979,13 @@ int do_lb_reset(struct sip_msg *req, struct lb_data *data)
}
}

//Refresh Queue Order (Starts at 1)
i=1;
for(it_d=data->dsts; it_d; it_d=it_d->next){
it_d->queue_loc=i;
i++;
}

return 0;
}

@@ -1076,6 +1101,7 @@ int lb_count_call(struct lb_data *data, struct sip_msg *req,struct ip_addr *ip,
struct dlg_cell *dlg;
struct lb_resource *res;
struct lb_dst *dst;
struct lb_dst *it_d;
int i,k;

/* search for the destination we need to count for */
@@ -1099,10 +1125,16 @@ int lb_count_call(struct lb_data *data, struct sip_msg *req,struct ip_addr *ip,
return -1;
}

//Move chosen dst in virtual queue (won't be used unless flag is set when session starts)
for( it_d=data->dsts ; it_d; it_d=it_d->next){
if(it_d->queue_loc > dst->queue_loc){it_d->queue_loc--;}
}
dst->queue_loc = data->dst_no;

/* get references to the resources */
if (rl->n>call_res_no) {
call_res = (struct lb_resource**)pkg_realloc
(call_res, rl->n*sizeof(struct lb_resorce*));
(call_res, rl->n*sizeof(struct lb_resource*));
if (call_res==NULL) {
call_res_no = 0;
LM_ERR("no more pkg mem - res ptr realloc\n");
2 changes: 2 additions & 0 deletions modules/load_balancer/lb_data.h
Original file line number Diff line number Diff line change
@@ -39,6 +39,7 @@
#define LB_FLAGS_RELATIVE (1<<0) /* do relative versus absolute estimation. default is absolute */
#define LB_FLAGS_NEGATIVE (1<<1) /* do not skip negative loads. default to skip */
#define LB_FLAGS_RANDOM (1<<2) /* pick a random destination among all selected dsts with equal load */
#define LB_FLAGS_QUEUE (1<<3) /* picks the next destination in the virtual queue*/
#define LB_FLAGS_DEFAULT 0

#define LB_DST_PING_DSBL_FLAG (1<<0)
@@ -76,6 +77,7 @@ struct lb_dst {
unsigned short int protos[LB_MAX_IPS]; /* Protocol of the request URI */
unsigned short ips_cnt;
struct lb_dst *next;
unsigned int queue_loc;
};

struct lb_data {
6 changes: 5 additions & 1 deletion modules/load_balancer/load_balancer.c
Original file line number Diff line number Diff line change
@@ -232,7 +232,7 @@ static int fixup_resources(void** param, int param_no)
/* try first as number */
s.s = (char*)*param;
s.len = strlen(s.s);
if (str2int(&s, (unsigned int*)&lbgp->grp_no)==0) {
if (str2sint(&s, (int*)&lbgp->grp_no)==0) {
lbgp->grp_pv = NULL;
pkg_free(*param);
} else {
@@ -608,6 +608,10 @@ static int w_lb_start(struct sip_msg *req, char *grp, char *rl, char *fl)
flags |= LB_FLAGS_RANDOM;
LM_DBG("pick a random destination among all selected dsts with equal load\n");
break;
case 'q':
flags |= LB_FLAGS_QUEUE;
LM_DBG("cycle destinations through a virtual queue");
break;
default:
LM_DBG("skipping unknown flag: [%c]\n", *f);
}