<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rock Solid &#187; Development</title>
	<atom:link href="http://rocksolid.gibraltarsoftware.com/category/development/feed" rel="self" type="application/rss+xml" />
	<link>http://rocksolid.gibraltarsoftware.com</link>
	<description>Notes from the folks behind Gibraltar Software</description>
	<lastBuildDate>Thu, 19 Jan 2012 23:24:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Gibraltar 3.0 New Feature Dive &#8211; Live Sessions</title>
		<link>http://rocksolid.gibraltarsoftware.com/development/logging/gibraltar-3-0-new-feature-dive-live-sessions</link>
		<comments>http://rocksolid.gibraltarsoftware.com/development/logging/gibraltar-3-0-new-feature-dive-live-sessions#comments</comments>
		<pubDate>Thu, 15 Dec 2011 01:58:58 +0000</pubDate>
		<dc:creator>Kendall</dc:creator>
				<category><![CDATA[Gibraltar]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Product Information]]></category>

		<guid isPermaLink="false">http://rocksolid.gibraltarsoftware.com/?p=1001</guid>
		<description><![CDATA[Watch server logs in real time remotely over slow networks with the new Gibraltar Live Session view.]]></description>
			<content:encoded><![CDATA[<p>The Gibraltar Agent has always supported viewing the real time log messages from an application, provided your application was a Windows application (WinForms and WPF) and you were the one running the application.  But, what if you want to see what’s happening inside a Windows Service or a process running somewhere else?  In Gibraltar 2.0 you had to have your process explicitly publish a snapshot of your log data up to a Hub or via email.  This required you to code some way to signal your application when you wanted to publish information and then have all of the data collected in that process since it started get shipped to you.</p>
<p>For Gibraltar 3.0 we’ve introduced a new way of seeing your log data in real time: Live Sessions.  When you enable live sessions you can view log data remotely, efficiently, in real time.  In Analyst you’ll see a new node in the tree view called Live sessions.  When you select that, you’ll see a list of all of the available sessions which you can pick from.</p>
<p>When you first click the Live View tab a data connection is established and you’ll get the last thousand messages that were logged.  Once that data’s come across, new messages are shown as they are recorded.  You can filter the display to show just messages of a particular severity or to search their text for a particular value.</p>
<div id="attachment_1003" class="wp-caption aligncenter" style="width: 550px"><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/Live-View-In-Action.png"><img class="size-large wp-image-1003" title="Live View In Action" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/Live-View-In-Action-1024x602.png" alt="" width="540" height="317" /></a><p class="wp-caption-text">This is your server, live!</p></div>
<p>If you switch away from one session to another the live view stream will continue to run in the background – keeping it current with the most recent thousand messages.  Gibraltar takes steps to keep this memory efficient so you can have multiple live streams running at the same time without performance issues.</p>
<p>If you want to keep watching an application while you work you can double click it and get an independent window which will update in real time as long as the remote application is running.</p>
<h1>Efficient over the Network</h1>
<p>The data stream that’s used by Live Sessions is designed to be very efficient over networks.  It is highly compressed (using the same techniques employed by the Agent to write log files), connection based, and only running when there is an active viewer monitoring the session.  In real world scenarios the live stream for a busy server can be easily viewed over a low bandwidth, intermittent connection like a tethered phone or Mifi.</p>
<ul>
<li>If the connection is lost, the data stream restarts with the last message you received so it can show you all of the messages</li>
<li>If no one is watching a live session then the data is buffered in the Agent but not sent across the network.</li>
</ul>
<h1>Safety First</h1>
<p>There are a number of features designed to make sure live sessions don’t cause a problem to your application:</p>
<ul>
<li><strong>Asynchronous, buffered transmission:</strong>  The Agent publishes data to any set of listeners asynchronously from recording the log file to ensure slow network connections or network connectivity problems won’t slow down recording the main log file.</li>
<li><strong>Drop on overflow:</strong>  If there are more log messages waiting to be sent than can be sent over the network new messages will be dropped instead of holding up the application.  This is in contrast to the log file which will switch to synchronous while it catches up.</li>
<li><strong>Encryption optional:</strong>  You can choose to enable SSL for live session communication so it will be encrypted end-to-end.</li>
</ul>
<h1>Live Sessions and Firewalls</h1>
<p>The Live Session protocol is designed to work with most firewall configurations:</p>
<ul>
<li><strong>All connections are outbound:</strong> The Agent and Analyst establish connections to the central server to communicate.  No connections are directly created between the Agent and Analyst.  This works well with NAT and often requires no explicit firewall rules or exceptions.</li>
<li><strong>Separate ports are used for Agent and Analyst:</strong>  If you need to create a firewall rule you can create separate rules for Agent and Analyst traffic (ports 29970 and 29971 respectively)</li>
<li><strong>Connections are asynchronous:</strong>  Many firewalls will simply fail to respond to attempts to connect to ports that aren’t open, causing very long timeouts.  By performing all connections asynchronously this prevents the application from being unresponsive.</li>
</ul>
<h1>Try it out Today</h1>
<p>If you&#8217;d like to check out Live Sessions for yourself, you&#8217;ll need to <a title="Gibraltar Version History" href="https://www.gibraltarsoftware.com/Support/Version_History.aspx">download the latest build of Gibraltar 3.0</a> and upgrade to the included Agent, Analyst and Hub.  The Hub Server does the central relaying between agents and analysts so it has to be set up in the center.  Live Sessions are not available with the subscription Hub Service operated by us at this time, you have to have your own private Gibraltar Hub.</p>
]]></content:encoded>
			<wfw:commentRss>http://rocksolid.gibraltarsoftware.com/development/logging/gibraltar-3-0-new-feature-dive-live-sessions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Getting to Know Gibraltar &#8211; Adding Exceptions</title>
		<link>http://rocksolid.gibraltarsoftware.com/development/logging/getting-to-know-gibraltar-adding-exceptions</link>
		<comments>http://rocksolid.gibraltarsoftware.com/development/logging/getting-to-know-gibraltar-adding-exceptions#comments</comments>
		<pubDate>Wed, 07 Dec 2011 21:55:59 +0000</pubDate>
		<dc:creator>Gary</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Gibraltar]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Product Information]]></category>
		<category><![CDATA[Exceptions]]></category>

		<guid isPermaLink="false">http://rocksolid.gibraltarsoftware.com/?p=1101</guid>
		<description><![CDATA[Continuing with our Getting to Know Gibraltar series - see how you can record and handle exceptions in an easy, step-by-step way.]]></description>
			<content:encoded><![CDATA[<p><a href="http://rocksolid.gibraltarsoftware.com/?p=1051">In my last post</a> we set up a minimalist application, attached Gibraltar to it, and reported some trace information. In this post we’re going to build on that and add exceptions. First we are going to add an unhandled exception, so we change our code so that it looks like this:</p>
<pre class="brush: csharp; title: ; notranslate">
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace GibraltarGettingStartedApp
{

	class Program
	{
		static int Main(string[] args)
			{
				Trace.WriteLine(&quot;About to Blow up...&quot;);
				int zero = 0;
				Trace.Close();
				return 1 / zero;
			}
		}
	}
}
</pre>
<p>That should get the runtime’s panties in a bunch, let’s try it. <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/wlEmoticon-smile1.png" alt="Smile" /></p>
<p><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/SNAGHTML22a2b5ec.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="SNAGHTML22a2b5ec" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/SNAGHTML22a2b5ec_thumb.png" alt="SNAGHTML22a2b5ec" width="577" height="157" border="0" /></a></p>
<p>Yep, that did it! Now, let’s see what Gibraltar logged…</p>
<p><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image7.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image_thumb3.png" alt="image" width="435" height="52" border="0" /></a></p>
<p>Gibraltar knows we crashed and if we open up the record…</p>
<p><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image8.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image_thumb4.png" alt="image" width="566" height="106" border="0" /></a></p>
<p>We know what the problem was, we can click the link and go right to the line in the source code and Gibraltar tells us what the user experience is going to be, “This fatal error will not be reported to the user, then the application will exit”. All and all, pretty cool.</p>
<p>As an aside, let me close down VS, I want to test if I click the link, will it open the file and go to the line? It does! That’s cool, though I notice that it only opens the actual file and not the solution or project that the file is in. Hmm, I’ll need to investigate that more as it’d be better if the entire solution was opened, don’t you think?</p>
<p>Let’s try running the same unhandled exception in a winforms application and see what happens. We’ll need to run the exe from the commandline, as the VS debugger will “get in the way” and try to do “clever stuff”, but when we do, we see the following dialog:</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="SNAGHTML298b97c" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/SNAGHTML298b97c.png" alt="SNAGHTML298b97c" width="472" height="301" border="0" /></p>
<p>Here Gibraltar is giving us even more help. It’s popped up a dialog which will actually help us recover from the crash and carry on using our application. If we select “Restart Application” Gibraltar will restart the application for us and enable us to carry on using our application. Of course, this facility should only be used in a testing environment. In the real world, I don’t think it would be wise to restart and to continue using an application which had just suffered from a crash, as there is no way to know what state the underlying model is in. However, from a testing perspective, it’s an excellent tool.</p>
<p>Of course, the same information is recorded in Gibraltar:</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image9.png" alt="image" width="475" height="48" border="0" /></p>
<p>Notice that the “Status” has been recorded as “Normal”. If we open the record we can see why:</p>
<p><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image10.png"><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image_thumb5.png" alt="image" width="442" height="146" border="0" /></a></p>
<p>It’s because we chose to continue the execution and shut down the application normally after.</p>
<p>Okay, let’s change our console application code to handle the exception…</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace GibraltarGettingStartedApp
{
	class Program
	{
		static int Main(string[] args)
		{
			Trace.WriteLine(&quot;About to Blow up...&quot;);
			int zero = 0;
			Trace.Close();
			try { return 1 / zero; }
			catch (DivideByZeroException e) { }
			return 0;
		}
	}
}
</pre>
<p>And let’s see what difference that made to Gibraltar…</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image11.png" alt="image" width="507" height="70" border="0" /></p>
<p>Hmm, as far as Gibraltar is concerned everything is normal, there is no sign of the handled exception. For a clue as to why that is, let’s examine logging best practices, you can read them at…</p>
<p><a title="http://www.gibraltarsoftware.com/Support/Documentation/Logging_BestPractices.html" href="http://www.gibraltarsoftware.com/Support/Documentation/Logging_BestPractices.html">http://www.gibraltarsoftware.com/Support/Documentation/Logging_BestPractices.html</a></p>
<p>And they quite clearly state:</p>
<blockquote><p>“We strongly recommend that in all cases where an exception is consumed within a catch block that you log the exception with an Informational severity rather than silently swallowing the error.”</p></blockquote>
<p>Okay, so this states that if we handle an exception, and we want that fact recorded by Gibraltar, then we have to log it. That makes sense really. So, let’s change our code to the following:</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace GibraltarGettingStartedApp
{
	class Program
	{
		static int Main(string[] args)
		{
			Trace.WriteLine(&quot;About to Blow up...&quot;);
			int zero = 0;
			try { return 1 / zero; }
			catch (DivideByZeroException e)
			{
				Trace.WriteLine(&quot;Error: &quot; + e.Message);
			}
			Trace.Close();
			return 0;
		}
	}
}
</pre>
<p>Now let’s see how that’s affected Gibraltar:</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image12.png" alt="image" width="499" height="90" border="0" /></p>
<p>This time you can plainly see that the error has been recorded, which is good, but notice too that there’s no exception tab:</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image13.png" alt="image" width="236" height="113" border="0" /></p>
<p>Of course, we should be able to do better and we can. If we use the TraceInformation method, and pass a formatted string, along with the exception, then Gibraltar will give us a much richer experience.</p>
<p>So, let’s change our code to use that method:</p>
<pre class="brush: csharp; title: ; notranslate">
using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;

namespace GibraltarGettingStartedApp
{
	class Program
	{
		static int Main(string[] args)
		{
			Trace.WriteLine(&quot;About to Blow up...&quot;);
			int zero = 0;
			try { return 1 / zero; }
			catch (DivideByZeroException e)
			{
				Trace.TraceInformation(&quot;Error: {0}&quot;,e.Message,e);
			}
			Trace.Close();
			return 0;
		}
	}
}
</pre>
<p>And let’s look at the information provided in Gibraltar:</p>
<p><img style="background-image: none; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="image" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/image14.png" alt="image" width="332" height="112" border="0" /></p>
<p>This time, as you can see, we get the “Exceptions” tab. This is because Gibraltar scans the insertion variables and, if it finds one that is an exception, then it uses that as the exception for the log message (regardless of its severity). Pretty cool eh?</p>
<p>In this post we added an unhandled exception to your console application to see what effect that had on Gibraltar. We then added an unhandled exception to a winforms application so we could see the enhanced features available to us there and then we finished up by handling that exception and seeing why best practice is to log handled exceptions.</p>
<p>I hope you’ll join me next time as we continue our exploration of Gibraltar, until then, happy coding! <img class="wlEmoticon wlEmoticon-smile" style="border-style: none;" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/wlEmoticon-smile1.png" alt="Smile" /></p>
]]></content:encoded>
			<wfw:commentRss>http://rocksolid.gibraltarsoftware.com/development/logging/getting-to-know-gibraltar-adding-exceptions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VistaDB 4.3 Performance Optimization</title>
		<link>http://rocksolid.gibraltarsoftware.com/development/vistadb-4-3-performance-optimization</link>
		<comments>http://rocksolid.gibraltarsoftware.com/development/vistadb-4-3-performance-optimization#comments</comments>
		<pubDate>Wed, 07 Dec 2011 18:40:34 +0000</pubDate>
		<dc:creator>Jay</dc:creator>
				<category><![CDATA[Data]]></category>
		<category><![CDATA[Database Engine]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Product Information]]></category>
		<category><![CDATA[VistaDB]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://rocksolid.gibraltarsoftware.com/?p=1106</guid>
		<description><![CDATA[Our biggest VistaDB update yet provides a significant performance boost in a number of common query scenarios while improving compatibility with SQL Server and broader support for SQL commands.]]></description>
			<content:encoded><![CDATA[<div id="attachment_1114" class="wp-caption alignright" style="width: 144px"><a href="https://www.gibraltarsoftware.com/Support/VistaDB/Embedded/Latest_Version"><img class="size-full wp-image-1114 " title="Download VistaDB 4.3" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/VistaDB.png" alt="Download VistaDB 4.3" width="134" height="160" /></a><p class="wp-caption-text">Download VistaDB 4.3</p></div>
<p>We are happy to announce the biggest update to the VistaDB engine since Gibraltar Software took over the product last year. It&#8217;s actually our <a title="Version History" href="https://www.gibraltarsoftware.com/Support/Version_History.aspx" target="_blank">fifth update</a>, though our earlier releases were more limited in scope consisting of a new streamlined licensing system and a number of bug fixes—often providing closer compatibility with SQL Server scripts.</p>
<p>The main focus of VistaDB 4.3 is query performance, particularly with multiple JOINs. We’re pleased to report 2.5x improvements in many cases and discuss below what’s happening inside the VistaDB engine to achieve these results. Let’s start with an overview of how VistaDB produces query results.</p>
<h1>How Does My Query Work?</h1>
<p>VistaDB queries are executed in three general phases:</p>
<ul>
<li><strong>Parse:</strong> The SQL query text is parsed into a tree of objects representing each language element.</li>
<li><strong>Prepare:</strong> The statement/expression tree is recursively processed to identify table and column references and to determine the data types of results.</li>
<li><strong>Execute:</strong> The statement/expression tree is recursively processed to execute statements and provide results in order (returning to the calling application as each row is ready).</li>
</ul>
<p>If there were no optimizations at all, the engine would walk every row of the parent table. And for each of those rows, then walk every row of the first joined table looking for matches to the ON clause. For each of those rows it would then repeat the process for every row of every additional table referenced in the query. Obviously, this would be ridiculously slow when joining multiple tables of any real size, or even when querying a single table with a large number of rows when you don’t actually want most of them.</p>
<p>To be more efficient, VistaDB performs an additional optimization step at the start of the Execute phase. This step recursively walks the WHERE clause and ON clauses and converts the comparison expressions (and special functions such as BETWEEN) into a more efficient representation as constrains in which each constraint specifies a range of values for a particular column based on constants, parameter values, or the value of a column from an earlier table in the parse tree.</p>
<p>In optimizing the parse tree, VistaDB simplifies the execution plan into a series of constrained tables you could imagine as being evaluated left-to-right. Constraints that can’t be resolved are declared <em>non-optimizable</em> and must be handled by testing the WHERE clause. Similarly, target columns for which there isn’t an available index are also non-optimizable and must be tested row-by-row. These optimized conditions are then processed for logical ANDs and ORs to calculate an overall optimized filter for each table.</p>
<h1>Building On What Already Works Well</h1>
<p>VistaDB has always done well with queries in which a range of rows can be retrieved on a single-column index with an identifiable starting and ending value based on the current rows of tables “to the left” of it. For example, if the parent (FROM) table is restricted by a single comparison in the WHERE clause such as: WHERE ParentTable.ColA = @ChosenValue; (with an index on ColA), then the engine doesn’t need to walk every row of ParentTable, it can start with the first row in the index with a value of @ChosenValue for ColA, and walk each row in the index until it passes the last row with a value of @ChosenValue for ColA. If another table is then joined in it doesn’t need to consider any combinations outside of that range on ParentTable; they’re already certain to be excluded by that condition in the WHERE clause.</p>
<h1>Improvements in VistaDB 4.3</h1>
<p>We use VistaDB extensively in our Gibraltar application monitoring system and noticed that VistaDB performance left something to be desired for some of our more complex queries. For example, it is common to use a placeholder ID (perhaps a UNIQUEIDENTIFIER) as a foreign key into a small lookup table which can contain additional information fields universal to that value. In Gibraltar we have tables such as Application_Type and Boot_Mode which provide caption and description labels for display purposes. They can be joined directly into a query about one or more sessions, like so:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT * FROM Session_Details SD
	JOIN Processor_Architecture OSA
		ON OSA.PK_Architecture_Id = SD.FK_OS_Architecture_Id
	JOIN Boot_Mode BM ON BM.PK_Boot_Mode_Id = SD.FK_OS_Boot_Mode_Id
	JOIN Processor_Architecture RA
		ON RA.PK_Architecture_Id = SD.FK_Runtime_Architecture_Id
</pre>
<p>The joined tables are tiny, only 5 or so rows each, so (in theory) this should be very efficient. Each joined table can have its unique matching row directly looked up based on the corresponding column value in the parent table. Perfect, right? But this query was taking several seconds. The base query (SELECT * FROM Session_Details) took less than half a second, and that’s querying the entire table! What we found in VistaDB 4.2 was that as each JOIN was added to this query, the overall query time nearly doubled! Something was clearly less efficient than it should be.</p>
<p><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/VistaDB43Perf.png"><img class="alignright size-full wp-image-1110" title="VistaDB 4.3 vs VistaDB 4.2" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/VistaDB43Perf.png" alt="" width="477" height="287" /></a><br />
As we analyzed the engine internals, we found a lot of opportunities to improve performance which we&#8217;ll be implementing over the coming year. As a first step, we decided to focus in VistaDB 4.3 on reducing the overhead for multiple joins and optimize for the most common cases.</p>
<p>We expect that the majority of joins will be on a single equality between a single column from each table with a foreign key relationship between them. Since this should by definition identify a single value (and often a single row), it should be the most efficient filter to narrow down the joined table based on those “to the left”. So the optimization logic will now catch these top-priority conditions early on and bypass the rest of the expensive reduction pass.</p>
<p>And in queries like our example, we integrated column value caching to eliminate the need to search for the same rows over and over again. When a table is joined on a UNIQUE single column index, the table can cache the row in a Dictionary keyed by the column value from the other table, and each time it comes back to that value, it grabs the row from cache instead of searching the index and reading it from disk again.</p>
<p>We also coded our caching to ensure that it doesn’t consume excessive memory when processing large tables. The cache only holds hard references to the most recently accessed rows. By using weak references to less recently used rows they stick around when memory is plentiful but can be garbage-collected if necessary. For more info on on weak references, check out Kendall&#8217;s Code Project article and sample code on <a title="Using weak references to conserve memory" href="http://www.codeproject.com/KB/string/StringReference.aspx" target="_blank">creating a single instance string store</a>.</p>
<p>As shown in the graph above, VistaDB 4.3 is several times faster for many common queries. More importantly, in queries such as above, performance degrades linearly as more tables are joined, rather than exponentially as before.</p>
<h1>Stay Tuned for More to Come</h1>
<p>The query optimizations we&#8217;ve introduced in VistaDB 4.3 are just a start. Subsequent releases will have additional query optimizations as well as other performance improvements such as support for bulk insert and enhanced multi-user scalability. We also will be adding new features such as enhanced support for Entity Framework, enhanced compatibility with SQL Server and improvements to our development tools (Data Builder, Data Migration Wizard, etc).</p>
<p>We&#8217;ll be writing additional blog posts about our adventures taking VistaDB to the next level, so check back often or leave a question/comment below or in our <a title="Visit our support forums for VistaDB and Gibraltar" href="http://community.gibraltarsoftware.com/forums/">support forums</a> &#8211;we&#8217;d love to hear from you!</p>
]]></content:encoded>
			<wfw:commentRss>http://rocksolid.gibraltarsoftware.com/development/vistadb-4-3-performance-optimization/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Gibraltar 3.0 New Feature Dive &#8211; Super sized Sessions</title>
		<link>http://rocksolid.gibraltarsoftware.com/development/logging/gibraltar-3-0-new-feature-dive-super-sized-sessions</link>
		<comments>http://rocksolid.gibraltarsoftware.com/development/logging/gibraltar-3-0-new-feature-dive-super-sized-sessions#comments</comments>
		<pubDate>Fri, 02 Dec 2011 02:59:09 +0000</pubDate>
		<dc:creator>Kendall</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Logging]]></category>
		<category><![CDATA[Product Information]]></category>
		<category><![CDATA[Gibraltar]]></category>
		<category><![CDATA[Release]]></category>

		<guid isPermaLink="false">http://rocksolid.gibraltarsoftware.com/?p=1002</guid>
		<description><![CDATA[Find out how we've updated Gibraltar to handle applications that run forever or record a crazy amount of information.  All this and more in our continuing series on Gibraltar 3.0.]]></description>
			<content:encoded><![CDATA[<p>A major challenge customers have had with Gibraltar 2.0 is working with long running and large sessions.  This stems from the early on design decision to target smart client applications for the first releases of Gibraltar.  From this decision we made a series of assumptions &#8211; how large sessions would be, how people would want to count and interpret them, when they would get sent in, etc.  For example, early beta versions we assumed by default that you only wanted to keep 50MB of total log data and each session would be around 5MB.  Looking back, this just isn&#8217;t how things turned out at all.</p>
<p>Once you start using Gibraltar with server applications &#8211; like web sites or even windows services then a few things happen:</p>
<ul>
<li><strong>Long Life:</strong>  Gibraltar equates a session lifetime to the application domain it runs in.  For windows services this could be months, possibly even years.  For web sites it&#8217;s typically a day or less.</li>
<li><strong>Session Size:</strong> It&#8217;s hard to imagine in a single user smart client recording more than 50MB of information.  Our analysis of log files we receive and our customers use indicates this is a pretty fair assumption.  For a busy corporate line of business web application you can easily generate 500MB of log data each day.</li>
<li><strong>Submitting Sessions:</strong> By default, Gibraltar waits for a session to end before sending in the data.  This works well with end-user applications but doesn&#8217;t match up with operating your own web sites or services.  What use is it to find out a month later your Windows Service was having a problem?  You could trigger sending data manually and even when an error happened, but if your session got to large this could be dangerous because we merged together all of the data first to send it.</li>
</ul>
<p>The biggest problems people have with using Gibraltar 2.x in these situations is:</p>
<ul>
<li>If you log a lot of data, you need a lot of memory and processor to submit the data to be able to view it &#8211; about five times as much as the log data.  To add insult to injury, every time it submitted the data it pushed it all to the server, and that got completely re-analyzed for issues then copied down to each Analyst.  Very inefficient.</li>
<li>You had to add code to your application to explicitly push the session to the server to see any of the data.  And when you did you could run into the first problem.</li>
</ul>
<p>No question about it,<strong> this sucks and it had to stop</strong>.</p>
<blockquote><p>Editor&#8217;s Note: Not all of the optimizations discussed below have shipped in Gibraltar 3.0 Beta 2.</p></blockquote>
<h1>Smaller Data Files</h1>
<p>Our original compression approach was based on a sampling of files between 5 and 50MB.  It turns out that the files we really should worry about were in the 50 to 500MB range.  Saving 25% on a 5MB file isn&#8217;t likely to impress anyone.  Cutting 100MB off a log file makes a real difference.  We&#8217;ve substantially revised how we compress files and will get an average of 65% reduction in size for typical files.  That&#8217;s right &#8211; they&#8217;re now 1/3rd as big.  This is all done with no impact on the throughput of the log system because of the asynchronous, queued approach Gibraltar uses to record data.</p>
<p>We also reduced the memory it takes in the Agent to perform this compression.  Previously it was possible to use up to your maximum log file size in RAM (in extreme cases) while logging.  To avoid the problem of merging fragments (which uses even more memory) some customers ran into this when they dramatically upped their log file sizes. Now the compression uses a fixed buffer size measured in KB to ensure it&#8217;s both efficient and predictable.</p>
<p>These smaller files have another advantage:  We previously zipped files before they were sent to the hub to save network time.  This would get us about a 40% reduction in file size but took time, processor, and disk space.  With the new scheme there&#8217;s no advantage to doing this &#8211; the files would actually get slightly larger.  So we can skip this step which saves time on both the client and server.</p>
<p>We&#8217;ve also added a feature to let you understand why your data files are as big as they are.  In Analyst, you can open a session and then click File Stats on the Session Details tab.</p>
<p style="text-align: center;"><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/Session-Details.png"><img class="aligncenter size-full wp-image-1075" title="Session Details" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/Session-Details.png" alt="" width="541" height="177" /></a></p>
<p>Here&#8217;s the analysis we get for one of our Gibraltar Hubs we&#8217;re using for testing.  It logged about 700,000 messages in a 24 hour period.</p>
<p style="text-align: center;"><a href="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/Sesion-File-Summary.png"><img class="aligncenter size-full wp-image-1074" title="Sesion File Summary" src="http://rocksolid.gibraltarsoftware.com/wp-content/uploads/Sesion-File-Summary.png" alt="" width="428" height="414" /></a></p>
<p>You can see that the average size of each log message is 57 bytes.  Now that&#8217;s good stuff from a compression standpoint.  The process also recorded a fair number of metrics and performance counters.  There are metrics for each data operation, web service call, etc. and these add up to a total of about 350,000 individual samples at an average size of 31 bytes.  All of the performance counter samples &#8211; 35,000 of them &#8211; came in at an average of 10 bytes.  All in, the file was just over 50MB.</p>
<p>From this information you can get a good feel for what&#8217;s driving your log file size.  Now, you may never care &#8211; but when you get into logging millions of messages and millions of metrics then it&#8217;s good to have around.</p>
<h1>Incremental Data Files</h1>
<p>For Gibraltar 3.0 we&#8217;ve changed it so that the individual file fragments Gibraltar stores data into (each representing a period of time) are never merged together &#8211; all the way down to Analyst.  When data needs to be made available Gibraltar has always rolled over the current log file (called a session fragment) and started a new one.  Previously these fragments all had to be merged together before the data could be sent anywhere off the computer.  Now they&#8217;re each managed individually.  Thanks to this change, each time your application wants to send data to the Hub only the fragments that haven&#8217;t already been sent are processed.  Likewise when this data needs to be analyzed for issues or sent down to clients that want to view the details it&#8217;s just the new information.</p>
<p>We&#8217;ve also gone through the processes that send data &#8211; whether it&#8217;s to the Hub server, email, or files &#8211; and worked to eliminate unnecessary file copies that were being done previously in an overabundance of copies (these get expensive if you have a 300MB file) and minimize the memory required.  The bottom line is that you can safely send session data at any time &#8211; regardless of how much data you&#8217;ve logged or how long your application&#8217;s been running.</p>
<h1>Let Your Application Run Forever</h1>
<p>Making the session files smaller and keeping them in fragments helps with large sessions, but when you have a really long application there are a few other things that kick into play.  First, you want to make sure you can discard older log data off the computer (to keep down local disk space) even while the application was still running.  In many cases, Gibraltar 2.x would end up throwing away the start of the session and all you&#8217;d have is the last 150MB of data (if you used the default limits).   For 3.0, session fragments can be sent automatically as soon as the log file rolls over for any reason.  The default limits of 50MB and one day mean that for each Windows Service you&#8217;d at least get a fragment every day &#8211; which would be sent up to the server and then pruned locally.  You can still trigger sending data more often from within the application like you used to and it&#8217;ll work great.</p>
<p>The Hub server works better with this as well &#8211; it will analyze each fragment without having to load up information it&#8217;s previously worked through.  This means you get steady updates and the memory required on the server is dramatically reduced.  We&#8217;ve had customers with Gibraltar 2.x that had servers perpetually behind analyzing sessions because by the time they analyzed a large file they received another copy of it with just a modest amount of new information.  Now this is a non-issue because the server can load just the new data and check it.</p>
<h1>Of Course, You&#8217;d Like to see All of That</h1>
<p>The final problem area for Gibraltar with very large sessions was viewing them in Analyst.  Historically you could load up a session with between 1.2 and 2 million messages.  More than that and it&#8217;d fail with an out of memory exception.  This was because Gibraltar Analyst was a 32-bit only application.  We&#8217;ve rewritten our graphing system to use the <a href="http://www.devexpress.com/Products/NET/Controls/Charting/" target="_blank">DevExpress XtraCharts</a> like we use for Charting and that means we&#8217;re good to go for 64-bit in Analyst.  If you have 8GB of RAM, you can use all of it for session data if you want.  In practice this means you&#8217;re still limited to a session with perhaps 10-15 million messages.  We&#8217;re going to work on that in a future release to really achieve our goal of infinite logging.</p>
<p>This is all fine and good, but it&#8217;s still missing something&#8230; The ability to handle the server-on-fire-right-now scenario we&#8217;ve all experienced at some time in our career.  For the story on that, stay tuned for our next deep dive!</p>
]]></content:encoded>
			<wfw:commentRss>http://rocksolid.gibraltarsoftware.com/development/logging/gibraltar-3-0-new-feature-dive-super-sized-sessions/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

