DCSIMG
August 2012 - Posts - Bnaya Eshet

Bnaya Eshet

Disclaimer

August 2012 - Posts

Visual Rx - Backward Compatibility

Visual Rx - Backward Compatibility

I have just publish a new release of Visual Rx SDK which is targeting Rx versions 1.0.10621 and 1.1.11111.

this release is result of a community request which was added to the Issue Tracker. you can add other request or vote for existing one in here.

Rx, Visual Rx, Monitoring, IObservable, IObserver, Trace, Diagnostic

this release is also available on the NuGet Gallery.
the NuGet page for version 1.0.10621 is available for download in here and the page for version 1.1.11111 is available in here.

Rx, Visual Rx, Monitoring, IObservable, IObserver, Trace, Diagnostic

the same Visual Rx viewer is compatible with all versions.

Visual Rx - Part 5

Visual Rx - Part 5

this post is part of the Visual Rx series and it will focus on controlling the Visual Rx publication on the coding part.

you can see this series TOC in here.

I was talking about enabling / disabling the Visual Rx publication (through the predefine publication channel), using the VirtualRxSettings.Enable property, in part 1 of this series.

Enable / Disable

let look at a Enable / Disable snippet:

Code Snippet
  1. Task<VisualRxInitResult> info = VisualRxSettings.Initialize(
  2.     VisualRxWcfDiscoveryProxy.Create());
  3.  
  4. VisualRxInitResult infos = info.Result;
  5. Trace.WriteLine(infos);
  6.  
  7. var xs = Observable.Interval(TimeSpan.FromSeconds(0.5))
  8.     .Take(10);
  9. xs = xs.Monitor("Enable / Disable", 1);
  10. xs.Subscribe(
  11.     v => VisualRxSettings.Enable = v < 3 || v > 6);

lines 1,2 define the publication channel to Wcf Discovery.
lines 4,5 is waiting to the channel construction completion and log it to the Trace.
lines 7,8 create a datum stream.
line 9 is monitoring the stream.

line 11, within the Subscribe method I toggle the publication (on / off), you should be aware that the current value has been already sent by the time that the toggling logic took place, which mean that the toggling will affect the next value.

the toggle state for values 4-7 is off therefore the Visual Rx Viewer will show the stream as follow:

Rx, Visual Rx, Trace, Monitor, Monitoring, IObservable, IOserver

enabling or disabling the publication is totally at your control.

Partial publication
real-life scenario may demand a finer control over the datum's publication. 
you may want to enable or disable a partial publication based on the datum's stream name, keywords, channel key or even the datum itself.

this can be achieved by using the VisualRxSetting.AddFilter API.

the following snippet is showing how to split different streams into different channels:

Code Snippet
  1. Task<VisualRxInitResult> info = VisualRxSettings.Initialize(
  2.     VisualRxWcfDiscoveryProxy.Create(),
  3.     VisualRxWcfQueuedProxy.Create(),
  4.     VisualRxTraceSourceProxy.Create());
  5.  
  6. VisualRxSettings.AddFilter((marble, channelKey) =>
  7.     {
  8.         bool enable = false;
  9.         switch (marble.Name)
  10.         {
  11.             case "Stream A":
  12.                 enable = channelKey == VisualRxWcfDiscoveryProxy.KIND;
  13.                 break;
  14.             case "Stream B":
  15.                 enable = channelKey == VisualRxTraceSourceProxy.KIND;
  16.                 break;
  17.             default:
  18.                 enable = channelKey == VisualRxWcfQueuedProxy.KIND;
  19.                 break;
  20.         }
  21.         return enable;
  22.     });
  23.  
  24. VisualRxInitResult infos = info.Result;
  25. Trace.WriteLine(infos);
  26.  
  27. var xs = Observable.Interval(TimeSpan.FromSeconds(0.5))
  28.    .Take(10);
  29. xs = xs.Monitor("Stream A", 1);
  30. var ys = Observable.Interval(TimeSpan.FromSeconds(1))
  31.    .Take(10);
  32. ys = ys.Monitor("Stream B", 2);
  33.  
  34. xs.Subscribe();
  35. ys.Subscribe();

the result will be that the Visual Rx Viewer will monitor "Stream A" while "Stream B" will be log to the TraceSource under the "Visual Rx" setting.

the Viewer will present the following:

Rx, Visual Rx, Trace, Monitor, Monitoring, IObservable, IOserver

while the TraceSource output is going to the default listener (therefore it will go to the output window on debugging).
the output will look as follow:

Code Snippet
  1. <MarbleBase z:Id="i1" i:type="MarbleNext">
  2.   <BinaryValue i:nil="true" />
  3.   <DateCreatedUtc>2012-08-13T12:07:31.8190414Z</DateCreatedUtc>
  4.   <FormattedValue>0</FormattedValue>
  5.   <IndexOrder>2</IndexOrder>
  6.   <Keywords />
  7.   <Kind>OnNext</Kind>
  8.   <MachineName i:nil="true" />
  9.   <Name>Stream B</Name>
  10.   <Offset>PT0.4960332S</Offset>
  11.   <Options>None</Options>
  12.   <StringValue>0</StringValue>
  13.   <ThreadId>14</ThreadId>
  14. </MarbleBase>
  15.  
  16. ...
  17.  
  18. VisualRx Information: 0 :
  19. <MarbleBase z:Id="i1" i:type="MarbleComplete">
  20.   <BinaryValue i:nil="true" />
  21.   <DateCreatedUtc>2012-08-13T12:07:40.9455634Z</DateCreatedUtc>
  22.   <FormattedValue i:nil="true" />
  23.   <IndexOrder>2</IndexOrder>
  24.   <Keywords />
  25.   <Kind>OnCompleted</Kind>
  26.   <MachineName i:nil="true" />
  27.   <Name>Stream B</Name>
  28.   <Offset>PT9.6220625S</Offset>
  29.   <Options>None</Options>
  30.   <StringValue i:nil="true" />
  31.   <ThreadId>14</ThreadId>
  32. </MarbleBase>

if you want you can even filter by the actual data,
for example you can omit item that doesn't relevant to the current monitoring session.

the following code omit publication for datum that doesn't belong to the "Extreme" category.

first I will use the following declarations:

Code Snippet
  1. public enum Category
  2. {
  3.     BallGame,
  4.     Snow,
  5.     Extreme,
  6.     Water,
  7.     Weapon
  8. }
  9.  
  10. public class Item
  11. {
  12.     public Item(long value)
  13.     {
  14.         Value = value;
  15.         this.Category = (Category)(value % 5);
  16.     }
  17.     public long Value { get; private set; }
  18.     public Category Category { get; private set; }
  19. }

the following snippet does the filtering:

Code Snippet
  1. Task<VisualRxInitResult> info = VisualRxSettings.Initialize(
  2.     VisualRxWcfDiscoveryProxy.Create());
  3.  
  4. VisualRxSettings.AddFilter((marble, channelKey) =>
  5.     {
  6.         Item item = marble.RawValue as Item;
  7.         if (item != null && marble.Name == "Items")
  8.             return item.Category == Category.Extreme;
  9.         return true; // it is best practice to return true
  10.                      // because this way you don't
  11.                      // interfere with other filters
  12.     });
  13.  
  14. VisualRxInitResult infos = info.Result;
  15. Trace.WriteLine(infos);
  16.  
  17. var xs = Observable.Interval(TimeSpan.FromSeconds(0.5))
  18.     .Select(v => new Item(v))
  19.    .Take(10);
  20. xs = xs.Monitor("Items", 1);
  21. xs = xs.Monitor("Other monitoring", 1); // actually monitor the same aspect
  22.  
  23. xs.Subscribe();

focusing on the filtering at lines 4-12, you can see that I filtered out datum that belong to the "Items" monitor and doesn't have the "Extreme" category.
in order to show the differences in the Visual Rx Viewer,
I was monitoring twice (lines 20, 21) once with the "Items" name which will be filtered and the second time is actually monitoring the same data but this time with "Other monitoring" name.
the result will be as follow:

Rx, Visual Rx, Trace, Monitor, Monitoring, IObservable, IOserver

you can download the source code and check the tests App.Config file to see how can you set the configuration for the TraceSource channel.

the following is one option where most of the listener are disabled:

Code Snippet
  1. <system.diagnostics>
  2.   <sources>
  3.     <!-- Visual Rx TraceSource publication -->
  4.     <source name="VisualRx" switchName="defaultswitch">
  5.       <listeners>
  6.         <!--<remove name="Default"/>-->
  7.         <!--<add name="consoleListener" />-->
  8.         <!--<add name="xmlFileMonitorListener"/>-->
  9.         <!--<add name="customListener"/>-->
  10.       </listeners>
  11.     </source>
  12.   </sources>
  13.   <switches>
  14.     <!-- Critical, Error, Warning, Information, Verbose
  15.          ActivityTracing: Start, Stop, Suspend, Resume, Transfer
  16.     -->
  17.     <add name="defaultswitch" value="Verbose"/>
  18.   </switches>
  19.   <sharedListeners>
  20.     <add name="customListener"
  21.         type="System.Reactive.Contrib.TestMonitor.CustomTraceListener,System.Reactive.Contrib.TestMonitor"
  22.          traceOutputOptions="ProcessId, DateTime"/>
  23.     <add name="consoleListener"
  24.         type="System.Diagnostics.ConsoleTraceListener"
  25.          traceOutputOptions="ProcessId, DateTime"/>
  26.     <add name="eventlogListener"
  27.         type="System.Diagnostics.EventLogTraceListener"
  28.         initializeData="Application">
  29.       <filter type="System.Diagnostics.EventTypeFilter"
  30.         initializeData="Error"/>
  31.     </add>
  32.     <add name="textFileListener"
  33.         type="System.Diagnostics.TextWriterTraceListener"
  34.         initializeData="RxContrib.log" />
  35.     <add name="xmlFileMonitorListener"
  36.         type="System.Diagnostics.XmlWriterTraceListener"
  37.         initializeData="Monitor.xml" />
  38.     <add name="defaultListener"
  39.         type="System.Diagnostics.DefaultTraceListener" traceOutputOptions="ProcessId"/>
  40.     <!--<add name="nlog" type="NLog.NLogTraceListener, NLog" />-->
  41.   </sharedListeners>
  42. </system.diagnostics>

if you want to filter by keyword just ask about the marble.Keywords:

Code Snippet
  1. VisualRxSettings.AddFilter((marble, channelKey) =>
  2.     marble.Keywords.Contains("Key1"));

the following snippet:

Code Snippet
  1. Task<VisualRxInitResult> info = VisualRxSettings.Initialize(
  2.     VisualRxWcfDiscoveryProxy.Create());
  3.  
  4. VisualRxSettings.AddFilter((marble, channelKey) =>
  5.     marble.Keywords.Contains("Key1"));
  6.  
  7. VisualRxInitResult infos = info.Result;
  8. Trace.WriteLine(infos);
  9.  
  10. var xs = Observable.Interval(TimeSpan.FromSeconds(0.5))
  11.    .Take(10);
  12. xs = xs.Monitor("Stream A", 1, "Key1", "Key3", "Key4");
  13. var ys = Observable.Interval(TimeSpan.FromSeconds(1))
  14.    .Take(10);
  15. ys = ys.Monitor("Stream B", 2, "Key2", "Key3");
  16.  
  17. xs.Subscribe();
  18. ys.Subscribe();

will be present in the viewer where only the "Stream A" will be shown on the Visual Rx Viewer because "Stream B" doesn't have the "Key1" keyword:

Rx, Visual Rx, Trace, Monitor, Monitoring, IObservable, IOserver

Clear Filters

at any time you can wipe-out all the filters by using the ClearFilters API (this one can help for testability).

Code Snippet
  1. VirtualRxSettings.ClearFilters();
Summary

the filtering capability can keep a real-life system performance unaffected by data that doesn't relevant to the current monitoring session.

Future Feature

one of the feature that I want to add in the future is a remote tool that will control simple filtering like which keywords is actively monitored.


Shout it kick it on DotNetKicks.com

Visual Rx - Part 4

Visual Rx - Part 4

this post is the 4th of the Visual Rx post series.
this post will focus on the communication channel settings.

you can see this series TOC in here.

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx, IObservable, IObserver, ISubject, Monitor, Monitoring

at the time I'm writing this post there is 4 available communication channel (out of the box).

  • Wcf discovery - will try to dynamically locate the end point of the viewer service (or any other discoverable service which apply to the Visual Rx contract).
    this is the easiest proxy and it is recommended to local network scenarios.
  • Wcf queued - which submit the datum though MSMQ channel (the default viewer is compatible with this channel).
  • Trace Source - publish the data though the standard .NET Trace Source. using the "VisualRx" trace source name (for internal messages it use "VisualRx.Log")
    the app.config setting will be discuss on latter posts.
  • Wcf Fixed Address - is a new one, it is let you specify a Wcf Binding and End-Point (and gives you the full flexibility of the Wcf library).
Visual Rx Viewer side:

at the viewer side you simply dealing with a traditional Wcf application configuration (for setting a Wcf channels).
from version 2.0.20622.10 the default application setting is enabling Wcf discovery over named-pipe and Wcf fixed address over basic http.
other setting like MSMQ and Wcf discovery over TCP is remarked.
you can see the full application setting in here.
but the part that you are rely care about is:

Code Snippet
  1. <!-- used by VisualRxWcfQueuedProxy -->
  2. <!--<endpoint address="net.msmq://localhost/private/VisualRx" binding="netMsmqBinding"
  3.           bindingConfiguration="netMsmq"
  4.           contract="System.Reactive.Contrib.Monitoring.Contracts.IVisualRxServiceAdapter" />-->
  5. <!-- used by VisualRxWcfFixedAddressProxy -->
  6. <endpoint address="VisualRx" binding="basicHttpBinding"
  7.           contract="System.Reactive.Contrib.Monitoring.Contracts.IVisualRxServiceAdapter" />
  8.  
  9. <!-- used by VisualRxWcfDiscoveryProxy -->
  10. <!--<endpoint name="tcpMonitor" address="Monitor"
  11.           binding="netTcpBinding"
  12.           contract="System.Reactive.Contrib.Monitoring.Contracts.IVisualRxServiceAdapter"/>-->
  13. <!-- used by VisualRxWcfDiscoveryProxy -->
  14. <endpoint name="namepipeMonitor" address="Monitor"
  15.           binding="netNamedPipeBinding"
  16.           contract="System.Reactive.Contrib.Monitoring.Contracts.IVisualRxServiceAdapter"/>

removing the remark from lines 2-4 will enable MSMQ channel  (make sure that MSMQ is install on the machine).

lines 6-8 is the Wcf fixed address over http.

lines 10-16 is the Wcf discovery endpoints (the TCP endpoint is remarked).

actually this is all you have to do from a viewer perspective.

 
Visual Rx Code side

at the code side you should choose which channel proxy do you want to use at the setting initialization of VisualRxSetting.

you can choose multiple channels at once, but you have to make sure that you don't create a duplication in terms of a viewer will get the same result, from multiple channels, which will lead to duplication of data at the viewer side.

the following snippet is enabling all 3 Wcf channel types:

Code Snippet
  1. Task<VisualRxInitResult> info = VisualRxSettings.Initialize(
  2.     VisualRxWcfDiscoveryProxy.Create(),
  3.     VisualRxWcfFixedAddressProxy.CreateDefaultHttp(Environment.MachineName),
  4.     VisualRxWcfQueuedProxy.Create());

each channel creation is having a few overloads.
the sample above is using the most simplistic ones.

Wcf Discovery

the Wcf discovery is the most easy channel, because you don't have to configure a fix address and the proxy will locate the viewer dynamically.

the downside of this channel is that it is limit to a local network boundary and if that network has a vast number of machine the discover process could be slow and heavy.

you can set the timeout for discovery both in the code and the viewer sides.

the viewer setting is take place within the application configuration at the following section:

Code Snippet
  1.  
  2.   <standardEndpoints>
  3.     <udpDiscoveryEndpoint>
  4.       <!-- modify the udpDiscoveryEndpoint -->
  5.       <standardEndpoint name="adhocDiscoveryEndpointConfiguration" maxResponseDelay="00:00:00.001"/>
  6.     </udpDiscoveryEndpoint>
  7.   </standardEndpoints>
  8. </system.serviceModel>

it is define the maximum time that the viewer will randomly delay its answer (this number has to be lower then the proxy timeout setting which will be discuss in the next section), Wcf is using this setting in order to reduce the network pressure.

at the proxy side you can use the default creation which is using a 3 seconds timeout and retry to discover new viewer at a 30 minutes interval.

but you can pass a VisualRxWcfDiscoverySettings parameter and set those setting manually.

Code Snippet
  1. var setting = new VisualRxWcfDiscoverySettings
  2. {
  3.      DiscoveryTimeoutSeconds = 2,
  4.      RediscoverIntervalMinutes = 15
  5. };
  6. VisualRxSettings.CollectMachineInfo = true;
  7. Task<VisualRxInitResult> info = VisualRxSettings.Initialize(
  8.      VisualRxWcfDiscoveryProxy.Create(setting));

the Wcf discovery proxy will try to locate both named-pipe and TCP end-points (no need to any special setting for that).

Wcf Fixed End-Point

the Wcf fixed end-point is having 3 creation options:

Code Snippet
  1. VisualRxWcfFixedAddressProxy CreateDefaultHttp(string host);
  2. VisualRxWcfFixedAddressProxy Create(Binding binding, string uri);
  3. VisualRxWcfFixedAddressProxy Create(Binding binding, EndpointAddress endpoint);
  • CreateDefaultHttp is the most simple one and it operate over a basic http binding. all you have to do is to supply the Machine name or IP address of the viewer machine.
  • Create is having 2 overloads which is getting any Wcf binding and the end-point address of the viewer. it is very flexible in terms of the binding, it can take advantage of any binding setting (like security, session or even a restful like webHttpBinding).
MSMQ

the Wcf Queued binding is operating over MSMQ and it is having the following overloads:

Code Snippet
  1. VisualRxWcfQueuedProxy Create();
  2. VisualRxWcfQueuedProxy Create(TimeSpan timeToLive);
  3. VisualRxWcfQueuedProxy Create(NetMsmqBinding binding);
  4. VisualRxWcfQueuedProxy Create(NetMsmqBinding binding, string queuePath);
  • the default creation is using a private queue named VisualRx and time to live of 30 minutes (time to live define the period that the message will live in the queue before it will become stale).
  • the second overload let you control the time to live setting.
  • the 3rd one is let you a full control over the binding.
  • and the 4th is also let you control over the queue path.

that all for this post the TraceSource will be discuss in further posts.

Summary

communication between your run-time streams and the viewer is fairly flexible and you actually can add your own custom proxy by implementing the IVisualRxProxy interface.


Shout it kick it on DotNetKicks.com

Visual Rx - TOC

Visual Rx - TOC

Visual Rx is a bundle of API and a Viewer which can monitor and visualize Rx datum stream (at run-time).

the current post in the Visual Rx series includes:

  • Part 1: Code side.
  • Part 2: Viewer side.
  • Part 3: How to start using Visual Rx.
  • Part 4: Setting the communication channels.
  • Part 5: publication filtering.

 

you can vote for feature at the CodePlex site under the Issue Tracker tab.

you can download the SDK and the Viewer from here.

Visual Rx - Part 3

Visual Rx - Part 3

this post is part of the Visual Rx series and it will focus on how to start working with Visual Rx.

you can see this series TOC in here.

as I was mention in previous posts Visual Rx is divided into 2 parts:

  • SDK - which is the code side on which you define the VisualRxSetting and use Monitor extension method.
  • Viewer - which is listening to the SDK communication channel and visualize the Rx stream.

both parts available at the download page of Visual Rx on CodePlex.

the SDK is also available at NuGet.
the NuGet package include the Rx dlls and the the Visual Rx dlls.

you can get it either directly from the NuGet site:

Rx, Visual Rx, Monitor, Monitoring, Trace, Viewer

or from visual studio add reference (after you will install the NuGet Visual Studio extension which will add "Manage NuGet Packages"):

Rx, Visual Rx, Monitor, Monitoring, Trace, Viewer

Rx, Visual Rx, Monitor, Monitoring, Trace, Viewer

 

the Viewer is also available in 2 flavor:

  • XCopy - which is a zip that contain the viewer exe + dependencies.
  • MSI - a setup file which will install the viewer on your machine.
  • in the future it may be also available though clickonce.
Where can I get sample code?

you can download the source code from CodePlex and
run the MS-Tests under the System.Reactive.Contrib.Monitoring.UnitTests project (most test is under the Demo folder).

Rx, Visual Rx, Monitor, Monitoring, Trace, Viewer

More

finally you can vote for feature at the CodePlex site under the Issue Tracker tab.

Summary

I hope that you find the Visual Rx useful.
please vote for feature so I will know what does the community value most.

on later post will discuss more advance scenarios.


kick it on DotNetKicks.com Shout it

Visual Rx - Part 2

Visual Rx - Part 2

this is the second post in the Visual Rx series.
this post will focus on the viewer side.

you can see this series TOC in here.

as we saw in the previous post the main view of the Visual Rx viewer is using a tab control (the default tab is the "All" tab) out of the box the viewer is also having a grid tab, additional tab will be added per keyword.
(the grid is actually a plugin and it can be remove by deleting it from the relative Plugins folder).

all tabs except of the grid tab is presenting the data using a marble diagrams.

the Visual Rx viewer is a plug-able application and you can have a custom tabs if you want to present the data in a different way (more on this topic in latter posts).

Application Level

on the top left you can see 3 buttons, Pause, Clear and About.

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

the Clear button will clear the current presenting data on all tabs.

Pause will freeze the view (without loosing data).
it is essential for analyzing a fast stream at runtime.
this is a toggle button which will change between Pause and Resume. the data continue to be collected while the viewer is in a pause mode (even those this data doesn't display).
Resume will immediately display all the data that was collected during the pause phase and resume to display a new data.

Single Tab level

under each tab you can find the "show tab actions" link (marked by yellow) which will expand a tab's level actions (those actions will affect the only current tab).

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

clicking on this link will expand / collapse the tab's level actions.

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

the tab's level actions include the following functionalities:

  • Clear will clear the diagrams from the current tab (while preserving other tabs diagrams).
  • Global Time, Private Time and Sequence are different ways of ordering the marbles on the marble line:
    • Global time will show the marble on a timeline with a correlation between all marble diagrams within the current tab (this is useful when the diagram streams are related to each other, like the case of Rx combinators like Merge).
    • Private time will conduct the diagram timeline on a single diagram base.
    • Sequence will present the marbles in correlation to their creation order regardless of the creation time (it is useful for operators like Range or when multiple marble were produce at the same time).

on the previous post we was looking at the following code:

Code Snippet
  1. var inputA1 = Observable.Interval(TimeSpan.FromSeconds(1.5)).Take(7);
  2. inputA1 = inputA1.Monitor("Input A1", 1, "ScenarioA", "Input");
  3. var inputA2 = Observable.Interval(TimeSpan.FromSeconds(2)).Take(5);
  4. inputA2 = inputA2.Monitor("Input A2", 2, "ScenarioA", "Input");
  5. var outputA = Observable.Merge(inputA1, inputA2);
  6. outputA = outputA.Monitor("Output A", 3, "ScenarioA", "Output");
  7. var inputB = Observable.Interval(TimeSpan.FromSeconds(1)).Take(10);
  8. inputB = inputB.Monitor("Input B", 4, "ScenarioB", "Input");
  9. var outputB = from item in inputB
  10. group item by item % 3 into g
  11. select g;
  12. outputB = outputB.MonitorGroup("Output B", 5, "ScenarioB", "Output");
  13. outputA.Subscribe();
  14. outputB.Subscribe(g => g.Subscribe());

the default Global Time view will present the data as follow:

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

as you can see the diagrams time line is in correlation with each other, Private Time will shift the diagram marble to the left:

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

still the time ratio were preserved on per diagram based.

the Sequence option will ignore the time ratio and present the data in a simple sequence:

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

let resume the the rest of the actions:

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

  • Scroll To End is a toggle button which will automatically keep the horizontal scrolling bar attached to the right end, which mean that the newest data will always be visible
  • the Track-bar is a zooming bar
  • and though the combo-box you can define the presented time scale (fast stream time scale may better present in millisecond units).

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

Marble diagram level

at the marble diagram level you can find a popup action bar which response to click on the marble title.

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

the action includes:

  • Refresh - which refresh the marble view.
  • Global Time, Private Time and Sequence on a single marble level.

the last functionality is collapse ability.
clicking on the marble collapser will collapse the marble:

Profile, Rx, Diagnostic, Contrib, Marble, Bnaya, Dubug, Trace, Visual Rx

Summary

the Visual Rx viewer is a reach viewer which was design to support Rx dataflow analysis.
you can take it further by using a custom plug-ins but this will be discuss on latter posts.

you can download the Viewer and the SDK from codeplex and the SDK can also be download from NuGet (search for VisualRx).

you can vote for feature at the CodePlex site under the Issue Tracker tab.

kick it on DotNetKicks.com Shout it