<?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>XING Blog &#187; Tech Blog</title>
	<atom:link href="http://blog.xing.com/category/english/tech-blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.xing.com</link>
	<description>The corporate blog of XING</description>
	<lastBuildDate>Fri, 20 Nov 2009 15:05:05 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>XING: Uptimes, Downtimes – and what we do</title>
		<link>http://blog.xing.com/2009/11/xing-uptimes-downtimes-%e2%80%93-and-what-we-do/</link>
		<comments>http://blog.xing.com/2009/11/xing-uptimes-downtimes-%e2%80%93-and-what-we-do/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 15:16:27 +0000</pubDate>
		<dc:creator>Dr. Johannes Mainusch</dc:creator>
				<category><![CDATA[Tech Blog]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=8029</guid>
		<description><![CDATA[<div id="attachment_8032" class="wp-caption alignright" style="width: 310px"><a href="http://blog.xing.com/wp-content/uploads/2009/11/XING-uptime-average.png"></a><p class="wp-caption-text">XING is fully available 99.85% of the time.</p></div>
<p>It happens pretty rarely, but sometimes our platform is affected too by operational faults and malfunctions. Of course we try to keep these hiccups to an absolute minimum. Our content is stored and&#8230;</p>]]></description>
			<content:encoded><![CDATA[<div id="attachment_8032" class="wp-caption alignright" style="width: 310px"><a href="http://blog.xing.com/wp-content/uploads/2009/11/XING-uptime-average.png"><img class="size-medium wp-image-8032" title="XING-uptime-average" src="http://blog.xing.com/wp-content/uploads/2009/11/XING-uptime-average-300x225.png" alt="XING-uptime-average" width="300" height="225" /></a><p class="wp-caption-text">XING is fully available 99.85% of the time.</p></div>
<p>It happens pretty rarely, but sometimes our platform is affected too by operational faults and malfunctions. Of course we try to keep these hiccups to an absolute minimum. Our content is stored and supplied from two different data processing centers for instance, which means that our users can be re-routed from one to the other dependently on demand and performance.  All systems have a failover cluster operation guaranteeing high performance and stability, as well as having sufficient reserves to cope better with peak loads. Making sure our platform is both available and fast is our number one priority.</p>
<p>Sometimes though, like last Wednesday&#8217;s morning for instance, we do encounter unforeseen problems. There isn’t an IT system anywhere that is 100% fault-tolerant – there will always be systematic <em>single points of failure</em> that will send part or all of the entire system crashing with them. In this latest case a defect network component corrupted a mechanism, which was specifically required to safeguard against failure (<em>Spanning Tree Protocol</em>). We will be analyzing and intercepting this error to make sure it doesn’t crop up again.<span id="more-8029"></span></p>
<p>A look at the figures for the past twelve months shows that we meet our high targets, with an average uptime ratio of 99.95%. In other words, this means that XING can’t have been offline for more than four hours and 2 minutes over the entire year. Or to put it yet another way: This is equivalent to around 44 seconds a day. Crashes affecting just certain parts of the platform have also been included in this statistic.</p>
<p>Here are the availability figures for the past twelve months:</p>
<table style="border: 1px dotted #e97f02;border-spacing: 10px; margin-bottom: 10px;" border="0">
<tbody>
<tr>
<td style="color: #e97f02;">Month</td>
<td style="color: #e97f02;">Availability</td>
</tr>
<tr>
<td>Nov 08</td>
<td>99,88%</td>
</tr>
<tr>
<td>Dez 08</td>
<td>99,75%</td>
</tr>
<tr>
<td>Jan 09</td>
<td>99,60%</td>
</tr>
<tr>
<td>Feb 09</td>
<td>99,97%</td>
</tr>
<tr>
<td>Mrz 09</td>
<td>99,80%</td>
</tr>
<tr>
<td>Apr 09</td>
<td>99,93%</td>
</tr>
<tr>
<td>Mai 09</td>
<td>99,87%</td>
</tr>
<tr>
<td>Jun 09</td>
<td>99,96%</td>
</tr>
<tr>
<td>Jul 09</td>
<td>99,95%</td>
</tr>
<tr>
<td>Aug 09</td>
<td>99,83%</td>
</tr>
<tr>
<td>Sep 09</td>
<td>99,76%</td>
</tr>
<tr>
<td>Oct 09</td>
<td>99,91%</td>
</tr>
<tr>
<td>Average</td>
<td>99,85%</td>
</tr>
</tbody>
</table>
<p>To form a meaningful graph from these figures the vertical axis needs to be scaled up dramatically in order to see any fluctuations at all:</p>
<div id="attachment_8031" class="wp-caption alignnone" style="width: 510px"><a href="http://blog.xing.com/wp-content/uploads/2009/11/XING-uptime-12months.png"><img class="size-full wp-image-8031" title="XING-uptime-12months" src="http://blog.xing.com/wp-content/uploads/2009/11/XING-uptime-12months.png" alt="XING-uptime-12months" width="500" height="375" /></a><p class="wp-caption-text">Chart: XING availability during the last twelve months.</p></div>
<p>Despite this record, every minute of downtime is a blow to us – as we know how important it is that our members can send messages, make contacts and network at any time. That’s why we’ll keep doing everything in our power to maximize stability and availability of our platform.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/11/xing-uptimes-downtimes-%e2%80%93-and-what-we-do/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Agile development with Kanban: XING reveals all at the w-jax&#8217;09 in Munich</title>
		<link>http://blog.xing.com/2009/11/agile-development-with-kanban-xing-reveals-all-at-the-w-jax09-in-munich/</link>
		<comments>http://blog.xing.com/2009/11/agile-development-with-kanban-xing-reveals-all-at-the-w-jax09-in-munich/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 16:46:43 +0000</pubDate>
		<dc:creator>Susanne Reppin</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[agile development]]></category>
		<category><![CDATA[Kanban]]></category>
		<category><![CDATA[Scrum]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=7983</guid>
		<description><![CDATA[<div id="attachment_7912" class="wp-caption alignright" style="width: 310px"><a href="http://blog.xing.com/wp-content/uploads/2009/11/XING_WJAX09_Vortrag.JPG"></a><p class="wp-caption-text"> Susanne Reppin (left) and Dr. Johannes Mainusch on the wjax stage.</p></div>
<p>Just how agile is XING? How agilely do we feel? At this year’s <a href="http://it-republik.de/jaxenter/wjax09/">w-jax 09</a>, <a href="https://www.xing.com/profile/Johannes_Mainusch">Johannes Mainusch</a> and myself talked openly about the XING culture, what kind of people we are,&#8230;</p>]]></description>
			<content:encoded><![CDATA[<div id="attachment_7912" class="wp-caption alignright" style="width: 310px"><a href="http://blog.xing.com/wp-content/uploads/2009/11/XING_WJAX09_Vortrag.JPG"><img class="size-medium wp-image-7912 " title="XING_WJAX09_Vortrag" src="http://blog.xing.com/wp-content/uploads/2009/11/XING_WJAX09_Vortrag-300x225.jpg" alt=" Susanne Reppin (left) and Dr. Johannes Mainusch on the wjax stage." width="300" height="225" /></a><p class="wp-caption-text"> Susanne Reppin (left) and Dr. Johannes Mainusch on the wjax stage.</p></div>
<p>Just how agile is XING? How agilely do we feel? At this year’s <a href="http://it-republik.de/jaxenter/wjax09/">w-jax 09</a>, <a href="https://www.xing.com/profile/Johannes_Mainusch">Johannes Mainusch</a> and myself talked openly about the XING culture, what kind of people we are, what we’re aiming for and what’s important to us. XING releases weekly updates on the platform, innovating therefore all the time during ongoing operation of the platform. We don’t want to have to put a halt to anything, and not when it comes to agile software development either.</p>
<p>XING already develops projects effectively using Scrum (see also <a href="http://blog.xing.com/2009/05/einfuhrung-von-scrum-bei-xing-%e2%80%93-ein-erfahrungsbericht/">Scrum @ XING – a case study</a>). Alongside this, we’ve been working for nine months to put Kanban in place for one our maintenance teams – as both a methodology and philosophy. The initial idea for this came from Ralf Wirdemann, who’s an agile coach. Selecting Kanban fits in with our belief in agile and lean software development and to drive this forward in the future.<span id="more-7983"></span></p>
<p>People took a great interest in our <a href="http://it-republik.de/jaxenter/wjax09/sessions?tid=1289">speech</a> (here&#8217;s the <a href="http://www.slideshare.net/XING_com/agil-bleiben-motorhaube-auf-bei-xing">slideshare</a> and our <a href="http://blog.xing.com/wp-content/uploads/2009/11/w-jax09_XING_AG.pdf">PDF with notes</a>, both in German). We explained why Scrum is so well-suited to our project work, as it protects the team from disruptions during the sprints – but that precisely this protection is contra-productive when applied to a team operating in close interplay with live operation of the platform. Kanban is considerably better suited to integrating disruptions – which bugs are after all – in an ad hoc way, and is therefore ideal for a maintenance team.</p>
<p>One of the major success factors here is of course the team itself. All team members were already experienced in agile development and wanted to learn more in a professional context. After about six weeks we were all surprised at how much more effectively and fast we could now go about our daily work.</p>
<p>Please note: The full talk held at the w-jax 2009 in Munich will be published in the next few weeks by w-jax.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/11/agile-development-with-kanban-xing-reveals-all-at-the-w-jax09-in-munich/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>False alarm with outdated virus scanner: An update will help</title>
		<link>http://blog.xing.com/2009/11/false-alarm-with-outdated-virus-scanner-an-update-will-help/</link>
		<comments>http://blog.xing.com/2009/11/false-alarm-with-outdated-virus-scanner-an-update-will-help/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 09:24:02 +0000</pubDate>
		<dc:creator>Christian Burtchen</dc:creator>
				<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[virus alarm]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=7969</guid>
		<description><![CDATA[<p>Just to make it perfectly clear from the outset: There is no virus on the XING platform, nor is there any code that might be damaging to your computer. Under certain – very specific – circumstances, you might find though&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Just to make it perfectly clear from the outset: There is no virus on the XING platform, nor is there any code that might be damaging to your computer. Under certain – very specific – circumstances, you might find though that your virus scanner sets off a false alarm if it hasn’t been updated for a long time.</p>
<p>The reason: A module we have developed ourselves that serves to load files in a browser once the page itself has already been loaded. This is useful because it means we don’t have to send all functionalities and graphics that might possibly be used through the network at once for every page accessed, which saves you a lot of time waiting for pages to load. If you then decide to use a feature or function that isn’t yet loaded – such as the photo upload in your profile, this small additional feature can then be loaded separately.</p>
<p>The browser feature that our module accesses posed a security loopholes in earlier versions of Internet Explorer. You can read more about this here: <a href="http://www.securiteam.com/windowsntfocus/5MP0G15RFM.html">Microsoft Internet Explorer onreadystatechange Memory Corruption Vulnerability</a>.</p>
<p>The good news is that Microsoft solved this problem in their own browser some time ago. (It might be worth you visiting <a href="http://windowsupdate.com/">windowsupdate.com</a> to make sure your operating system and Internet Explorer are both fully up-to-date.)</p>
<p>If you use an outdated version of the virus scanner F-Secure though, which has not received an update since the removal of the security loophole in Internet Explorer, it will show you a false alarm if you use the Microsoft browser.<span id="more-7969"></span></p>
<p><a href="https://www.xing.com/profile/Bjoern_Kaiser6">Björn Kaiser</a>, one of our software experts, had this to say about the matter: “We did everything in our power here to make sure we avoided any major difficulties here. Even though it wasn’t a security breach at all, we still didn’t want to unsettle our users with nonsensical warning messages from a virus scanner that wasn’t updated. He spent three days trying to pinpoint the exact source of the problem, combing through 60,000 lines of Javascript code to locate the one line that triggers the warning message. One harmless line, lots of work! Thanks to my colleague <a href="https://www.xing.com/profile/Ingo_Chao">Ingo</a> as well for all the great debugging he did …”</p>
<p>Doing without onreadystatechange was out of the question. This would have meant that certain modules wouldn’t work at all anymore. The solution our developers came up with was relatively simple in comparison: Thanks to</p>
<p>var handler = ["onr", "eadystatec", "hange"].join(&#8221;");</p>
<p>the virus scanner no longer recognizes the supposedly bad “onreadystatechange“. The string function join enables the components to be brought together and implemented though – without triggering the false alarm.</p>
<p>There was of course no danger to your data or computer at any point in time here. We contacted the manufacturer too to make sure that this was in fact a case of a false alarm.</p>
<p>Having said this you should make it a top priority, in your own interests, to update your virus scanner to the latest standards. At the same time we’ll continue to do everything to ensure the most secure networking possible on our platform, without any unnecessary warning messages.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/11/false-alarm-with-outdated-virus-scanner-an-update-will-help/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Making errors look good</title>
		<link>http://blog.xing.com/2009/10/making-errors-look-good/</link>
		<comments>http://blog.xing.com/2009/10/making-errors-look-good/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 15:55:19 +0000</pubDate>
		<dc:creator>Timothy Payton</dc:creator>
				<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[DOM complexity]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=7553</guid>
		<description><![CDATA[<p>There are many html forms on XING – when you sign up, when you write a message, or when you discuss in a group. We do most of our form validations on the server side. This allows us to apply complex&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>There are many html forms on XING – when you sign up, when you write a message, or when you discuss in a group. We do most of our form validations on the server side. This allows us to apply complex validations, prevents code duplication, and apply security checks.</p>
<p>This works well – you define the requirements for the specific field (such as &lt;input&gt;) and Rails returns the page with an error message, also highlighting the corresponding field in red. Sounds good, but that’s actually where the problem is. Rails surrounds the field with a &lt;div&gt; that is styled via CSS.<span id="more-7553"></span></p>
<p>This additional &lt;div&gt; <em>may</em> lead to CSS problems especially in pixel-precise layouts such as the XING html forms, it <em>may</em> break the HTML structure &#8211; and it <em>will</em> add completely unneeded DOM complexity.</p>
<h3>Changing how Rails handles fields with errors</h3>
<p>The technical details of how we solved it follow. We were not the first ones to encounter this problem, inquirylabs also talked about (and solved) it in their blog post <a href="http://blog.inquirylabs.com/2006/04/13/highlight-background-of-fields-with-errors/">Highlight background of fields with errors</a>. The basic idea is rather simple: We rewrote the method Rails uses to handle form field errors to create cleaner html. The best solution we can think of is to add a class directly to the error elements, and that class has styling to border the error fields in red. No added DOM elements, no more broken structure, just clean code.</p>
<p>Here is the default rails html output</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div class=&quot;fieldWithErrors&quot;&gt;
&lt;input /&gt;Test&lt;/div&gt;</pre></div></div>

<p>Here is what our changes output</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;input class=&quot;input-error&quot; /&gt;Test</pre></div></div>

<p>Luckily, Rails already provides a simple entry point for cleaning things up. In active_record_helper.rb in the actionpack gem, there is a class variable defined @@field_error_proc, which can be redefined to apply custom error handling on the html input fields. We’ve uploaded the code to github: <a href="http://github.com/xing/classy_field_errors">http://github.com/xing/classy_field_errors</a>.</p>
<p>It&#8217;s a plugin, so just:</p>
<ul>
<li>script/plugin install git://github.com/xing/classy_field_errors.git</li>
<li>Put the css contained in field_error_proc.css in your base css file</li>
</ul>
<p>The method we call inside the block, does exactly what we want. You pass it an element and a css class. It then applies that css class to input, textarea, or select elements, either adding the class to the existing classes or adding a class attribute to the element.</p>
<p>The method itself just calls the HtmlElement class method add_css_class which does what you’d think it does: It instantiates an HtmlElement object, <em>adds the class</em> passed into the elements and returns the changed html_element (which is really a string).</p>
<p>So, with the added class, we can do the same error highlighting, but without any added DOM complexity and with the intended semantic separation of HTML for content and CSS for styling.</p>
<p>Our solution produces the same basic results as inquirylabs, but also took care of 2 edge cases:</p>
<ul>
<li> it only adds the CSS class if the element doesn&#8217;t have it already, so in the rare case that an input field has two errors, the code remains clean</li>
<li> the code also works with self-closing &lt;input/&gt; tags</li>
</ul>
<p>Thanks to Ladislav Martincik, Sebastian Roebke, Mark Schuette and Hendrik Mans who all contributed to making this code highly efficient and clean.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/10/making-errors-look-good/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A Rails plugin to store a collection of boolean values as a single bit field</title>
		<link>http://blog.xing.com/2009/08/a-rails-plugin-to-store-a-collection-of-boolean-values-as-a-single-bit-field/</link>
		<comments>http://blog.xing.com/2009/08/a-rails-plugin-to-store-a-collection-of-boolean-values-as-a-single-bit-field/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 11:42:44 +0000</pubDate>
		<dc:creator>Sebastian Röbke</dc:creator>
				<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=6896</guid>
		<description><![CDATA[<p>As you probably know, boolean values in software systems represent the states &#8220;true&#8221; or &#8220;false&#8221;. For some use cases in a software application, you may need a lot of them.</p>
<p>To give you a very simplified example, imagine a form where&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>As you probably know, boolean values in software systems represent the states &#8220;true&#8221; or &#8220;false&#8221;. For some use cases in a software application, you may need a lot of them.</p>
<p>To give you a very simplified example, imagine a form where the user can check which languages he or she speaks:</p>
<p><img class="alignnone size-full wp-image-6898" src="http://blog.xing.com/wp-content/uploads/2009/08/FlagShihTzu_Pic1.png" alt="XING_FlagShihTzu_boolean_selection" width="309" height="108" /></p>
<p><span id="more-6896"></span>Let&#8217;s assume that every language option should be stored as a boolean value in a &#8220;users&#8221; database table, being either &#8220;true&#8221; or &#8220;false&#8221;, depending on which of the boxes are checked.</p>
<p><img class="alignnone size-full wp-image-6899" src="http://blog.xing.com/wp-content/uploads/2009/08/FlagShihTzu_Pic2.png" alt="XING_FlagShihTzu_database_table" width="492" height="33" /></p>
<p>Technically, modern relational database systems such as <a href="http://www.mysql.com/">MySQL</a> can handle many columns per table just fine. However, adding new columns to a table while the database is on load is not that easy if the table already has millions of rows. This is a change that could take hours to complete, depending on the database system and data size. Additionally, there are <a href="http://dev.mysql.com/doc/refman/5.0/en/column-count-limit.html">limits of how many columns</a> can be stored in a single table.</p>
<p>For quite some time, we have been using a nice technique to store boolean values of some large tables more efficiently as a single bit field. Using this approach, we can add new boolean attributes whenever we need to, without needing to alter the database tables, which would cause a downtime. For the part of our system that is based on the <a href="http://www.rubyonrails.org/">Ruby on Rails framework</a>, we have solved this via our own plugin, that we are happy to share:</p>
<p><a href="http://github.com/xing/flag_shih_tzu/tree/master">FlagShihTzu</a>  &#8211; A rails plugin to store a collection of boolean attributes in a single ActiveRecord column as a bit field.</p>
<p>We have <a href="http://github.com/xing/flag_shih_tzu/tree/master">uploaded the plugin</a> with documentation on how it works. It was already covered in <a href="http://ruby5.envylabs.com/episodes/6">episode #5</a> of the <a href="http://ruby5.envylabs.com/">Ruby5 podcast</a>!</p>
<p>As some of our other <a href="http://github.com/xing">XING open source projects</a>, the code is hosted on <a href="http://www.github.com/">GitHub</a>, a great website to share and collaborate on open source software. So if you have ideas to improve the plugin, please contribute!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/08/a-rails-plugin-to-store-a-collection-of-boolean-values-as-a-single-bit-field/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>New tip: Please change to a new browser</title>
		<link>http://blog.xing.com/2009/08/new-tip-please-change-to-a-new-browser/</link>
		<comments>http://blog.xing.com/2009/08/new-tip-please-change-to-a-new-browser/#comments</comments>
		<pubDate>Mon, 10 Aug 2009 08:44:36 +0000</pubDate>
		<dc:creator>Dr. Johannes Mainusch</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[Internet Explorer 6]]></category>
		<category><![CDATA[OpenSocial]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=6525</guid>
		<description><![CDATA[<p>Anyone logging in to <a href="https://www.xing.com/opensocial/applist">the application section</a> with Internet Explorer 6 (IE6) will now be asked to update their browser. Here are a few thoughts on this from me:</p>
<div id="attachment_6573" class="wp-caption alignright" style="width: 310px"><p class="wp-caption-text">The logo from &#34;IE6 must die!&#34;</p></div>
<p>Oh, how we would love to shout: “IE6&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Anyone logging in to <a href="https://www.xing.com/opensocial/applist">the application section</a> with Internet Explorer 6 (IE6) will now be asked to update their browser. Here are a few thoughts on this from me:</p>
<div id="attachment_6573" class="wp-caption alignright" style="width: 310px"><img class="size-medium wp-image-6573" title="ie6nomore-logo" src="http://blog.xing.com/wp-content/uploads/2009/08/ie6nomore-logo-300x76.jpg" alt="The logo from &quot;IE6 must die!&quot;" width="300" height="76" /><p class="wp-caption-text">The logo from &quot;IE6 must die!&quot;</p></div>
<p>Oh, how we would love to shout: “IE6 must die!”. (Did you hear about the <a href="http://mashable.com/2009/07/17/ie6-must-die-twibon/">twitter movement</a>? Or about this action from <a href="http://www.ie6nomore.com/">more than 70 websites</a>?) Oh, how we would like to make our platform available in black and white to all Internet Explorer users (for the small proportion of the online world who remember the changeover from black and white TV to color…). But alas this is a helpless battle of the honorable Web <em>Don Quixotes </em>against the electronic windmills of the great multinationals of this world.</p>
<p>Why all this fluster you may ask? Here’s the reason:<span id="more-6525"></span></p>
<p>Over the past few weeks we have been monitoring which browsers our members use to surf our site. I had to laugh a little when I read recently in a Web gazette that 11.7% of Germans still used IE6. I didn’t realize the figure could be pinpointed so precisely!</p>
<p>So here’s our precise data for the last seven days:</p>
<div id="attachment_6474" class="wp-caption alignnone" style="width: 505px"><img class="size-full wp-image-6474" title="XING_browsers" src="http://blog.xing.com/wp-content/uploads/2009/08/XING_browsers.png" alt="Overview of browsers used for XING." width="495" height="324" /><p class="wp-caption-text">Overview of browsers used for XING.</p></div>
<p>This graph shows usage of the different major browsers against time shown on the horizontal axis. The green area at the bottom – representing usage of IE6 – is particularly interesting here. Its structure reveals three things immediately:</p>
<ol>
<li>IE6 is not used very much at      the weekend.</li>
<li>Chinese users, a high      proportion of which use IE6, surf the platform during the European night.</li>
<li>During working hours on      weekdays, members using IE6 exceeds the 20% mark.</li>
</ol>
<p>So why is this? Well, because IE6 is so prevalent still in so many large corporations. I know from previous companies I have worked in how reluctant firms can be to switch browsers when the current one is connected up to anything from 50 to several hundred Internet applications, all of which have to work every single day. At tens of thousands of work stations throughout an organization.</p>
<p>It isn’t worth pestering users to switch either, as they very often don’t have administrative access to their work computer. And the administrators in large companies often don’t have the remit or the budget to carry out a changeover on <em>all</em> computers in a company. And if I was CEO of a large firm I think I’d probably be hesitant about initiating such an infrastructural project with uncertain risks in a completely heterogeneous environment.</p>
<p>To sum up: It seems that Internet Explorer 6 is (regrettably) here to stay, for as long as it still operates on current Windows operating systems at least.</p>
<p>… Come to think of it, XING in black &amp; white might well have a certain retro, futuristic charm about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/08/new-tip-please-change-to-a-new-browser/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>I only believe what I see: 50% less traffic</title>
		<link>http://blog.xing.com/2009/07/i-only-believe-what-i-see-50-less-traffic/</link>
		<comments>http://blog.xing.com/2009/07/i-only-believe-what-i-see-50-less-traffic/#comments</comments>
		<pubDate>Mon, 27 Jul 2009 07:42:11 +0000</pubDate>
		<dc:creator>Christopher Blum</dc:creator>
				<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[browser]]></category>
		<category><![CDATA[IE6]]></category>
		<category><![CDATA[iFrame]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Open]]></category>
		<category><![CDATA[OpenSocial]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=6169</guid>
		<description><![CDATA[<p>It won’t surprise you that one of our key efforts is reducing the workload that the platform puts on your and our machines. The <a href="../../../../../2009/07/ship-it-introducing-the-xing-partner-ecosystem/">introduction of OpenSocial applications</a> increased the challenge – the applications are hosted on different machines (with their&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>It won’t surprise you that one of our key efforts is reducing the workload that the platform puts on your and our machines. The <a href="../../../../../2009/07/ship-it-introducing-the-xing-partner-ecosystem/">introduction of OpenSocial applications</a> increased the challenge – the applications are hosted on different machines (with their own performance issues), and we integrated them via iFrames, on the front page, on the profile page and in what we call the canvas view.</p>
<p>So, at the moment, you might have several iFrames on your start page. An elegant solution, except for the heavy load they put on your browser – the extreme case, Internet Explorer, requires up to 8 Megabyte of RAM for each rendered iFrame. Furthermore, as the front and profile page often extends vertically way beyond the viewport. But still we have to render the content in iFrames you might not even see.</p>
<p>Wait. Do we have to do that?<span id="more-6169"></span></p>
<p>The answer is obviously no. This was one of the things that seriously bugged me, and I really wanted to come up with a solution. So, in the weekly four hours that each developer has for his own independent (of course: XING-related) research, I tried to develop a mechanism that:</p>
<p>(1)    Detects whether an application is in the viewport</p>
<p>(2)    Only renders and loads the iFrame if an empty place-holding element is visible</p>
<p>(3)    Performs the check (1) regularly to detect whether rendering is necessary now</p>
<p>My first solution was to initially render the iFrame and only set its “src” attribute when the element is visible.<br />
Well, that caused problems in a particular browser &#8211; hint: Youtube will soon be <a href="http://www.techcrunch.com/2009/07/14/youtube-will-be-next-to-kiss-ie6-support-goodbye/">phasing out support for it</a> – who throws a mixed content warning on SSL encrypted pages if the “src” attribute is empty, “about:blank” or simply missing.<br />
Besides that the iFrame is the most expensive html tag across all browsers in terms of <a href="http://www.stevesouders.com/blog/2009/06/03/using-iframes-sparingly/">rendering speed</a>.</p>
<p>Therefore I decided to initially put an empty html element (eg. &lt;div&gt;) into the page, which gets replaced by the application iFrame as soon as it appears in the user’s viewport.</p>
<p>The last step was not that high on the challenge scale again:  The script checks whether the iFrame is visible every 200ms, and also on resizing the window and scrolling within it. Easy stuff.</p>
<p>The really yummy part: Not only do our customers and we profit enormously from this – we reduced the OpenSocial-induced traffic by 50%, but also for coders using the JavaScript framework Prototype. We’ve released the function as a <a href="http://github.com/xing/prototype-within-viewport/" target="_blank">plugin for Prototype on GitHub</a> for you to download and embed in your projects. It adds a custom event, named &#8220;within:viewport&#8221;, which can be used like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">loadIframe <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> placeholder<span style="color: #339933;">,</span> iframe<span style="color: #339933;">;</span>
&nbsp;
  placeholder <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
  iframe <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Element<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;iframe&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    width<span style="color: #339933;">:</span> <span style="color: #CC0000;">315</span><span style="color: #339933;">,</span>
    height<span style="color: #339933;">:</span> <span style="color: #CC0000;">315</span><span style="color: #339933;">,</span>
    src<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;http://iframe-url&quot;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  placeholder.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span>iframe<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// This is where the magic happens...</span>
$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;placeholder&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">observe</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;within:viewport&quot;</span><span style="color: #339933;">,</span> loadIframe<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The plugin can also be used for other expensive operations like for instance to load large graphics only when they are visible to the user.</p>
<p><strong>Happy Hacking!</strong></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/07/i-only-believe-what-i-see-50-less-traffic/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Migrating our search from Ferret to SOLR</title>
		<link>http://blog.xing.com/2009/07/migrating-our-search-from-ferret-to-solr/</link>
		<comments>http://blog.xing.com/2009/07/migrating-our-search-from-ferret-to-solr/#comments</comments>
		<pubDate>Mon, 06 Jul 2009 09:44:48 +0000</pubDate>
		<dc:creator>Ralph von der Heyden</dc:creator>
				<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[DrB]]></category>
		<category><![CDATA[engineering]]></category>
		<category><![CDATA[Ferret]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[SOLR]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=5526</guid>
		<description><![CDATA[<p>Search is a big issue here at XING. Each day, we are processing numerous search queries, spread across events, jobs, company profiles and user search. For such a high search volume, you need rock solid technology that you can trust.&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>Search is a big issue here at XING. Each day, we are processing numerous search queries, spread across events, jobs, company profiles and user search. For such a high search volume, you need rock solid technology that you can trust. For the last two and a half years, this technology has been <a href="http://ferret.davebalmain.com/trac/">Ferret</a>.</p>
<h3>Why we chose Ferret initally</h3>
<p>Ferret was introduced when we needed a search service for <a href="https://www.xing.com/jobs/">XING Jobs</a>, which was the first part of our application using the <a href="http://rubyonrails.org/">Ruby on Rails</a> framework. At that time, Ferret was just right. As it is written in super fast C code, it became  first choice when it comes to performance. But it is also partly written in <a href="http://www.ruby-lang.org/">Ruby</a>, which allowed us to write the analyzer, query parser and tokenizer in our favorite language (oh the joy!). Ferret has served us very well until now.<span id="more-5526"></span></p>
<p>But things have changed. Over the years, we have extended the Ferret-search to <a href="https://www.xing.com/events">XING Events</a> and <a href="https://www.xing.com/companies/">Company Profiles</a>, increasing our initial search volume by magnitudes. Furthermore, the search queries created by our application became far more complex, for example using several languages in just one indexed field. This lead to scaling problems, and our experiences using a <a href="http://www.ruby-doc.org/stdlib/libdoc/drb/rdoc/index.html">DRb</a>-based (think <a href="http://en.wikipedia.org/wiki/Remote_Method_Invocation">RMI</a> for Ruby) remote interface for the search service turned out to be brittle and crash prone under certain circumstances, especially when multiple clients caused high load on the search servers. Another problem we faced was that, as a new developer it takes quite some time to become acquainted with Ferret and our implementations around it.</p>
<div style="border-top: 2px solid #e97f02; border-bottom: 2px solid #e97f02; margin: 10px 0px 10px 10px; padding-right: 2px; display: block; float: right; padding-bottom: 5px; font-family: sans-serif; font-style: italic; font-variant: normal; font-weight: normal; font-size: 18px; line-height: normal; width: 160px; padding-top: 5px; text-align: right; font-size-adjust: none; font-stretch: normal;">«We had a couple of choices: maintain ferret ourselves, find someone to do it for us &#8211; or switch.»</div>
<p>So on one of those occasions where we had to go into debugging mode deep within the DRb world, we really wished to have a simpler remote interface, maybe something like HTTP that could easily be scaled by standard means (think load balancers). On another occasion we encountered some serious memory leaks that had gone unnoticed under moderate load with simple queries. They had to be fixed by ourselves because the few official maintainers were busy with other projects or generally unavailable when we tried to reach them. Patches in their bug tracker were left untouched for months, and the official website is frequently unavailable.</p>
<p>We were left with a couple of choices: We could basically maintain ferret ourselves, find someone who would do it for us or find an alternative and switch. As you can imagine this ensured a lot of heated discussions within our engineering department, since in the end ferret was &#8220;kind of working&#8221;. As the frequency of problems increased, we chose to investigate other possibilities and technologies.</p>
<h3>Ferret-ing out alternatives</h3>
<p>One of the main lessons we learned while staying with ferret, and we learned it the hard way, was that a good search engine needs a good community of users and developers contributing. There was no such thing for Ferret. Of all the named arguments, this is the most important one. In general we think that when using an open source product, you better choose one that has a lively community around it. This guarantees that errors that were fixed by third parties will flow back into the main product, that you find experts to consult you around the world and that you can exchange knowledge on forums, wikis and conferences. So we started looking for a search service that:</p>
<ol>
<li>Was easy to scale</li>
<li>Had a &#8220;developer-friendly&#8221; interface we could hook into</li>
<li>Was actively developed and supported</li>
</ol>
<p>So we evaluated <a href="http://lucene.apache.org/solr/">SOLR</a>, which is based on the <a href="http://lucene.apache.org/">Lucene</a> information retrieval library, just like Ferret. This means the syntax for our analyzers, query parsers and tokenizers do not differ so much from what we are used to. But unlike Ferret, SOLR is a real industry standard. There are lots of maintainers, bug reporters, wiki authors, consulting companies and conference panels, so in short: There is a profound ecosystem surrounding the SOLR search engine.</p>
<div style="border-top: 2px solid #e97f02; border-bottom: 2px solid #e97f02; margin: 10px 10px 10px 0px; display: block; float: left; padding-bottom: 5px; font-family: sans-serif; font-style: italic; font-variant: normal; font-weight: normal; font-size: 18px; line-height: normal; width: 160px; padding-top: 5px; text-align: left; font-size-adjust: none; font-stretch: normal;">«We carefully watched how long it takes until a SOLR maintainter reacts on an issue in their bugtracker.»</div>
<p>We carefully watched how long it takes until a SOLR maintainer reacts to an issue created in their <a href="http://issues.apache.org/jira/browse/SOLR">JIRA bugtracker</a>, and these guys are really fast and willing to solve all incoming bugs. They include patches written by third parties in the official sources, and release new versions of their software regularly. Furthermore, as SOLR is an industry standard, we already had developers in our team that have worked with it before. And, last but not least, SOLR works over a standard HTTP interface. On the one hand, this liberates us from awkward DRb code, on the other hand this allows painless scaling with standard HTTP load balancers. Furthermore, the <a href="http://github.com/mattmatt/acts_as_solr/tree/master">acts_as_solr Rails plugin</a> makes it feel like any other Ruby library.</p>
<p>While Ferret works with Ruby only, SOLR can be used with a plethora of programming languages. So it is no wonder that our fellow perl programmers have already made the switch to SOLR about a year ago. Employing only one search engine for all parts of our application will reduce the maintenance effort in the future. The shorter training period will ensure that all of our developers (even the ones trying to avoid DRb) will be familiar with our search technology. And, beyond that, SOLR offers far more features than Ferret, like <a href="http://en.wikipedia.org/wiki/Faceted_search">faceted search</a>, allowing us to implement a more powerful and user friendly search, for example through freely filtering and ordering search results by all available dimensions.</p>
<h3>The upcoming migration</h3>
<p>The introduction of SOLR follows a very smooth migration path. First, we cleaned up our own search interface for the Rails application, which is search engine agnostic now. Then we configured SOLR to mimic the behavior of our proven and tested Ferret search engine, to have a drop in replacement. Next, we will pick a beta group out of our <a href="http://corporate.xing.com/">7 million members</a>. This is what happens next, so you might be among them.</p>
<p>Search queries of this beta group will be run by SOLR instead of Ferret to compare the quality of the results. As soon as we are sure everything works as expected, we will extend the beta group to all users gradually. At this point in time, we are ready to develop new and awesome search features with SOLR technology under the hood.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/07/migrating-our-search-from-ferret-to-solr/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Understanding the pain: Memory Leaks In Internet Explorer</title>
		<link>http://blog.xing.com/2009/06/memory_leaks_internet_explorer/</link>
		<comments>http://blog.xing.com/2009/06/memory_leaks_internet_explorer/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 09:39:24 +0000</pubDate>
		<dc:creator>Christopher Blum</dc:creator>
				<category><![CDATA[Tech Blog]]></category>
		<category><![CDATA[internet explorer]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[leaks]]></category>
		<category><![CDATA[memory]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=5059</guid>
		<description><![CDATA[<p>At our weekly frontend engineering meeting, I recently held a presentation about a common problem with the Internet Explorer that developers should put more attention on: memory leaks due to its two distinct garbage collectors. And: how to avoid them.&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>At our weekly frontend engineering meeting, I recently held a presentation about a common problem with the Internet Explorer that developers should put more attention on: memory leaks due to its two distinct garbage collectors. And: how to avoid them. So, have some <span style="font-size: x-small;">&lt;insert favourite food to be consumed while being attentive /&gt; </span>and don&#8217;t forget to imagine the other attendee&#8217;s chuckles now and then although there&#8217;s no Chuck Norris joke.</p>
<div id="__ss_1570309" style="width: 500px; text-align: left; margin-top:10px;"><object width="500" height="417" data="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=memoryleaksinie-090611164326-phpapp02&amp;stripped_title=memory-leaks-in-internet-explorer-1570309" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=memoryleaksinie-090611164326-phpapp02&amp;stripped_title=memory-leaks-in-internet-explorer-1570309" /><param name="allowfullscreen" value="true" /></object></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/06/memory_leaks_internet_explorer/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Performance improvements by using display: inline-block on the startpage</title>
		<link>http://blog.xing.com/2009/04/performance-improvements-by-using-display-inline-block-on-the-startpage/</link>
		<comments>http://blog.xing.com/2009/04/performance-improvements-by-using-display-inline-block-on-the-startpage/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 15:56:12 +0000</pubDate>
		<dc:creator>Ingo Chao</dc:creator>
				<category><![CDATA[Tech Blog]]></category>

		<guid isPermaLink="false">http://blog.xing.com/?p=4194</guid>
		<description><![CDATA[<p>by <a href="https://www.xing.com/profile/Ingo_Chao" target="_blank">Ingo Chao</a> and <a href="https://www.xing.com/profile/Christopher_Blum2" target="_blank">Christopher Blum</a></p>
<p>Our start page after logging in got faster. It takes significantly less time until the user can interact with the application.<span id="more-4194"></span></p>
<p>Before, the alignment of the start page boxes (e.g. &#8216;What&#8217;s new in my network&#8217;, &#8216;Visitors to&#8230;</p>]]></description>
			<content:encoded><![CDATA[<p>by <a href="https://www.xing.com/profile/Ingo_Chao" target="_blank">Ingo Chao</a> and <a href="https://www.xing.com/profile/Christopher_Blum2" target="_blank">Christopher Blum</a></p>
<p>Our start page after logging in got faster. It takes significantly less time until the user can interact with the application.<span id="more-4194"></span></p>
<p>Before, the alignment of the start page boxes (e.g. &#8216;What&#8217;s new in my network&#8217;, &#8216;Visitors to my profile&#8217;) was calculated via JavaScript, a time-consuming task. Since drag and drop of the boxes always causes a reflow,  any new combination of boxes implied a re-calculation.</p>
<p>This was acceptable until the new feature boxes required the ability to self-adjust in dimension. The idle time while waiting for the content to render plus the calculation of the alignment could, depending on the browser&#8217;s JavaScript engine, easily have taken a few seconds or more, especially in Internet Explorer.</p>
<p>We now use the CSS 2.1 property display: inline-block for these boxes (and some hacks for Firefox 2 and Internet Explorer &lt; 8 that do not support this property). Inline-block is a CSS-concept of blocks that form &#8216;lines&#8217; (in CSS-terms: line-boxes), similar to what single words in a text do. Even if a word is taller, the line contains all the words.</p>
<p>The browser flows the resulting lines of boxes into a vertical stack. The start page, even if a reflow occurs, self-aligns by pure CSS. In fact the old JavaScript solution tried to re-engineer the behavior of inline-blocks. Still, drag and drop requires Scriptaculous&#8217; JavaScript methods, but not the alignment, which is time-critical for frontend performance and user experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.xing.com/2009/04/performance-improvements-by-using-display-inline-block-on-the-startpage/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
