mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-26 06:32:13 +00:00
[MAJOR] migrate the connection logic to stream interface
The connection setup code has been refactored in order to make it run only on low level (stream interface). Several complicated functions have been removed from backend.c, and we now have sess_update_stream_int() to manage an assigned connection, sess_prepare_conn_req() to assign a server to a connection request, perform_http_redirect() to redirect instead of connecting to server, and return_srv_error() to return connection error status messages. The stream_interface status changes are checked before adjusting buffer flags, so that the buffers can be informed about this lower level update. A new connection is initiated by changing si->state from SI_ST_INI to SI_ST_REQ. The code seems to work but is awfully dirty. Some functions need to be moved, and the layering is not yet quite clear. A lot of dead old code has simply been removed.
This commit is contained in:
parent
d7704b5343
commit
efb453c259
@ -2,7 +2,7 @@
|
||||
include/proto/backend.h
|
||||
Functions prototypes for the backend.
|
||||
|
||||
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
|
||||
Copyright (C) 2000-2008 Willy Tarreau - w@1wt.eu
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
@ -33,8 +33,6 @@ int assign_server(struct session *s);
|
||||
int assign_server_address(struct session *s);
|
||||
int assign_server_and_queue(struct session *s);
|
||||
int connect_server(struct session *s);
|
||||
int srv_count_retry_down(struct session *t, int conn_err);
|
||||
int srv_retryable_connect(struct session *t);
|
||||
int srv_redispatch_connect(struct session *t);
|
||||
int backend_parse_balance(const char **args, char *err,
|
||||
int errlen, struct proxy *curproxy);
|
||||
|
@ -111,7 +111,7 @@ static inline void buffer_shutw(struct buffer *buf)
|
||||
/* marks the buffer as "shutdown" ASAP for reads */
|
||||
static inline void buffer_shutr_now(struct buffer *buf)
|
||||
{
|
||||
buf->flags |= BF_SHUTR_NOW;
|
||||
buf->flags |= BF_SHUTR_NOW | BF_SHUTR;
|
||||
}
|
||||
|
||||
/* marks the buffer as "shutdown" ASAP for writes */
|
||||
@ -123,7 +123,7 @@ static inline void buffer_shutw_now(struct buffer *buf)
|
||||
/* marks the buffer as "shutdown" ASAP in both directions */
|
||||
static inline void buffer_abort(struct buffer *buf)
|
||||
{
|
||||
buf->flags |= BF_SHUTR_NOW | BF_SHUTW_NOW;
|
||||
buf->flags |= BF_SHUTR_NOW | BF_SHUTR | BF_SHUTW_NOW;
|
||||
}
|
||||
|
||||
/* set the buffer to hijacking mode */
|
||||
|
@ -32,7 +32,8 @@
|
||||
* interface is performing some retries (eg: connection error).
|
||||
*/
|
||||
enum {
|
||||
SI_ST_INI = 0, /* interface not initialized yet and might not exist */
|
||||
SI_ST_INI = 0, /* interface not sollicitated yet */
|
||||
SI_ST_REQ, /* connection initiation desired and not started yet */
|
||||
SI_ST_QUE, /* interface waiting in queue */
|
||||
SI_ST_TAR, /* interface in turn-around state after failed connect attempt */
|
||||
SI_ST_ASS, /* server just assigned to this interface */
|
||||
|
102
src/backend.c
102
src/backend.c
@ -1832,108 +1832,6 @@ int connect_server(struct session *s)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function checks the retry count during the connect() job.
|
||||
* It updates the session's retries, so that the caller knows what it
|
||||
* has to do. It uses the last connection error to set the log when
|
||||
* it expires. It returns 1 when it has expired, and 0 otherwise.
|
||||
*/
|
||||
int srv_count_retry_down(struct session *t, int conn_err)
|
||||
{
|
||||
/* we are in front of a retryable error */
|
||||
t->conn_retries--;
|
||||
|
||||
if (t->conn_retries < 0) {
|
||||
/* if not retryable anymore, let's abort */
|
||||
//t->req->wex = TICK_ETERNITY;
|
||||
//srv_close_with_err(t, conn_err, SN_FINST_C,
|
||||
// 503, error_message(t, HTTP_ERR_503));
|
||||
|
||||
if (!t->req->cons->err_type) {
|
||||
t->req->cons->err_type = SI_ET_CONN_ERR;
|
||||
t->req->cons->err_loc = t->srv;
|
||||
}
|
||||
|
||||
if (t->srv)
|
||||
t->srv->failed_conns++;
|
||||
t->be->failed_conns++;
|
||||
|
||||
/* We used to have a free connection slot. Since we'll never use it,
|
||||
* we have to inform the server that it may be used by another session.
|
||||
*/
|
||||
if (may_dequeue_tasks(t->srv, t->be))
|
||||
process_srv_queue(t->srv);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This function performs the retryable part of the connect() job.
|
||||
* It updates the session's and retries, so that the caller knows
|
||||
* what it has to do. It returns 1 when it breaks out of the loop,
|
||||
* or 0 if it needs to redispatch.
|
||||
*/
|
||||
int srv_retryable_connect(struct session *t)
|
||||
{
|
||||
int conn_err;
|
||||
|
||||
/* This loop ensures that we stop before the last retry in case of a
|
||||
* redispatchable server.
|
||||
*/
|
||||
do {
|
||||
/* initiate a connection to the server */
|
||||
conn_err = connect_server(t);
|
||||
switch (conn_err) {
|
||||
|
||||
case SN_ERR_NONE:
|
||||
//fprintf(stderr,"0: c=%d, s=%d\n", c, s);
|
||||
if (t->srv)
|
||||
t->srv->cum_sess++;
|
||||
return 1;
|
||||
|
||||
case SN_ERR_INTERNAL:
|
||||
if (!t->req->cons->err_type) {
|
||||
t->req->cons->err_type = SI_ET_CONN_OTHER;
|
||||
t->req->cons->err_loc = t->srv;
|
||||
}
|
||||
|
||||
//t->req->wex = TICK_ETERNITY;
|
||||
//srv_close_with_err(t, SN_ERR_INTERNAL, SN_FINST_C,
|
||||
// 500, error_message(t, HTTP_ERR_500));
|
||||
if (t->srv)
|
||||
t->srv->cum_sess++;
|
||||
if (t->srv)
|
||||
t->srv->failed_conns++;
|
||||
t->be->failed_conns++;
|
||||
/* release other sessions waiting for this server */
|
||||
if (may_dequeue_tasks(t->srv, t->be))
|
||||
process_srv_queue(t->srv);
|
||||
return 1;
|
||||
}
|
||||
/* ensure that we have enough retries left */
|
||||
if (srv_count_retry_down(t, conn_err))
|
||||
return 1;
|
||||
} while (t->srv == NULL || t->conn_retries > 0 || !(t->be->options & PR_O_REDISP));
|
||||
|
||||
/* We're on our last chance, and the REDISP option was specified.
|
||||
* We will ignore cookie and force to balance or use the dispatcher.
|
||||
*/
|
||||
/* let's try to offer this slot to anybody */
|
||||
if (may_dequeue_tasks(t->srv, t->be))
|
||||
process_srv_queue(t->srv);
|
||||
|
||||
if (t->srv)
|
||||
t->srv->cum_sess++; //FIXME?
|
||||
|
||||
/* it's left to the dispatcher to choose a server */
|
||||
t->flags &= ~(SN_DIRECT | SN_ASSIGNED | SN_ADDR_SET);
|
||||
t->prev_srv = t->srv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* This function performs the "redispatch" part of a connection attempt. It
|
||||
* will assign a server if required, queue the connection if required, and
|
||||
* handle errors that might arise at this level. It can change the server
|
||||
|
989
src/proto_http.c
989
src/proto_http.c
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user