mirror of
https://github.com/octoleo/lsyncd.git
synced 2025-01-06 00:30:46 +00:00
Updates to tunnel logic.
Delay before tunnel is considered up. Working delay if restart fails. Disabled state. Kill all tunnel processes on graceful exit
This commit is contained in:
parent
dcf611d4f8
commit
cce6e5423b
145
lsyncd.lua
145
lsyncd.lua
@ -2419,11 +2419,11 @@ local Sync = ( function
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Returns true if the relative path is excluded or filtered
|
-- Returns true if the relative path is excluded or filtered
|
||||||
--
|
--
|
||||||
local function testFilter
|
local function testFilter
|
||||||
(
|
(
|
||||||
self, -- the Sync
|
self, -- the Sync
|
||||||
@ -2477,7 +2477,9 @@ local Sync = ( function
|
|||||||
local delay = self.processes[ pid ]
|
local delay = self.processes[ pid ]
|
||||||
|
|
||||||
-- not a child of this sync?
|
-- not a child of this sync?
|
||||||
if not delay then return end
|
if not delay then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
if delay.status
|
if delay.status
|
||||||
then
|
then
|
||||||
@ -2562,6 +2564,8 @@ local Sync = ( function
|
|||||||
end
|
end
|
||||||
|
|
||||||
self.processes[ pid ] = nil
|
self.processes[ pid ] = nil
|
||||||
|
-- we handled this process
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -3229,9 +3233,10 @@ Tunnel = (function()
|
|||||||
|
|
||||||
local TUNNEL_STATUS = {
|
local TUNNEL_STATUS = {
|
||||||
DOWN = 0,
|
DOWN = 0,
|
||||||
CONNECTING = 1,
|
DISABLED = 1,
|
||||||
UP = 2,
|
CONNECTING = 2,
|
||||||
RETRY_TIMEOUT = 3,
|
UP = 3,
|
||||||
|
RETRY_TIMEOUT = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
local nextTunnelName = 1
|
local nextTunnelName = 1
|
||||||
@ -3243,7 +3248,8 @@ Tunnel = (function()
|
|||||||
checkCommand = nil,
|
checkCommand = nil,
|
||||||
checkExitCodes = {0},
|
checkExitCodes = {0},
|
||||||
checkMaxFailed = 5,
|
checkMaxFailed = 5,
|
||||||
reconnectDelay = 10
|
retryDelay = 10,
|
||||||
|
readyDelay = 5
|
||||||
}
|
}
|
||||||
-- export constants
|
-- export constants
|
||||||
Tunnel.TUNNEL_CMD_TYPES = TUNNEL_CMD_TYPES
|
Tunnel.TUNNEL_CMD_TYPES = TUNNEL_CMD_TYPES
|
||||||
@ -3261,7 +3267,7 @@ Tunnel = (function()
|
|||||||
alarm = false
|
alarm = false
|
||||||
}
|
}
|
||||||
-- provides a default name if needed
|
-- provides a default name if needed
|
||||||
if options.name ~= nil
|
if options.name == nil
|
||||||
then
|
then
|
||||||
options.name = 'Tunnel' .. nextTunnelName
|
options.name = 'Tunnel' .. nextTunnelName
|
||||||
end
|
end
|
||||||
@ -3303,14 +3309,20 @@ Tunnel = (function()
|
|||||||
-- lsyncd.kill()
|
-- lsyncd.kill()
|
||||||
-- check if child processes are running
|
-- check if child processes are running
|
||||||
if self.status == TUNNEL_STATUS.CONNECTING then
|
if self.status == TUNNEL_STATUS.CONNECTING then
|
||||||
local good = true
|
-- we can only be good if processes exist
|
||||||
for pid, type in ipairs(self.processes) do
|
local good = self.processes:size() > 0 or self.options.onShoot == true
|
||||||
if type == TUNNEL_CMD_TYPES.CMD
|
|
||||||
and lsyncd.kill(pid, 0) ~= 0 then
|
for pid, pd in self.processes:walk() do
|
||||||
-- required command does not exist
|
if pd.type == TUNNEL_CMD_TYPES.CMD then
|
||||||
good = false
|
-- process needs to run for at least some time
|
||||||
|
if (pd.started + self.options.readyDelay) > timestamp
|
||||||
|
or lsyncd.kill(pid, 0) ~= 0 then
|
||||||
|
-- required command does not exist›
|
||||||
|
good = false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if good then
|
if good then
|
||||||
log(
|
log(
|
||||||
'Tunnel',
|
'Tunnel',
|
||||||
@ -3328,13 +3340,15 @@ Tunnel = (function()
|
|||||||
if self.status == TUNNEL_STATUS.DOWN then
|
if self.status == TUNNEL_STATUS.DOWN then
|
||||||
self:start()
|
self:start()
|
||||||
elseif self.status == TUNNEL_STATUS.RETRY_TIMEOUT then
|
elseif self.status == TUNNEL_STATUS.RETRY_TIMEOUT then
|
||||||
log(
|
|
||||||
'Tunnel',
|
|
||||||
'Retry setup ', self.options.name
|
|
||||||
)
|
|
||||||
if self.alarm <= timestamp then
|
if self.alarm <= timestamp then
|
||||||
|
log(
|
||||||
|
'Tunnel',
|
||||||
|
'Retry setup ', self.options.name
|
||||||
|
)
|
||||||
self:start()
|
self:start()
|
||||||
end
|
end
|
||||||
|
elseif self.status == TUNNEL_STATUS.DISABLED then
|
||||||
|
self.alarm = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3375,7 +3389,7 @@ Tunnel = (function()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- delay tunnel check by 1 second
|
-- delay tunnel check by 1 second
|
||||||
block:wait( now( ) + 1 )
|
block:wait( now( ) + 1 )
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
@ -3393,7 +3407,7 @@ Tunnel = (function()
|
|||||||
self.status == TUNNEL_STATUS.UP then
|
self.status == TUNNEL_STATUS.UP then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.options.mode == "command" then
|
if self.options.mode == "command" then
|
||||||
self.status = TUNNEL_STATUS.CONNECTING
|
self.status = TUNNEL_STATUS.CONNECTING
|
||||||
self.alarm = false
|
self.alarm = false
|
||||||
@ -3420,11 +3434,14 @@ Tunnel = (function()
|
|||||||
local pid = lsyncd.exec(bin, table.unpack(self.options.command, 2))
|
local pid = lsyncd.exec(bin, table.unpack(self.options.command, 2))
|
||||||
--local pid = spawn(bin, table.unpack(self.options.command, 2))
|
--local pid = spawn(bin, table.unpack(self.options.command, 2))
|
||||||
if pid and pid > 0 then
|
if pid and pid > 0 then
|
||||||
self.processes[pid] = TUNNEL_CMD_TYPES.CMD
|
self.processes[pid] = {
|
||||||
|
type = TUNNEL_CMD_TYPES.CMD,
|
||||||
|
started = now()
|
||||||
|
}
|
||||||
self.checksFailed = 0
|
self.checksFailed = 0
|
||||||
self.alarm = now() + 1
|
self.alarm = now() + 1
|
||||||
else
|
else
|
||||||
self.alarm = now() + self.options.reconnectDelay
|
self.alarm = now() + self.options.retryDelay
|
||||||
self.status = TUNNEL_STATUS.RETRY_TIMEOUT
|
self.status = TUNNEL_STATUS.RETRY_TIMEOUT
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -3441,9 +3458,15 @@ Tunnel = (function()
|
|||||||
pid,
|
pid,
|
||||||
exitcode
|
exitcode
|
||||||
)
|
)
|
||||||
local ctype = self.processes[pid]
|
local proc = self.processes[pid]
|
||||||
|
|
||||||
|
if proc == nil then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
log('Debug',
|
||||||
|
"collect tunnel event. pid: ", pid," exitcode: ", exitcode)
|
||||||
-- cases in which the tunnel command is handled
|
-- cases in which the tunnel command is handled
|
||||||
if ctype == TUNNEL_CMD_TYPES.CMD then
|
if proc.type == TUNNEL_CMD_TYPES.CMD then
|
||||||
if self.options.onShot then
|
if self.options.onShot then
|
||||||
log(
|
log(
|
||||||
'Info',
|
'Info',
|
||||||
@ -3452,17 +3475,28 @@ Tunnel = (function()
|
|||||||
)
|
)
|
||||||
self.status = TUNNEL_STATUS.UP
|
self.status = TUNNEL_STATUS.UP
|
||||||
else
|
else
|
||||||
log(
|
if self.status == TUNNEL_STATUS.CONNECTING then
|
||||||
'Info',
|
log(
|
||||||
'Tunnel died. Restarting',
|
'Warning',
|
||||||
|
'Starting tunnel failed.',
|
||||||
self.options.name
|
self.options.name
|
||||||
)
|
)
|
||||||
self.status = TUNNEL_STATUS.DOWN
|
self.status = TUNNEL_STATUS.RETRY_TIMEOUT
|
||||||
self.alarm = now() + 1
|
self.alarm = now() + 5
|
||||||
self:start()
|
else
|
||||||
|
log(
|
||||||
|
'Info',
|
||||||
|
'Tunnel died. Restarting',
|
||||||
|
self.options.name
|
||||||
|
)
|
||||||
|
|
||||||
|
self.status = TUNNEL_STATUS.DOWN
|
||||||
|
self.alarm = true
|
||||||
|
self:start()
|
||||||
|
end
|
||||||
end
|
end
|
||||||
-- cases in which the check function has executed a program
|
-- cases in which the check function has executed a program
|
||||||
elseif ctype == TUNNEL_CMD_TYPES.CHK then
|
elseif proc.type == TUNNEL_CMD_TYPES.CHK then
|
||||||
local found = false
|
local found = false
|
||||||
if type(self.options.checkExitCodes) == 'table' then
|
if type(self.options.checkExitCodes) == 'table' then
|
||||||
|
|
||||||
@ -3507,12 +3541,14 @@ Tunnel = (function()
|
|||||||
-- Stops all tunnel processes
|
-- Stops all tunnel processes
|
||||||
--
|
--
|
||||||
function Tunnel:kill ()
|
function Tunnel:kill ()
|
||||||
for pid, typ in pairs(self.processes) do
|
log('Tunnel', 'Shutdown tunnel ', self.options.name)
|
||||||
if typ == TUNNEL_CMD_TYPES.CMD then
|
for pid, pr in self.processes:walk() do
|
||||||
|
if pr.type == TUNNEL_CMD_TYPES.CMD then
|
||||||
|
log('Tunnel','Kill process ', pid)
|
||||||
lsyncd.kill(pid, 9)
|
lsyncd.kill(pid, 9)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
self.status = TUNNEL_STATUS.DOWN
|
self.status = TUNNEL_STATUS.DISABLED
|
||||||
end
|
end
|
||||||
|
|
||||||
function Tunnel:isReady ()
|
function Tunnel:isReady ()
|
||||||
@ -3550,10 +3586,10 @@ local Tunnels = ( function
|
|||||||
tunnel
|
tunnel
|
||||||
)
|
)
|
||||||
table.insert( tunnelList, tunnel )
|
table.insert( tunnelList, tunnel )
|
||||||
|
|
||||||
return tunnel
|
return tunnel
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Allows a for-loop to walk through all syncs.
|
-- Allows a for-loop to walk through all syncs.
|
||||||
--
|
--
|
||||||
@ -3561,7 +3597,7 @@ local Tunnels = ( function
|
|||||||
( )
|
( )
|
||||||
return ipairs( tunnelList )
|
return ipairs( tunnelList )
|
||||||
end
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Returns the number of syncs.
|
-- Returns the number of syncs.
|
||||||
--
|
--
|
||||||
@ -3575,12 +3611,8 @@ local Tunnels = ( function
|
|||||||
-- Cycle through all tunnels and call their invoke function
|
-- Cycle through all tunnels and call their invoke function
|
||||||
--
|
--
|
||||||
local function invoke(timestamp)
|
local function invoke(timestamp)
|
||||||
if nextCycle and nextCycle > timestamp then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
for _,tunnel in ipairs( tunnelList )
|
for _,tunnel in ipairs( tunnelList )
|
||||||
do
|
do
|
||||||
print("invoke t", tunnel)
|
|
||||||
tunnel:invoke(timestamp)
|
tunnel:invoke(timestamp)
|
||||||
end
|
end
|
||||||
nextCycle = now() + 5
|
nextCycle = now() + 5
|
||||||
@ -3601,7 +3633,22 @@ local Tunnels = ( function
|
|||||||
|
|
||||||
return rv
|
return rv
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- closes all tunnels
|
||||||
|
--
|
||||||
|
local function killAll()
|
||||||
|
local rv = true
|
||||||
|
for _, tunnel in ipairs( tunnelList ) do
|
||||||
|
local ta = tunnel:kill()
|
||||||
|
if ta ~= true then
|
||||||
|
rv = false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return rv
|
||||||
|
end
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Public interface
|
-- Public interface
|
||||||
--
|
--
|
||||||
@ -3611,7 +3658,8 @@ local Tunnels = ( function
|
|||||||
iwalk = iwalk,
|
iwalk = iwalk,
|
||||||
size = size,
|
size = size,
|
||||||
invoke = invoke,
|
invoke = invoke,
|
||||||
getAlarm = getAlarm
|
getAlarm = getAlarm,
|
||||||
|
killAll = killAll
|
||||||
}
|
}
|
||||||
end )( )
|
end )( )
|
||||||
|
|
||||||
@ -3625,11 +3673,11 @@ tunnel = function (options)
|
|||||||
)
|
)
|
||||||
local rv = Tunnel.new(options)
|
local rv = Tunnel.new(options)
|
||||||
Tunnels.add(rv)
|
Tunnels.add(rv)
|
||||||
|
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Syncs - a singleton
|
-- Syncs - a singleton
|
||||||
@ -5033,6 +5081,7 @@ function runner.cycle(
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
|
Tunnels.killAll()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -5567,7 +5616,7 @@ function runner.initialize( firstTime )
|
|||||||
-- makes sure the user gave Lsyncd anything to do
|
-- makes sure the user gave Lsyncd anything to do
|
||||||
if Syncs.size() == 0
|
if Syncs.size() == 0
|
||||||
then
|
then
|
||||||
log( 'Error', 'Nothing to watch!' )
|
log( 'Error', 'Nothing to watch!' )
|
||||||
|
|
||||||
os.exit( -1 )
|
os.exit( -1 )
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user