Added statistics on tasks. Added debug cycling of gab resync.

This commit is contained in:
Patrick Simpson 2017-02-08 18:05:42 +01:00
parent 3117418785
commit 773f0b07bf
13 changed files with 167 additions and 34 deletions

View File

@ -47,6 +47,76 @@ namespace Acacia.Features.DebugSupport
Properties.Refresh();
}
private class DebugCycleInfo
{
private int cycleIndex = 0;
private int cycleCount;
private Timer timer = new Timer();
private GAB.FeatureGAB gab;
private int zeroCount = 1000;
public DebugCycleInfo(DebugDialog dlg, GAB.FeatureGAB gab, int count)
{
this.cycleCount = count;
this.gab = gab;
timer.Interval = 1000;
timer.Tick += (a, b) =>
{
dlg.Text = string.Format("Cycle {0} of {1}", cycleIndex + 1, cycleCount);
dlg.GarbageCollect();
if (((DebugInfo)dlg.Properties.SelectedObject).ActiveTasks == 0)
{
// Make sure the value is stable at zero
++zeroCount;
if (zeroCount >= 3)
{
zeroCount = 0;
Logger.Instance.Debug(this, "CYCLER");
++cycleIndex;
if (cycleIndex >= cycleCount)
{
timer.Stop();
dlg.Hide();
ThisAddIn.Instance.Quit();
}
else
{
DebugCycle();
}
}
}
};
}
public void Run()
{
timer.Start();
}
private void DebugCycle()
{
Tasks.Task(gab, "DebugCycle", () =>
{
gab.FullResync();
});
}
}
private DebugCycleInfo cycle;
internal void DebugCycle(int count)
{
GAB.FeatureGAB gab = ThisAddIn.Instance.GetFeature<GAB.FeatureGAB>();
if (gab != null)
{
cycle = new DebugCycleInfo(this, gab, count);
cycle.Run();
}
}
#region Logging
private const string INDENT = "+";
@ -89,6 +159,11 @@ namespace Acacia.Features.DebugSupport
private void buttonGC_Click(object sender, EventArgs e)
{
GarbageCollect();
}
private void GarbageCollect()
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();

View File

@ -32,6 +32,7 @@ namespace Acacia.Features.DebugSupport
{
Version,
Memory,
Tasks,
Wrappers,
Misc,
System,
@ -133,6 +134,25 @@ namespace Acacia.Features.DebugSupport
#endregion
#region Tasks
[DebugCategory(DebugCategory.Tasks)]
public string Threading
{
get { return Tasks.Executor.Name; }
}
[DebugCategory(DebugCategory.Tasks)]
public long ActiveTasks { get { return Statistics.StartedTasks - Statistics.FinishedTasks; } }
[DebugCategory(DebugCategory.Tasks)]
public long StartedTasks { get { return Statistics.StartedTasks; } }
[DebugCategory(DebugCategory.Tasks)]
public long FinishedTasks { get { return Statistics.FinishedTasks; } }
#endregion
#region Wrappers
[DebugCategory(DebugCategory.Wrappers)]
@ -163,12 +183,6 @@ namespace Acacia.Features.DebugSupport
}
}
[DebugCategory(DebugCategory.Misc)]
public string Threading
{
get { return Tasks.Executor.Name; }
}
[DebugCategory(DebugCategory.Misc)]
public bool ZPushSync
{
@ -227,7 +241,7 @@ namespace Acacia.Features.DebugSupport
#endregion
#region Outlook
#region Outlook
[DebugCategory(DebugCategory.System)]
public string OutlookVersion
@ -247,7 +261,7 @@ namespace Acacia.Features.DebugSupport
}
}
#endregion
#endregion
#region Helpers

View File

@ -45,11 +45,19 @@ namespace Acacia.Features.DebugSupport
RegisterButton(this, "Settings", false, ShowSettings);
}
public override void AfterStartup()
{
ShowAbout();
}
#region About dialog
public void ShowAbout()
{
new AboutDialog().ShowDialog();
DebugDialog dd = new DebugDialog();
dd.Show();
dd.DebugCycle(5);
}
#endregion

View File

@ -25,6 +25,9 @@ namespace Acacia.Features.DebugSupport
{
public static class Statistics
{
public static long StartedTasks;
public static long FinishedTasks;
public static long CreatedWrappers;
public static long DeletedWrappers;
public static long DisposedWrappers;

View File

@ -226,6 +226,11 @@ namespace Acacia.Features
}
public virtual void AfterStartup()
{
}
#endregion
#region Z-Push channels

View File

@ -333,10 +333,14 @@ namespace Acacia.Features.GAB
}
// Do the resync
int remaining = _gabsByDomainName.Count;
foreach (GABHandler gab in _gabsByDomainName.Values)
{
Logger.Instance.Debug(this, "FullResync: Starting resync: {0}", gab.DisplayName);
Tasks.Task(this, "FullResync", () => gab.FullResync());
Tasks.Task(this, "FullResync", () =>
{
gab.FullResync();
});
}
}
finally

View File

@ -41,6 +41,7 @@ namespace Acacia.Stubs
/// Restarts the application
/// </summary>
void Restart();
void Quit();
void InvokeUI(Action action);

View File

@ -57,6 +57,11 @@ namespace Acacia.Stubs.OutlookWrappers
_app.Quit();
}
public void Quit()
{
_app.Quit();
}
public event NSOutlook.ApplicationEvents_11_ItemLoadEventHandler ItemLoad
{
add { _app.ItemLoad += value; }

View File

@ -44,9 +44,6 @@ namespace Acacia
private set;
}
// TODO: remove?
private Control _dispatcher;
#region Features
/// <summary>
@ -92,10 +89,6 @@ namespace Acacia
int lcid = Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(lcid);
// Create a dispatcher
_dispatcher = new Control();
_dispatcher.CreateControl();
// The synchronization context is needed to allow background tasks to jump back to the UI thread.
// It's null in older versions of .Net, this fixes that
if (SynchronizationContext.Current == null)
@ -142,6 +135,9 @@ namespace Acacia
// Done
Logger.Instance.Debug(this, "Startup done");
Acacia.Features.DebugSupport.Statistics.StartupTime.Stop();
foreach (Feature feature in Features)
feature.AfterStartup();
}
catch (System.Exception e)
{

View File

@ -15,9 +15,11 @@
/// Consult LICENSE file for details
using Acacia.Features;
using Acacia.Features.DebugSupport;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
using System.Windows.Forms;
namespace Acacia.Utils
@ -64,10 +66,29 @@ namespace Acacia.Utils
}
public interface TaskExecutor
public abstract class TaskExecutor
{
string Name { get; }
void ExecuteTask(AcaciaTask task);
public abstract string Name { get; }
public void AddTask(AcaciaTask task)
{
Interlocked.Increment(ref Statistics.StartedTasks);
EnqueueTask(task);
}
abstract protected void EnqueueTask(AcaciaTask task);
protected void PerformTask(AcaciaTask task)
{
try
{
task.Execute();
}
finally
{
Interlocked.Increment(ref Statistics.FinishedTasks);
}
}
}
public static class Tasks
@ -103,12 +124,12 @@ namespace Acacia.Utils
public static void Task(Feature owner, string name, Action action)
{
Executor.ExecuteTask(new AcaciaTask(owner, name, action));
Task(new AcaciaTask(owner, name, action));
}
public static void Task(AcaciaTask task)
{
Executor.ExecuteTask(task);
Executor.AddTask(task);
}
}
}

View File

@ -1,4 +1,6 @@
/// Copyright 2016 Kopano b.v.

using Acacia.Features.DebugSupport;
/// Copyright 2016 Kopano b.v.
///
/// This program is free software: you can redistribute it and/or modify
/// it under the terms of the GNU Affero General Public License, version 3,
@ -13,7 +15,6 @@
/// along with this program.If not, see<http://www.gnu.org/licenses/>.
///
/// Consult LICENSE file for details
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@ -40,15 +41,15 @@ namespace Acacia.Utils
while (!_tasks.IsCompleted)
{
AcaciaTask task = _tasks.Take();
task.Execute();
PerformTask(task);
}
}
public void ExecuteTask(AcaciaTask task)
protected override void EnqueueTask(AcaciaTask task)
{
_tasks.Add(task);
}
public string Name { get { return "Background"; } }
override public string Name { get { return "Background"; } }
}
}

View File

@ -73,7 +73,7 @@ namespace Acacia.Utils
{
AcaciaTask task = _tasks.Dequeue();
Logger.Instance.Trace(task.Id, "Beginning task");
task.Execute();
PerformTask(task);
Logger.Instance.Info(task.Id, "Ending task: {0}ms", timer.ElapsedMilliseconds);
// Execute another task if available and we haven't taken too long.
} while (_tasks.Count > 0 && timer.ElapsedMilliseconds < 50);
@ -99,7 +99,7 @@ namespace Acacia.Utils
/// </summary>
/// <param name="name">The name, for debugging and logging.</param>
/// <param name="action">The action to execute</param>
public void ExecuteTask(AcaciaTask task)
override protected void EnqueueTask(AcaciaTask task)
{
if (_init == InitState.Uninitialised)
{
@ -112,6 +112,6 @@ namespace Acacia.Utils
_tasks.Enqueue(task);
}
public string Name { get { return "MainThread"; } }
override public string Name { get { return "MainThread"; } }
}
}

View File

@ -24,11 +24,11 @@ namespace Acacia.Utils
{
public class TasksSynchronous : TaskExecutor
{
public void ExecuteTask(AcaciaTask task)
protected override void EnqueueTask(AcaciaTask task)
{
task.Execute();
PerformTask(task);
}
public string Name { get { return "Synchronous"; } }
override public string Name { get { return "Synchronous"; } }
}
}