Skip to content

Commit 876f1fd

Browse files
authored
fix: correct the way to get total upstream_xx_time when retry happened (#6)
1 parent f40967b commit 876f1fd

2 files changed

Lines changed: 151 additions & 3 deletions

File tree

lib/resty/ngxvar/http.lua

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@ local C = ffi.C
55
local ffi_string = ffi.string
66
local ngx = ngx
77
local ngx_var = ngx.var
8+
local re_gmatch = ngx.re.gmatch
89
local str_t = ffi.new("ngx_str_t[1]")
910
local pcall = pcall
1011
local num_type = {}
12+
local ups_num_type = {}
1113
local tonumber = tonumber
14+
local str_find = string.find
1215
local str_buf = get_string_buf(1024)
1316

1417

@@ -107,19 +110,19 @@ end
107110
vars.upstream_response_time = function (r)
108111
return upstream_response_time(r, 0)
109112
end
110-
num_type.upstream_response_time = true
113+
ups_num_type.upstream_response_time = true
111114

112115

113116
vars.upstream_header_time = function (r)
114117
return upstream_response_time(r, 1)
115118
end
116-
num_type.upstream_header_time = true
119+
ups_num_type.upstream_header_time = true
117120

118121

119122
vars.upstream_connect_time = function (r)
120123
return upstream_response_time(r, 2)
121124
end
122-
num_type.upstream_connect_time = true
125+
ups_num_type.upstream_connect_time = true
123126

124127

125128
function vars.scheme(r)
@@ -144,6 +147,11 @@ end
144147
local _M = {}
145148

146149

150+
function _M.enable_patch(state)
151+
var_patched = state
152+
end
153+
154+
147155
function _M.request()
148156
local r = get_request()
149157
if not r then
@@ -154,12 +162,41 @@ function _M.request()
154162
end
155163

156164

165+
local function sum_upstream_num(s)
166+
local idx = str_find(s, " ", 1, true)
167+
if not idx then
168+
-- fast path
169+
return tonumber(s)
170+
end
171+
172+
local sum = 0
173+
local iterator, err = re_gmatch(s, [[(\d+(.\d+)?)]], "jo")
174+
if not iterator then
175+
ngx.log(ngx.ERR, "failed to create iterator: ", err)
176+
return nil
177+
end
178+
179+
while true do
180+
local val = iterator()
181+
if not val then
182+
break
183+
end
184+
185+
sum = sum + tonumber(val[1])
186+
end
187+
188+
return sum
189+
end
190+
191+
157192
function _M.fetch(name, request)
158193
local method = vars[name]
159194

160195
if not var_patched or not method then
161196
if num_type[name] then
162197
return tonumber(ngx_var[name])
198+
elseif ups_num_type[name] then
199+
return sum_upstream_num(ngx_var[name])
163200
end
164201

165202
return ngx_var[name]

t/without_patch.t

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# vim:set ft= ts=4 sw=4 et fdm=marker:
2+
3+
use Test::Nginx::Socket::Lua 'no_plan';
4+
5+
repeat_each(2);
6+
no_diff();
7+
no_long_string();
8+
log_level('info');
9+
10+
our $HttpConfig = <<"_EOC_";
11+
resolver ipv6=off local=on;
12+
13+
lua_package_path "lib/?.lua;;";
14+
init_by_lua_block {
15+
require "resty.core"
16+
package.loaded.mock = {}
17+
ngx.var = package.loaded.mock
18+
local var = require("resty.ngxvar")
19+
var.enable_patch(false)
20+
}
21+
_EOC_
22+
23+
add_block_preprocessor(sub {
24+
my ($block) = @_;
25+
26+
if (!$block->http_config) {
27+
$block->set_value("http_config", $HttpConfig);
28+
}
29+
30+
if (!$block->request) {
31+
$block->set_value("request", "GET /t");
32+
}
33+
34+
if (!$block->error_log && !$block->no_error_log) {
35+
$block->set_value("no_error_log", "[error]\n[alert]");
36+
}
37+
});
38+
39+
run_tests();
40+
41+
__DATA__
42+
43+
=== TEST 1: upstream_response_time
44+
--- config
45+
location /t {
46+
content_by_lua_block {
47+
package.loaded.mock.upstream_response_time = "102.023"
48+
local var = require("resty.ngxvar")
49+
ngx.say(var.fetch("upstream_response_time"))
50+
ngx.say(type(var.fetch("upstream_response_time")))
51+
52+
package.loaded.mock.upstream_response_time = "102.023, 0.000"
53+
ngx.say(var.fetch("upstream_response_time"))
54+
55+
package.loaded.mock.upstream_response_time = "102.023 : 1.200"
56+
ngx.say(var.fetch("upstream_response_time"))
57+
}
58+
}
59+
--- response_body
60+
102.023
61+
number
62+
102.023
63+
103.223
64+
65+
66+
67+
=== TEST 2: upstream_connect_time
68+
--- config
69+
location /t {
70+
content_by_lua_block {
71+
package.loaded.mock.upstream_connect_time = "102.023"
72+
local var = require("resty.ngxvar")
73+
ngx.say(var.fetch("upstream_connect_time"))
74+
ngx.say(type(var.fetch("upstream_connect_time")))
75+
76+
package.loaded.mock.upstream_connect_time = "102.023, 0.000"
77+
ngx.say(var.fetch("upstream_connect_time"))
78+
79+
package.loaded.mock.upstream_connect_time = "102.023 : 1.200"
80+
ngx.say(var.fetch("upstream_connect_time"))
81+
}
82+
}
83+
--- response_body
84+
102.023
85+
number
86+
102.023
87+
103.223
88+
89+
90+
91+
=== TEST 3: upstream_header_time
92+
--- config
93+
location /t {
94+
content_by_lua_block {
95+
package.loaded.mock.upstream_header_time = "102.023"
96+
local var = require("resty.ngxvar")
97+
ngx.say(var.fetch("upstream_header_time"))
98+
ngx.say(type(var.fetch("upstream_header_time")))
99+
100+
package.loaded.mock.upstream_header_time = "102.023, 0.000"
101+
ngx.say(var.fetch("upstream_header_time"))
102+
103+
package.loaded.mock.upstream_header_time = "102.023 : 1.200"
104+
ngx.say(var.fetch("upstream_header_time"))
105+
}
106+
}
107+
--- response_body
108+
102.023
109+
number
110+
102.023
111+
103.223

0 commit comments

Comments
 (0)