Mercurial > hg > nginx-quic
view src/os/unix/ngx_files.h @ 4667:d05ab8793a69 stable-1.2
Merge of r4622, r4623: balancing changes.
*) Upstream: smooth weighted round-robin balancing.
For edge case weights like { 5, 1, 1 } we now produce { a, a, b, a, c, a, a }
sequence instead of { c, b, a, a, a, a, a } produced previously.
Algorithm is as follows: on each peer selection we increase current_weight
of each eligible peer by its weight, select peer with greatest current_weight
and reduce its current_weight by total number of weight points distributed
among peers.
In case of { 5, 1, 1 } weights this gives the following sequence of
current_weight's:
a b c
0 0 0 (initial state)
5 1 1 (a selected)
-2 1 1
3 2 2 (a selected)
-4 2 2
1 3 3 (b selected)
1 -4 3
6 -3 4 (a selected)
-1 -3 4
4 -2 5 (c selected)
4 -2 -2
9 -1 -1 (a selected)
2 -1 -1
7 0 0 (a selected)
0 0 0
To preserve weight reduction in case of failures the effective_weight
variable was introduced, which usually matches peer's weight, but is
reduced temporarily on peer failures.
This change also fixes loop with backup servers and proxy_next_upstream
http_404 (ticket #47), and skipping alive upstreams in some cases if there
are multiple dead ones (ticket #64).
*) Upstream: fixed ip_hash rebalancing with the "down" flag.
Due to weight being set to 0 for down peers, order of peers after sorting
wasn't the same as without the "down" flag (with down peers at the end),
resulting in client rebalancing for clients on other servers. The only
rebalancing which should happen after adding "down" to a server is one
for clients on the server.
The problem was introduced in r1377 (which fixed endless loop by setting
weight to 0 for down servers). The loop is no longer possible with new
smooth algorithm, so preserving original weight is safe.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 04 Jun 2012 11:21:58 +0000 |
parents | 8865fd1f3aa5 |
children | 626f288fa5ed |
line wrap: on
line source
/* * Copyright (C) Igor Sysoev * Copyright (C) Nginx, Inc. */ #ifndef _NGX_FILES_H_INCLUDED_ #define _NGX_FILES_H_INCLUDED_ #include <ngx_config.h> #include <ngx_core.h> typedef int ngx_fd_t; typedef struct stat ngx_file_info_t; typedef ino_t ngx_file_uniq_t; typedef struct { u_char *name; size_t size; void *addr; ngx_fd_t fd; ngx_log_t *log; } ngx_file_mapping_t; typedef struct { DIR *dir; struct dirent *de; struct stat info; unsigned type:8; unsigned valid_info:1; } ngx_dir_t; typedef struct { size_t n; glob_t pglob; u_char *pattern; ngx_log_t *log; ngx_uint_t test; } ngx_glob_t; #define NGX_INVALID_FILE -1 #define NGX_FILE_ERROR -1 #ifdef __CYGWIN__ #define NGX_HAVE_CASELESS_FILESYSTEM 1 #define ngx_open_file(name, mode, create, access) \ open((const char *) name, mode|create|O_BINARY, access) #else #define ngx_open_file(name, mode, create, access) \ open((const char *) name, mode|create, access) #endif #define ngx_open_file_n "open()" #define NGX_FILE_RDONLY O_RDONLY #define NGX_FILE_WRONLY O_WRONLY #define NGX_FILE_RDWR O_RDWR #define NGX_FILE_CREATE_OR_OPEN O_CREAT #define NGX_FILE_OPEN 0 #define NGX_FILE_TRUNCATE O_CREAT|O_TRUNC #define NGX_FILE_APPEND O_WRONLY|O_APPEND #define NGX_FILE_NONBLOCK O_NONBLOCK #if (NGX_HAVE_OPENAT) #define NGX_FILE_NOFOLLOW O_NOFOLLOW #if defined(O_DIRECTORY) #define NGX_FILE_DIRECTORY O_DIRECTORY #else #define NGX_FILE_DIRECTORY 0 #endif #if defined(O_SEARCH) #define NGX_FILE_SEARCH O_SEARCH|NGX_FILE_DIRECTORY #elif defined(O_EXEC) #define NGX_FILE_SEARCH O_EXEC|NGX_FILE_DIRECTORY #else #define NGX_FILE_SEARCH O_RDONLY|NGX_FILE_DIRECTORY #endif #endif /* NGX_HAVE_OPENAT */ #define NGX_FILE_DEFAULT_ACCESS 0644 #define NGX_FILE_OWNER_ACCESS 0600 #define ngx_close_file close #define ngx_close_file_n "close()" #define ngx_delete_file(name) unlink((const char *) name) #define ngx_delete_file_n "unlink()" ngx_fd_t ngx_open_tempfile(u_char *name, ngx_uint_t persistent, ngx_uint_t access); #define ngx_open_tempfile_n "open()" ssize_t ngx_read_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset); #if (NGX_HAVE_PREAD) #define ngx_read_file_n "pread()" #else #define ngx_read_file_n "read()" #endif ssize_t ngx_write_file(ngx_file_t *file, u_char *buf, size_t size, off_t offset); ssize_t ngx_write_chain_to_file(ngx_file_t *file, ngx_chain_t *ce, off_t offset, ngx_pool_t *pool); #define ngx_read_fd read #define ngx_read_fd_n "read()" /* * we use inlined function instead of simple #define * because glibc 2.3 sets warn_unused_result attribute for write() * and in this case gcc 4.3 ignores (void) cast */ static ngx_inline ssize_t ngx_write_fd(ngx_fd_t fd, void *buf, size_t n) { return write(fd, buf, n); } #define ngx_write_fd_n "write()" #define ngx_write_console ngx_write_fd #define ngx_linefeed(p) *p++ = LF; #define NGX_LINEFEED_SIZE 1 #define NGX_LINEFEED "\x0a" #define ngx_rename_file(o, n) rename((const char *) o, (const char *) n) #define ngx_rename_file_n "rename()" #define ngx_change_file_access(n, a) chmod((const char *) n, a) #define ngx_change_file_access_n "chmod()" ngx_int_t ngx_set_file_time(u_char *name, ngx_fd_t fd, time_t s); #define ngx_set_file_time_n "utimes()" #define ngx_file_info(file, sb) stat((const char *) file, sb) #define ngx_file_info_n "stat()" #define ngx_fd_info(fd, sb) fstat(fd, sb) #define ngx_fd_info_n "fstat()" #define ngx_link_info(file, sb) lstat((const char *) file, sb) #define ngx_link_info_n "lstat()" #define ngx_is_dir(sb) (S_ISDIR((sb)->st_mode)) #define ngx_is_file(sb) (S_ISREG((sb)->st_mode)) #define ngx_is_link(sb) (S_ISLNK((sb)->st_mode)) #define ngx_is_exec(sb) (((sb)->st_mode & S_IXUSR) == S_IXUSR) #define ngx_file_access(sb) ((sb)->st_mode & 0777) #define ngx_file_size(sb) (sb)->st_size #define ngx_file_fs_size(sb) ngx_max((sb)->st_size, (sb)->st_blocks * 512) #define ngx_file_mtime(sb) (sb)->st_mtime #define ngx_file_uniq(sb) (sb)->st_ino ngx_int_t ngx_create_file_mapping(ngx_file_mapping_t *fm); void ngx_close_file_mapping(ngx_file_mapping_t *fm); #if (NGX_HAVE_CASELESS_FILESYSTEM) #define ngx_filename_cmp(s1, s2, n) strncasecmp((char *) s1, (char *) s2, n) #else #define ngx_filename_cmp ngx_memcmp #endif #define ngx_realpath(p, r) (u_char *) realpath((char *) p, (char *) r) #define ngx_realpath_n "realpath()" #define ngx_getcwd(buf, size) (getcwd((char *) buf, size) != NULL) #define ngx_getcwd_n "getcwd()" #define ngx_path_separator(c) ((c) == '/') #if defined(PATH_MAX) #define NGX_HAVE_MAX_PATH 1 #define NGX_MAX_PATH PATH_MAX #else #define NGX_MAX_PATH 4096 #endif #define NGX_DIR_MASK_LEN 0 ngx_int_t ngx_open_dir(ngx_str_t *name, ngx_dir_t *dir); #define ngx_open_dir_n "opendir()" #define ngx_close_dir(d) closedir((d)->dir) #define ngx_close_dir_n "closedir()" ngx_int_t ngx_read_dir(ngx_dir_t *dir); #define ngx_read_dir_n "readdir()" #define ngx_create_dir(name, access) mkdir((const char *) name, access) #define ngx_create_dir_n "mkdir()" #define ngx_delete_dir(name) rmdir((const char *) name) #define ngx_delete_dir_n "rmdir()" #define ngx_dir_access(a) (a | (a & 0444) >> 2) #define ngx_de_name(dir) ((u_char *) (dir)->de->d_name) #if (NGX_HAVE_D_NAMLEN) #define ngx_de_namelen(dir) (dir)->de->d_namlen #else #define ngx_de_namelen(dir) ngx_strlen((dir)->de->d_name) #endif static ngx_inline ngx_int_t ngx_de_info(u_char *name, ngx_dir_t *dir) { dir->type = 0; return stat((const char *) name, &dir->info); } #define ngx_de_info_n "stat()" #define ngx_de_link_info(name, dir) lstat((const char *) name, &(dir)->info) #define ngx_de_link_info_n "lstat()" #if (NGX_HAVE_D_TYPE) /* * some file systems (e.g. XFS on Linux and CD9660 on FreeBSD) * do not set dirent.d_type */ #define ngx_de_is_dir(dir) \ (((dir)->type) ? ((dir)->type == DT_DIR) : (S_ISDIR((dir)->info.st_mode))) #define ngx_de_is_file(dir) \ (((dir)->type) ? ((dir)->type == DT_REG) : (S_ISREG((dir)->info.st_mode))) #define ngx_de_is_link(dir) \ (((dir)->type) ? ((dir)->type == DT_LNK) : (S_ISLNK((dir)->info.st_mode))) #else #define ngx_de_is_dir(dir) (S_ISDIR((dir)->info.st_mode)) #define ngx_de_is_file(dir) (S_ISREG((dir)->info.st_mode)) #define ngx_de_is_link(dir) (S_ISLNK((dir)->info.st_mode)) #endif #define ngx_de_access(dir) (((dir)->info.st_mode) & 0777) #define ngx_de_size(dir) (dir)->info.st_size #define ngx_de_fs_size(dir) \ ngx_max((dir)->info.st_size, (dir)->info.st_blocks * 512) #define ngx_de_mtime(dir) (dir)->info.st_mtime ngx_int_t ngx_open_glob(ngx_glob_t *gl); #define ngx_open_glob_n "glob()" ngx_int_t ngx_read_glob(ngx_glob_t *gl, ngx_str_t *name); void ngx_close_glob(ngx_glob_t *gl); ngx_err_t ngx_trylock_fd(ngx_fd_t fd); ngx_err_t ngx_lock_fd(ngx_fd_t fd); ngx_err_t ngx_unlock_fd(ngx_fd_t fd); #define ngx_trylock_fd_n "fcntl(F_SETLK, F_WRLCK)" #define ngx_lock_fd_n "fcntl(F_SETLKW, F_WRLCK)" #define ngx_unlock_fd_n "fcntl(F_SETLK, F_UNLCK)" #if (NGX_HAVE_F_READAHEAD) #define NGX_HAVE_READ_AHEAD 1 #define ngx_read_ahead(fd, n) fcntl(fd, F_READAHEAD, (int) n) #define ngx_read_ahead_n "fcntl(fd, F_READAHEAD)" #elif (NGX_HAVE_POSIX_FADVISE) #define NGX_HAVE_READ_AHEAD 1 ngx_int_t ngx_read_ahead(ngx_fd_t fd, size_t n); #define ngx_read_ahead_n "posix_fadvise(POSIX_FADV_SEQUENTIAL)" #else #define ngx_read_ahead(fd, n) 0 #define ngx_read_ahead_n "ngx_read_ahead_n" #endif #if (NGX_HAVE_O_DIRECT) ngx_int_t ngx_directio_on(ngx_fd_t fd); #define ngx_directio_on_n "fcntl(O_DIRECT)" ngx_int_t ngx_directio_off(ngx_fd_t fd); #define ngx_directio_off_n "fcntl(!O_DIRECT)" #elif (NGX_HAVE_F_NOCACHE) #define ngx_directio_on(fd) fcntl(fd, F_NOCACHE, 1) #define ngx_directio_on_n "fcntl(F_NOCACHE, 1)" #elif (NGX_HAVE_DIRECTIO) #define ngx_directio_on(fd) directio(fd, DIRECTIO_ON) #define ngx_directio_on_n "directio(DIRECTIO_ON)" #else #define ngx_directio_on(fd) 0 #define ngx_directio_on_n "ngx_directio_on_n" #endif size_t ngx_fs_bsize(u_char *name); #if (NGX_HAVE_OPENAT) #define ngx_openat_file(fd, name, mode, create, access) \ openat(fd, (const char *) name, mode|create, access) #define ngx_openat_file_n "openat()" #define ngx_file_at_info(fd, name, sb, flag) \ fstatat(fd, (const char *) name, sb, flag) #define ngx_file_at_info_n "fstatat()" #define NGX_AT_FDCWD (ngx_fd_t) AT_FDCWD #endif #define ngx_stderr STDERR_FILENO #define ngx_set_stderr(fd) dup2(fd, STDERR_FILENO) #define ngx_set_stderr_n "dup2(STDERR_FILENO)" #if (NGX_HAVE_FILE_AIO) ssize_t ngx_file_aio_read(ngx_file_t *file, u_char *buf, size_t size, off_t offset, ngx_pool_t *pool); extern ngx_uint_t ngx_file_aio; #endif #endif /* _NGX_FILES_H_INCLUDED_ */