blob: 423ba578692eb70fe2eb369524105d8970ba4b63 [file]
-- Licensed to the Apache Software Foundation (ASF) under one
-- or more contributor license agreements. See the NOTICE file
-- distributed with this work for additional information
-- regarding copyright ownership. The ASF licenses this file
-- to you under the Apache License, Version 2.0 (the
-- "License"); you may not use this file except in compliance
-- with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
-- The remap half of the shutdown race. A global script's __shutdown__ releases
-- process global resources, so remap Lua must not run after it either. These
-- states live in the same plugin image as the global ones only when
-- proxy.config.plugin.dynamic_reload_mode is disabled.
--
-- The remap instance is configured with a single Lua state, so the first
-- /remap-hold request occupies it and every later one waits on its mutex. Those
-- waiting requests are the ones that must not enter Lua once __shutdown__ has run.
local test_directory = os.getenv('TS_LUA_SHUTDOWN_TEST_DIR')
-- Written by global_shutdown.lua once the __shutdown__ functions have run.
local shutdown_path = nil
-- Written while this state is occupied by the request below.
local active_path = nil
-- Only the first /remap-hold occupies the state; the rest queue behind it and
-- return promptly, so the load keeps requests waiting on the mutex.
local held_once = false
-- Long enough for the client to observe this state as occupied, short enough that
-- stalling this event thread does not starve the rest of the load.
local hold_seconds = 0.5
if test_directory then
shutdown_path = test_directory .. '/lua-shutdown-done'
active_path = test_directory .. '/lua-remap-state.active'
end
function do_remap()
ts.debug('do_remap called')
if shutdown_path then
local done = io.open(shutdown_path, 'r')
if done then
done:close()
ts.debug('do_remap ran after __shutdown__')
end
end
local uri = ts.client_request.get_uri()
if uri == '/remap-hello' then
ts.http.set_resp(200, 'Remap Lua response')
return
end
if not active_path or uri ~= '/remap-hold' then
return
end
if held_once then
-- Answer from here rather than going to the origin, so the load stays
-- pointed at this Lua state.
ts.http.set_resp(200, 'Remap Lua queued')
return
end
held_once = true
local active = assert(io.open(active_path, 'w'))
active:write('active')
active:close()
local deadline = ts.now() + hold_seconds
while ts.now() < deadline do
end
os.remove(active_path)
ts.http.set_resp(200, 'Remap Lua hold')
end