changed alarm interface.

This commit is contained in:
Axel Kittenberger 2010-11-30 17:08:15 +00:00
parent a6cb5ff61e
commit 3a04de8215
2 changed files with 82 additions and 99 deletions

View File

@ -13,20 +13,30 @@
-- @param extra ... a free token to store anything in it.
-- here used as string.
--
local function myAlarm(timestamp, extra)
log("Normal", extra)
-- creates a new alarm in 5 seconds after this one rang
alarm(timestamp + 5, myAlarm, extra)
end
lalarm = {
init = function(inlet)
-- creates the first alarm in 5 seconds from now.
inlet.alarm(now() + 5, "Beep")
end,
-- creates the first alarm in 5 seconds from now.
alarm(now() + 5, myAlarm, "Beep!")
-- called when alarms ring
alarm = function(inlet, timestamp, extra)
log("Normal", extra)
spawn(inlet.createBlanketEvent(), "/bin/echo", "hello")
-- creates a new alarm in 5 seconds after this one rang
inlet.alarm(timestamp + 5, extra)
end,
action = function(inlet)
-- just discard anything that happes in source dir.
inlet.discardEvent(inlet.getEvent())
end
}
-----
-- Just a minimal dummy sync in sake for this example.
-- Lsyncd needs to feel like it is doing something useful.
-- Any real application needs to watch anything otherwise
-- probably shouldn't use Lsyncd :-)
sync{source="/usr/local/etc/", onModify = function() end }
-- Lsyncd needs to watch something, altough in this minimal example
-- it isnt used.
sync{source="/usr/local/etc/", lalarm }

View File

@ -637,6 +637,13 @@ local Inlet, InletControl = (function()
end
}
------
-- registers an alarm.
alarm = function(timestamp, func, extra)
return sync:addAlarm(timestamp, func, extra)
end
-----
-- adds an exclude.
--
@ -884,6 +891,7 @@ local Inlet, InletControl = (function()
-- this one is split, one for user one for runner.
return {
addExclude = addExclude,
alarm = alarm,
createBlanketEvent = createBlanketEvent,
discardEvent = discardEvent,
getEvent = getEvent,
@ -1030,13 +1038,33 @@ end)()
-- Holds information about one observed directory inclusively subdirs.
--
local Sync = (function()
-----
-- Syncs that have no name specified by the user script
-- get an incremental default name 'Sync[X]'
--
local nextDefaultName = 1
-----
-- Adds an user alarm.
-- Calls the user function at timestamp.
--
local function addAlarm(self, timestamp, extra)
local idx
for k, v in ipairs(self.alarms) do
if timestamp < v.timestamp then
idx = k
break
end
end
local a = {timestamp = timestamp,
extra = extra}
if idx then
table.insert(self.alarms, idx, a)
else
table.insert(self.alarms, a)
end
end
-----
-- Adds an exclude.
--
@ -1280,20 +1308,27 @@ local Sync = (function()
-- Returns the nearest alarm for this Sync.
--
local function getAlarm(self)
-- first checks if more processses could be spawned
if self.processes:size() >= self.config.maxProcesses then
return nil
end
local alarm
-- finds the nearest delay waiting to be spawned
for _, d in ipairs(self.delays) do
if d.status == "wait" then
return d.alarm
-- first checks if more processses could be spawned
if self.processes:size() < self.config.maxProcesses then
-- finds the nearest delay waiting to be spawned
for _, d in ipairs(self.delays) do
if d.status == "wait" then
alarm = d.alarm
break
end
end
end
-- nothing to spawn.
return nil
-- return the earlier alarm, user alarms or events
if #self.alarms == 0 then
return alarm
elseif not alarm or self.alarms[1].timestamp < alarm then
return self.alarms[1].timestamp
else
return alarm
end
end
@ -1362,6 +1397,18 @@ local Sync = (function()
end
end
end
-- invokes user alarms
while #self.alarms > 0 and self.alarms[1].timestamp <= timestamp do
InletControl.setSync(self)
if type(self.config.alarm) == "function" then
self.config.alarm(Inlet,
self.alarms[1].timestamp, self.alarms[1].extra)
else
log("Error", "registered alarm, but there is no alarm function")
end
table.remove(self.alarms, 1)
end
end
-----
@ -1384,7 +1431,6 @@ local Sync = (function()
end
end
------
-- adds and returns a blanket delay thats blocks all
-- (used in startup)
@ -1425,21 +1471,13 @@ local Sync = (function()
f:write("\n")
end
--[[--
-- DEBUG delays
local _delay = delay
delay = function(self, ...)
_delay(self, ...)
statusReport(self, io.stdout)
end
--]]
-----
-- Creates a new Sync
--
local function new(config)
local s = {
-- fields
alarms = {},
config = config,
delays = CountArray.new(),
source = config.source,
@ -1447,7 +1485,7 @@ local Sync = (function()
excludes = Excludes.new(),
-- functions
addAlarm = addAlarm,
addBlanketDelay = addBlanketDelay,
addExclude = addExclude,
collect = collect,
@ -2247,60 +2285,6 @@ local StatusFile = (function()
return {write = write, getAlarm = getAlarm}
end)()
------
-- Lets the userscript make its own alarms
--
local UserAlarms = (function()
local alarms = {}
-----
-- Calls the user function at timestamp
--
local function alarm(timestamp, func, extra)
local idx
for k, v in ipairs(alarms) do
if timestamp < v.timestamp then
idx = k
break
end
end
local a = {timestamp = timestamp,
func = func,
extra = extra}
if idx then
table.insert(alarms, idx, a)
else
table.insert(alarms, a)
end
end
----
-- Retrieves the nearest alarm
--
local function getAlarm()
if #alarms == 0 then
return nil
else
return alarms[1].timestamp
end
end
-----
-- Calls user alarms
--
local function invoke(timestamp)
while #alarms > 0 and alarms[1].timestamp <= timestamp do
alarms[1].func(alarms[1].timestamp, alarms[1].extra)
table.remove(alarms, 1)
end
end
-- public interface
return { alarm = alarm,
getAlarm = getAlarm,
invoke = invoke }
end)()
--============================================================================
-- lsyncd runner plugs. These functions will be called from core.
--============================================================================
@ -2383,8 +2367,6 @@ function runner.cycle(timestamp)
s:invokeActions(timestamp)
end
UserAlarms.invoke(timestamp)
if settings.statusFile then
StatusFile.write(timestamp)
end
@ -2697,7 +2679,6 @@ function runner.getAlarm()
end
-- checks if a statusfile write has been delayed
checkAlarm(StatusFile.getAlarm())
checkAlarm(UserAlarms.getAlarm())
log("Debug", "getAlarm returns: ",alarm)
return alarm
@ -2815,14 +2796,6 @@ function spawnShell(agent, command, ...)
return spawn(agent, "/bin/sh", "-c", command, "/bin/sh", ...)
end
-----
-- Calls func at timestamp.
-- Use now() to receive current timestamp
-- add seconds with '+' to it)
--
alarm = UserAlarms.alarm
-----
-- Comfort routine also for user.
-- Returns true if 'String' starts with 'Start'