##// END OF EJS Templates
improved log concept
cin -
r36:313f708a50e9 diagnostics
parent child
Show More
@@ -0,0 +1,37
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab.Diagnostics {
7 public class ConsoleTraceListener {
8
9 static readonly object _consoleLock = new object();
10
11 public void Subscribe() {
12 LogChannel<TraceEvent>.Default.Events += Default_Events;
13 }
14
15 public void Unsubscribe() {
16 LogChannel<TraceEvent>.Default.Events -= Default_Events;
17 }
18
19 void Default_Events(object sender, ValueEventArgs<TraceEvent> e) {
20 LogEvent((TraceContext)sender, e.Value);
21 }
22
23 void LogEvent(TraceContext context, TraceEvent evt) {
24 var msg = new StringBuilder();
25 for (int i = 0; i < context.CurrentOperation.Level; i++)
26 msg.Append(" ");
27 msg.Append(evt.EventType);
28 msg.AppendFormat("[{0}]: ",context.ThreadId);
29 msg.Append(evt.Message);
30
31 lock (_consoleLock) {
32 Console.ForegroundColor = (ConsoleColor)(context.ThreadId % 15 + 1);
33 Console.WriteLine(msg.ToString());
34 }
35 }
36 }
37 }
@@ -0,0 +1,24
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab.Diagnostics {
7 public class LogChannel<TEvent> {
8 static LogChannel<TEvent> _default = new LogChannel<TEvent>();
9
10 public static LogChannel<TEvent> Default {
11 get {
12 return _default;
13 }
14 }
15
16 public event EventHandler<ValueEventArgs<TEvent>> Events;
17
18 public void LogEvent(TEvent data) {
19 var t = Events;
20 if (t!= null)
21 t(TraceContext.Current,new ValueEventArgs<TEvent>(data));
22 }
23 }
24 }
@@ -0,0 +1,97
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading;
6 using System.Threading.Tasks;
7
8 namespace Implab.Diagnostics {
9 public class TraceContext {
10 LogicalOperation m_currentOperation;
11 readonly LogicalOperation m_traceBound;
12 readonly int m_threadId;
13 readonly TraceContext m_parent;
14
15 readonly static object _consoleLock = new object();
16
17 [ThreadStatic]
18 static TraceContext _current;
19
20 public static TraceContext Current {
21 get {
22 if (_current == null)
23 _current = new TraceContext();
24 return _current;
25 }
26 }
27
28 TraceContext(TraceContext context) {
29 if (context == null)
30 throw new ArgumentNullException("context");
31
32 m_parent = context;
33 m_currentOperation = context.CurrentOperation;
34 m_traceBound = context.CurrentOperation;
35 m_threadId = Thread.CurrentThread.ManagedThreadId;
36
37 LogEvent(TraceEventType.Transfer, String.Empty);
38 }
39
40 TraceContext() {
41 m_currentOperation = new LogicalOperation();
42 m_traceBound = m_currentOperation;
43 m_threadId = Thread.CurrentThread.ManagedThreadId;
44 }
45
46 public static void Transfer(TraceContext from) {
47 _current = from == null ? new TraceContext() : new TraceContext(from);
48 }
49
50 public TraceContext ParentContext {
51 get {
52 return m_parent;
53 }
54 }
55
56 public LogicalOperation CurrentOperation {
57 get {
58 return m_currentOperation;
59 }
60 }
61
62 public LogicalOperation TraceBound {
63 get {
64 return m_traceBound;
65 }
66 }
67
68 public int ThreadId {
69 get {
70 return m_threadId;
71 }
72 }
73
74 public void StartLogicalOperation() {
75 StartLogicalOperation(null);
76 }
77
78 public void StartLogicalOperation(string name) {
79 LogEvent(TraceEventType.OperationStarted, "{0}", name);
80 m_currentOperation = new LogicalOperation(name, m_currentOperation);
81 }
82
83 public void EndLogicalOperation() {
84 if (m_traceBound == m_currentOperation) {
85 LogEvent(TraceEventType.Error, "Trying to end the operation which isn't belongs to current trace");
86 } else {
87 var op = m_currentOperation;
88 m_currentOperation = m_currentOperation.Parent;
89 LogEvent(TraceEventType.OperationCompleted, "{0} {1} ms", op.Name, op.Duration);
90 }
91 }
92
93 void LogEvent(TraceEventType type, string format, params object[] args) {
94 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(type, format, args));
95 }
96 }
97 }
@@ -0,0 +1,27
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Implab.Diagnostics {
7 public class TraceEvent {
8 public string Message {
9 get;
10 private set;
11 }
12
13 public TraceEventType EventType {
14 get;
15 private set;
16 }
17
18 public TraceEvent(TraceEventType type, string message) {
19 EventType = type;
20 Message = message;
21 }
22
23 public static TraceEvent Create(TraceEventType type, string format, params object[] args) {
24 return new TraceEvent(type, String.Format(format, args));
25 }
26 }
27 }
@@ -0,0 +1,53
1 using System;
2 using System.Collections.Generic;
3 using System.Diagnostics;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace Implab.Diagnostics {
9 /// <summary>
10 /// Класс для публикации событий выполнения программы, события публикуются через <see cref="LogChannel{TraceEvent}"/>
11 /// </summary>
12 public static class TraceLog {
13 [Conditional("TRACE")]
14 public static void Transfer(TraceContext from) {
15 TraceContext.Transfer(from);
16 }
17
18 [Conditional("TRACE")]
19 public static void StartLogicalOperation() {
20 TraceContext.Current.StartLogicalOperation();
21 }
22
23 [Conditional("TRACE")]
24 public static void StartLogicalOperation(string name) {
25 TraceContext.Current.StartLogicalOperation(name);
26 }
27
28 [Conditional("TRACE")]
29 public static void EndLogicalOperation() {
30 TraceContext.Current.EndLogicalOperation();
31 }
32
33 [Conditional("TRACE")]
34 public static void TraceInformation(string format, params object[] arguments) {
35 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Information, format, arguments));
36 }
37
38 [Conditional("TRACE")]
39 public static void TraceWarning(string format, params object[] arguments) {
40 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Warning, format, arguments));
41 }
42
43 [Conditional("TRACE")]
44 public static void TraceError(string format, params object[] arguments) {
45 LogChannel<TraceEvent>.Default.LogEvent(TraceEvent.Create(TraceEventType.Error, format, arguments));
46 }
47
48 [Conditional("TRACE")]
49 public static void TraceError(Exception err) {
50 TraceError("{0}", err);
51 }
52 }
53 }
1 NO CONTENT: modified file, binary diff hidden
NO CONTENT: modified file, binary diff hidden
@@ -1,61 +1,63
1 <?xml version="1.0" encoding="utf-8"?>
1 <?xml version="1.0" encoding="utf-8"?>
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
2 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3 <PropertyGroup>
3 <PropertyGroup>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
4 <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
5 <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
6 <ProductVersion>10.0.0</ProductVersion>
6 <ProductVersion>10.0.0</ProductVersion>
7 <SchemaVersion>2.0</SchemaVersion>
7 <SchemaVersion>2.0</SchemaVersion>
8 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
8 <ProjectGuid>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</ProjectGuid>
9 <OutputType>Library</OutputType>
9 <OutputType>Library</OutputType>
10 <RootNamespace>Implab</RootNamespace>
10 <RootNamespace>Implab</RootNamespace>
11 <AssemblyName>Implab</AssemblyName>
11 <AssemblyName>Implab</AssemblyName>
12 </PropertyGroup>
12 </PropertyGroup>
13 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
13 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
14 <DebugSymbols>true</DebugSymbols>
14 <DebugSymbols>true</DebugSymbols>
15 <DebugType>full</DebugType>
15 <DebugType>full</DebugType>
16 <Optimize>false</Optimize>
16 <Optimize>false</Optimize>
17 <OutputPath>bin\Debug</OutputPath>
17 <OutputPath>bin\Debug</OutputPath>
18 <DefineConstants>TRACE;DEBUG;</DefineConstants>
18 <DefineConstants>TRACE;DEBUG;</DefineConstants>
19 <ErrorReport>prompt</ErrorReport>
19 <ErrorReport>prompt</ErrorReport>
20 <WarningLevel>4</WarningLevel>
20 <WarningLevel>4</WarningLevel>
21 <ConsolePause>false</ConsolePause>
21 <ConsolePause>false</ConsolePause>
22 </PropertyGroup>
22 </PropertyGroup>
23 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
23 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
24 <DebugType>full</DebugType>
24 <DebugType>full</DebugType>
25 <Optimize>true</Optimize>
25 <Optimize>true</Optimize>
26 <OutputPath>bin\Release</OutputPath>
26 <OutputPath>bin\Release</OutputPath>
27 <ErrorReport>prompt</ErrorReport>
27 <ErrorReport>prompt</ErrorReport>
28 <WarningLevel>4</WarningLevel>
28 <WarningLevel>4</WarningLevel>
29 <ConsolePause>false</ConsolePause>
29 <ConsolePause>false</ConsolePause>
30 </PropertyGroup>
30 </PropertyGroup>
31 <ItemGroup>
31 <ItemGroup>
32 <Reference Include="System" />
32 <Reference Include="System" />
33 </ItemGroup>
33 </ItemGroup>
34 <ItemGroup>
34 <ItemGroup>
35 <Compile Include="Diagnostics\IEventListener.cs" />
35 <Compile Include="Diagnostics\ConsoleTraceListener.cs" />
36 <Compile Include="Diagnostics\LogChannel.cs" />
36 <Compile Include="Diagnostics\LogicalOperation.cs" />
37 <Compile Include="Diagnostics\LogicalOperation.cs" />
37 <Compile Include="Diagnostics\Log.cs" />
38 <Compile Include="Diagnostics\TraceLog.cs" />
38 <Compile Include="Diagnostics\LogContext.cs" />
39 <Compile Include="Diagnostics\TraceContext.cs" />
40 <Compile Include="Diagnostics\TraceEvent.cs" />
39 <Compile Include="Diagnostics\TraceEventType.cs" />
41 <Compile Include="Diagnostics\TraceEventType.cs" />
40 <Compile Include="ICancellable.cs" />
42 <Compile Include="ICancellable.cs" />
41 <Compile Include="IProgressHandler.cs" />
43 <Compile Include="IProgressHandler.cs" />
42 <Compile Include="IProgressNotifier.cs" />
44 <Compile Include="IProgressNotifier.cs" />
43 <Compile Include="IPromise.cs" />
45 <Compile Include="IPromise.cs" />
44 <Compile Include="IPromiseBase.cs" />
46 <Compile Include="IPromiseBase.cs" />
45 <Compile Include="ITaskController.cs" />
47 <Compile Include="ITaskController.cs" />
46 <Compile Include="ManagedPromise.cs" />
48 <Compile Include="ManagedPromise.cs" />
47 <Compile Include="Parallels\DispatchPool.cs" />
49 <Compile Include="Parallels\DispatchPool.cs" />
48 <Compile Include="Parallels\ArrayTraits.cs" />
50 <Compile Include="Parallels\ArrayTraits.cs" />
49 <Compile Include="Parallels\MTQueue.cs" />
51 <Compile Include="Parallels\MTQueue.cs" />
50 <Compile Include="Parallels\WorkerPool.cs" />
52 <Compile Include="Parallels\WorkerPool.cs" />
51 <Compile Include="TaskController.cs" />
53 <Compile Include="TaskController.cs" />
52 <Compile Include="ProgressInitEventArgs.cs" />
54 <Compile Include="ProgressInitEventArgs.cs" />
53 <Compile Include="Properties\AssemblyInfo.cs" />
55 <Compile Include="Properties\AssemblyInfo.cs" />
54 <Compile Include="Promise.cs" />
56 <Compile Include="Promise.cs" />
55 <Compile Include="Parallels\AsyncPool.cs" />
57 <Compile Include="Parallels\AsyncPool.cs" />
56 <Compile Include="Safe.cs" />
58 <Compile Include="Safe.cs" />
57 <Compile Include="ValueEventArgs.cs" />
59 <Compile Include="ValueEventArgs.cs" />
58 </ItemGroup>
60 </ItemGroup>
59 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
61 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
60 <ItemGroup />
62 <ItemGroup />
61 </Project> No newline at end of file
63 </Project>
@@ -1,50 +1,50
1 using Implab.Diagnostics;
1 using Implab.Diagnostics;
2 using System;
2 using System;
3 using System.Threading;
3 using System.Threading;
4
4
5 namespace Implab.Parallels {
5 namespace Implab.Parallels {
6 /// <summary>
6 /// <summary>
7 /// Класс для распаралеливания задач.
7 /// Класс для распаралеливания задач.
8 /// </summary>
8 /// </summary>
9 /// <remarks>
9 /// <remarks>
10 /// Используя данный класс и лямда выражения можно распараллелить
10 /// Используя данный класс и лямда выражения можно распараллелить
11 /// вычисления, для этого используется концепция обещаний.
11 /// вычисления, для этого используется концепция обещаний.
12 /// </remarks>
12 /// </remarks>
13 public static class AsyncPool {
13 public static class AsyncPool {
14
14
15 public static Promise<T> Invoke<T>(Func<T> func) {
15 public static Promise<T> Invoke<T>(Func<T> func) {
16 var p = new Promise<T>();
16 var p = new Promise<T>();
17 var caller = LogContext.Current;
17 var caller = TraceContext.Current;
18
18
19 ThreadPool.QueueUserWorkItem(param => {
19 ThreadPool.QueueUserWorkItem(param => {
20 Log.Transfer(caller);
20 TraceLog.Transfer(caller);
21 try {
21 try {
22 p.Resolve(func());
22 p.Resolve(func());
23 } catch(Exception e) {
23 } catch(Exception e) {
24 p.Reject(e);
24 p.Reject(e);
25 }
25 }
26 });
26 });
27
27
28 return p;
28 return p;
29 }
29 }
30
30
31 public static Promise<T> InvokeNewThread<T>(Func<T> func) {
31 public static Promise<T> InvokeNewThread<T>(Func<T> func) {
32 var p = new Promise<T>();
32 var p = new Promise<T>();
33
33
34 var caller = LogContext.Current;
34 var caller = TraceContext.Current;
35
35
36 var worker = new Thread(() => {
36 var worker = new Thread(() => {
37 Log.Transfer(caller);
37 TraceLog.Transfer(caller);
38 try {
38 try {
39 p.Resolve(func());
39 p.Resolve(func());
40 } catch (Exception e) {
40 } catch (Exception e) {
41 p.Reject(e);
41 p.Reject(e);
42 }
42 }
43 });
43 });
44 worker.IsBackground = true;
44 worker.IsBackground = true;
45 worker.Start();
45 worker.Start();
46
46
47 return p;
47 return p;
48 }
48 }
49 }
49 }
50 }
50 }
@@ -1,97 +1,97
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Linq;
3 using System.Linq;
4 using System.Text;
4 using System.Text;
5 using System.Threading;
5 using System.Threading;
6 using System.Diagnostics;
6 using System.Diagnostics;
7 using Implab.Diagnostics;
7 using Implab.Diagnostics;
8
8
9 namespace Implab.Parallels {
9 namespace Implab.Parallels {
10 public class WorkerPool : DispatchPool<Action> {
10 public class WorkerPool : DispatchPool<Action> {
11
11
12 MTQueue<Action> m_queue = new MTQueue<Action>();
12 MTQueue<Action> m_queue = new MTQueue<Action>();
13 int m_queueLength = 0;
13 int m_queueLength = 0;
14 readonly int m_threshold = 1;
14 readonly int m_threshold = 1;
15
15
16 public WorkerPool(int minThreads, int maxThreads, int threshold)
16 public WorkerPool(int minThreads, int maxThreads, int threshold)
17 : base(minThreads, maxThreads) {
17 : base(minThreads, maxThreads) {
18 m_threshold = threshold;
18 m_threshold = threshold;
19 InitPool();
19 InitPool();
20 }
20 }
21
21
22 public WorkerPool(int minThreads, int maxThreads) :
22 public WorkerPool(int minThreads, int maxThreads) :
23 base(minThreads, maxThreads) {
23 base(minThreads, maxThreads) {
24 InitPool();
24 InitPool();
25 }
25 }
26
26
27 public WorkerPool(int threads)
27 public WorkerPool(int threads)
28 : base(threads) {
28 : base(threads) {
29 InitPool();
29 InitPool();
30 }
30 }
31
31
32 public WorkerPool()
32 public WorkerPool()
33 : base() {
33 : base() {
34 InitPool();
34 InitPool();
35 }
35 }
36
36
37 public Promise<T> Invoke<T>(Func<T> task) {
37 public Promise<T> Invoke<T>(Func<T> task) {
38 if (task == null)
38 if (task == null)
39 throw new ArgumentNullException("task");
39 throw new ArgumentNullException("task");
40 if (IsDisposed)
40 if (IsDisposed)
41 throw new ObjectDisposedException(ToString());
41 throw new ObjectDisposedException(ToString());
42
42
43 var promise = new Promise<T>();
43 var promise = new Promise<T>();
44
44
45 var caller = LogContext.Current;
45 var caller = TraceContext.Current;
46
46
47 EnqueueTask(delegate() {
47 EnqueueTask(delegate() {
48 Log.Transfer(caller);
48 TraceLog.Transfer(caller);
49 try {
49 try {
50 promise.Resolve(task());
50 promise.Resolve(task());
51 } catch (Exception e) {
51 } catch (Exception e) {
52 promise.Reject(e);
52 promise.Reject(e);
53 }
53 }
54 });
54 });
55
55
56 return promise;
56 return promise;
57 }
57 }
58
58
59 protected void EnqueueTask(Action unit) {
59 protected void EnqueueTask(Action unit) {
60 Debug.Assert(unit != null);
60 Debug.Assert(unit != null);
61 var len = Interlocked.Increment(ref m_queueLength);
61 var len = Interlocked.Increment(ref m_queueLength);
62 m_queue.Enqueue(unit);
62 m_queue.Enqueue(unit);
63
63
64 if (len > m_threshold*ActiveThreads)
64 if (len > m_threshold*ActiveThreads)
65 GrowPool();
65 GrowPool();
66 }
66 }
67
67
68 protected override bool TryDequeue(out Action unit) {
68 protected override bool TryDequeue(out Action unit) {
69 if (m_queue.TryDequeue(out unit)) {
69 if (m_queue.TryDequeue(out unit)) {
70 Interlocked.Decrement(ref m_queueLength);
70 Interlocked.Decrement(ref m_queueLength);
71 return true;
71 return true;
72 }
72 }
73 return false;
73 return false;
74 }
74 }
75
75
76 protected override bool Suspend() {
76 protected override bool Suspend() {
77 // This override solves race condition
77 // This override solves race condition
78 // WORKER CLIENT
78 // WORKER CLIENT
79 // ---------------------------------------
79 // ---------------------------------------
80 // TryDeque == false
80 // TryDeque == false
81 // Enqueue(unit), queueLen++
81 // Enqueue(unit), queueLen++
82 // GrowPool? == NO
82 // GrowPool? == NO
83 // ActiveThreads--
83 // ActiveThreads--
84 // Suspend
84 // Suspend
85 // queueLength > 0
85 // queueLength > 0
86 // continue
86 // continue
87 if (m_queueLength > 0)
87 if (m_queueLength > 0)
88 return true;
88 return true;
89 return base.Suspend();
89 return base.Suspend();
90 }
90 }
91
91
92 protected override void InvokeUnit(Action unit) {
92 protected override void InvokeUnit(Action unit) {
93 unit();
93 unit();
94 }
94 }
95
95
96 }
96 }
97 }
97 }
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now