##// END OF EJS Templates
Added IObservable to TraceRegistry
cin -
r288:90cef6117ced v3
parent child
Show More
@@ -1,25 +1,27
1 <Project Sdk="Microsoft.NET.Sdk">
1 <Project Sdk="Microsoft.NET.Sdk">
2 <PropertyGroup Condition="'$(OSTYPE)'=='linux'">
2 <PropertyGroup Condition="'$(OSTYPE)'=='linux'">
3 <TargetFrameworks>netcoreapp2.0;;net46</TargetFrameworks>
3 <TargetFrameworks>netcoreapp2.0;;net46</TargetFrameworks>
4 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.6-api/</FrameworkPathOverride>
4 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.6-api/</FrameworkPathOverride>
5 </PropertyGroup>
5 </PropertyGroup>
6
6
7 <PropertyGroup Condition="'$(OSTYPE)'=='windows'">
7 <PropertyGroup Condition="'$(OSTYPE)'=='windows'">
8 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
8 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
9 </PropertyGroup>
9 </PropertyGroup>
10
10
11 <PropertyGroup>
11 <PropertyGroup>
12 <OutputType>Exe</OutputType>
12 <OutputType>Exe</OutputType>
13 <IsPackable>false</IsPackable>
13 <IsPackable>false</IsPackable>
14 </PropertyGroup>
14 </PropertyGroup>
15
15
16 <ItemGroup>
16 <ItemGroup>
17 <ProjectReference Include="../Implab/Implab.csproj" />
17 <ProjectReference Include="../Implab/Implab.csproj" />
18 <ProjectReference Include="..\Implab.ServiceHost\Implab.ServiceHost.csproj" />
18 <ProjectReference Include="..\Implab.ServiceHost\Implab.ServiceHost.csproj" />
19 </ItemGroup>
19 </ItemGroup>
20
20
21 <ItemGroup>
21 <ItemGroup>
22 <PackageReference Include="Unity" Version="5.8.5" />
22 <PackageReference Include="Unity" Version="5.8.6" />
23 <PackageReference Include="System.Reactive" Version="4.0.0" />
24
23 </ItemGroup>
25 </ItemGroup>
24
26
25 </Project>
27 </Project>
@@ -1,45 +1,42
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Diagnostics;
3 using System.Diagnostics;
4 using System.Dynamic;
4 using System.Dynamic;
5 using System.Linq;
5 using System.Linq;
6 using Implab.Components;
6 using Implab.Components;
7 using Implab.Diagnostics;
7 using Implab.Diagnostics;
8 using Implab.ServiceHost.Unity;
8 using Implab.ServiceHost.Unity;
9 using Implab.Xml;
9 using Implab.Xml;
10 using Unity;
10 using Unity;
11 using Unity.Injection;
11 using Unity.Injection;
12 using Unity.Registration;
12 using Unity.Registration;
13
13
14 namespace Implab.Playground {
14 namespace Implab.Playground {
15 using System.Reactive.Linq;
15 using static Trace<Bar>;
16 using static Trace<Bar>;
16
17
17 class Foo {
18 class Foo {
18
19
19 }
20 }
20
21
21 class Bar : Foo {
22 class Bar : Foo {
22
23
23 }
24 }
24 public class Program {
25 public class Program {
25
26
26 static void Main(string[] args) {
27 static void Main(string[] args) {
27 Trace<Foo>.Log("First!");
28 Trace<Foo>.Log("First!");
28 Log("+1!");
29 Log("+1!");
29
30
30 using(TraceRegistry.Global.Subscribe(x => {
31 using(TraceRegistry.Global.OfType<TraceSourceChannel>().Subscribe(ch => {
31 var ch = x as TraceSourceChannel;
32 if (ch == null)
33 return;
34
35 Console.WriteLine($"{ch.Id}: {ch.Source.Name}");
32 Console.WriteLine($"{ch.Id}: {ch.Source.Name}");
36
33
37 }, true)) {
34 })) {
38 Trace<Foo>.Log("Hi!");
35 Trace<Foo>.Log("Hi!");
39 Log("Respect!");
36 Log("Respect!");
40 }
37 }
41 }
38 }
42
39
43
40
44 }
41 }
45 }
42 }
@@ -1,27 +1,27
1 <Project Sdk="Microsoft.NET.Sdk">
1 <Project Sdk="Microsoft.NET.Sdk">
2
2
3 <PropertyGroup>
3 <PropertyGroup>
4 <TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
4 <TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
5 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.6-api/</FrameworkPathOverride>
5 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.6-api/</FrameworkPathOverride>
6 <Authors>Sergey Smirnov</Authors>
6 <Authors>Sergey Smirnov</Authors>
7 <Title>Implab.SrviceHost library</Title>
7 <Title>Implab.SrviceHost library</Title>
8 <Description>Provides simple and flexible XML configuration for the Unity IoC</Description>
8 <Description>Provides simple and flexible XML configuration for the Unity IoC</Description>
9 <Copyright>2018 Sergey Smirnov</Copyright>
9 <Copyright>2018 Sergey Smirnov</Copyright>
10 <Version>1.0.0</Version>
10 <Version>1.0.0</Version>
11 <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl>
11 <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl>
12 <PackageProjectUrl>https://implab.org</PackageProjectUrl>
12 <PackageProjectUrl>https://implab.org</PackageProjectUrl>
13 <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl>
13 <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl>
14 <RepositoryType>mercurial</RepositoryType>
14 <RepositoryType>mercurial</RepositoryType>
15 <PackageTags>IoC; Unity; Dependency Injection</PackageTags>
15 <PackageTags>IoC; Unity; Dependency Injection</PackageTags>
16 <TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
16 <TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
17 </PropertyGroup>
17 </PropertyGroup>
18
18
19 <ItemGroup>
19 <ItemGroup>
20 <PackageReference Include="Unity" Version="5.8.5" />
20 <PackageReference Include="Unity" Version="5.8.6" />
21 </ItemGroup>
21 </ItemGroup>
22
22
23 <ItemGroup>
23 <ItemGroup>
24 <ProjectReference Include="..\Implab\Implab.csproj" />
24 <ProjectReference Include="..\Implab\Implab.csproj" />
25 </ItemGroup>
25 </ItemGroup>
26
26
27 </Project>
27 </Project>
@@ -1,41 +1,34
1 using System;
1 using System;
2 using System.Threading;
2 using System.Threading;
3 using System.Threading.Tasks;
3 using System.Threading.Tasks;
4 using Implab.Components;
4 using Implab.Components;
5 using Implab.Diagnostics;
5 using Implab.Diagnostics;
6 using Xunit;
6 using Xunit;
7
7
8 namespace Implab.Test {
8 namespace Implab.Test {
9
9
10 public class DiagnosticsTest {
10 public class DiagnosticsTest {
11 class Foo {}
11 class Foo {}
12
12
13 [Fact]
13 [Fact]
14 public void TestRegistration() {
14 public void TestRegistration() {
15 var channel = TraceSourceChannel<Foo>.Default;
15 var channel = TraceSourceChannel<Foo>.Default;
16
16
17 Assert.Equal(typeof(Foo), channel.Id);
17 Assert.Equal(typeof(Foo), channel.Id);
18 Assert.Equal(typeof(Foo).FullName, channel.Source.Name);
18 Assert.Equal(typeof(Foo).FullName, channel.Source.Name);
19
19
20 TraceSourceChannel found = null;
20 TraceSourceChannel found = null;
21 int visited = 0;
21 int visited = 0;
22
22
23 TraceRegistry.Global.Subscribe(x => {
23 TraceRegistry.Global.Subscribe(x => {
24 visited++;
24 visited++;
25 found = x as TraceSourceChannel;
25 found = x as TraceSourceChannel;
26 }, false);
26 });
27
28 Assert.Equal(0, visited);
29
30 TraceRegistry.Global.Subscribe(x => {
31 visited++;
32 found = x as TraceSourceChannel;
33 }, true);
34
27
35 Assert.Equal(1,visited);
28 Assert.Equal(1,visited);
36 Assert.Equal(channel, found);
29 Assert.Equal(channel, found);
37
30
38 }
31 }
39
32
40 }
33 }
41 } No newline at end of file
34 }
@@ -1,23 +1,24
1 <Project Sdk="Microsoft.NET.Sdk">
1 <Project Sdk="Microsoft.NET.Sdk">
2 <PropertyGroup Condition="'$(OSTYPE)'=='linux'">
2 <PropertyGroup Condition="'$(OSTYPE)'=='linux'">
3 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
3 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
4 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.5/</FrameworkPathOverride>
4 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46'">/usr/lib/mono/4.5/</FrameworkPathOverride>
5 </PropertyGroup>
5 </PropertyGroup>
6
6
7 <PropertyGroup Condition="'$(OSTYPE)'=='windows'">
7 <PropertyGroup Condition="'$(OSTYPE)'=='windows'">
8 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
8 <TargetFrameworks>netcoreapp2.0;net46</TargetFrameworks>
9 </PropertyGroup>
9 </PropertyGroup>
10
10
11 <PropertyGroup>
11 <PropertyGroup>
12 <IsPackable>false</IsPackable>
12 <IsPackable>false</IsPackable>
13 </PropertyGroup>
13 </PropertyGroup>
14
14
15 <ItemGroup>
15 <ItemGroup>
16 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0-preview-20180109-01" />
16 <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.6.0-preview-20180109-01" />
17 <PackageReference Include="System.Reactive" Version="4.0.0" />
17 <PackageReference Include="xunit" Version="2.3.1" />
18 <PackageReference Include="xunit" Version="2.3.1" />
18 <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
19 <PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
19 <ProjectReference Include="../Implab/Implab.csproj"/>
20 <ProjectReference Include="../Implab/Implab.csproj"/>
20 <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
21 <DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
21 </ItemGroup>
22 </ItemGroup>
22
23
23 </Project>
24 </Project>
@@ -1,83 +1,86
1 using System;
1 using System;
2 using System.Collections.Generic;
2 using System.Collections.Generic;
3 using System.Diagnostics;
3 using System.Diagnostics;
4 using Implab.Parallels;
4 using Implab.Parallels;
5
5
6 namespace Implab.Diagnostics {
6 namespace Implab.Diagnostics {
7 public class TraceRegistry {
7 public class TraceRegistry: IObservable<TraceChannel> {
8
8
9 class Subscription : IDisposable {
9 class Subscription : IDisposable {
10 readonly WeakReference<TraceRegistry> m_registry;
10 readonly WeakReference<TraceRegistry> m_registry;
11 readonly Action<object> m_unsubscribe;
12
11
13 public Subscription(TraceRegistry registry) {
12 public Subscription(TraceRegistry registry) {
14 m_registry = new WeakReference<TraceRegistry>(registry);
13 m_registry = new WeakReference<TraceRegistry>(registry);
15 }
14 }
16
15
17 public void Dispose() {
16 public void Dispose() {
18 TraceRegistry t;
17 TraceRegistry t;
19 if (m_registry.TryGetTarget(out t))
18 if (m_registry.TryGetTarget(out t))
20 t.RemoveSubscription(this);
19 t.RemoveSubscription(this);
21 }
20 }
22 }
21 }
23
22
23 /// <summary>
24 /// The global collection of available diagnostic channels
25 /// </summary>
26 /// <returns></returns>
24 public static TraceRegistry Global { get; } = new TraceRegistry();
27 public static TraceRegistry Global { get; } = new TraceRegistry();
25
28
26 readonly object m_lock = new object();
29 readonly object m_lock = new object();
27
30
28 readonly Dictionary<object, Action<TraceChannel>> m_subscriptions = new Dictionary<object, Action<TraceChannel>>();
31 readonly Dictionary<object, IObserver<TraceChannel>> m_subscriptions = new Dictionary<object, IObserver<TraceChannel>>();
29 readonly SimpleAsyncQueue<TraceChannel> m_channels = new SimpleAsyncQueue<TraceChannel>();
32 readonly SimpleAsyncQueue<TraceChannel> m_channels = new SimpleAsyncQueue<TraceChannel>();
30
33
31 internal void Register(TraceChannel channel) {
34 public void Register(TraceChannel channel) {
32 // notifications can run in parallel
35 // notifications can run in parallel
33 Action<TraceChannel>[] handlers = null;
36 IObserver<TraceChannel>[] handlers = null;
34
37
35 lock(m_lock) {
38 lock(m_lock) {
36 m_channels.Enqueue(channel);
39 m_channels.Enqueue(channel);
37 if (m_subscriptions.Count > 0) {
40 if (m_subscriptions.Count > 0) {
38 handlers = new Action<TraceChannel>[m_subscriptions.Count];
41 handlers = new IObserver<TraceChannel>[m_subscriptions.Count];
39 m_subscriptions.Values.CopyTo(handlers, 0);
42 m_subscriptions.Values.CopyTo(handlers, 0);
40 }
43 }
41 }
44 }
42
45
43 if (handlers != null)
46 if (handlers != null)
44 foreach(var h in handlers)
47 foreach(var h in handlers)
45 h(channel);
48 h.OnNext(channel);
46 }
49 }
47
50
48 /// <summary>
51 /// <summary>
49 /// Subscribes the specified handler to notifications about new trace
52 /// Subscribes the specified handler to notifications about new trace
50 /// channels
53 /// channels
51 /// </summary>
54 /// </summary>
52 /// <param name="handler"></param>
55 /// <param name="handler"></param>
53 /// <returns></returns>
56 /// <returns></returns>
54 public IDisposable Subscribe(Action<TraceChannel> handler, bool existing) {
57 public IDisposable Subscribe(IObserver<TraceChannel> handler) {
55 Safe.ArgumentNotNull(handler, nameof(handler));
58 Safe.ArgumentNotNull(handler, nameof(handler));
56
59
57 var cookie = new Subscription(this);
60 var cookie = new Subscription(this);
58
61
59 IEnumerable<TraceChannel> snap;
62 IEnumerable<TraceChannel> snap;
60
63
61 // lock to ensure that no new channels will be added
64 // lock to ensure that no new channels will be added
62 // while the subscription is added
65 // while the subscription is added
63 lock(m_lock) {
66 lock(m_lock) {
64 m_subscriptions.Add(cookie, handler);
67 m_subscriptions.Add(cookie, handler);
65 snap = m_channels.Snapshot();
68 snap = m_channels.Snapshot();
66 }
69 }
67
70
68 // announce previously declared channels if required
71 // announce previously declared channels if required
69 if (existing) {
72 if (snap != null) {
70 foreach(var c in snap)
73 foreach(var c in snap)
71 handler(c);
74 handler.OnNext(c);
72 }
75 }
73
76
74 // return the subscription
77 // return the subscription
75 return cookie;
78 return cookie;
76 }
79 }
77
80
78 void RemoveSubscription(object cookie) {
81 void RemoveSubscription(object cookie) {
79 lock(m_lock)
82 lock(m_lock)
80 m_subscriptions.Remove(cookie);
83 m_subscriptions.Remove(cookie);
81 }
84 }
82 }
85 }
83 } No newline at end of file
86 }
@@ -1,26 +1,26
1 <Project Sdk="Microsoft.NET.Sdk">
1 <Project Sdk="Microsoft.NET.Sdk">
2
2
3 <PropertyGroup>
3 <PropertyGroup>
4 <Authors>Sergey Smirnov</Authors>
4 <Authors>Sergey Smirnov</Authors>
5 <Title>Implab library</Title>
5 <Title>Implab library</Title>
6 <Description>Provides some helper clesses like XML serialization helpers, JSON XML reader,
6 <Description>Provides some helper clesses like XML serialization helpers, JSON XML reader,
7 JSON pull-parser, ECMA-style promises, lightweight synchonization routines Signal
7 JSON pull-parser, ECMA-style promises, lightweight synchonization routines Signal
8 and SharedLock, Trace helpers on top of System.Diagnostics, ObjectPool etc.
8 and SharedLock, Trace helpers on top of System.Diagnostics, ObjectPool etc.
9 </Description>
9 </Description>
10 <Copyright>2012-2018 Sergey Smirnov</Copyright>
10 <Copyright>2012-2018 Sergey Smirnov</Copyright>
11 <Version>3.0.12</Version>
11 <Version>3.0.14</Version>
12 <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl>
12 <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl>
13 <PackageProjectUrl>https://implab.org</PackageProjectUrl>
13 <PackageProjectUrl>https://implab.org</PackageProjectUrl>
14 <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl>
14 <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl>
15 <RepositoryType>mercurial</RepositoryType>
15 <RepositoryType>mercurial</RepositoryType>
16 <PackageTags>IMPLAB;Json pull-parser;Json Xml;async;diagnostics;serialization;</PackageTags>
16 <PackageTags>IMPLAB;Json pull-parser;Json Xml;async;diagnostics;serialization;</PackageTags>
17 <TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
17 <TargetFrameworks>netstandard2.0;net46</TargetFrameworks>
18 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46' and '$(OSTYPE)'=='linux'">/usr/lib/mono/4.5/</FrameworkPathOverride>
18 <FrameworkPathOverride Condition="'$(TargetFramework)'=='net46' and '$(OSTYPE)'=='linux'">/usr/lib/mono/4.5/</FrameworkPathOverride>
19 <DefineConstants Condition="'$(TargetFramework)'=='net46'">NETFX_TRACE_BUG;$(DefineConstants)</DefineConstants>
19 <DefineConstants Condition="'$(TargetFramework)'=='net46'">NETFX_TRACE_BUG;$(DefineConstants)</DefineConstants>
20 </PropertyGroup>
20 </PropertyGroup>
21
21
22 <ItemGroup>
22 <ItemGroup>
23 <EmbeddedResource Include="Xml\json.xsl"/>
23 <EmbeddedResource Include="Xml\json.xsl"/>
24 </ItemGroup>
24 </ItemGroup>
25
25
26 </Project>
26 </Project>
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now