<?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>Blog &#124; Confiz Solutions</title>
	<atom:link href="http://www.confiz.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.confiz.com/blog</link>
	<description>Just another WordPress weblog</description>
	<lastBuildDate>Tue, 06 Mar 2012 08:40:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.4</generator>
		<item>
		<title>Got the bucks for Heroku?</title>
		<link>http://www.confiz.com/blog/uncategorized/got-the-bucks-for-heroku/</link>
		<comments>http://www.confiz.com/blog/uncategorized/got-the-bucks-for-heroku/#comments</comments>
		<pubDate>Tue, 06 Mar 2012 08:24:04 +0000</pubDate>
		<dc:creator>ahsan.saleem</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=152</guid>
		<description><![CDATA[We are hosting one of our loaded Ruby applications on Heroku for last 4 months. We like it! But it does affect the wallet. We currently use 10 web dynos and 6 background workers costing us about $500 for just the application layer. Considering high performance of Heroku dynos, its quite good. However, Heroku&#8217;s dedicated [...]]]></description>
			<content:encoded><![CDATA[<p>We are hosting one of our loaded Ruby applications on Heroku for last 4 months. We like it! But it does affect the wallet. </p>
<p>We currently use 10 web dynos and 6 background workers costing us about $500 for just the application layer. Considering high performance of Heroku dynos, its quite good. However, Heroku&#8217;s dedicated DB plans are not that sweet of a story. Minimum offering is $200 Ronin which comes with 1 compute unit and only 1.7 GB of RAM. For any Database of considerable size, that&#8217;s nothing. Our DB holds about 20 Million records and approximate 6/7 queries hitting it at any second. We started to see wait times on Ronin and our end user were not happy.</p>
<p>To alleviate the pain for our users, we updated the DB plan to Fugu ($400) considering the fact that it has 5x more compute units. That did us NO good. Investigation revealed that if your queries are less in number but high in arithmetic (lots of count, max, min etc) than this plan suits you but for high query frequency you need IKA plan for a decent start. And guess what; this plans cost $800!</p>
<p>Heroku while being expensive is not all bad. The ease of use via web console and Heroku command line is great. Do note that you can scale the application layer in seconds but for DB, you have to take an outage and export your DB to a bigger plan &#8211; so no quick scaling for DB layer.</p>
<p>Customer service was OK. Response time is quick but we only got superficial response times for the most part while investigating scaling issues. Finally we signed up New Relic Pro to our app (additionally costing us $30 a day)</p>
<p>My advice is carefully choose Heroku if you got the buck! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/uncategorized/got-the-bucks-for-heroku/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Sustian Mobile Apps (A Technical Perspective)</title>
		<link>http://www.confiz.com/blog/uncategorized/how-to-sustian-mobile-apps-a-technical-perspective/</link>
		<comments>http://www.confiz.com/blog/uncategorized/how-to-sustian-mobile-apps-a-technical-perspective/#comments</comments>
		<pubDate>Mon, 05 Mar 2012 12:19:21 +0000</pubDate>
		<dc:creator>ahsan.saleem</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=149</guid>
		<description><![CDATA[As the title suggests, following thoughts focus on sustaining successful delivery and evolution of mobile apps especially from a technical manager&#8217;s perspective. We, at Confiz, recently launched a successful program of mobile apps on different platforms. The program consisted of A/V messaging app (iOS, Android, Web and Server) and Media app (iOS, Android and Server). [...]]]></description>
			<content:encoded><![CDATA[<p>As the title suggests, following thoughts focus on sustaining successful delivery and evolution of mobile apps especially from a technical manager&#8217;s perspective. We, at Confiz, recently launched a successful program of mobile apps on different platforms. The program consisted of A/V messaging app (iOS, Android, Web and Server) and Media app (iOS, Android and Server). The apps cleared beta period (of about 2 months) and entered production phase 3 months ago. We had and are still having and exciting run with these apps &#8211; as we are still evolving the apps in terms of features and growing user base. There were some lessons nonetheless:</p>
<p><em>1) Bugs are nasty &#8211; keep an eye on them</em></p>
<p>Like any piece of software mobile apps whether iOS or Android, are prone to software bugs. Mobile apps are usually thick clients with a few megabytes of code running on a client handset and throwing exceptions daily. Its important to catch them over the network and compare the severity and quantity of exceptions over builds. A very useful service is <a href="http://www.bugsense.com" target="_blank">BugSense </a>who hooks into your iOS compiler and Android JVM, and records all handled and unhandled (fatal/crashes) exceptions over the network. To save network data, you can optimize recording of bugs by putting a delay and bulk recording of exceptions. BugSense provides detail information along exception trace like application number, hardware and OS etc. A great internal test cycle and unit test habits are important but I have found non-technical user possessing magical powers to produce scenarios and errors that techies miss out while testing.</p>
<p><em>2) Versioning</em></p>
<p>iTunes and Android MarketPlace make it pretty simple to version mobile apps. You can release a new version via iTunes or market and user gets the notification however what you can not do via iTunes or market is &#8216;force&#8217; an update to client device. For example, on a Halloween, you accidentally published an app that messed up user data or had some other critical bug. Your day just got scarier! You can release a fixed version again but there is a propagation delay (sometimes 4-5 hours on Android market). We worked around the problem by building a simple yet robust versioning system within our apps. Its all about keeping a version number within build plus creating a web service on server side to check the version. With a simple boolean flag you can block an application from further usage only to prevent further destruction of user data and love for your app.</p>
<p><em>3) Testing of Apps</em></p>
<p>This is the most exciting part. As discussed above, once a bad build is shipped then its impossible to retrieve. So you really have to test the apps thoroughly before shipping. Unfortunately, automated testing of mobile apps is not as simple as automated web site testing. There aren&#8217;t any tools available &#8211; if there are then they are expensive. Also you need a testing team which can write pretty good code to &#8216;auto-test&#8217; the app.</p>
<p>Another challenge is diversity of Android handsets which will drive you crazy. Almost every manufacturer manipulates the Android Kernel and as a result some feature of your app stops working. Its impossible to buy all handsets. Possible options are limiting the handsets to 8-10 famous sets or buy a slightly expensive <a href="http://www.deviceanywhere.com" target="_blank">Device AnyWhere</a> account (costs around $3000 as a starter). Its quite slow though but they have most sets available for remote testing.</p>
<p><em>4) Network Response (3G and Wifi)<br />
</em></p>
<p>Application experience changes drastically because of network and data speed. If you only test on Wifi, you will never know how your application behaves on cellular data which is slower. Testing on a slower network also implies you to really think about use of network in your app and optimizing it. It is also important to build in your app handy messages to educate user when network slowness is frustrating user. ideally if there isn&#8217;t a response in 7-10 sec, user should know why and in a  simple language (not HTTP error code language)</p>
<p><em>e) User Feedback</em></p>
<p>We have found it handy to build a quick and simple Feedback feature with in your app. While user can leave comments on iTunes and Market but they take time. User will log in to market and leave a message. While a quick button on your app that populates the feedback screen can let user encourage or scare you with in seconds. With a simple integration within your server you can put a dashboard to list the feedback. Ont tip: always log users hardware, app version and OS to stay on top of issues.</p>
<p>thanks</p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/uncategorized/how-to-sustian-mobile-apps-a-technical-perspective/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beta OTA Distribution of Android Apps</title>
		<link>http://www.confiz.com/blog/uncategorized/beta-ota-distribution-of-android-apps/</link>
		<comments>http://www.confiz.com/blog/uncategorized/beta-ota-distribution-of-android-apps/#comments</comments>
		<pubDate>Tue, 27 Dec 2011 13:10:48 +0000</pubDate>
		<dc:creator>ahsan.saleem</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=143</guid>
		<description><![CDATA[An interesting discovery by our engineer Mateen. Android marketplace does not provide a mechanism to ship a beta or test version of Android apps. So alternatively you can email the apk to users which is not most efficient. A better solution is to setup a webpage or a hockeykit instance. In case you decide to [...]]]></description>
			<content:encoded><![CDATA[<p>An interesting discovery by our engineer Mateen.</p>
<p>Android marketplace does not provide a mechanism to ship a beta or test version of Android apps. So alternatively you can email the apk to users which is not most efficient. A better solution is to setup a webpage or a <a href="http://hockeykit.net/index.html" target="_blank">hockeykit </a>instance.</p>
<p>In case you decide to build your own webpage, the simple anchor &lt;a&gt; link will not allow the download of app to Android handsets. You need to alter the anchor tag:</p>
<p>&lt;a href=&#8221;downloads/my_apk.apk&#8221; <strong>type=&#8221;application/vnd.android.package-archive&#8221;</strong>&gt;Download App&lt;/a&gt;</p>
<p>Also you need to check &#8216;Allow untrusted sources&#8217; under Settings-&gt;Manage Applications on your Android handset to install a non-market apk</p>
<p>happy holidays!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/uncategorized/beta-ota-distribution-of-android-apps/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Selecting the Right Cloud Platform</title>
		<link>http://www.confiz.com/blog/tech-session/selecting-the-right-cloud-platform/</link>
		<comments>http://www.confiz.com/blog/tech-session/selecting-the-right-cloud-platform/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 12:14:28 +0000</pubDate>
		<dc:creator>ahsan.saleem</dc:creator>
				<category><![CDATA[Tech Session]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[Heroku]]></category>
		<category><![CDATA[PAAS]]></category>
		<category><![CDATA[Xeround]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=126</guid>
		<description><![CDATA[While the array of cloud platforms (Platform as service) has increased significantly recently, its still a hard job to find the perfect host for your website. The obvious advantages of cloud platforms over dedicated servers start with cost and extend to ease of maintenance. For instance, on EC2 it takes about 30 min or less [...]]]></description>
			<content:encoded><![CDATA[<p>While the array of cloud platforms (<a href="http://" target="_blank">Platform as service</a>) has increased significantly recently, its still a hard job to find the perfect host for your website. The obvious advantages of cloud platforms over dedicated servers start with cost and extend to ease of maintenance. For instance, on EC2 it takes about 30 min or less to fire a new server instance and the Amazon&#8217;s ability to charge its customer on per hour basis, makes<a href="http://" target="_blank"> EC2</a><a href="aws.amazon.com/ec2/"> </a>a very attractive option. <a href="aws.amazon.com/autoscaling/" target="_blank">AutoScale </a>is another great add-on to EC2 platform and lets the consumer automate the computing power usage based on user load.</p>
<p>We recently did an extended research on available cloud platforms for a client. The requirements were however no straight forward. Client&#8217;s top priorities were ability of platform to scale automatically, ease of maintenance, and performance of infrastructure. Then, to make the task challenging and exciting, the client wanted a geographical fail-over ability in case of a disaster. Amazon alone had 2 major <a href="http://www.pcworld.com/article/225877/amazon_outage_crashes_reddit_quora_and_other_websites.html" target="_blank">outages</a> in year 2011 so users are quite concern about business continuity in time of a disaster.</p>
<p>We evaluated many options starting from Amzon EC2, RDS, <a href="www.heroku.com">Heroku</a>, Bluebox, RackSpace, High Velocity, <a href="xeround.com" target="_blank">Xeround </a>etc and concluded that only one provider will not be able to answer all questions from our client. So we divided the architecture into App layer and DB layer and choose different hosts for each layer. In such a division the biggest concern is network latency but interesting fact is most cloud platforms are built over EC2 with additional wrapping so within EC2 network latency is not huge at all. We ran some test with Heroku (app) and Xeround (DB) and found network latency to be less than half a sec per transaction.</p>
<p>You can find below a presentation we put together after our analysis of different cloud hosts. There is a slide that links to a Google spreadsheet with calculation of estimated cost for our proposed infrastructure. Feel free to drop a comment to correct me or ask me</p>
<p>Presentation:
<div style="width:425px"> <strong><a href="http://www.slideshare.net/asaleem81/selecting-the-right-cloud-host" title="Selecting the Right Cloud Host" target="_blank">Selecting the Right Cloud Host</a></strong>  </div>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/tech-session/selecting-the-right-cloud-platform/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Kung-fu Chop To The Load Best &#8211; Part Deux</title>
		<link>http://www.confiz.com/blog/tech-session/kung-fu-chop-to-the-load-best-part-deux/</link>
		<comments>http://www.confiz.com/blog/tech-session/kung-fu-chop-to-the-load-best-part-deux/#comments</comments>
		<pubDate>Mon, 22 Aug 2011 12:40:45 +0000</pubDate>
		<dc:creator>ahsan.saleem</dc:creator>
				<category><![CDATA[Tech Session]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[performance tuning]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=95</guid>
		<description><![CDATA[This is part II of my post on load testing for a server side solution. Part 1 discussed an overall strategy and importance of running organized load testing. Here I will discuss some tips that helped us scale our Ruby app to bear a load of 50TPS+ on a Large amazon EC2 instance. You can [...]]]></description>
			<content:encoded><![CDATA[<p>This is part II of my <a href="http://www.confiz.com/blog/?p=91">post</a> on load testing for a server side solution. Part 1 discussed an overall strategy and importance of running organized load testing. Here I will discuss some tips that helped us scale our Ruby app to bear a load of 50TPS+ on a Large amazon EC2 instance. You can find part 1 to my post <a title="here" href="http://www.confiz.com/blog/?p=91" target="_blank">here<br />
</a></p>
<p>An mentioned in part 1 of the post, this information is by no means exhaustive but to server as a guide line for performance tuning.</p>
<p><strong>Load Test Simulator</strong></p>
<p>We used a very simply and handy tool, <a href="http://jakarta.apache.org/jmeter/" target="_blank">JMeter</a>, to simulate load on our server. It gives nice flexibility in terms of setting up request load (multiple threads) and we can also configure data pool to diversify payload. The load tests can be scheduled or setup for fixed time. The results are real time and quantitative (no charts or graphics though). Attached a couple of sample screen shots from JMeter that demonstrate thread settings and real time results of a sample load test</p>
<p><a href="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter11.png"><img class="alignnone size-medium wp-image-108" src="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter11-300x168.png" alt="" width="300" height="168" /></a></p>
<p><a href="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter22.png"><img class="alignnone size-medium wp-image-109" src="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter22-300x66.png" alt="" width="300" height="66" /></a></p>
<p><strong>Some Cheeky Moves that Enhance Performance</strong></p>
<p><em>In Memory Processing is a Blessing: </em>Processing (calculation, comparison, searching is much much faster in memory than on disk. Though MySQL comes with native SQLCache (read <a href="http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html" target="_blank">here</a>). Other options such as <a href="http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html">Memcache</a> are also available that give user more control on caching policies<a href="http://dev.mysql.com/doc/refman/5.1/en/query-cache-operation.html"><br />
</a></p>
<p><em>Group Process Database Requests</em>: A common programming practice is to programatically loop DB inserts. For large data sets this becomes quite a performance bottleneck because of a separate DB transaction being initiated every time (new connection, new statement object, new commit every iteration). This bottleneck can we avoided by using a group insert e.g.: insert into _table  (col1, col 2) values (&#8216;val1&#8242; , &#8216;val2&#8242;), (&#8216;val3&#8242;,&#8217;val4&#8242;) , (&#8216;val5&#8242;,&#8217;val6&#8242;) &#8230;..</p>
<p><em>Move Independent Processing to Background: </em>In our experience quite some processing (like firing emails, PUSH, or updating OLAP schemas) can be moved to background to run independently using a good background processing solution. The one we used was <a href="http://rubygems.org/gems/resque" target="_blank">Recue</a>. It uses Redis to create a namespace and is quite efficient</p>
<p><em>:include is faster than JOIN:</em> take a look at http://stackoverflow.com/questions/1208636/rails-include-vs-joins</p>
<p><strong>Calibrating App Server and DB Threads</strong></p>
<p>A normal processing sequence of a request landing on a server is : HTTP Server -&gt; Interpreter/Compiler -&gt; DB</p>
<p>Modern day Web, application an DB servers come with configurations to increase or decrease thread counts. More threads mean more parallel processing BUT more system resource requirement as well so its very important to:</p>
<p>a) Set the number of threads for each server layer that does not burn out your CPU and Memory, OR does not use CPU and memory at all</p>
<p>b) Keep a balanced ratio between server layers. If Application server threads are too many and DB threads are too low then most of the time application server threads will be hitting DB asking for a connection and producing load that does not help user</p>
<p><em>Apache Server Threads</em></p>
<p>Apacher server config can be calibrated to set an optimal value for <a href="http://httpd.apache.org/docs/2.0/mod/mpm_common.html#maxclients" target="_blank">MaxClients</a> which represents the simultaneous requests the apache server will handle. At any time apache threads can be viewed by hitting http://your-server/server-status. A sample snapshot follows:</p>
<p><a href="http://www.confiz.com/blog/wp-content/uploads/2011/08/apache1.png"><img class="alignnone size-medium wp-image-113" src="http://www.confiz.com/blog/wp-content/uploads/2011/08/apache1-300x111.png" alt="" width="300" height="111" /></a></p>
<p><em>MySQL Threads</em></p>
<p>MySQL uses a thread based client connection model. The more the connections, higher will be load on MySQL and system hardware resources. Read <a href="http://dev.mysql.com/doc/refman/5.0/en/connection-threads.html">more</a></p>
<p><strong>Monitor Your Load Tests</strong></p>
<p>Load tests are as good as the results deduced from them. The results should at the minimum record the following:</p>
<p>a) System Throughput (No of requests going in per sec VS number of  requests completed per sec) &#8211; we used JMeter for this purpose</p>
<p>Screenshot: <a href="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter23.png"><img class="alignnone size-medium wp-image-115" src="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter23-300x66.png" alt="" width="300" height="66" /></a></p>
<p>b) System Response Time (Time to entertain single request. There is no point of taking a load too high and keep user waiting for a response) &#8211; we used JMeter to record System response time</p>
<p>Screenshot: <a href="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter3.png"><img class="alignnone size-medium wp-image-116" src="http://www.confiz.com/blog/wp-content/uploads/2011/08/JMeter3-300x66.png" alt="" width="300" height="66" /></a></p>
<p>c) Server Hardware Status (CPU, memory, Disk-Swap are the most important in my opinion) &#8211; we used <a href="mmonit.com/monit/">monit</a> for this purpose</p>
<p>Screenshot: <a href="http://www.confiz.com/blog/wp-content/uploads/2011/08/monit1.png"><img class="alignnone size-medium wp-image-120" src="http://www.confiz.com/blog/wp-content/uploads/2011/08/monit1-300x265.png" alt="" width="300" height="265" /></a></p>
<p>Have fun optimizing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/tech-session/kung-fu-chop-to-the-load-best-part-deux/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kung-Fu Chop To the Load Beast &#8211; Part I</title>
		<link>http://www.confiz.com/blog/tech-session/kung-fu-chop-to-the-load-beast-part-i/</link>
		<comments>http://www.confiz.com/blog/tech-session/kung-fu-chop-to-the-load-beast-part-i/#comments</comments>
		<pubDate>Thu, 07 Jul 2011 10:51:53 +0000</pubDate>
		<dc:creator>ahsan.saleem</dc:creator>
				<category><![CDATA[Tech Session]]></category>
		<category><![CDATA[Load Testing]]></category>
		<category><![CDATA[Optimization]]></category>
		<category><![CDATA[Scaling]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=91</guid>
		<description><![CDATA[A common goal every website or online service provider share is to have maximum visitors or server hits possible. That, of course, does not include  spam or denial-of-service attack on the server. While more traffic or hits means more business, it also generates the need to ensure the scalability and load capacity of the server. [...]]]></description>
			<content:encoded><![CDATA[<p>A common goal every website or online service provider share is to  have maximum visitors or server hits possible. That, of course, does not  include  spam or denial-of-service attack  on the server. While more traffic or hits means more business, it  also generates the need to ensure the scalability and load capacity of  the server. Interestingly, most engineers haste in order to test the  load capacity of the server and put tons of loads the very first day and  expect to see great results. Guess what? the server either gets  non-responsive (meaning probably crashed) or it did take the load but  the engineer did not know they over-killed the hardware and received a  shockingly high server invoice at end of month.</p>
<p>Clearly one nor want too small a server muscle, neither too big and  expensive of a server. To look eye-to-eye with the load creep, there is  need of a strategy. Here is part I of my kung-fu attempt to chop it  down. I would like to keep it high level and at a strategic level. In  part II I will discuss specific details of</p>
<div><a href="https://sites.google.com/a/confiz.com/ahsan-saleem/home/kung-fu-chop-to-the-load-beast/Kung%20Fu%20Panda%20%287%29.jpg?attredirects=0"><img class="alignright" style="border: 0pt none" src="https://sites.google.com/a/confiz.com/ahsan-saleem/_/rsrc/1310023563090/home/kung-fu-chop-to-the-load-beast/Kung%20Fu%20Panda%20%287%29.jpg?height=160&amp;width=200" border="0" alt="" width="200" height="160" /></a></div>
<p>our recent optimization exercise on Rails. I must  disclaim that server tuning or optimization is a big topic with tons of  material available and what follows is my experience working with load  testing and optimization of a Ruby on Rails server for a messaging  engine project.</p>
<p><strong>Before You Start Optimizing and Scaling</strong>:</p>
<p>a) Size the Beast: Estimate your target load on server. I prefer a  number like transactions per min rather than transactions per second.  Per seconds is much smaller a number when you have heavy processing and a  normal transaction spans over a few seconds. It is also important to  clearly define what a transaction means in your system, does a single  DB hit counts for a transaction or entertaining a user request end-end  counts for a transaction?</p>
<p>b) Benchmark Response Times: The goal of optimization and scaling  should not be solely handling more load on the server, but also serving  requests within a decent response time. A server handling tons of loads  but keeping the user waiting for longer period will soon put the CEO out  of business</p>
<p>c) Choose an appropriate load generation mechanism: This could be a free tool like <a href="http://www.google.com/url?q=http%3A%2F%2Fjakarta.apache.org%2Fjmeter%2F&amp;sa=D&amp;sntz=1&amp;usg=AFrqEze1xzWnxuxlkJeX4xwEkc-wzz7T6Q" target="_blank">JMeter </a>or <a href="http://www.google.com/url?q=http%3A%2F%2Fwww.soapui.org%2F&amp;sa=D&amp;sntz=1&amp;usg=AFrqEzf-tj1lngBJLYQv20yl2uIQ5BNOZA" target="_blank">SOAPUI </a>who  can can create massive HTTP hits on the server. The flexibility these  tools provide is quite nice ranging from configuring exact load to put  on server using multi-threading and ability to attach a data pool to  vary request data. You can also write your own code to generate a load  if the request structure is complex. In our case, we used both.</p>
<p><strong>Places to look for Optimization</strong>:</p>
<p>a) Starting with code optimizations. Hotspots are DB calls, third  party web service calls and parsing large JSONs, XMLs etc. I have  experienced that using an async approach of DB writing and JSON/XML  parsing (wherever possible) greatly improves system performance and user  experience. We optimized one of our routines by 800% using asynchronous DB writing</p>
<p>b) Application server threads: Application server request threads  should always maintain appropriate ratio with hardware muscle. You don&#8217;t   want to do too much or too less parallel request handling on application  server. Too much will lead to CPU or Memory starvation and too less  means you have getting an oversize server invoice month end. With out  pretty standard request size, we have enabled 50 maxClients for Apache  on standard EC2 XLarge instance and hitting about 50% of CPU capacity</p>
<p>c) Caching: Caching saves us from disk and notwork latency by reusing  already fetched data. Caching is also available at multiple levels  starting from Web serer caching, SQL caching provided by standard RDBMS  and third party caching such as <a href="http://www.google.com/url?q=http%3A%2F%2Fmemcached.org%2F&amp;sa=D&amp;sntz=1&amp;usg=AFrqEzd8xGifuqVppAG9Q_Gexy_OPk9c0w" target="_blank">Memcached</a></p>
<p>d)  DB Indexing: This is not something super latest or cutting-edge and has  been in use for a while, but, there is a catch. Normally we create DB  indexes on tables whom we hit the most in searching etc. However, if  there are massive CUD operation (Create, Update and Delete) on the table  as well then indexes will really slow them down because it updates the  B-trees every time</p>
<p><strong>Guide Yourself in Load Testing</strong>:</p>
<p>a) A cyclic approach is  what works. Run more than one tests while recording them. I have found  it useful to create a simple spreadsheet that records details and  results of every test run. I suggest to record basic information like  hardware profile, change in settings/hardware from previous test, load  put on server, throughput of the server, exceptions/crashed, and  duration of test</p>
<p>b) Its important to bring one change at a time to the system &#8211; let it be DB index, <a href="http://www.google.com/url?q=http%3A%2F%2Fmemcached.org%2F&amp;sa=D&amp;sntz=1&amp;usg=AFrqEzd8xGifuqVppAG9Q_Gexy_OPk9c0w" target="_blank">memcached</a>,  or more memory attached to the system If we bring more than one changes  to the system for test run then it will be hard to determine the  adverse or positive affect of a change independently</p>
<p>c) Profile your system: We recorded following information during the tests. CPU, memory and disk usage using <a href="http://www.google.com/url?q=http%3A%2F%2Fmunin-monitoring.org%2F&amp;sa=D&amp;sntz=1&amp;usg=AFrqEzfNdJplIGHu4VLYyrUQQYdpgnbP1w" target="_blank">Munin</a>, system throughput using <a href="http://www.google.com/url?q=http%3A%2F%2Fnewrelic.com%2F&amp;sa=D&amp;sntz=1&amp;usg=AFrqEzfojPiqhjnTjZWO3zHrAXtX-hnwJA" target="_blank">NewRelic</a> and system response times using <a href="http://www.google.com/url?q=http%3A%2F%2Fjakarta.apache.org%2Fjmeter%2F&amp;sa=D&amp;sntz=1&amp;usg=AFrqEze1xzWnxuxlkJeX4xwEkc-wzz7T6Q" target="_blank">JMeter</a></p>
<p>c)  Do not forget longevity tests: While we run many short duration tests  it is important to run 10 hour or a day long tests as well to figure out  if there are any dormant memory leaks that might crash the system in a  few days time</p>
<p>Below is my attempt to picture the optimization process in a simple flow chart:</p>
<div><a href="https://sites.google.com/a/confiz.com/ahsan-saleem/home/kung-fu-chop-to-the-load-beast/load%20test.jpg?attredirects=0"><img src="https://sites.google.com/a/confiz.com/ahsan-saleem/_/rsrc/1310024960893/home/kung-fu-chop-to-the-load-beast/load%20test.jpg?height=300&amp;width=400" border="0" alt="" width="400" height="300" /></a></div>
<p>In part II I will discuss specifics of our recent load testing exercise on Rails</p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/tech-session/kung-fu-chop-to-the-load-beast-part-i/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Is All About SOA!</title>
		<link>http://www.confiz.com/blog/uncategorized/is-all-about-soa/</link>
		<comments>http://www.confiz.com/blog/uncategorized/is-all-about-soa/#comments</comments>
		<pubDate>Thu, 30 Jun 2011 10:43:33 +0000</pubDate>
		<dc:creator>ahsan.saleem</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[encoding.com]]></category>
		<category><![CDATA[SAAS]]></category>
		<category><![CDATA[SOA]]></category>
		<category><![CDATA[UrbanAirship.com]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=88</guid>
		<description><![CDATA[If you recall the online/offline debates 5-6 years back when SOA (Service Oriented Architecture) was the buzzword around Silicon Valley, at least I were of the opinion that SOA was more of a marketing gimmick than a technology leap. Most of the money marketing SOA was put by tech giants like IBM, Microsoft, TIBCO, Amazon [...]]]></description>
			<content:encoded><![CDATA[<p>If you recall the online/offline debates 5-6 years back when SOA  (Service Oriented Architecture) was the buzzword around Silicon Valley,  at least I were of the opinion that SOA was more of a marketing gimmick  than a technology leap. Most of the money marketing SOA was put by tech  giants like IBM, Microsoft, TIBCO, Amazon etc. Though I still believe  that SOA classifies as a philosophy of Software Architecturing, am I  becoming a fan every passing day. I remember the first lesson of  programming I had twelve years back &#8216;not to re-invent the wheel&#8217;. SOA is  a perfect example of why &#8216;reusing the wheel&#8217; is a great idea,  engineering-wise and business-wise.</p>
<p>We were recently challenged at work to design and develop a next  generation multi-media messaging system for a fortune corporate. The  requirements were very interesting. Starting with cross platform support  i.e. iPhone, Andriod, BB, WP7 and Web, the system was also required to  record live audio and video and send as real-time attachments. The  diaspora of media support in different mobile platforms is quite big thus the need of inter-format media encoding.  Additional features were PUSH notifications upon message receive, and  coupling with client&#8217;s proprietary LDAP. We planned a stage-wise release that is starting from a group of hundred users to  acceptance-test the system, we targetted a 2nd release to 10K users and  then eventually to full scale i.e. 30K users. the anticipated load on  the system was 30 TPS resulting from 4-5 new message check calls from  every user per second.</p>
<p>During the design phase of the system, we faced the question of  choosing between non-SOA approach (do-it-yourself) versus a services  based architecture for features like media encoding, PUSH messages and  file storage. Though the decision of not doing-it-yourself means lesser  control, lesser customization, dependency on a third company but thanks  to SOA buzz created many years ago, plenty of smart people have founded  SAAS companies that cater to most users needs of media encoding, storage  and notifications. So our engineering team and client decided smartly  and chose the SOA approach. We evaluated different options and settled  with Encoding.com for media encoding, UrbanAship for notifications and S3  for media storage. One of the reason of choosing Encoding.com was its  capability of solid integration with S3 storage.</p>
<p>The decision of  following an SOA approach helped us in many ways. First and far-most we  saved so much time. Rather setting up our own server for solutions like  ffmpeg and then handling scaling and reliability, we shipped all the  media encoding burden on encoding.com&#8217;s shoulders. Although they do have some  scalability and video rotation issues but overall they have solid  services to offer. PUSH notifications are generally not fully relied upon, but UrbanAship  has been pretty solid delivering notifications. As I think of the time  and effort we have saved in building our next generation messaging  system by choosing an SOA architecture, its quite amazing. Not tp  mention the savings in cost of development for the client!</p>
<p>As we  move forward and add new interesting features to our system, we want to  build upon the already &#8216;handy&#8217; SOA architecture. Our next targets are addition of great Analytics for system usage. We have boiled down the list  of available services to Google Analytics and Flurry. The  range of analysis provided by both are quite interesting and we are  inclined to  use one of these SAAS providers than building our own analytics  solution.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/uncategorized/is-all-about-soa/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Starling Queue over Unix Socket</title>
		<link>http://www.confiz.com/blog/tech-session/starling-queue-over-unix-socket/</link>
		<comments>http://www.confiz.com/blog/tech-session/starling-queue-over-unix-socket/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 14:26:36 +0000</pubDate>
		<dc:creator>Hisham Malik</dc:creator>
				<category><![CDATA[Tech Session]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[EventMachine]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[starling]]></category>
		<category><![CDATA[TCP]]></category>
		<category><![CDATA[Unix Socket]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=70</guid>
		<description><![CDATA[Now that we have a memcache-client that uses Unix sockets instead of TCP socket, we automagically have the starling client that is capable of communication of unix sockets by simply doing the requiring &#8216;memcache_extensions.rb&#8217; before creating the starling client. However, while Starling uses the memcache protocol, the Starling server itself only provides option to listen [...]]]></description>
			<content:encoded><![CDATA[<p>Now that we have a <a href="http://www.confiz.com/blog/tech-session/ruby-memcache-client-using-unix-sockets/">memcache-client</a> that uses Unix sockets instead of TCP socket, we automagically have the starling client that is capable of communication of unix sockets by simply doing the requiring &#8216;memcache_extensions.rb&#8217; before creating the starling client. However, while <a href="http://github.com/starling/starling/">Starling</a> uses the memcache protocol, the <a href="http://github.com/starling/starling/">Starling</a> server itself only provides option to listen on a TCP socket. <span id="more-70"></span>A quick look under the hood reveals that Starling server itself uses <a href="http://rubyeventmachine.com/">EventMachine</a> which provides supports both TCP and Unix-domain servers. The <a href="http://rubyeventmachine.com/">EventMachine</a> starts up TCP server if a port is specified and assumes a Unix-domain Server, if the port is nil. So enabling Starling over Unix socket, simply becomes a matter of passing nil as &#8216;port&#8217; to the <a href="http://rubyeventmachine.com/">EventMachine</a> object and specifying the unix socket to use in the &#8216;host&#8217; parameter.</p>
<p>To implement this in a graceful and backward compatible fashion, we added &#8216;-s&lt;SOCKET&gt;&#8217; and &#8216;&#8211;socket &lt;SOCKET&gt;&#8217; option to the <a href="http://github.com/starling/starling/">Starling</a> server by overriding some of its function documented in <a href="http://www.confiz.com/blog/wp-content/uploads/2010/11/starling_extension.rb_.zip">simobo_extensions.rb</a>.</p>
<p>To run this modified <a href="http://github.com/starling/starling/">Starling</a> server, we need to created a ruby script along the same lines as the original starling script to run the server but use the overridden functionality before creating the <a href="http://github.com/starling/starling/">Starling</a> server object.</p>
<pre style="padding-left: 30px">#!/usr/bin/env ruby

require 'rubygems'#  unless ENV['NO_RUBYGEMS']
require 'starling'

curr_dir = File.dirname(__FILE__)
require File.join(curr_dir, '../lib/extensions/starling_extension.rb')

StarlingServer::Runner.run
</pre>
<p>The above script assume that the new starling script is in &#8216;scripts&#8217; folder and the starling extension is in &#8216;lib/extensions&#8217; folder, relative to the Rails application root. Now to start the starling server, all that is required is to call the script passing in the socket file to use:</p>
<pre style="padding-left: 30px">ruby script/starling -s /tmp/starling.sock
</pre>
<p><a href="http://www.confiz.com/blog/wp-content/uploads/2010/11/starling_extension.rb_1.zip">Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/tech-session/starling-queue-over-unix-socket/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Ruby Memcache Client using Unix Sockets</title>
		<link>http://www.confiz.com/blog/tech-session/ruby-memcache-client-using-unix-sockets/</link>
		<comments>http://www.confiz.com/blog/tech-session/ruby-memcache-client-using-unix-sockets/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 12:40:21 +0000</pubDate>
		<dc:creator>Hisham Malik</dc:creator>
				<category><![CDATA[Tech Session]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[TCP socket]]></category>
		<category><![CDATA[Unix Socket]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=62</guid>
		<description><![CDATA[Using TCP sockets provides portability and location independence, there is an inherent overhead on performance due to TCP headers, checksum, flow control, and marshalling/unmarshalling of data packets. On Unix machines, this overhead can be avoided through use of Unix domain sockets resulting in performance gains. Memcache server supports unix sockets, but the existing memcache clients [...]]]></description>
			<content:encoded><![CDATA[<p>Using TCP sockets provides portability and location independence, there  is an inherent overhead on performance due to TCP headers, checksum,  flow control, and marshalling/unmarshalling of data packets. On Unix  machines, this overhead can be avoided through use of Unix domain  sockets resulting in performance gains.</p>
<p>Memcache server supports unix sockets, but the existing memcache clients available for Ruby only support TCP sockets. <span id="more-62"></span>Our aim was to integrate it with existing memcache client implementation in such a way that both flavors can be used with little change in existing memcache configurations. For that purpose, we simply introduced an &#8216;is_socket&#8217; flag and used the existing &#8216;servers&#8217; parameters to specify the unix socket location or tcp server address.</p>
<p>First, we install the <a href="http://github.com/mperham/memcache-client">memcache-client</a> gem and download <a href="../wp-content/uploads/2010/11/memcache_extension.rb_.zip">memcache_extension.rb</a> file containing the overridden functions of the client to support Unix sockets. The <a href="../wp-content/uploads/2010/11/memcache_extension.rb_.zip">memcache_extension.rb</a> file should be placed in an appropriate directory (lib perhaps), in your application, so that anytime we need to use the modified memcache client code, we insert the statement</p>
<pre>require "memcache_extension.rb"</pre>
<p>before creating a memcache client.</p>
<p>Also by default, the Memcache client uses tcp socket, and any overrides are picked up from memcache.yml file. So in order to activate the unix socket, we will need to add the following lines to the memcache.yml file:</p>
<pre style="padding-left: 30px">servers: /tmp/memcached.sock
is_socket: true</pre>
<p>Finally, ensure that memcached server is listening on the unix socket:</p>
<pre style="padding-left: 30px">memcached -s /tmp/memcached.sock</pre>
<p>Note that Rails contains a memcache client by default. To use the desired memcache-client in Rails &lt; 2.3, we need to perform some brain-surgery originally described <a href="http://www.mikeperham.com/2009/03/03/using-memcache-client-16x-in-rails-23/">here</a>, but modified slightly to fit our needs.</p>
<p><a href="http://www.confiz.com/blog/wp-content/uploads/2010/11/memcache_extension.rb_.zip">Source</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/tech-session/ruby-memcache-client-using-unix-sockets/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Integrating Sphinx into WiceGrid</title>
		<link>http://www.confiz.com/blog/tech-session/integrating-sphinx-into-wicegrid/</link>
		<comments>http://www.confiz.com/blog/tech-session/integrating-sphinx-into-wicegrid/#comments</comments>
		<pubDate>Mon, 01 Nov 2010 14:17:23 +0000</pubDate>
		<dc:creator>Hisham Malik</dc:creator>
				<category><![CDATA[Tech Session]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sphinx]]></category>

		<guid isPermaLink="false">http://www.confiz.com/blog/?p=27</guid>
		<description><![CDATA[WiceGrid is a ruby data grid scaffolding plugin with some unique features such as sorting and out of the box search for grids generated using the plugin. While WiceGrid worked well for small data sets it does not scale and searches are extremely slow when working with millions of records. To enable scalability of WiceGrid, [...]]]></description>
			<content:encoded><![CDATA[<p><a title="WiceGrid" href="http://leikind.org/wicegrid" target="_blank">WiceGrid</a> is a ruby data grid scaffolding plugin with some unique features such as sorting and out of the box search for grids generated using the plugin. While <a title="WiceGrid" href="http://leikind.org/wicegrid" target="_blank">WiceGrid</a> worked well for small data sets it does not scale and searches are extremely slow when working with millions of records.</p>
<p>To enable scalability of <a title="WiceGrid" href="http://leikind.org/wicegrid" target="_blank">WiceGrid</a>, which offers some great functionality, we went about integrating it with a search engine. This avoids database table locking during read queries and results in a significant performance improvement by using indexes optimized for fetching data summaries and associations. Our choice for search engine is <a title="Sphinx" href="http://www.sphinxsearch.com/" target="_blank">Sphinx</a>, although others too can be used to achieve similar results.<span id="more-27"></span>The integration with <a title="Sphinx" href="http://www.sphinxsearch.com/" target="_blank">Sphinx</a> was carried out such that existing applications that use <a title="WiceGrid" href="http://leikind.org/wicegrid" target="_blank">WiceGrid</a> are not broken. If performance limitations using <a title="WiceGrid" href="http://leikind.org/wicegrid" target="_blank">WiceGrid</a> is observed due to massive data volume, then this is just the thing for you!</p>
<p>The details of the integration are below:</p>
<p>First step is to configure sphinx is to specify if you want search results or facets and any preference in which your results are to be sorted.</p>
<pre style="padding-left: 30px">def initialize(klass, controller, opts = {})  #:nodoc:</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">@options = {</pre>
<pre style="padding-left: 90px">:after                =&gt; nil,</pre>
<pre style="padding-left: 90px">:conditions           =&gt; nil,</pre>
<pre style="padding-left: 90px">:csv_file_name        =&gt; nil,</pre>
<pre style="padding-left: 90px">:custom_order         =&gt; {},</pre>
<pre style="padding-left: 90px">:enable_export_to_csv =&gt; Defaults::ENABLE_EXPORT_TO_CSV,</pre>
<pre style="padding-left: 90px">:include              =&gt; nil,</pre>
<pre style="padding-left: 90px">:joins                =&gt; nil,</pre>
<pre style="padding-left: 90px">:name                 =&gt; Defaults::GRID_NAME,</pre>
<pre style="padding-left: 90px"> <img src='http://www.confiz.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder                =&gt; nil,</pre>
<pre style="padding-left: 90px"> <img src='http://www.confiz.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder_direction      =&gt; Defaults::ORDER_DIRECTION,</pre>
<pre style="padding-left: 90px">:page                 =&gt; 1,</pre>
<pre style="padding-left: 90px">:per_page             =&gt; Defaults::PER_PAGE,</pre>
<pre style="padding-left: 90px">:saved_query          =&gt; nil,</pre>
<pre style="padding-left: 90px">:total_entries        =&gt; nil,</pre>
<pre style="padding-left: 90px">:with                 =&gt; nil,</pre>
<pre style="padding-left: 90px">:without              =&gt; nil,</pre>
<pre style="padding-left: 90px"><strong>:sort_mode            =&gt; nil,</strong></pre>
<pre style="padding-left: 90px"><strong>:is_sphinx            =&gt; false,</strong></pre>
<pre style="padding-left: 90px"><strong>:is_facets             =&gt; false</strong></pre>
<pre style="padding-left: 60px">}</pre>
<pre style="padding-left: 60px"><strong>@klass.define_indexes if @status[:is_sphinx] or @status[:is_facets]</strong></pre>
<pre style="padding-left: 60px"><strong>@status[:indexes] = collect_indexes if @status[:is_sphinx] or @status[:is_facets]</strong></pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 30px">end</pre>
<p>A non-trivial task is is to distinguish Sphinx fields from Sphinx attributes.Fields are content for your search queries and attributes are used for filtering, sorting grouping ..etc. Sphinx server requires that searching on fields and attributes is separately passed by the client. In order to implement this, w</p>
<p>we first call the define_index method on the model and then collect the indexes manually.</p>
<pre style="padding-left: 30px">def collect_indexes</pre>
<pre style="padding-left: 60px">all_indexes =[]</pre>
<pre style="padding-left: 60px">for index in @klass.sphinx_indexes.first.fields</pre>
<pre style="padding-left: 90px">all_indexes &lt;&lt; index.unique_name</pre>
<pre style="padding-left: 60px">end</pre>
<pre style="padding-left: 60px">all_indexes</pre>
<pre style="padding-left: 30px">end</pre>
<p>Now, to convert the filter options received from wicegrid, the standard sql implementation generates the &#8216;conditions&#8217; clause based on the filter. For Sphinx, the &#8216;conditions&#8217; clause is used for fields, whereas a separate &#8216;with&#8217; clause is used for attributes. This is where the collected indexes come into play and we use them for distinguishing the two.</p>
<pre style="padding-left: 30px">def form_ar_options_sphinx(opts = {})</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px"><strong>add_filter_to_conditions</strong></pre>
<pre style="padding-left: 60px"><strong>add_filter_to_with</strong></pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 60px">.</pre>
<pre style="padding-left: 30px">end</pre>
<p>In standard WiceGrid plugin, a separate query for getting the number of records is used for pagination purposes. Sphinx provides a separate count query for the data it has indexed, which is more optimized and can be used where sphinx was enabled.</p>
<pre style="padding-left: 30px">alias_method :size, :count</pre>
<pre style="padding-left: 30px">def count  #:nodoc:</pre>
<pre style="padding-left: 60px"><strong>if @status[:is_sphinx] or @status[:is_facets]</strong></pre>
<pre style="padding-left: 90px"><strong>form_ar_options_with_sphinx(:skip_ordering =&gt; true, :forget_generated_options =&gt; true)</strong></pre>
<pre style="padding-left: 90px"><strong>@klass.search_count('',:conditions =&gt; @ar_options[:conditions],</strong></pre>
<pre style="padding-left: 90px"><strong>:joins =&gt; @ar_options[:joins], :include =&gt; @ar_options[:include],</strong></pre>
<pre style="padding-left: 90px"><strong>:with =&gt; @ar_options[:with], :without =&gt; @ar_options[:without])</strong></pre>
<pre style="padding-left: 60px"><strong>else</strong></pre>
<pre style="padding-left: 90px">form_ar_options(:skip_ordering =&gt; true, :forget_generated_options =&gt; true)</pre>
<pre style="padding-left: 90px">@klass.count(:conditions =&gt; @ar_options[:conditions], :joins =&gt; @ar_options[:joins], :include =&gt; @ar_options[:include])</pre>
<pre style="padding-left: 60px"><strong>end</strong></pre>
<pre style="padding-left: 30px">end</pre>
<p>Another feature of Sphinx is to that it provides facets which are count summaries for the sphinx indexes defined on the records. This data is very useful for analysis purposes and we aimed to incorporate this functionality into WiceGrid. Since facet results are not derived from ActiveRecord, but is basically a hash table of counts, we need to override the pagination functionality of WiceGrid to ignore pagination in case of facets.</p>
<pre style="padding-left: 30px">module GridViewHelper</pre>
<pre style="padding-left: 60px"><strong>alias_method <img src='http://www.confiz.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> riginal_pagination_panel_content ,:pagination_panel_content</strong></pre>
<pre style="padding-left: 60px">def pagination_panel_content(grid, extra_request_parameters, allow_showing_all_records) #:nodoc:</pre>
<pre style="padding-left: 90px"><strong>return if grid.is_facets</strong></pre>
<pre style="padding-left: 90px">original_pagination_panel_content(grid, extra_request_parameters, allow_showing_all_records)</pre>
<pre style="padding-left: 60px">end</pre>
<pre style="padding-left: 30px">end
</pre>
<p><a href="http://www.confiz.com/blog/wp-content/uploads/2010/11/wice_grid.rb_1.zip">Source Code</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.confiz.com/blog/tech-session/integrating-sphinx-into-wicegrid/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

