mirror of
https://github.com/Kopano-dev/kopano-ol-extension.git
synced 2023-10-10 13:37:40 +02:00
Added statistics on tasks. Added debug cycling of gab resync.
This commit is contained in:
parent
3117418785
commit
773f0b07bf
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -226,6 +226,11 @@ namespace Acacia.Features
|
||||
|
||||
}
|
||||
|
||||
public virtual void AfterStartup()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Z-Push channels
|
||||
|
@ -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
|
||||
|
@ -41,6 +41,7 @@ namespace Acacia.Stubs
|
||||
/// Restarts the application
|
||||
/// </summary>
|
||||
void Restart();
|
||||
void Quit();
|
||||
|
||||
void InvokeUI(Action action);
|
||||
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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"; } }
|
||||
}
|
||||
}
|
||||
|
@ -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"; } }
|
||||
}
|
||||
}
|
||||
|
@ -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"; } }
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user