Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
32 changes: 26 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,52 @@ addons:
- liburi-perl
- libwww-perl
- perl
- valgrind

cache:
directories:
- download-cache

env:
global:
- JOBS=2
- OPENRESTY_PREFIX=/usr/local/openresty
- OPENRESTY_VER=1.11.2.3
- JOBS=2
- OPENRESTY_PREFIX=/usr/local/openresty
- OPENRESTY_VER=1.19.9.1
jobs:
- TEST_NGINX_USE_VALGRIND=0
- TEST_NGINX_USE_VALGRIND=1

install:
- if [ ! -f download-cache/openresty-$OPENRESTY_VER.tar.gz ]; then
wget -P download-cache https://openresty.org/download/openresty-$OPENRESTY_VER.tar.gz;
fi
- git clone https://github.com/openresty/test-nginx.git ../test-nginx

# install openresty-openssl111-dev
- sudo apt-get -y install --no-install-recommends wget gnupg ca-certificates
- wget -O - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
- echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main"
| sudo tee /etc/apt/sources.list.d/openresty.list
- sudo apt-get update || echo 'apt-get update failed, but ignore it'
- sudo apt-get -y install --no-install-recommends openresty-openssl111 openresty-openssl111-dev

script:
- if [ TEST_NGINX_USE_VALGRIND = 1 ]; then export luajit_xcflags='-DLUAJIT_USE_VALGRIND -DLUAJIT_USE_SYSMALLOC'; fi
- tar xzf download-cache/openresty-$OPENRESTY_VER.tar.gz &&
cd openresty-$OPENRESTY_VER
- ./configure --prefix=$OPENRESTY_PREFIX -j$JOBS
> build.log 2>&1 || (cat build.log && exit 1)
- ./configure --prefix=$OPENRESTY_PREFIX
--with-cc-opt="-I/usr/local/openresty/openssl111/include"
--with-ld-opt="-L/usr/local/openresty/openssl111/lib -Wl,-rpath,/usr/local/openresty/openssl111/lib"
--with-luajit-xcflags="$luajit_xcflags"
-j$JOBS
> build.log 2>&1 || (cat build.log && exit 1)
- make -j$JOBS > build.log 2>&1 ||
(cat build.log && exit 1)
- sudo make install > build.log 2>&1 ||
(cat build.log && exit 1)
- cd ..
- export PATH=$OPENRESTY_PREFIX/nginx/sbin:$PATH
- make test jobs=$JOBS
- make test jobs=$JOBS > build.log 2>&1 ||
(cat build.log && exit 1)
- cat build.log
- if [ `grep -c '== Invalid' build.log` -gt 0 ]; then echo 'valgrind complaining' && exit 1; fi
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ LDFLAGS := -shared
# on Mac OS X, one should set instead:
# LDFLAGS := -bundle -undefined dynamic_lookup

ifeq ($(shell uname),Darwin)
LDFLAGS := -bundle -undefined dynamic_lookup
C_SO_NAME := librestychash.dylib
endif

MY_CFLAGS := $(CFLAGS) -DBUILDING_SO
MY_LDFLAGS := $(LDFLAGS) -fvisibility=hidden

Expand All @@ -39,7 +44,9 @@ clean:; rm -f *.o *.so a.out *.d

install:
$(INSTALL) -d $(DESTDIR)$(LUA_LIB_DIR)/resty
$(INSTALL) -d $(DESTDIR)$(LUA_LIB_DIR)/resty/balancer
$(INSTALL) lib/resty/*.lua $(DESTDIR)$(LUA_LIB_DIR)/resty
$(INSTALL) lib/resty/balancer/*.lua $(DESTDIR)$(LUA_LIB_DIR)/resty/balancer
$(INSTALL) $(C_SO_NAME) $(DESTDIR)$(LUA_LIB_DIR)/

test : all
Expand Down
2 changes: 2 additions & 0 deletions README.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ Synopsis

local rr_up = package.loaded.my_rr_up

-- Note that Round Robin picks the first server randomly
local server = rr_up:find()

assert(b.set_current_peer(server))
Expand Down Expand Up @@ -137,6 +138,7 @@ The `id` should be `table.concat({host, string.char(0), port})` like the nginx c
when we need to keep consistency with nginx chash.

The `id` can be any string value when we do not need to keep consistency with nginx chash.
The `weight` should be a non negative integer.

```lua
local nodes = {
Expand Down
13 changes: 11 additions & 2 deletions chash.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>

#include "chash.h"


Expand Down Expand Up @@ -164,7 +166,9 @@ chash_point_sort(chash_point_t arr[], uint32_t n)

for (i = 0; i < n; i++) {
node = &arr[i];
index = node->hash / step; // can not bigger than m
index = node->hash / step;

assert(index < m); // index must less than m

for (end = index; end >= 0; end--) {
if (points[end].id == 0) {
Expand All @@ -188,7 +192,10 @@ chash_point_sort(chash_point_t arr[], uint32_t n)

/* left shift after end when node->hash is bigger than them */
/* only end == index can match this */
while (points[end + 1].id != 0 && points[end + 1].hash < node->hash) {
while (end + 1 < m
&& points[end + 1].id != 0
&& points[end + 1].hash < node->hash)
{
points[end].hash = points[end + 1].hash;
points[end].id = points[end + 1].id;
end += 1;
Expand Down Expand Up @@ -223,6 +230,8 @@ chash_point_sort(chash_point_t arr[], uint32_t n)
}

insert:
assert(end < m && end >= 0);

points[end].id = node->id;
points[end].hash = node->hash;
}
Expand Down
47 changes: 47 additions & 0 deletions lib/resty/balancer/utils.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
local _M = {}

_M.name = "balancer-utils"
_M.version = "0.03"

local new_tab
do
local ok
ok, new_tab = pcall(require, "table.new")
if not ok or type(new_tab) ~= "function" then
new_tab = function (narr, nrec) return {} end
end
end
_M.new_tab = new_tab


local nkeys, tab_nkeys
do
local ok
ok, nkeys = pcall(require, "table.nkeys")
if not ok or type(nkeys) ~= "function" then
nkeys = function(tab)
local count = 0
for _, _ in pairs(tab) do
count = count + 1
end
return count
end

else
tab_nkeys = nkeys
end
end
_M.nkeys = nkeys


function _M.copy(nodes)
local newnodes = new_tab(0, tab_nkeys and tab_nkeys(nodes) or 4)
for id, weight in pairs(nodes) do
newnodes[id] = tonumber(weight)
end

return newnodes
end


return _M
26 changes: 13 additions & 13 deletions lib/resty/chash.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
local bit = require "bit"
local ffi = require 'ffi'

local utils = require "resty.balancer.utils"

local new_tab = utils.new_tab
local copy = utils.copy

local ffi_new = ffi.new
local C = ffi.C
Expand Down Expand Up @@ -38,13 +42,6 @@ void chash_point_delete(chash_point_t *old_points, uint32_t old_length,
uint32_t id);
]]


local ok, new_tab = pcall(require, "table.new")
if not ok or type(new_tab) ~= "function" then
new_tab = function (narr, nrec) return {} end
end


--
-- Find shared object file package.cpath, obviating the need of setting
-- LD_LIBRARY_PATH
Expand All @@ -58,6 +55,12 @@ local function load_shared_lib(so_name)

local cpath = package.cpath

local postfix = ".so"
if ffi.os == "OSX" then
postfix = ".dylib"
end
so_name = so_name .. postfix

for k, _ in string_gmatch(cpath, "[^;]+") do
local fpath = string_match(k, "(.*/)")
fpath = fpath .. so_name
Expand All @@ -77,9 +80,9 @@ local _M = {}
local mt = { __index = _M }


local clib = load_shared_lib("librestychash.so")
local clib = load_shared_lib("librestychash")
if not clib then
error("can not load librestychash.so")
error("can not load librestychash")
end

local CONSISTENT_POINTS = 160 -- points per server
Expand All @@ -95,10 +98,7 @@ local function _precompute(nodes)
total_weight = total_weight + weight
end

local newnodes = new_tab(0, n)
for id, weight in pairs(nodes) do
newnodes[id] = weight
end
local newnodes = copy(nodes)

local ids = new_tab(n, 0)
local npoints = total_weight * CONSISTENT_POINTS
Expand Down
35 changes: 22 additions & 13 deletions lib/resty/roundrobin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,17 @@ local pairs = pairs
local next = next
local tonumber = tonumber
local setmetatable = setmetatable
local math_random = math.random

local utils = require "resty.balancer.utils"

local copy = utils.copy
local nkeys = utils.nkeys
local new_tab = utils.new_tab

local _M = {}
local mt = { __index = _M }


local function copy(nodes)
local newnodes = {}
for id, weight in pairs(nodes) do
newnodes[id] = weight
end

return newnodes
end


local _gcd
_gcd = function (a, b)
if b == 0 then
Expand Down Expand Up @@ -46,18 +41,32 @@ local function get_gcd(nodes)
return only_key, gcd, max_weight
end

local function get_random_node_id(nodes)
local count = nkeys(nodes)

local id = nil
local random_index = math_random(count)

for _ = 1, random_index do
id = next(nodes, id)
end

return id
end


function _M.new(_, nodes)
local newnodes = copy(nodes)
local only_key, gcd, max_weight = get_gcd(newnodes)
local last_id = get_random_node_id(nodes)

local self = {
nodes = newnodes, -- it's safer to copy one
only_key = only_key,
max_weight = max_weight,
gcd = gcd,
cw = max_weight,
last_id = nil,
last_id = last_id,
}
return setmetatable(self, mt)
end
Expand All @@ -68,7 +77,7 @@ function _M.reinit(self, nodes)
self.only_key, self.gcd, self.max_weight = get_gcd(newnodes)

self.nodes = newnodes
self.last_id = nil
self.last_id = get_random_node_id(nodes)
self.cw = self.max_weight
end

Expand Down
24 changes: 24 additions & 0 deletions lua-resty-balancer-0.04-0.rockspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package = "lua-resty-balancer"
version = "0.04-0"
source = {
url = "git://github.com/openresty/lua-resty-balancer",
tag = "v0.04",
}

description = {
summary = "A generic consistent hash implementation for OpenResty",
homepage = "https://github.com/openresty/lua-resty-balancer",
license = "Apache License 2.0",
maintainer = "Yichun Zhang (agentzh) <agentzh@gmail.com>",
}

build = {
type = "builtin",
modules = {
["librestychash"] = {"chash.c"},

["resty.chash"] = "lib/resty/chash.lua",
["resty.roundrobin"] = "lib/resty/roundrobin.lua",
["resty.balancer.utils"] = "lib/resty/balancer/utils.lua",
}
}
Loading