mirror of https://github.com/octoleo/lsyncd.git
This commit is contained in:
parent
0a6fac9c0c
commit
daa7aa22ee
|
@ -17,6 +17,8 @@ prefix = "sleep 1 && "
|
||||||
slowbash = {
|
slowbash = {
|
||||||
delay = 5,
|
delay = 5,
|
||||||
|
|
||||||
|
maxProcesses = 5,
|
||||||
|
|
||||||
onStartup = function(event)
|
onStartup = function(event)
|
||||||
log("Normal", "cp -r from ", event.source, " -> ", event.target)
|
log("Normal", "cp -r from ", event.source, " -> ", event.target)
|
||||||
spawnShell(event,
|
spawnShell(event,
|
||||||
|
|
10
lsyncd.c
10
lsyncd.c
|
@ -903,8 +903,6 @@ handle_event(lua_State *L,
|
||||||
|
|
||||||
/* used to execute two events in case of unmatched MOVE_FROM buffer */
|
/* used to execute two events in case of unmatched MOVE_FROM buffer */
|
||||||
struct inotify_event *after_buf = NULL;
|
struct inotify_event *after_buf = NULL;
|
||||||
logstring("Inotify", "got an event");
|
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -921,6 +919,11 @@ handle_event(lua_State *L,
|
||||||
if (event && (IN_IGNORED & event->mask)) {
|
if (event && (IN_IGNORED & event->mask)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (event && event->len == 0) {
|
||||||
|
/* sometimes inotify sends such strange events,
|
||||||
|
* (e.g. when touching a dir */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (event == NULL) {
|
if (event == NULL) {
|
||||||
/* a buffered MOVE_FROM is not followed by anything,
|
/* a buffered MOVE_FROM is not followed by anything,
|
||||||
|
@ -1004,9 +1007,9 @@ handle_event(lua_State *L,
|
||||||
exit(-1); // ERRNO
|
exit(-1); // ERRNO
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
/* if there is a buffered event executes it */
|
/* if there is a buffered event executes it */
|
||||||
if (after_buf) {
|
if (after_buf) {
|
||||||
|
logstring("Inotify", "handling buffered event.");
|
||||||
handle_event(L, after_buf);
|
handle_event(L, after_buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1114,6 +1117,7 @@ masterloop(lua_State *L)
|
||||||
}
|
}
|
||||||
/* checks if there is an unary MOVE_FROM left in the buffer */
|
/* checks if there is an unary MOVE_FROM left in the buffer */
|
||||||
if (move_event) {
|
if (move_event) {
|
||||||
|
logstring("Inotify", "handling unary move from.");
|
||||||
handle_event(L, NULL);
|
handle_event(L, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
131
lsyncd.lua
131
lsyncd.lua
|
@ -25,7 +25,7 @@ lsyncd_version = "2.0beta1"
|
||||||
-----
|
-----
|
||||||
-- Hides the core interface from user scripts
|
-- Hides the core interface from user scripts
|
||||||
--
|
--
|
||||||
_l = lsyncd
|
local _l = lsyncd
|
||||||
lsyncd = nil
|
lsyncd = nil
|
||||||
local lsyncd = _l
|
local lsyncd = _l
|
||||||
_l = nil
|
_l = nil
|
||||||
|
@ -250,7 +250,7 @@ local Inlet, InletControl = (function()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function getPath(event)
|
local function getPath(event)
|
||||||
if not event.move then
|
if event.move ~= "To" then
|
||||||
return e2d[event].path
|
return e2d[event].path
|
||||||
else
|
else
|
||||||
return e2d[event].path2
|
return e2d[event].path2
|
||||||
|
@ -278,11 +278,23 @@ local Inlet, InletControl = (function()
|
||||||
-- "Create",
|
-- "Create",
|
||||||
-- "Delete",
|
-- "Delete",
|
||||||
-- "Modify",
|
-- "Modify",
|
||||||
-- "Move"
|
-- "MoveFr",
|
||||||
|
-- "MoveTo"
|
||||||
--
|
--
|
||||||
etype = function(event)
|
etype = function(event)
|
||||||
return e2d[event].etype
|
return e2d[event].etype
|
||||||
end,
|
end,
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- Returns 'Fr'/'To' for events of moves.
|
||||||
|
move = function(event)
|
||||||
|
local d = e2d[event]
|
||||||
|
if d.move then
|
||||||
|
return d.move
|
||||||
|
else
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- Status
|
-- Status
|
||||||
|
@ -399,9 +411,10 @@ local Inlet, InletControl = (function()
|
||||||
}
|
}
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
-- Turns a delay to a event.
|
||||||
-- Encapsulates a delay into an event for the user
|
-- Encapsulates a delay into an event for the user
|
||||||
--
|
--
|
||||||
local function toEvent(delay)
|
local function d2e(delay)
|
||||||
if delay.etype ~= "Move" then
|
if delay.etype ~= "Move" then
|
||||||
if not delay.event then
|
if not delay.event then
|
||||||
local event = {}
|
local event = {}
|
||||||
|
@ -424,10 +437,8 @@ local Inlet, InletControl = (function()
|
||||||
e2d[delay.event2] = delay
|
e2d[delay.event2] = delay
|
||||||
|
|
||||||
-- move events have a field 'event'
|
-- move events have a field 'event'
|
||||||
-- false for move source events
|
event.move = "Fr"
|
||||||
-- true for move desination events
|
event2.move = "To"
|
||||||
event.move = false
|
|
||||||
event2.move = true
|
|
||||||
end
|
end
|
||||||
return delay.event, delay.event2
|
return delay.event, delay.event2
|
||||||
end
|
end
|
||||||
|
@ -439,7 +450,7 @@ local Inlet, InletControl = (function()
|
||||||
-- and is blocked by everything.
|
-- and is blocked by everything.
|
||||||
--
|
--
|
||||||
local function createBlanketEvent()
|
local function createBlanketEvent()
|
||||||
return toEvent(sync:addBlanketDelay())
|
return d2e(sync:addBlanketDelay())
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
@ -459,7 +470,7 @@ local Inlet, InletControl = (function()
|
||||||
-- Gets the next not blocked event from queue.
|
-- Gets the next not blocked event from queue.
|
||||||
--
|
--
|
||||||
local function getEvent()
|
local function getEvent()
|
||||||
return toEvent(sync:getNextDelay(lysncd.now()))
|
return d2e(sync:getNextDelay(lysncd.now()))
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
@ -495,7 +506,7 @@ local Inlet, InletControl = (function()
|
||||||
}, {
|
}, {
|
||||||
setSync = setSync,
|
setSync = setSync,
|
||||||
getInterior = getInterior, -- TODO <- remove
|
getInterior = getInterior, -- TODO <- remove
|
||||||
toEvent = toEvent,
|
d2e = d2e,
|
||||||
}
|
}
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
|
@ -541,7 +552,7 @@ local Sync = (function()
|
||||||
end
|
end
|
||||||
InletControl.setSync(self)
|
InletControl.setSync(self)
|
||||||
|
|
||||||
local rc = self.config.collect(InletControl.toEvent(delay), exitcode)
|
local rc = self.config.collect(InletControl.d2e(delay), exitcode)
|
||||||
-- TODO honor return codes of the collect
|
-- TODO honor return codes of the collect
|
||||||
removeDelay(self, delay)
|
removeDelay(self, delay)
|
||||||
log("Delay","Finish of ",delay.etype," on ",
|
log("Delay","Finish of ",delay.etype," on ",
|
||||||
|
@ -549,17 +560,33 @@ local Sync = (function()
|
||||||
self.processes[pid] = nil
|
self.processes[pid] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-----
|
||||||
|
-- Stacks a newDelay on the oldDelay,
|
||||||
|
-- the oldDelay blocks the new Delay.
|
||||||
|
--
|
||||||
|
-- A delay can block 'n' other delays,
|
||||||
|
-- but is blocked at most by one, the latest delay.
|
||||||
|
--
|
||||||
|
local function stack(oldDelay, newDelay)
|
||||||
|
newDelay.status = "block"
|
||||||
|
if not oldDelay.blocks then
|
||||||
|
oldDelay.blocks = {}
|
||||||
|
end
|
||||||
|
table.insert(oldDelay.blocks, newDelay)
|
||||||
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- Puts an action on the delay stack.
|
-- Puts an action on the delay stack.
|
||||||
--
|
--
|
||||||
local function delay(self, etype, time, path, path2)
|
local function delay(self, etype, time, path, path2)
|
||||||
log("Function", "delay(", self.config.name,", ",etype,", ",path,")")
|
log("Function", "delay(", self.config.name,", ",etype,", ",path,")")
|
||||||
if path2 then
|
if path2 then
|
||||||
log("Function", "...delay(+",path2,")")
|
log("Function", "+ ",path2)
|
||||||
end
|
end
|
||||||
|
|
||||||
if etype == "Move" and not self.config.onMove then
|
if etype == "Move" and not self.config.onMove then
|
||||||
-- if there is no move action defined, split a move as delete/create
|
-- if there is no move action defined,
|
||||||
|
-- split a move as delete/create
|
||||||
log("Delay", "splitting Move into Delete & Create")
|
log("Delay", "splitting Move into Delete & Create")
|
||||||
delay(self, "Delete", time, path, nil)
|
delay(self, "Delete", time, path, nil)
|
||||||
delay(self, "Create", time, path2, nil)
|
delay(self, "Create", time, path2, nil)
|
||||||
|
@ -576,34 +603,31 @@ local Sync = (function()
|
||||||
-- new delay
|
-- new delay
|
||||||
local nd = Delay.new(etype, alarm, path, path2)
|
local nd = Delay.new(etype, alarm, path, path2)
|
||||||
if nd.etype == "Blanket" then
|
if nd.etype == "Blanket" then
|
||||||
-- always stack blanket events.
|
-- always stack blanket events on the last event
|
||||||
log("Delay", "Stacking blanket event.")
|
log("Delay", "Stacking blanket event.")
|
||||||
table.insert(self.delays, nd)
|
if #self.delays > 0 then
|
||||||
return
|
stack(self.delays[#self.delays], nd)
|
||||||
end
|
end
|
||||||
|
|
||||||
if nd.etype == "Move" then
|
|
||||||
log("Delay", "Stacking a move event ",path," -> ",path2)
|
|
||||||
table.insert(self.delays, nd)
|
table.insert(self.delays, nd)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- detects blocks and collapses by working from back til
|
-- detects blocks and collapses by working from back until
|
||||||
-- front through the fifo
|
-- front through the fifo
|
||||||
InletControl.setSync(self)
|
InletControl.setSync(self)
|
||||||
local ne = InletControl.toEvent(nd)
|
local ne, ne2 = InletControl.d2e(nd)
|
||||||
local il = #self.delays -- last delay
|
local il = #self.delays -- last delay
|
||||||
|
|
||||||
while il > 0 do
|
while il > 0 do
|
||||||
|
-- get 'old' delay
|
||||||
local od = self.delays[il]
|
local od = self.delays[il]
|
||||||
-- tries to collapse identical paths
|
-- tries to collapse identical paths
|
||||||
local oe, oe2 = InletControl.toEvent(od)
|
local oe, oe2 = InletControl.d2e(od)
|
||||||
local ne = InletControl.toEvent(nd) -- TODO more logic on moves
|
|
||||||
|
|
||||||
if oe.etype == "Blanket" then
|
if oe.etype == "Blanket" then
|
||||||
-- everything is blocked by a blanket event.
|
-- everything is blocked by a blanket event.
|
||||||
log("Delay", "Stacking ",nd.etype," upon blanket event.")
|
log("Delay", "Stacking ",nd.etype," upon blanket event.")
|
||||||
|
stack(od, nd)
|
||||||
table.insert(self.delays, nd)
|
table.insert(self.delays, nd)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
@ -611,8 +635,10 @@ local Sync = (function()
|
||||||
-- this mini loop repeats the collapse a second
|
-- this mini loop repeats the collapse a second
|
||||||
-- time for move events
|
-- time for move events
|
||||||
local oel = oe
|
local oel = oe
|
||||||
while oel do
|
local nel = ne
|
||||||
local c = self.config.collapse(oel, ne, self.config)
|
|
||||||
|
while oel and nel do
|
||||||
|
local c = self.config.collapse(oel, nel, self.config)
|
||||||
if c == 0 then
|
if c == 0 then
|
||||||
-- events nullificate each ether
|
-- events nullificate each ether
|
||||||
od.etype = "None" -- TODO better remove?
|
od.etype = "None" -- TODO better remove?
|
||||||
|
@ -625,24 +651,30 @@ local Sync = (function()
|
||||||
log("Delay",nd.etype," replaces event ",
|
log("Delay",nd.etype," replaces event ",
|
||||||
od.etype," on ",path)
|
od.etype," on ",path)
|
||||||
self.delays[il] = nd
|
self.delays[il] = nd
|
||||||
|
-- TODO turn moveFroms into deletes.
|
||||||
return
|
return
|
||||||
elseif c == 3 then
|
elseif c == 3 then
|
||||||
log("Delay", "Stacking ",nd.etype," upon ",
|
log("Delay", "Stacking ",nd.etype," upon ",
|
||||||
od.etype," on ",path)
|
od.etype," on ",path)
|
||||||
|
stack(od, nd)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
-- after first iteration check move destination
|
|
||||||
-- after second stop eitherway
|
-- loops over all oe, oe2, ne, ne2 combos.
|
||||||
if oel == oe2 then
|
if oel == oe and oe2 then
|
||||||
oel = false
|
-- do another time for oe2 if present
|
||||||
else
|
|
||||||
oel = oe2
|
oel = oe2
|
||||||
|
elseif nel == ne then
|
||||||
|
-- do another time for ne2 if present
|
||||||
|
-- start with first oe
|
||||||
|
nel = ne2
|
||||||
|
oel = oe
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
il = il - 1
|
il = il - 1
|
||||||
end
|
end
|
||||||
if il <= 0 then
|
if il <= 0 then
|
||||||
log("Delay", "Stacking ",nd.etype," on ",path)
|
log("Delay", "Registering ",nd.etype," on ",path)
|
||||||
end
|
end
|
||||||
-- there was no hit on collapse or it decided to stack.
|
-- there was no hit on collapse or it decided to stack.
|
||||||
table.insert(self.delays, nd)
|
table.insert(self.delays, nd)
|
||||||
|
@ -1496,13 +1528,9 @@ default = {
|
||||||
--
|
--
|
||||||
collapse = function(event1, event2, config)
|
collapse = function(event1, event2, config)
|
||||||
if event1.path == event2.path then
|
if event1.path == event2.path then
|
||||||
if event1.etype == "Move" or event2.etype == "Move" then
|
local e1 = event1.etype .. event1.move
|
||||||
-- currently moves are always blocks
|
local e2 = event2.etype .. event2.move
|
||||||
return 3
|
return config.collapseTable[e1][e2]
|
||||||
else
|
|
||||||
-- asks the collapseTable what to do
|
|
||||||
return config.collapseTable[event1.etype][event2.etype]
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
@ -1519,13 +1547,24 @@ default = {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-----
|
-----
|
||||||
-- used by default collapse function
|
-- Used by default collapse function.
|
||||||
|
-- Specifies how two event should be collapsed when here
|
||||||
|
-- horizontal event meets upon a vertical event.
|
||||||
|
-- values:
|
||||||
|
-- 0 ... nullification of both events.
|
||||||
|
-- 1 ... absorbtion of horizontal event.
|
||||||
|
-- 2 ... replace of vertical event.
|
||||||
|
-- 3 ... stack both events, vertical blocking horizonal.
|
||||||
|
-- 9 ... combines two move events.
|
||||||
--
|
--
|
||||||
collapseTable = {
|
collapseTable = {
|
||||||
Attrib = { Attrib = 1, Modify = 2, Create = 2, Delete = 2 },
|
Attrib = {Attrib=1, Modify=2, Create=2, Delete=2, MoveFr=3, MoveTo= 2},
|
||||||
Modify = { Attrib = 1, Modify = 1, Create = 2, Delete = 2 },
|
Modify = {Attrib=1, Modify=1, Create=2, Delete=2, MoveFr=3, MoveTo= 2},
|
||||||
Create = { Attrib = 1, Modify = 1, Create = 1, Delete = 0 },
|
Create = {Attrib=1, Modify=1, Create=1, Delete=0, MoveFr=3, MoveTo= 2},
|
||||||
Delete = { Attrib = 1, Modify = 1, Create = 3, Delete = 1 },
|
Delete = {Attrib=1, Modify=1, Create=3, Delete=1, MoveFr=3, MoveTo= 2},
|
||||||
|
MoveFr = {Attrib=3, Modify=3, Create=3, Delete=3, MoveFr=3, MoveTo= 3},
|
||||||
|
-- MoveTo = {Attrib=3, Modify=3, Create=2, Delete=2, MoveFr=9, MoveTo= 2}, TODO 9
|
||||||
|
MoveTo = {Attrib=3, Modify=3, Create=2, Delete=2, MoveFr=3, MoveTo= 2},
|
||||||
},
|
},
|
||||||
|
|
||||||
-----
|
-----
|
||||||
|
|
Loading…
Reference in New Issue