beagle r4764 - trunk/beagle/Util
- From: dbera svn gnome org
- To: svn-commits-list gnome org
- Subject: beagle r4764 - trunk/beagle/Util
- Date: Sun, 25 May 2008 16:41:30 +0000 (UTC)
Author: dbera
Date: Sun May 25 16:41:30 2008
New Revision: 4764
URL: http://svn.gnome.org/viewvc/beagle?rev=4764&view=rev
Log:
* Scheduler.cs: Punish misbehaving tasks. Frustrated by the numerous large-log-file complains, allow at most 200 exceptions before a task is automatically cancelled. One part of my brain wants to disallow even a single exception, but ... to keep with existing behaviour I am allowing a large number of exceptions for long running generator tasks. Ration your exceptions.
Show the list of cancelled tasks in beagle-status.
Also deal with task cancellation correctly i.e. DoTaskReal might itself cancel a task so take that into consideration, do not schedule a cancelled task and some other such things.
Modified:
trunk/beagle/Util/Scheduler.cs
Modified: trunk/beagle/Util/Scheduler.cs
==============================================================================
--- trunk/beagle/Util/Scheduler.cs (original)
+++ trunk/beagle/Util/Scheduler.cs Sun May 25 16:41:30 2008
@@ -191,6 +191,9 @@
public void Schedule (Scheduler scheduler)
{
+ if (this.cancelled)
+ return; // do not schedule a cancelled task
+
// Increment the task groups the first
// time a task is scheduled.
if (this.scheduler == null)
@@ -226,13 +229,32 @@
public void Cancel ()
{
+ Cancel (null);
+ }
+
+ public void Cancel (string reason)
+ {
if (! cancelled) {
+ AddToCancelledTaskList (reason);
DecrementAllTaskGroups ();
Cleanup (); // clean up after cancelled tasks
}
cancelled = true;
}
+ private void AddToCancelledTaskList (string reason)
+ {
+ string task_desc = String.Format ("Cancelled task: {5}\n" +
+ " Tag: {0}\n" +
+ " Creator: {1}\n" +
+ "Description: {2}\n" +
+ " Priority: {3} ({4})\n",
+ Tag, Creator, Description, Priority, SubPriority,
+ (reason == null ? String.Empty : reason));
+ if (scheduler != null)
+ scheduler.ReportCancelledTask (task_desc);
+ }
+
///////////////////////////////
// The Task's count keeps track of how many
@@ -244,6 +266,18 @@
get { return count; }
}
+ // Keeps track of how many times the task was executed but
+ // there was some exception
+ private int misfires = 0;
+
+ // Allow at most this many exceptions per task
+ // This is a bit high since some tasks like the generators are
+ // long running tasks. This should be a high enough number
+ // to tolerate some exceptional cases but stop the task
+ // in case it went into an infinite loop with exceptions.
+ // Ideally all exceptions should be caught and handled downstream.
+ const int MAX_TASK_EXCEPTION = 200;
+
///////////////////////////////
public void SpawnChild (Task child_task)
@@ -272,6 +306,7 @@
try {
DoTaskReal ();
} catch (Exception ex) {
+ misfires ++;
Logger.Log.Warn (ex,
"Caught exception in DoTaskReal\n" +
" Tag: {0}\n" +
@@ -279,12 +314,23 @@
"Description: {2}\n" +
" Priority: {3} ({4})",
Tag, Creator, Description, Priority, SubPriority);
+ if (misfires >= MAX_TASK_EXCEPTION) {
+ Log.Warn ("More than {5} exceptions in DoTaskReal. Disabling further execution of task:\n" +
+ " Tag: {0}\n" +
+ " Creator: {1}\n" +
+ "Description: {2}\n" +
+ " Priority: {3} ({4})",
+ Tag, Creator, Description, Priority, SubPriority, MAX_TASK_EXCEPTION);
+ Cancel ("Exceptions in DoTaskReal");
+ }
}
sw.Stop ();
if (Debug)
Logger.Log.Debug ("Finished task {0} in {1}", Tag, sw);
- if (Reschedule) {
+ if (cancelled) {
+ return;
+ } else if (Reschedule) {
++count;
if (Debug)
Log.Debug ("Rescheduling task {0}", Tag);
@@ -311,6 +357,9 @@
DoCleanup ();
} catch (Exception ex) {
Logger.Log.Warn (ex, "Caught exception cleaning up task '{0}'", Tag);
+ } finally {
+ Reschedule = false;
+ scheduler = null;
}
}
@@ -557,7 +606,7 @@
private Hashtable tasks_by_tag = new Hashtable ();
private int total_executed_task_count = 0;
-
+
public void Add (Task task)
{
if (task == null)
@@ -1041,6 +1090,18 @@
//////////////////////////////////////////////////////////////////////////////
+ // A list of descriptions of cancelled tasks
+ // Kept for display purposes; it is useful to know
+ // which tasks were cancelled and why.
+ private ArrayList cancelled_tasks = new ArrayList ();
+
+ internal void ReportCancelledTask (string description)
+ {
+ cancelled_tasks.Add (description);
+ }
+
+ //////////////////////////////////////////////////////////////////////////////
+
private static StringBuilder cached_sb = new StringBuilder ();
public SchedulerInformation GetCurrentStatus ()
@@ -1090,6 +1151,11 @@
current_status.BlockedTasks.Add (cached_sb.ToString ());
}
+ // Add the cancelled tasks to blocked_task list for the time being
+ // This is avoid ABI change in libbeagle
+ foreach (string description in cancelled_tasks)
+ current_status.BlockedTasks.Add (description);
+
current_status.TotalTaskCount = total_executed_task_count;
current_status.StatusString = status_str;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]