mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-09 16:47:18 +02:00
MEDIUM: server: split srv_update_status() in two functions
Considering that srv_update_status() is now synchronous again since
3ff577e1
("MAJOR: server: make server state changes synchronous again"),
and that we can easily identify if the update is from an operational
or administrative context thanks to "MINOR: server: pass adm and op cause
to srv_update_status()".
And given that administrative and operational updates cannot be cumulated
(since srv_update_status() is called synchronously and independently for
admin updates and state/operational updates, and the function directly
consumes the changes).
We split srv_update_status() in 2 distinct parts:
Either <type> is 0, meaning the update is an operational update which
is handled by directly looking at cur_state and next_state to apply the
proper transition.
Also, the check to prevent operational state from being applied
if MAINT admin flag is set is no longer needed given that the calling
functions already ensure this (ie: srv_set_{running,stopping,stopped)
Or <type> is 1, meaning the update is an administrative update, where
cur_admin and next_admin are evaluated to apply the proper transition and
deduct the resulting server state (next_state is updated implicitly).
Once this is done, both operations share a common code path in
srv_update_status() to update proxy and servers stats if required.
Thanks to this change, the function's behavior is much more predictable,
it is not an all-in-one function anymore. Either we apply an operational
change, else it is an administrative change. That's it, we cannot mix
the 2 since both code paths are now properly separated.
This commit is contained in:
parent
76e255520f
commit
f71e0645c1
88
src/server.c
88
src/server.c
@ -5260,36 +5260,19 @@ static void srv_lb_propagate(struct server *s)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function applies server's status changes.
|
||||
/* directly update server state based on an operational change
|
||||
* (compare current and next state to know which transition to apply)
|
||||
*
|
||||
* Must be called with the server lock held. This may also be called at init
|
||||
* time as the result of parsing the state file, in which case no lock will be
|
||||
* held, and the server's warmup task can be null.
|
||||
* <type> should be 0 for operational and 1 for administrative
|
||||
* <cause> must be srv_op_st_chg_cause enum for operational and
|
||||
* srv_adm_st_chg_cause enum for administrative
|
||||
* The function returns the number of requeued sessions (either taken by
|
||||
* the server or redispatched to others servers) due to the server state
|
||||
* change.
|
||||
*/
|
||||
static void srv_update_status(struct server *s, int type, int cause)
|
||||
static int _srv_update_status_op(struct server *s, enum srv_op_st_chg_cause cause)
|
||||
{
|
||||
int xferred;
|
||||
int prev_srv_count = s->proxy->srv_bck + s->proxy->srv_act;
|
||||
int srv_was_stopping = (s->cur_state == SRV_ST_STOPPING) || (s->cur_admin & SRV_ADMF_DRAIN);
|
||||
enum srv_state srv_prev_state = s->cur_state;
|
||||
int log_level;
|
||||
struct buffer *tmptrash = NULL;
|
||||
enum srv_op_st_chg_cause op_cause = (!type) ? cause : SRV_OP_STCHGC_NONE;
|
||||
enum srv_adm_st_chg_cause adm_cause = (type) ? cause : SRV_ADM_STCHGC_NONE;
|
||||
|
||||
/* If currently main is not set we try to apply pending state changes */
|
||||
if (!(s->cur_admin & SRV_ADMF_MAINT)) {
|
||||
int next_admin;
|
||||
|
||||
/* Backup next admin */
|
||||
next_admin = s->next_admin;
|
||||
|
||||
/* restore current admin state */
|
||||
s->next_admin = s->cur_admin;
|
||||
int log_level;
|
||||
int srv_was_stopping = (s->cur_state == SRV_ST_STOPPING) || (s->cur_admin & SRV_ADMF_DRAIN);
|
||||
int xferred = 0;
|
||||
|
||||
if ((s->cur_state != SRV_ST_STOPPED) && (s->next_state == SRV_ST_STOPPED)) {
|
||||
srv_lb_propagate(s);
|
||||
@ -5312,7 +5295,7 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
"%sServer %s/%s is DOWN", s->flags & SRV_F_BACKUP ? "Backup " : "",
|
||||
s->proxy->id, s->id);
|
||||
|
||||
srv_append_op_chg_cause(tmptrash, s, op_cause);
|
||||
srv_append_op_chg_cause(tmptrash, s, cause);
|
||||
srv_append_more(tmptrash, s, xferred, 0);
|
||||
|
||||
ha_warning("%s.\n", tmptrash->area);
|
||||
@ -5323,8 +5306,6 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
tmptrash->area);
|
||||
send_email_alert(s, log_level, "%s",
|
||||
tmptrash->area);
|
||||
free_trash_chunk(tmptrash);
|
||||
tmptrash = NULL;
|
||||
}
|
||||
}
|
||||
else if ((s->cur_state != SRV_ST_STOPPING) && (s->next_state == SRV_ST_STOPPING)) {
|
||||
@ -5342,7 +5323,7 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
"%sServer %s/%s is stopping", s->flags & SRV_F_BACKUP ? "Backup " : "",
|
||||
s->proxy->id, s->id);
|
||||
|
||||
srv_append_op_chg_cause(tmptrash, s, op_cause);
|
||||
srv_append_op_chg_cause(tmptrash, s, cause);
|
||||
srv_append_more(tmptrash, s, xferred, 0);
|
||||
|
||||
ha_warning("%s.\n", tmptrash->area);
|
||||
@ -5385,7 +5366,7 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
"%sServer %s/%s is UP", s->flags & SRV_F_BACKUP ? "Backup " : "",
|
||||
s->proxy->id, s->id);
|
||||
|
||||
srv_append_op_chg_cause(tmptrash, s, op_cause);
|
||||
srv_append_op_chg_cause(tmptrash, s, cause);
|
||||
srv_append_more(tmptrash, s, xferred, 0);
|
||||
|
||||
ha_warning("%s.\n", tmptrash->area);
|
||||
@ -5401,11 +5382,22 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
/* now propagate the status change to any LB algorithms */
|
||||
srv_lb_propagate(s);
|
||||
}
|
||||
|
||||
s->next_admin = next_admin;
|
||||
return xferred;
|
||||
}
|
||||
|
||||
/* Now we try to apply pending admin changes */
|
||||
/* deduct and update server state from an administrative change
|
||||
* (use current and next admin to deduct the administrative transition that
|
||||
* may result in server state update)
|
||||
*
|
||||
* The function returns the number of requeued sessions (either taken by
|
||||
* the server or redispatched to others servers) due to the server state
|
||||
* change.
|
||||
*/
|
||||
static int _srv_update_status_adm(struct server *s, enum srv_adm_st_chg_cause cause)
|
||||
{
|
||||
struct buffer *tmptrash = NULL;
|
||||
int srv_was_stopping = (s->cur_state == SRV_ST_STOPPING) || (s->cur_admin & SRV_ADMF_DRAIN);
|
||||
int xferred = 0;
|
||||
|
||||
/* Maintenance must also disable health checks */
|
||||
if (!(s->cur_admin & SRV_ADMF_MAINT) && (s->next_admin & SRV_ADMF_MAINT)) {
|
||||
@ -5420,7 +5412,7 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
chunk_printf(tmptrash,
|
||||
"%sServer %s/%s was DOWN and now enters maintenance",
|
||||
s->flags & SRV_F_BACKUP ? "Backup " : "", s->proxy->id, s->id);
|
||||
srv_append_adm_chg_cause(tmptrash, s, adm_cause);
|
||||
srv_append_adm_chg_cause(tmptrash, s, cause);
|
||||
srv_append_more(tmptrash, s, -1, (s->next_admin & SRV_ADMF_FMAINT));
|
||||
|
||||
if (!(global.mode & MODE_STARTING)) {
|
||||
@ -5458,7 +5450,7 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
"%sServer %s/%s is going DOWN for maintenance",
|
||||
s->flags & SRV_F_BACKUP ? "Backup " : "",
|
||||
s->proxy->id, s->id);
|
||||
srv_append_adm_chg_cause(tmptrash, s, adm_cause);
|
||||
srv_append_adm_chg_cause(tmptrash, s, cause);
|
||||
srv_append_more(tmptrash, s, xferred, (s->next_admin & SRV_ADMF_FMAINT));
|
||||
|
||||
if (!(global.mode & MODE_STARTING)) {
|
||||
@ -5640,7 +5632,7 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
if (tmptrash) {
|
||||
chunk_printf(tmptrash, "%sServer %s/%s enters drain state",
|
||||
s->flags & SRV_F_BACKUP ? "Backup " : "", s->proxy->id, s->id);
|
||||
srv_append_adm_chg_cause(tmptrash, s, adm_cause);
|
||||
srv_append_adm_chg_cause(tmptrash, s, cause);
|
||||
srv_append_more(tmptrash, s, xferred, (s->next_admin & SRV_ADMF_FDRAIN));
|
||||
|
||||
if (!(global.mode & MODE_STARTING)) {
|
||||
@ -5717,6 +5709,28 @@ static void srv_update_status(struct server *s, int type, int cause)
|
||||
}
|
||||
}
|
||||
}
|
||||
return xferred;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function applies server's status changes.
|
||||
*
|
||||
* Must be called with the server lock held. This may also be called at init
|
||||
* time as the result of parsing the state file, in which case no lock will be
|
||||
* held, and the server's warmup task can be null.
|
||||
* <type> should be 0 for operational and 1 for administrative
|
||||
* <cause> must be srv_op_st_chg_cause enum for operational and
|
||||
* srv_adm_st_chg_cause enum for administrative
|
||||
*/
|
||||
static void srv_update_status(struct server *s, int type, int cause)
|
||||
{
|
||||
int prev_srv_count = s->proxy->srv_bck + s->proxy->srv_act;
|
||||
enum srv_state srv_prev_state = s->cur_state;
|
||||
|
||||
if (type)
|
||||
_srv_update_status_adm(s, cause);
|
||||
else
|
||||
_srv_update_status_op(s, cause);
|
||||
|
||||
/* explicitly commit state changes (even if it was already applied implicitly
|
||||
* by some lb state change function), so we don't miss anything
|
||||
|
Loading…
Reference in New Issue
Block a user