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