mirror of
https://github.com/octoleo/lsyncd.git
synced 2024-11-10 15:20:58 +00:00
This commit is contained in:
parent
0bf3e14cec
commit
34753fa43c
213
lsyncd.lua
213
lsyncd.lua
@ -14,7 +14,7 @@
|
|||||||
-- A security measurement.
|
-- A security measurement.
|
||||||
-- Core will exit if version ids mismatch.
|
-- Core will exit if version ids mismatch.
|
||||||
--
|
--
|
||||||
if lsyncd_version ~= nil then
|
if lsyncd_version then
|
||||||
-- checks if the runner is being loaded twice
|
-- checks if the runner is being loaded twice
|
||||||
print("You cannot use the lsyncd runner as configuration file!")
|
print("You cannot use the lsyncd runner as configuration file!")
|
||||||
os.exit(-1)
|
os.exit(-1)
|
||||||
@ -205,10 +205,12 @@ end
|
|||||||
-- .filename .. filename or nil (=dir itself)
|
-- .filename .. filename or nil (=dir itself)
|
||||||
-- (.movepeer) .. for MOVEFROM/MOVETO link to other delay
|
-- (.movepeer) .. for MOVEFROM/MOVETO link to other delay
|
||||||
-- }
|
-- }
|
||||||
|
-- .delaywd [wd] = [#] .. a list of lists of all delays from a watch descriptor.
|
||||||
-- }
|
-- }
|
||||||
--
|
--
|
||||||
local origins = new_array()
|
local origins = new_array()
|
||||||
local proto_delay = {atype=true, alarm=true, wd=true, sync=true, filename=true, movepeer=true}
|
local proto_origin = {actions=true, source=true, targetident=true, processes=true, delays=true, delaywd=true}
|
||||||
|
local proto_delay = {atype =true, alarm=true, wd=true, sync=true, filename=true, movepeer=true}
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- all watches
|
-- all watches
|
||||||
@ -243,16 +245,6 @@ local proto_sync = {origin=true, path=true, parent=true}
|
|||||||
local processes = new_count_array()
|
local processes = new_count_array()
|
||||||
local proto_process = {pid=true, atype=true, wd=true, sync=true, filename=true}
|
local proto_process = {pid=true, atype=true, wd=true, sync=true, filename=true}
|
||||||
|
|
||||||
------
|
|
||||||
-- TODO
|
|
||||||
--
|
|
||||||
local collapse_table = {
|
|
||||||
[ATTRIB] = { [ATTRIB] = ATTRIB, [MODIFY] = MODIFY, [CREATE] = CREATE, [DELETE] = DELETE },
|
|
||||||
[MODIFY] = { [ATTRIB] = MODIFY, [MODIFY] = MODIFY, [CREATE] = CREATE, [DELETE] = DELETE },
|
|
||||||
[CREATE] = { [ATTRIB] = CREATE, [MODIFY] = CREATE, [CREATE] = CREATE, [DELETE] = DELETE },
|
|
||||||
[DELETE] = { [ATTRIB] = DELETE, [MODIFY] = DELETE, [CREATE] = MODIFY, [DELETE] = DELETE },
|
|
||||||
}
|
|
||||||
set_array(collapse_table)
|
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- A list of names of the event types the core sends.
|
-- A list of names of the event types the core sends.
|
||||||
@ -277,19 +269,61 @@ set_array(event_names)
|
|||||||
--
|
--
|
||||||
local function delay_action(atype, wd, sync, filename, time)
|
local function delay_action(atype, wd, sync, filename, time)
|
||||||
log(DEBUG, "delay_action "..event_names[atype].."("..wd..") ")
|
log(DEBUG, "delay_action "..event_names[atype].."("..wd..") ")
|
||||||
local origin = sync.origin
|
local o = sync.origin
|
||||||
local delays = origin.delays
|
local delays = o.delays
|
||||||
local nd = {atype = atype,
|
local delaywd = o.delaywd
|
||||||
wd = wd,
|
local newd = {atype = atype,
|
||||||
sync = sync,
|
wd = wd,
|
||||||
filename = filename }
|
sync = sync,
|
||||||
set_prototype(nd, proto_delay)
|
filename = filename }
|
||||||
if time ~= nil and origin.actions.delay ~= nil then
|
set_prototype(newd, proto_delay)
|
||||||
nd.alarm = lsyncd.addto_clock(time, origin.actions.delay)
|
if time and o.actions.delay then
|
||||||
|
newd.alarm = lsyncd.addto_clock(time, o.actions.delay)
|
||||||
else
|
else
|
||||||
nd.alarm = lsyncd.now()
|
newd.alarm = lsyncd.now()
|
||||||
|
end
|
||||||
|
|
||||||
|
local dwd = delaywd[wd]
|
||||||
|
if not dwd then
|
||||||
|
dwd = {}
|
||||||
|
delaywd[wd] = dwd
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO COLLAPSE
|
||||||
|
if dwd[filename] then
|
||||||
|
local oldd = dwd[filename]
|
||||||
|
if newd.atype == MOVE_FROM or newd.atype == MOVE_TO or
|
||||||
|
oldd.atype == MOVE_FROM or oldd.atype == MOVE_TO then
|
||||||
|
-- do not collapse moves
|
||||||
|
log(NORMAL, "Not collapsing events with moves on "..filename)
|
||||||
|
-- TODO stackinfo
|
||||||
|
return
|
||||||
|
else
|
||||||
|
local col = o.actions.collapse_table[oldd.atype][newd.atype]
|
||||||
|
if col == -1 then
|
||||||
|
-- events cancel each other
|
||||||
|
log(NORMAL, "Nullfication: " ..event_names[newd.atype].." after "..
|
||||||
|
event_names[oldd.atype].." on "..filename)
|
||||||
|
oldd.atype = NONE
|
||||||
|
return
|
||||||
|
elseif col == 0 then
|
||||||
|
-- events tack
|
||||||
|
log(NORMAL, "Stacking " ..event_names[newd.atype].." after "..
|
||||||
|
event_names[oldd.atype].." on "..filename)
|
||||||
|
-- TODO stackinfo
|
||||||
|
else
|
||||||
|
log(NORMAL, "Collapsing "..event_names[newd.atype].." upon "..
|
||||||
|
event_names[oldd.atype].." to " ..
|
||||||
|
event_names[col].." on "..filename)
|
||||||
|
oldd.atype = col
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
table.insert(delays, newd)
|
||||||
|
else
|
||||||
|
dwd[filename] = newd
|
||||||
|
table.insert(delays, newd)
|
||||||
end
|
end
|
||||||
table.insert(delays, nd)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
----
|
----
|
||||||
@ -310,7 +344,7 @@ local function attend_dir(origin, path, parent)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local thiswatch = watches[wd]
|
local thiswatch = watches[wd]
|
||||||
if thiswatch == nil then
|
if not thiswatch then
|
||||||
-- new watch
|
-- new watch
|
||||||
thiswatch = {wd = wd, syncs = {} }
|
thiswatch = {wd = wd, syncs = {} }
|
||||||
set_prototype(thiswatch, proto_watch)
|
set_prototype(thiswatch, proto_watch)
|
||||||
@ -321,7 +355,7 @@ local function attend_dir(origin, path, parent)
|
|||||||
table.insert(thiswatch.syncs, sync)
|
table.insert(thiswatch.syncs, sync)
|
||||||
|
|
||||||
-- warmstart?
|
-- warmstart?
|
||||||
if origin.actions.startup == nil then
|
if not origin.actions.startup then
|
||||||
delay_action(CREATE, wd, sync, nil, nil)
|
delay_action(CREATE, wd, sync, nil, nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -339,7 +373,7 @@ end
|
|||||||
function lsyncd_collect_process(pid, exitcode)
|
function lsyncd_collect_process(pid, exitcode)
|
||||||
log(DEBUG, "collected "..pid)
|
log(DEBUG, "collected "..pid)
|
||||||
local process = processes[pid]
|
local process = processes[pid]
|
||||||
if process == nil then
|
if not process then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local sync = process.sync
|
local sync = process.sync
|
||||||
@ -358,37 +392,26 @@ local function invoke_action(delay)
|
|||||||
local origin = sync.origin
|
local origin = sync.origin
|
||||||
local actions = origin.actions
|
local actions = origin.actions
|
||||||
local func = nil
|
local func = nil
|
||||||
if delay.atype == CREATE then
|
local atype = delay.atype
|
||||||
if actions.create ~= nil then
|
if atype == NONE then
|
||||||
func = actions.create
|
-- a removed action
|
||||||
elseif actions.default ~= nil then
|
return
|
||||||
func = actions.default
|
elseif atype == CREATE then
|
||||||
end
|
func = actions.create or actions.default
|
||||||
elseif delay.atype == ATTRIB then
|
elseif atype == ATTRIB then
|
||||||
if actions.attrib ~= nil then
|
func = actions.attrib or actions.default
|
||||||
func = actions.attrib
|
elseif atype == MODIFY then
|
||||||
elseif actions.default ~= nil then
|
func = actions.modify or actions.default
|
||||||
func = actions.default
|
elseif atype == DELETE then
|
||||||
end
|
func = actions.delete or actions.default
|
||||||
elseif delay.atype == MODIFY then
|
elseif atype == MOVE then
|
||||||
if actions.modify ~= nil then
|
log(ERROR, "MOVE NOT YET IMPLEMENTED!") -- TODO
|
||||||
func = actions.modify
|
return
|
||||||
elseif actions.default ~= nil then
|
|
||||||
func = actions.default
|
|
||||||
end
|
|
||||||
elseif delay.atype == DELETE then
|
|
||||||
if actions.delete ~= nil then
|
|
||||||
func = actions.delete
|
|
||||||
elseif actions.default ~= nil then
|
|
||||||
func = actions.default
|
|
||||||
end
|
|
||||||
elseif delay.atype == MOVE then
|
|
||||||
log(ERROR, "MOVE NOT YET IMPLEMENTED!")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if func ~= nil then
|
if func then
|
||||||
local pid = func(origin.source, sync.path, delay.filename, origin.targetident)
|
local pid = func(origin.source, sync.path, delay.filename, origin.targetident)
|
||||||
if pid ~= nil and pid > 0 then
|
if pid and pid > 0 then
|
||||||
local process = {pid = pid,
|
local process = {pid = pid,
|
||||||
atype = delay.atype,
|
atype = delay.atype,
|
||||||
wd = delay.wd,
|
wd = delay.wd,
|
||||||
@ -415,9 +438,11 @@ function lsyncd_alarm(now)
|
|||||||
for _, o in ipairs(origins) do
|
for _, o in ipairs(origins) do
|
||||||
if o.processes.size < o.actions.max_processes then
|
if o.processes.size < o.actions.max_processes then
|
||||||
local delays = o.delays
|
local delays = o.delays
|
||||||
if delays[1] ~= nil and lsyncd.before_eq(delays[1].alarm, now) then
|
local d = delays[1]
|
||||||
invoke_action(o.delays[1])
|
if d and lsyncd.before_eq(d.alarm, now) then
|
||||||
|
invoke_action(d)
|
||||||
table.remove(delays, 1)
|
table.remove(delays, 1)
|
||||||
|
o.delaywd[d.wd][d.filename] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -441,36 +466,44 @@ function lsyncd_initialize(args)
|
|||||||
-- set to true if at least one origin has a startup function
|
-- set to true if at least one origin has a startup function
|
||||||
local have_startup = false
|
local have_startup = false
|
||||||
-- runs through the origins table filled by user calling directory()
|
-- runs through the origins table filled by user calling directory()
|
||||||
for _, origin in ipairs(origins) do
|
for _, o in ipairs(origins) do
|
||||||
-- resolves source to be an absolute path
|
-- resolves source to be an absolute path
|
||||||
local asrc = lsyncd.real_dir(origin.source)
|
local asrc = lsyncd.real_dir(o.source)
|
||||||
local actions = origin.actions
|
local actions = o.actions
|
||||||
if asrc == nil then
|
if not asrc then
|
||||||
print("Cannot resolve source path: ", origin.source)
|
print("Cannot resolve source path: ", o.source)
|
||||||
lsyncd.terminate(-1) -- ERRNO
|
lsyncd.terminate(-1) -- ERRNO
|
||||||
end
|
end
|
||||||
origin.source = asrc
|
o.source = asrc
|
||||||
origin.delays = new_count_array()
|
o.delays = new_count_array()
|
||||||
origin.processes = new_count_array()
|
o.delaywd = new_array()
|
||||||
|
o.processes = new_count_array()
|
||||||
|
|
||||||
if actions.max_processes == nil then
|
actions.max_processes =
|
||||||
actions.max_processes = 1 -- TODO DEFAULT MAXPROCESS
|
actions.max_processes or
|
||||||
end
|
settings.max_processes or
|
||||||
if actions.startup ~= nil then
|
defaults.max_processes
|
||||||
|
|
||||||
|
actions.collapse_table =
|
||||||
|
actions.collapse_table or
|
||||||
|
settings.collapse_table or
|
||||||
|
defaults.collapse_table
|
||||||
|
|
||||||
|
if actions.startup then
|
||||||
have_startup = true
|
have_startup = true
|
||||||
end
|
end
|
||||||
|
|
||||||
-- and add the dir watch inclusively all subdirs
|
-- and add the dir watch inclusively all subdirs
|
||||||
attend_dir(origin, "", nil)
|
attend_dir(o, "", nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
if have_startup then
|
if have_startup then
|
||||||
log(NORMAL, "--- startup ---")
|
log(NORMAL, "--- startup ---")
|
||||||
local pids = { }
|
local pids = { }
|
||||||
for _, origin in ipairs(origins) do
|
for _, o in ipairs(origins) do
|
||||||
local pid
|
local pid
|
||||||
if origin.actions.startup ~= nil then
|
if o.actions.startup then
|
||||||
local pid = origin.actions.startup(origin.source, origin.targetident)
|
local pid = o.actions.startup(o.source, o.targetident)
|
||||||
table.insert(pids, pid)
|
table.insert(pids, pid)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -492,7 +525,7 @@ function lsyncd_get_alarm()
|
|||||||
local have_alarm = false
|
local have_alarm = false
|
||||||
local alarm = 0
|
local alarm = 0
|
||||||
for _, o in ipairs(origins) do
|
for _, o in ipairs(origins) do
|
||||||
if o.delays[1] ~= nil and
|
if o.delays[1] and
|
||||||
o.processes.size < o.actions.max_processes then
|
o.processes.size < o.actions.max_processes then
|
||||||
if have_alarm then
|
if have_alarm then
|
||||||
alarm = lsyncd.earlier(alarm, o.delays[1].alarm)
|
alarm = lsyncd.earlier(alarm, o.delays[1].alarm)
|
||||||
@ -522,15 +555,15 @@ function lsyncd_event(etype, wd, isdir, time, filename, filename2)
|
|||||||
ftype = "file"
|
ftype = "file"
|
||||||
end
|
end
|
||||||
-- TODO comment out to safe performance
|
-- TODO comment out to safe performance
|
||||||
if filename2 == nil then
|
if filename2 then
|
||||||
log(DEBUG, "got event "..event_names[etype].." of "..ftype.." "..filename)
|
|
||||||
else
|
|
||||||
log(DEBUG, "got event "..event_names[etype].." of "..ftype.." "..filename.." to "..filename2)
|
log(DEBUG, "got event "..event_names[etype].." of "..ftype.." "..filename.." to "..filename2)
|
||||||
|
else
|
||||||
|
log(DEBUG, "got event "..event_names[etype].." of "..ftype.." "..filename)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- looks up the watch descriptor id
|
-- looks up the watch descriptor id
|
||||||
local w = watches[wd]
|
local w = watches[wd]
|
||||||
if w == nil then
|
if not w then
|
||||||
log(NORMAL, "event belongs to unknown or deleted watch descriptor.")
|
log(NORMAL, "event belongs to unknown or deleted watch descriptor.")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -580,8 +613,10 @@ function sync(source_dir, target_identifier, actions)
|
|||||||
source = source_dir,
|
source = source_dir,
|
||||||
targetident = target_identifier,
|
targetident = target_identifier,
|
||||||
}
|
}
|
||||||
if actions.max_actions == nil then
|
set_prototype(o, proto_origin)
|
||||||
actions.max_actions = 1
|
|
||||||
|
if not actions.max_actions then
|
||||||
|
actions.max_actions = 1 -- TODO move to init
|
||||||
end
|
end
|
||||||
table.insert(origins, o)
|
table.insert(origins, o)
|
||||||
return
|
return
|
||||||
@ -596,4 +631,24 @@ function default_overflow()
|
|||||||
end
|
end
|
||||||
overflow = default_overflow
|
overflow = default_overflow
|
||||||
|
|
||||||
|
--============================================================================
|
||||||
|
-- lsyncd default settings
|
||||||
|
--============================================================================
|
||||||
|
|
||||||
|
defaults = {
|
||||||
|
-----
|
||||||
|
-- TODO
|
||||||
|
--
|
||||||
|
max_processes = 1,
|
||||||
|
------
|
||||||
|
-- TODO
|
||||||
|
--
|
||||||
|
collapse_table = {
|
||||||
|
[ATTRIB] = { [ATTRIB] = ATTRIB, [MODIFY] = MODIFY, [CREATE] = CREATE, [DELETE] = DELETE },
|
||||||
|
[MODIFY] = { [ATTRIB] = MODIFY, [MODIFY] = MODIFY, [CREATE] = CREATE, [DELETE] = DELETE },
|
||||||
|
[CREATE] = { [ATTRIB] = CREATE, [MODIFY] = CREATE, [CREATE] = CREATE, [DELETE] = -1 },
|
||||||
|
[DELETE] = { [ATTRIB] = DELETE, [MODIFY] = DELETE, [CREATE] = MODIFY, [DELETE] = DELETE },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user