From da6713cdc4d29557cfb5bdaaca2bde6fc8df108b Mon Sep 17 00:00:00 2001 From: Kenneth Skovhede Date: Mon, 10 Mar 2014 14:24:01 +0100 Subject: [PATCH] Fixed scheduler to update last/next timestamps on schedules --- Duplicati/Server/Scheduler.cs | 43 ++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/Duplicati/Server/Scheduler.cs b/Duplicati/Server/Scheduler.cs index 05a0d5e01..f2525df7f 100644 --- a/Duplicati/Server/Scheduler.cs +++ b/Duplicati/Server/Scheduler.cs @@ -64,6 +64,11 @@ namespace Duplicati.Server /// The currently scheduled items /// private ISchedule[] m_schedule; + + /// + /// List of update tasks, used to set the timestamp on the schedule once completed + /// + private Dictionary, Tuple> m_updateTasks; /// /// Constructs a new scheduler @@ -75,9 +80,11 @@ namespace Duplicati.Server { m_thread = new Thread(new ThreadStart(Runner)); m_worker = worker; + m_worker.CompletedWork += OnCompleted; m_schedule = new ISchedule[0]; m_terminate = false; m_event = new AutoResetEvent(false); + m_updateTasks = new Dictionary, Tuple>(); m_thread.IsBackground = true; m_thread.Start(); } @@ -160,6 +167,24 @@ namespace Duplicati.Server return res; } + private void OnCompleted(object sender, EventArgs e) + { + Tuple t = null; + lock(m_lock) + { + if (m_updateTasks.TryGetValue(m_worker.CurrentTask, out t)) + m_updateTasks.Remove(m_worker.CurrentTask); + } + + if (t != null) + { + t.Item1.Time = t.Item2; + t.Item1.LastRun = t.Item3; + Program.DataConnection.AddOrUpdateSchedule(t.Item1); + } + + } + /// /// The actual scheduling procedure /// @@ -193,8 +218,9 @@ namespace Duplicati.Server //If time is exceeded, run it now if (start <= DateTime.Now) { + var jobsToRun = new List>(); //TODO: Cache this to avoid frequent lookups - foreach(var id in Program.DataConnection.GetBackupIDsForTags(sc.Tags)) + foreach(var id in Program.DataConnection.GetBackupIDsForTags(sc.Tags).Distinct()) { //See if it is already queued var tmplst = from n in m_worker.CurrentTasks @@ -206,7 +232,7 @@ namespace Duplicati.Server //If it is not already in queue, put it there if (!tmplst.Any(x => x == id)) - m_worker.AddTask(new Tuple(id, Duplicati.Server.Serialization.DuplicatiOperation.Backup)); + jobsToRun.Add(new Tuple(id, Duplicati.Server.Serialization.DuplicatiOperation.Backup)); } //Caluclate next time, by adding the interval to the start until we have @@ -223,9 +249,20 @@ namespace Duplicati.Server //TODO: Report this somehow continue; } - + + Tuple lastJob = jobsToRun.LastOrDefault(); + if (lastJob != null) + lock(m_lock) + m_updateTasks[lastJob] = new Tuple(sc, start, DateTime.UtcNow); + + foreach(var job in jobsToRun) + m_worker.AddTask(job); + if (start < DateTime.Now) + { + //TODO: Report this somehow continue; + } } scheduled[sc.ID] = start;