This is an automated email from the ASF dual-hosted git repository.

spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git


The following commit(s) were added to refs/heads/master by this push:
     new e7d26dc  feat: allow user-defined balancer with metadata in node 
(#4605)
e7d26dc is described below

commit e7d26dc4f0bd690c288867a248a69f0efeaea733
Author: 罗泽轩 <[email protected]>
AuthorDate: Wed Jul 21 13:06:04 2021 +0800

    feat: allow user-defined balancer with metadata in node (#4605)
---
 apisix/schema_def.lua       |  1 -
 apisix/utils/upstream.lua   |  2 +-
 docs/en/latest/admin-api.md |  1 +
 docs/zh/latest/admin-api.md |  1 +
 t/admin/upstream.t          |  9 ++---
 t/node/invalid-upstream.t   | 33 +---------------
 t/node/upstream-discovery.t | 95 ++++++++++++++++++++++++++++++++++++++++++++-
 7 files changed, 103 insertions(+), 39 deletions(-)

diff --git a/apisix/schema_def.lua b/apisix/schema_def.lua
index 5e67b92..58d6a04 100644
--- a/apisix/schema_def.lua
+++ b/apisix/schema_def.lua
@@ -420,7 +420,6 @@ local upstream_schema = {
         type = {
             description = "algorithms of load balancing",
             type = "string",
-            enum = {"chash", "roundrobin", "ewma", "least_conn"}
         },
         checks = health_checker,
         hash_on = {
diff --git a/apisix/utils/upstream.lua b/apisix/utils/upstream.lua
index 4417f07..74666da 100644
--- a/apisix/utils/upstream.lua
+++ b/apisix/utils/upstream.lua
@@ -47,7 +47,7 @@ function _M.compare_upstream_node(up_conf, new_t)
     for i = 1, #new_t do
         local new_node = new_t[i]
         local old_node = old_t[i]
-        for _, name in ipairs({"host", "port", "weight", "priority"}) do
+        for _, name in ipairs({"host", "port", "weight", "priority", 
"metadata"}) do
             if new_node[name] ~= old_node[name] then
                 return false
             end
diff --git a/docs/en/latest/admin-api.md b/docs/en/latest/admin-api.md
index 95612db..7ed1097 100644
--- a/docs/en/latest/admin-api.md
+++ b/docs/en/latest/admin-api.md
@@ -568,6 +568,7 @@ In addition to the basic complex equalization algorithm 
selection, APISIX's Upst
 * `chash`: consistent hash
 * `ewma`: pick one of node which has minimum latency. See 
https://en.wikipedia.org/wiki/EWMA_chart for details.
 * `least_conn`: pick node which has the lowest `(active_conn + 1) / weight`. 
Note the `active connection` concept is the same with Nginx: it is a connection 
in used by a request.
+* user-defined balancer which can be loaed via 
`require("apisix.balancer.your_balancer")`.
 
 `hash_on` can be set to different types:
 
diff --git a/docs/zh/latest/admin-api.md b/docs/zh/latest/admin-api.md
index de34148..ba907de 100644
--- a/docs/zh/latest/admin-api.md
+++ b/docs/zh/latest/admin-api.md
@@ -574,6 +574,7 @@ APISIX 的 Upstream 除了基本的负载均衡算法选择外,还支持对上
 - `chash`: 一致性哈希
 - `ewma`: 选择延迟最小的节点,计算细节参考 https://en.wikipedia.org/wiki/EWMA_chart
 - `least_conn`: 选择 `(active_conn + 1) / weight` 最小的节点。注意这里的 `active 
connection` 概念跟 Nginx 的相同:它是当前正在被请求使用的连接。
+- 用户自定义的 balancer,需要可以通过 `require("apisix.balancer.your_balancer")` 来加载。
 
 `hash_on` 比较复杂,这里专门说明下:
 
diff --git a/t/admin/upstream.t b/t/admin/upstream.t
index 270d20a..f7ad365 100644
--- a/t/admin/upstream.t
+++ b/t/admin/upstream.t
@@ -453,7 +453,7 @@ passed
 
 
 
-=== TEST 13: invalid type
+=== TEST 13: unknown type
 --- config
     location /t {
         content_by_lua_block {
@@ -465,7 +465,7 @@ passed
                     "nodes": {
                         "127.0.0.1:8080": 1
                     },
-                    "type": "invalid_type"
+                    "type": "unknown"
                 }]]
                 )
 
@@ -475,9 +475,8 @@ passed
     }
 --- request
 GET /t
---- error_code: 400
---- response_body
-{"error_msg":"invalid configuration: property \"type\" validation failed: 
matches none of the enum values"}
+--- response_body chomp
+passed
 --- no_error_log
 [error]
 
diff --git a/t/node/invalid-upstream.t b/t/node/invalid-upstream.t
index 5f1f3f5..1ef50b7 100644
--- a/t/node/invalid-upstream.t
+++ b/t/node/invalid-upstream.t
@@ -89,36 +89,7 @@ passed
 
 
 
-=== TEST 4: invalid upstream(wrong type)
---- config
-    location /t {
-        content_by_lua_block {
-            local t = require("lib.test_admin").test
-            local code, body = t('/apisix/admin/upstreams/1',
-                ngx.HTTP_PUT,
-                [[{
-                    "nodes": {
-                        "127.0.0.1:1980": 1
-                    },
-                    "type": "roundrobin_invalid"
-                }]]
-            )
-
-            if code >= 300 then
-                ngx.status = code
-            end
-            ngx.print(body)
-        }
-    }
---- request
-GET /t
---- error_code: 400
---- response_body
-{"error_msg":"invalid configuration: property \"type\" validation failed: 
matches none of the enum values"}
-
-
-
-=== TEST 5: set valid upstream(id: 1)
+=== TEST 4: set valid upstream(id: 1)
 --- config
     location /t {
         content_by_lua_block {
@@ -145,7 +116,7 @@ qr/"nodes":\{"127.0.0.1:1980":1\}/
 
 
 
-=== TEST 6: no error log
+=== TEST 5: no error log
 --- config
     location /t {
         content_by_lua_block {
diff --git a/t/node/upstream-discovery.t b/t/node/upstream-discovery.t
index 4c9306e..8ce9606 100644
--- a/t/node/upstream-discovery.t
+++ b/t/node/upstream-discovery.t
@@ -334,7 +334,100 @@ proxy request to 0.0.0.0:1980
 
 
 
-=== TEST 7: bad nodes return by the discovery
+=== TEST 7: create new server picker when metadata change
+--- apisix_yaml
+routes:
+  -
+    uris:
+        - /hello
+    upstream_id: 1
+--- config
+    location /t {
+        content_by_lua_block {
+            local discovery = require("apisix.discovery.init").discovery
+            discovery.mock = {
+                nodes = function()
+                    return {
+                        {host = "127.0.0.1", port = 1980, weight = 1, metadata 
= {a = 1}},
+                        {host = "0.0.0.0", port = 1980, weight = 1, metadata = 
{}},
+                    }
+                end
+            }
+            local http = require "resty.http"
+            local uri = "http://127.0.0.1:"; .. ngx.var.server_port .. "/hello"
+            local httpc = http.new()
+            local res, err = httpc:request_uri(uri, {method = "GET", keepalive 
= false})
+            ngx.say(res.status)
+
+            discovery.mock = {
+                nodes = function()
+                    return {
+                        {host = "127.0.0.1", port = 1980, weight = 1, metadata 
= {a = 1}},
+                        {host = "0.0.0.0", port = 1980, weight = 1, metadata = 
{b = 1}},
+                    }
+                end
+            }
+            local uri = "http://127.0.0.1:"; .. ngx.var.server_port .. "/hello"
+            local httpc = http.new()
+            local res, err = httpc:request_uri(uri, {method = "GET", keepalive 
= false})
+        }
+    }
+--- grep_error_log eval
+qr/create_obj_fun\(\): upstream nodes:/
+--- grep_error_log_out
+create_obj_fun(): upstream nodes:
+create_obj_fun(): upstream nodes:
+
+
+
+=== TEST 8: don't create new server picker when metadata doesn't change
+--- apisix_yaml
+routes:
+  -
+    uris:
+        - /hello
+    upstream_id: 1
+--- config
+    location /t {
+        content_by_lua_block {
+            local discovery = require("apisix.discovery.init").discovery
+            local meta1 = {a = 1}
+            local meta2 = {b = 2}
+            discovery.mock = {
+                nodes = function()
+                    return {
+                        {host = "127.0.0.1", port = 1980, weight = 1, metadata 
= meta1},
+                        {host = "0.0.0.0", port = 1980, weight = 1, metadata = 
meta2},
+                    }
+                end
+            }
+            local http = require "resty.http"
+            local uri = "http://127.0.0.1:"; .. ngx.var.server_port .. "/hello"
+            local httpc = http.new()
+            local res, err = httpc:request_uri(uri, {method = "GET", keepalive 
= false})
+            ngx.say(res.status)
+
+            discovery.mock = {
+                nodes = function()
+                    return {
+                        {host = "127.0.0.1", port = 1980, weight = 1, metadata 
= meta1},
+                        {host = "0.0.0.0", port = 1980, weight = 1, metadata = 
meta2},
+                    }
+                end
+            }
+            local uri = "http://127.0.0.1:"; .. ngx.var.server_port .. "/hello"
+            local httpc = http.new()
+            local res, err = httpc:request_uri(uri, {method = "GET", keepalive 
= false})
+        }
+    }
+--- grep_error_log eval
+qr/create_obj_fun\(\): upstream nodes:/
+--- grep_error_log_out
+create_obj_fun(): upstream nodes:
+
+
+
+=== TEST 9: bad nodes return by the discovery
 --- apisix_yaml
 routes:
   -

Reply via email to