This commit is contained in:
Axel Kittenberger 2010-10-26 11:26:57 +00:00
parent 0bf3e14cec
commit 34753fa43c

View File

@ -14,7 +14,7 @@
-- A security measurement.
-- Core will exit if version ids mismatch.
--
if lsyncd_version ~= nil then
if lsyncd_version then
-- checks if the runner is being loaded twice
print("You cannot use the lsyncd runner as configuration file!")
os.exit(-1)
@ -205,10 +205,12 @@ end
-- .filename .. filename or nil (=dir itself)
-- (.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 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
@ -243,16 +245,6 @@ local proto_sync = {origin=true, path=true, parent=true}
local processes = new_count_array()
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.
@ -277,19 +269,61 @@ set_array(event_names)
--
local function delay_action(atype, wd, sync, filename, time)
log(DEBUG, "delay_action "..event_names[atype].."("..wd..") ")
local origin = sync.origin
local delays = origin.delays
local nd = {atype = atype,
wd = wd,
sync = sync,
filename = filename }
set_prototype(nd, proto_delay)
if time ~= nil and origin.actions.delay ~= nil then
nd.alarm = lsyncd.addto_clock(time, origin.actions.delay)
local o = sync.origin
local delays = o.delays
local delaywd = o.delaywd
local newd = {atype = atype,
wd = wd,
sync = sync,
filename = filename }
set_prototype(newd, proto_delay)
if time and o.actions.delay then
newd.alarm = lsyncd.addto_clock(time, o.actions.delay)
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
table.insert(delays, nd)
end
----
@ -310,7 +344,7 @@ local function attend_dir(origin, path, parent)
end
local thiswatch = watches[wd]
if thiswatch == nil then
if not thiswatch then
-- new watch
thiswatch = {wd = wd, syncs = {} }
set_prototype(thiswatch, proto_watch)
@ -321,7 +355,7 @@ local function attend_dir(origin, path, parent)
table.insert(thiswatch.syncs, sync)
-- warmstart?
if origin.actions.startup == nil then
if not origin.actions.startup then
delay_action(CREATE, wd, sync, nil, nil)
end
@ -339,7 +373,7 @@ end
function lsyncd_collect_process(pid, exitcode)
log(DEBUG, "collected "..pid)
local process = processes[pid]
if process == nil then
if not process then
return
end
local sync = process.sync
@ -358,37 +392,26 @@ local function invoke_action(delay)
local origin = sync.origin
local actions = origin.actions
local func = nil
if delay.atype == CREATE then
if actions.create ~= nil then
func = actions.create
elseif actions.default ~= nil then
func = actions.default
end
elseif delay.atype == ATTRIB then
if actions.attrib ~= nil then
func = actions.attrib
elseif actions.default ~= nil then
func = actions.default
end
elseif delay.atype == MODIFY then
if actions.modify ~= nil then
func = actions.modify
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!")
local atype = delay.atype
if atype == NONE then
-- a removed action
return
elseif atype == CREATE then
func = actions.create or actions.default
elseif atype == ATTRIB then
func = actions.attrib or actions.default
elseif atype == MODIFY then
func = actions.modify or actions.default
elseif atype == DELETE then
func = actions.delete or actions.default
elseif atype == MOVE then
log(ERROR, "MOVE NOT YET IMPLEMENTED!") -- TODO
return
end
if func ~= nil then
if func then
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,
atype = delay.atype,
wd = delay.wd,
@ -415,9 +438,11 @@ function lsyncd_alarm(now)
for _, o in ipairs(origins) do
if o.processes.size < o.actions.max_processes then
local delays = o.delays
if delays[1] ~= nil and lsyncd.before_eq(delays[1].alarm, now) then
invoke_action(o.delays[1])
local d = delays[1]
if d and lsyncd.before_eq(d.alarm, now) then
invoke_action(d)
table.remove(delays, 1)
o.delaywd[d.wd][d.filename] = nil
end
end
end
@ -441,36 +466,44 @@ function lsyncd_initialize(args)
-- set to true if at least one origin has a startup function
local have_startup = false
-- 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
local asrc = lsyncd.real_dir(origin.source)
local actions = origin.actions
if asrc == nil then
print("Cannot resolve source path: ", origin.source)
local asrc = lsyncd.real_dir(o.source)
local actions = o.actions
if not asrc then
print("Cannot resolve source path: ", o.source)
lsyncd.terminate(-1) -- ERRNO
end
origin.source = asrc
origin.delays = new_count_array()
origin.processes = new_count_array()
o.source = asrc
o.delays = new_count_array()
o.delaywd = new_array()
o.processes = new_count_array()
if actions.max_processes == nil then
actions.max_processes = 1 -- TODO DEFAULT MAXPROCESS
end
if actions.startup ~= nil then
actions.max_processes =
actions.max_processes or
settings.max_processes or
defaults.max_processes
actions.collapse_table =
actions.collapse_table or
settings.collapse_table or
defaults.collapse_table
if actions.startup then
have_startup = true
end
-- and add the dir watch inclusively all subdirs
attend_dir(origin, "", nil)
attend_dir(o, "", nil)
end
if have_startup then
log(NORMAL, "--- startup ---")
local pids = { }
for _, origin in ipairs(origins) do
for _, o in ipairs(origins) do
local pid
if origin.actions.startup ~= nil then
local pid = origin.actions.startup(origin.source, origin.targetident)
if o.actions.startup then
local pid = o.actions.startup(o.source, o.targetident)
table.insert(pids, pid)
end
end
@ -492,7 +525,7 @@ function lsyncd_get_alarm()
local have_alarm = false
local alarm = 0
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
if have_alarm then
alarm = lsyncd.earlier(alarm, o.delays[1].alarm)
@ -522,15 +555,15 @@ function lsyncd_event(etype, wd, isdir, time, filename, filename2)
ftype = "file"
end
-- TODO comment out to safe performance
if filename2 == nil then
log(DEBUG, "got event "..event_names[etype].." of "..ftype.." "..filename)
else
if filename2 then
log(DEBUG, "got event "..event_names[etype].." of "..ftype.." "..filename.." to "..filename2)
else
log(DEBUG, "got event "..event_names[etype].." of "..ftype.." "..filename)
end
-- looks up the watch descriptor id
local w = watches[wd]
if w == nil then
if not w then
log(NORMAL, "event belongs to unknown or deleted watch descriptor.")
return
end
@ -580,8 +613,10 @@ function sync(source_dir, target_identifier, actions)
source = source_dir,
targetident = target_identifier,
}
if actions.max_actions == nil then
actions.max_actions = 1
set_prototype(o, proto_origin)
if not actions.max_actions then
actions.max_actions = 1 -- TODO move to init
end
table.insert(origins, o)
return
@ -596,4 +631,24 @@ function default_overflow()
end
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 },
}
}