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();
|
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
|
#region Logging
|
||||||
|
|
||||||
private const string INDENT = "+";
|
private const string INDENT = "+";
|
||||||
@ -89,6 +159,11 @@ namespace Acacia.Features.DebugSupport
|
|||||||
|
|
||||||
private void buttonGC_Click(object sender, EventArgs e)
|
private void buttonGC_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
|
GarbageCollect();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GarbageCollect()
|
||||||
|
{
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
GC.WaitForPendingFinalizers();
|
GC.WaitForPendingFinalizers();
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
|
@ -32,6 +32,7 @@ namespace Acacia.Features.DebugSupport
|
|||||||
{
|
{
|
||||||
Version,
|
Version,
|
||||||
Memory,
|
Memory,
|
||||||
|
Tasks,
|
||||||
Wrappers,
|
Wrappers,
|
||||||
Misc,
|
Misc,
|
||||||
System,
|
System,
|
||||||
@ -133,6 +134,25 @@ namespace Acacia.Features.DebugSupport
|
|||||||
|
|
||||||
#endregion
|
#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
|
#region Wrappers
|
||||||
|
|
||||||
[DebugCategory(DebugCategory.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)]
|
[DebugCategory(DebugCategory.Misc)]
|
||||||
public bool ZPushSync
|
public bool ZPushSync
|
||||||
{
|
{
|
||||||
@ -227,7 +241,7 @@ namespace Acacia.Features.DebugSupport
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Outlook
|
#region Outlook
|
||||||
|
|
||||||
[DebugCategory(DebugCategory.System)]
|
[DebugCategory(DebugCategory.System)]
|
||||||
public string OutlookVersion
|
public string OutlookVersion
|
||||||
@ -247,7 +261,7 @@ namespace Acacia.Features.DebugSupport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Helpers
|
#region Helpers
|
||||||
|
|
||||||
|
@ -45,11 +45,19 @@ namespace Acacia.Features.DebugSupport
|
|||||||
RegisterButton(this, "Settings", false, ShowSettings);
|
RegisterButton(this, "Settings", false, ShowSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public override void AfterStartup()
|
||||||
|
{
|
||||||
|
ShowAbout();
|
||||||
|
}
|
||||||
|
|
||||||
#region About dialog
|
#region About dialog
|
||||||
|
|
||||||
public void ShowAbout()
|
public void ShowAbout()
|
||||||
{
|
{
|
||||||
new AboutDialog().ShowDialog();
|
DebugDialog dd = new DebugDialog();
|
||||||
|
dd.Show();
|
||||||
|
dd.DebugCycle(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
@ -25,6 +25,9 @@ namespace Acacia.Features.DebugSupport
|
|||||||
{
|
{
|
||||||
public static class Statistics
|
public static class Statistics
|
||||||
{
|
{
|
||||||
|
public static long StartedTasks;
|
||||||
|
public static long FinishedTasks;
|
||||||
|
|
||||||
public static long CreatedWrappers;
|
public static long CreatedWrappers;
|
||||||
public static long DeletedWrappers;
|
public static long DeletedWrappers;
|
||||||
public static long DisposedWrappers;
|
public static long DisposedWrappers;
|
||||||
|
@ -226,6 +226,11 @@ namespace Acacia.Features
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual void AfterStartup()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Z-Push channels
|
#region Z-Push channels
|
||||||
|
@ -333,10 +333,14 @@ namespace Acacia.Features.GAB
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Do the resync
|
// Do the resync
|
||||||
|
int remaining = _gabsByDomainName.Count;
|
||||||
foreach (GABHandler gab in _gabsByDomainName.Values)
|
foreach (GABHandler gab in _gabsByDomainName.Values)
|
||||||
{
|
{
|
||||||
Logger.Instance.Debug(this, "FullResync: Starting resync: {0}", gab.DisplayName);
|
Logger.Instance.Debug(this, "FullResync: Starting resync: {0}", gab.DisplayName);
|
||||||
Tasks.Task(this, "FullResync", () => gab.FullResync());
|
Tasks.Task(this, "FullResync", () =>
|
||||||
|
{
|
||||||
|
gab.FullResync();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
|
@ -41,6 +41,7 @@ namespace Acacia.Stubs
|
|||||||
/// Restarts the application
|
/// Restarts the application
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void Restart();
|
void Restart();
|
||||||
|
void Quit();
|
||||||
|
|
||||||
void InvokeUI(Action action);
|
void InvokeUI(Action action);
|
||||||
|
|
||||||
|
@ -57,6 +57,11 @@ namespace Acacia.Stubs.OutlookWrappers
|
|||||||
_app.Quit();
|
_app.Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Quit()
|
||||||
|
{
|
||||||
|
_app.Quit();
|
||||||
|
}
|
||||||
|
|
||||||
public event NSOutlook.ApplicationEvents_11_ItemLoadEventHandler ItemLoad
|
public event NSOutlook.ApplicationEvents_11_ItemLoadEventHandler ItemLoad
|
||||||
{
|
{
|
||||||
add { _app.ItemLoad += value; }
|
add { _app.ItemLoad += value; }
|
||||||
|
@ -44,9 +44,6 @@ namespace Acacia
|
|||||||
private set;
|
private set;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove?
|
|
||||||
private Control _dispatcher;
|
|
||||||
|
|
||||||
#region Features
|
#region Features
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -92,10 +89,6 @@ namespace Acacia
|
|||||||
int lcid = Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI);
|
int lcid = Application.LanguageSettings.get_LanguageID(Microsoft.Office.Core.MsoAppLanguageID.msoLanguageIDUI);
|
||||||
Thread.CurrentThread.CurrentUICulture = new CultureInfo(lcid);
|
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.
|
// 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
|
// It's null in older versions of .Net, this fixes that
|
||||||
if (SynchronizationContext.Current == null)
|
if (SynchronizationContext.Current == null)
|
||||||
@ -142,6 +135,9 @@ namespace Acacia
|
|||||||
// Done
|
// Done
|
||||||
Logger.Instance.Debug(this, "Startup done");
|
Logger.Instance.Debug(this, "Startup done");
|
||||||
Acacia.Features.DebugSupport.Statistics.StartupTime.Stop();
|
Acacia.Features.DebugSupport.Statistics.StartupTime.Stop();
|
||||||
|
foreach (Feature feature in Features)
|
||||||
|
feature.AfterStartup();
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
|
@ -15,9 +15,11 @@
|
|||||||
/// Consult LICENSE file for details
|
/// Consult LICENSE file for details
|
||||||
|
|
||||||
using Acacia.Features;
|
using Acacia.Features;
|
||||||
|
using Acacia.Features.DebugSupport;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
|
|
||||||
namespace Acacia.Utils
|
namespace Acacia.Utils
|
||||||
@ -64,10 +66,29 @@ namespace Acacia.Utils
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TaskExecutor
|
public abstract class TaskExecutor
|
||||||
{
|
{
|
||||||
string Name { get; }
|
public abstract string Name { get; }
|
||||||
void ExecuteTask(AcaciaTask task);
|
|
||||||
|
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
|
public static class Tasks
|
||||||
@ -103,12 +124,12 @@ namespace Acacia.Utils
|
|||||||
|
|
||||||
public static void Task(Feature owner, string name, Action action)
|
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)
|
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
|
/// 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,
|
/// 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/>.
|
/// along with this program.If not, see<http://www.gnu.org/licenses/>.
|
||||||
///
|
///
|
||||||
/// Consult LICENSE file for details
|
/// Consult LICENSE file for details
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -40,15 +41,15 @@ namespace Acacia.Utils
|
|||||||
while (!_tasks.IsCompleted)
|
while (!_tasks.IsCompleted)
|
||||||
{
|
{
|
||||||
AcaciaTask task = _tasks.Take();
|
AcaciaTask task = _tasks.Take();
|
||||||
task.Execute();
|
PerformTask(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExecuteTask(AcaciaTask task)
|
protected override void EnqueueTask(AcaciaTask task)
|
||||||
{
|
{
|
||||||
_tasks.Add(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();
|
AcaciaTask task = _tasks.Dequeue();
|
||||||
Logger.Instance.Trace(task.Id, "Beginning task");
|
Logger.Instance.Trace(task.Id, "Beginning task");
|
||||||
task.Execute();
|
PerformTask(task);
|
||||||
Logger.Instance.Info(task.Id, "Ending task: {0}ms", timer.ElapsedMilliseconds);
|
Logger.Instance.Info(task.Id, "Ending task: {0}ms", timer.ElapsedMilliseconds);
|
||||||
// Execute another task if available and we haven't taken too long.
|
// Execute another task if available and we haven't taken too long.
|
||||||
} while (_tasks.Count > 0 && timer.ElapsedMilliseconds < 50);
|
} while (_tasks.Count > 0 && timer.ElapsedMilliseconds < 50);
|
||||||
@ -99,7 +99,7 @@ namespace Acacia.Utils
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="name">The name, for debugging and logging.</param>
|
/// <param name="name">The name, for debugging and logging.</param>
|
||||||
/// <param name="action">The action to execute</param>
|
/// <param name="action">The action to execute</param>
|
||||||
public void ExecuteTask(AcaciaTask task)
|
override protected void EnqueueTask(AcaciaTask task)
|
||||||
{
|
{
|
||||||
if (_init == InitState.Uninitialised)
|
if (_init == InitState.Uninitialised)
|
||||||
{
|
{
|
||||||
@ -112,6 +112,6 @@ namespace Acacia.Utils
|
|||||||
_tasks.Enqueue(task);
|
_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 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