<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-970528744702948483</id><updated>2024-09-06T12:59:57.939-07:00</updated><category term="erlang"/><category term="performance"/><category term="function programming"/><category term="http"/><category term="iolist"/><category term="programming"/><category term="rabbitmq"/><category term="tips"/><category term="tutorial"/><category term="xmerl"/><category term="articles"/><category term="atom"/><category term="auto-discovery"/><category term="binary"/><category term="bing"/><category term="c++"/><category term="clustering"/><category term="coding"/><category term="commandline"/><category term="database"/><category term="ei"/><category term="ei_interface"/><category term="ejabberd"/><category term="erlsom"/><category term="etop"/><category term="feed"/><category term="gen_tcp"/><category term="google"/><category term="highavailability"/><category term="howto"/><category term="ibrowse"/><category term="linux"/><category term="loops"/><category term="messagequeue"/><category term="microsoft"/><category term="mnesia"/><category term="object-oriented-design"/><category term="open standards"/><category term="parsing"/><category term="php"/><category term="rss"/><category term="scripts"/><category term="search"/><category term="spawn"/><category term="strings"/><category term="tcp"/><category term="tuning"/><category term="xml"/><category term="xml parsing"/><category term="yahoo"/><title type='text'>Concurrent future...</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default?start-index=26&amp;max-results=25'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>60</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-2988384213775607673</id><published>2011-06-21T13:13:00.001-07:00</published><updated>2011-06-21T13:16:07.704-07:00</updated><title type='text'>Moving blog</title><content type='html'>I have moved my blog from here to &lt;a href=&quot;http://dudefrommangalore.wordpress.com/&quot;&gt;wordpress&lt;/a&gt; for no apparent reason.  Using &lt;a href=&quot;http://feedburner.google.com&quot;&gt;feedburner&lt;/a&gt; to make the &lt;a href=&quot;http://feeds.feedburner.com/DudefrommangaloresWeblog&quot;&gt;subscription&lt;/a&gt; easier.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/2988384213775607673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/2988384213775607673' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/2988384213775607673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/2988384213775607673'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2011/06/moving-blog.html' title='Moving blog'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-1806800968273016160</id><published>2010-10-14T12:38:00.000-07:00</published><updated>2010-10-14T12:48:40.802-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="function programming"/><category scheme="http://www.blogger.com/atom/ns#" term="php"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>PHP author(s) doesn&#39;t understand functional programming</title><content type='html'>PHP try to emulate functional programming by providing the functions like &lt;a href=&quot;http://www.php.net/manual/en/function.array-reduce.php&quot;&gt;array_reduce&lt;/a&gt;. But what they lack is the knowledge of principals of functional programming.&lt;br /&gt;&lt;br /&gt;I had a problem where there are multiple arrays and need to be merged. array_merge function works only on 2 arrays. Merging multiple arrays need a for loop OR use array_reduce function [I thought]. But it turns out that array_reduce function is not functional as I imagined. Even though the documentation say that the last parameter to this function is the initial value for the array &lt;a href=&quot;http://en.wikipedia.org/wiki/Fold_%28higher-order_function%29&quot;&gt;fold&lt;/a&gt; function, actually it is not.&lt;br /&gt;&lt;br /&gt;If the initial parameter is not an integer, PHP will default to zero. For the above problem I tried the following&lt;br /&gt;&lt;br /&gt;array_reduce($my_arrays, &quot;array_merge&quot;, array());&lt;br /&gt;&lt;br /&gt;What I expected it is to work as&lt;br /&gt;&lt;br /&gt;$initial = array();&lt;br /&gt;foreach ( $my_arrays as $m ) { $initial = array_merge($initial, $m); }&lt;br /&gt;&lt;br /&gt;What I got was&lt;br /&gt;PHP Warning:  array_merge(): Argument #1 is not an array in Command line code on line 1&lt;br /&gt;PHP Warning:  array_merge(): Argument #1 is not an array in Command line code on line 1&lt;br /&gt;&lt;br /&gt;These kind of behavior will lead to serious problem in the system and is hard to debug.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/1806800968273016160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/1806800968273016160' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/1806800968273016160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/1806800968273016160'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/10/php-authors-doesnt-understand.html' title='PHP author(s) doesn&#39;t understand functional programming'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-5251725372126044723</id><published>2010-10-10T11:58:00.000-07:00</published><updated>2010-10-10T12:27:42.204-07:00</updated><title type='text'>State of the Interview process</title><content type='html'>I have attended several interviews and also have interviewed several people. I have seen the difference between the people I interviewed with and the way I do interview.&lt;br /&gt;&lt;br /&gt;In the interviews I have given for several job positions at companies I don&#39;t want to mention here, most of the time I felt that the person who is interviewing me is not at all achieving his goal of the interview. What that person is trying to do is to prove to me that he/she is smarter than me in all respect.&lt;br /&gt;&lt;br /&gt;For me interview is a combination of 2 words &quot;inter&quot; and &quot;view&quot;. That means exchanging views among people involved in the process. Thus what I expect is to have a debate on the subject in question. But mostly what happens is not a debate.&lt;br /&gt;&lt;br /&gt;In one interview, I was given a problem to solve. Instead of listening to my solution and to have a debate on my solution, the Interviewer was playing some game on this iPhone. I was explaning the solution to him and that person was not even listening to me. Instead he was trying to be an smart ass, saying your solution is wrong. My question is how can a solution be wrong if it can solve the problem. The solution may be not efficient enough. Nevertheless solution is never wrong. Other person may have different solution in mind (which may or may not be the efficient one), but still the purpose of the interview is not achieved.&lt;br /&gt;&lt;br /&gt;What I like to do when I am conducting an interview is not to prove that I am smarter than the interviewee (which I am :-)). What I am trying to gauge is the knowledge and the potential of the person opposite to me. I am a believer a person willing to learn and push his/her limit can do wonders. No one is born smart. Smartness is achieved by hard work and will to gain more knowledge. I always try to find a person who can fit into my immediate job description and is smart/hard working enough to achieve more in the near future.&lt;br /&gt;&lt;br /&gt;At least in the technology field, what I find is that interview is a lost cause. Most people are I interviewed with are trying to prove that they are smarter than me or they are the smartest people in the world. They are not even try to find if I can fit into the current job and can do more in the future.&lt;br /&gt;&lt;br /&gt;Another thing I try to achieve in the interview is the personality of the person I am interviewing. No matter how smart one is unless that person has the right attitude and the personality, he/she cannot fit into the team. It takes only one bad apple to disintegrate the whole basket of good apples. It is all about team work.&lt;br /&gt;&lt;br /&gt;Without a good team dynamics, it is not possible to achieve the long term goals. I takes ne person with wrong attitude in the a big team to lead the project to failure. What happens is that this person will demotivate others in the team. It is the responsibility of the manager solve this problem and also the responsibility of the team members to raise the issue. Again it is the responsibility of the manager to see the signs and take actions at the early stage.&lt;br /&gt;&lt;br /&gt;Having the social skills is equally important as the knowledge of the current field he/she is working in. Social skills refers to personality, how comfortable one can make others, how good of a team player one can be etc. etc.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/5251725372126044723/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/5251725372126044723' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5251725372126044723'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5251725372126044723'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/10/state-of-interview-process.html' title='State of the Interview process'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-5651381322181007180</id><published>2010-09-09T14:01:00.001-07:00</published><updated>2010-09-09T14:09:13.755-07:00</updated><title type='text'>Content vs Ads</title><content type='html'>Looking at several websites known to provide content, I am wondering what is important for these websites.. Content or Ads.&lt;br /&gt;&lt;br /&gt;There was a time when I used to get ads within the content, but now a days I am searching for content within ads. Page is full of ads and somewhere hidden is a small pre-text of content. I have to click on several ads (or real links) to figure out what is the actual content. Most of the time I end up clicking on ads which look like content (thanks to Google adsense ads buried in the content). Google makes it easy for publishers to format the ads so that it looks like the content. &quot;ads by Google&quot; is like a fine-print in the terms of service notice. It is barely visible.&lt;br /&gt;&lt;br /&gt;Apart from them, even big names like CNN is also doing it but in a different way. They are displaying big banner ads at the top of the page which pushes the content below the first fold of the page. They make sure that y&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2pu88ln491VQlMCPjanfQEhodiAyK4oLfLl8aNho81hxh92Jx0VaFdFJTncXhr3TZEOXL_-JwepwpjAWCVsmXuO-JY41BQ_z8sjQqQG5CitnveYiWmG8TSrG6Al5W0mZEmWM5TADynA/s1600/cnn-window.png&quot;&gt;&lt;img style=&quot;float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 320px; height: 194px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2pu88ln491VQlMCPjanfQEhodiAyK4oLfLl8aNho81hxh92Jx0VaFdFJTncXhr3TZEOXL_-JwepwpjAWCVsmXuO-JY41BQ_z8sjQqQG5CitnveYiWmG8TSrG6Al5W0mZEmWM5TADynA/s320/cnn-window.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5515023139142895426&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;ou view the ads.  Whether or not you click on the ads is not important, they are banner ads mostly used for brand awareness anyways.&lt;br /&gt;&lt;br /&gt;Look at this page from CNN. Big BMW ad at the top of the page covering approximately 80% of the page.&lt;br /&gt;&lt;br /&gt;Only title of the article is viewable on the first fold of the content. Hello... I know the title of the article from the website (in this case Yahoo! Finance). I am here to read the content of the article. You are already making money by the content distribution. Please stop throwing the ads at my face...</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/5651381322181007180/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/5651381322181007180' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5651381322181007180'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5651381322181007180'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/09/content-vs-ads.html' title='Content vs Ads'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2pu88ln491VQlMCPjanfQEhodiAyK4oLfLl8aNho81hxh92Jx0VaFdFJTncXhr3TZEOXL_-JwepwpjAWCVsmXuO-JY41BQ_z8sjQqQG5CitnveYiWmG8TSrG6Al5W0mZEmWM5TADynA/s72-c/cnn-window.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-5292521180236657788</id><published>2010-09-06T19:14:00.001-07:00</published><updated>2010-09-06T19:19:03.254-07:00</updated><title type='text'>Spelling checker in Craigslist</title><content type='html'>In-spite of being a market leader in listing business, I don&#39;t think craigslist understand anything about search. People do mistake while typing search term. So now a days it is absolutely necessary to have a spelling checker and correction service along with the search. It is missing in Craigslist. I found out today when I was searching for car. I typed &quot;toyta car&quot;. Instead of giving no results and suggesting corrected spelling, it is threw just a no result page at my face.&lt;br /&gt;&lt;br /&gt;Now a days it is not hard to build spelling correction in the system. It is not required to build you own spelling correction system. There are lot of APIs available. BOSS API is one of the prominent one which does provide spelling correction API.&lt;br /&gt;&lt;br /&gt;http://boss.yahooapis.com/ysearch/spelling/v1/toyta+car?appid=&lt;your appid here&gt;</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/5292521180236657788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/5292521180236657788' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5292521180236657788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5292521180236657788'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/09/spelling-checker-in-craigslist.html' title='Spelling checker in Craigslist'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-700701981695296836</id><published>2010-08-27T17:31:00.000-07:00</published><updated>2010-08-27T18:33:34.657-07:00</updated><title type='text'>HTML Message Ajax Design Pattern</title><content type='html'>Having more and more browsers supporting XMLHTTPRequest object to send the data to server and get the response from server without reloading the page, it is possible to refresh only a part of the page. There are various techniques to do this. One such technique is that the server send the XML back to the browser and the Javascript on the browser will convert the XML into HTML by creating the DOM nodes on the fly. This is useful but has some limitations.&lt;br /&gt;&lt;br /&gt; * If the Javascript is turned off, there is no graceful degradation of application&lt;br /&gt; * Since the Javascript is running on the browser (client side), changing the structure of the generated HTML is hard&lt;br /&gt; * This is not feasible when HTML generated is complex&lt;br /&gt;&lt;br /&gt;One can overcome these limitations by sending the HTML snippet in the response. Instead of sending the XML back to browser, generate the HTML on the server side itself. On the browser side, replace the content of the DOM node with the response HTML response from the server.&lt;br /&gt;&lt;br /&gt; If the Javascript is turned off on the browser, user will see at least the content of the HTML on the browser instead of just the XML content. So there is a graceful degradation of service on the client side&lt;br /&gt;&lt;br /&gt; If HTML generated need to be changed, application is not dependent on changing the Javascript and hoping that the client will reload the page and will get new Javascript. Even if the Javascript is changed, some web proxies may not pull the new Javascript, resulting in the browsers (clients) behind the proxies will continue to get the old Javascript and old HTML will get rendered.&lt;br /&gt;&lt;br /&gt; There are various frameworks like Symfony, Django make it possible to generate the complex HTML possible with least effort. In case the request is not made via XMLHTTPRequest, it is possible to send the whole page (with header, footer etc.) in the response. If the request is made via XMLHTTPRequest object, send the response without the layout decoration (just the HTML snippet). Javascript running on client side will replace the content of the DOM node as required.&lt;br /&gt;&lt;br /&gt; Take for example, there is an application where the page loaded has many graphics and only a part of the page changes when user take some action like filling a form for sending the email. It is absolutely unnecessary to generate the whole page again just for a simple action of sending an email. I will make an attempt to explain with the example of sending the feedback via a form embedded in the page. I will try to explain this with PHP Symfony framework and Javascript (AJAX).&lt;br /&gt;&lt;br /&gt; The URL for the page is /new-page. This page has a feedback form in it. The action of this form is handled by /feedback. Server side code for /feedback expect a form having a text content, sends an email to the product manager and send same page as new-page but replacing the form with thank you note.&lt;br /&gt;&lt;br /&gt;Below is a code for the new-page action.&lt;br /&gt;&lt;script src=&quot;http://gist.github.com/554498.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Code for new-page response.&lt;br /&gt;&lt;script src=&quot;http://gist.github.com/554496.js&quot;&gt; &lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Now is the magic of jQuery Javascript library to submit the content to /feedback url and use the response content to replace the HTML form.&lt;br /&gt;&lt;br /&gt;&lt;script src=&quot;http://gist.github.com/554508.js?file=feedback-form-javascript.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Server side code for handling the post from the browser to /feedback &lt;br /&gt;&lt;br /&gt;&lt;script src=&quot;http://gist.github.com/554511.js?file=feedback-handler-action.php&quot;&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;HTML response from /feedback&lt;br /&gt;&lt;script src=&quot;http://gist.github.com/554513.js?file=feedback-handler-response.html&quot;&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;In Symfony framework it is possible disable/enable the layout during run-time via setLayout() method of sfAction instance. Setting the parameter to false will disable the layout and send only the content of the action template back to the caller.&lt;br /&gt;&lt;br /&gt;There you go.. A simple way to improve the usability of the site even without Javascript support.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/700701981695296836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/700701981695296836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/700701981695296836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/700701981695296836'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/08/html-message-ajax-design-pattern.html' title='HTML Message Ajax Design Pattern'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-5273660419628573581</id><published>2010-08-25T16:58:00.001-07:00</published><updated>2010-08-25T17:02:27.874-07:00</updated><title type='text'>Execute action within another action</title><content type='html'>In the current project I am working on (using Symfony framework), I came across a situation where I had to call one action within another action and capture the content of 2nd action. This content is included within the result from 1st action. After doing some research found that it it possible to do so by calling getPresentationFor method of the controller object.&lt;br /&gt;&lt;br /&gt;Within the action&#39;s execute method,&lt;br /&gt;&lt;br /&gt;  $content = $this-&gt;getController()-&gt;getPresentationFor($module, &#39;my2ndAction&#39;);&lt;br /&gt;  $this-&gt;content = $content;</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/5273660419628573581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/5273660419628573581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5273660419628573581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5273660419628573581'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/08/execute-action-within-another-action.html' title='Execute action within another action'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-4346156070985124279</id><published>2010-08-05T23:17:00.000-07:00</published><updated>2010-08-05T23:21:04.895-07:00</updated><title type='text'>File System Over SSH</title><content type='html'>Some of the development I am doing require me to do the development on some remote machine. Since the development is done in Java, I need Eclipse environment. On the remote system I cannot run Eclipse as it is a server box and does not have display attached to it. I found an elegant solution for this. Thanx for &lt;a href=&quot;http://www.macfusionapp.org/&quot;&gt;Macfusion&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I can mount remote machine&#39;s directory on my local machine and work as if it is a local directory. All the dirty work of communication is taken care. I don&#39;t need nfs mounting which is not secure. Macfusion let me mount the directory on remote machine over ssh</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/4346156070985124279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/4346156070985124279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4346156070985124279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4346156070985124279'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/08/file-system-over-ssh.html' title='File System Over SSH'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-5367514243832519366</id><published>2010-07-11T12:21:00.000-07:00</published><updated>2010-08-24T10:01:24.103-07:00</updated><title type='text'>Why Erlang scares managers?</title><content type='html'>Managing is all about control. Managing is about knowing (almost) everything about what one is controlling. If the team is using something manager don&#39;t understand or willing to understand, manager is loosing control. Again it is all about control. &lt;br /&gt;&lt;br /&gt;99% of managers are comfortable with technologies like PHP, Java etc. Languages with new ideas like Erlang, LISP are far fetched for many managers. They don&#39;t want to learn about these new technologies or new ideas. Having these new technologies in the team force them to come out of the comfort zone and take the control away from them. This is not a good news for them. One argument I have heard every time I make a case for why Erlang (is better in-terms of hardware utilization and lines of code) is that &quot;It is hard to hire Erlang developers than PHP/Java developers&#39;. As I see competent developers want to learn new things than putting themselves in the same-old-same-old world. Competent developers are capable of learning new technologies and new ideas. &lt;br /&gt;&lt;br /&gt;Off course, there is a initial learning curve. It is always there anywhere you go. Developers/Engineers need to learn the new way of doing things anywhere they go. Some companies are willing to give more time to developers to get familiar with the internal technologies and some don&#39;t. But it is a absolute necessity. Everyone does not follow the same development methods or procedures. In a big organization, this changes from group to group.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/5367514243832519366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/5367514243832519366' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5367514243832519366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/5367514243832519366'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/07/why-erlang-scares-managers.html' title='Why Erlang scares managers?'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-4943430942910220984</id><published>2010-06-27T15:07:00.000-07:00</published><updated>2010-06-27T15:10:43.165-07:00</updated><title type='text'>To stay or to leave....</title><content type='html'>There comes a time when one has to stop doing the things one was doing for along time. It is hard to do that... Sometime it feels it is impossible.. Some people lack courage to do that, some people lack motivation and for some people situation don&#39;t let them.. &lt;br /&gt;&lt;br /&gt;Once the decision is taken, is it possible to revert that decision.. Yes.. I think it is possible to that. Question is what it the cost of reverting the decision. I don&#39;t think it is much..</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/4943430942910220984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/4943430942910220984' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4943430942910220984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4943430942910220984'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/06/to-stay-or-to-leave.html' title='To stay or to leave....'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-6030984251897397901</id><published>2010-04-20T15:14:00.000-07:00</published><updated>2010-04-20T15:15:21.306-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="object-oriented-design"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>Dog is not Cat</title><content type='html'>While talking to my friend today, something struck me regarding the notion of object oriented programming, hierarchy of classes and how these concepts are over used.&lt;br /&gt;&lt;br /&gt;Objected oriented design is heavily used for thousands of years. For example, constructing a home. If you think about it, home is built in a very modular way (aka object oriented way). Every part of home is a object [door, window, wall, roof etc.]. They can be put together in many ways to construct a home. The final shape of home may change, but the the basic building blocks remain the same.&lt;br /&gt;&lt;br /&gt;Now to the point of using this in computer programming. I think object oriented programming is misunderstood in the software industry. People seems to confuse reusability of the code with object orientation. For example, take the hierarchy of animals. Animal is a base class, cat is derived from class Animal. Now let&#39;s say I want to declare a new class Dog. Since Dog class was not considered while implementing Cat class, common functionality of Animal (like see, listen etc.) are implemented in Cat class. Now when one want to design Dog class, since Cat already has the functionalities required by Dog, derive Dog from Cat. This is so wrong. Logically when you derive one class from another, you are implying &quot;is-a&quot; relation. That means, by deriving Dog from Cat [just because you have functionality required by Dog is implemented in Cat], you are implying that Dog is a Cat. &lt;br /&gt;&lt;br /&gt;Cases like these, it is better to sit back and think a little. May be code re-factoring will help here. One can move the functionalities that are required by both Dog and Cat [may be Elephant, Tiger etc.] can be moved into the Animal class and implement those functionalities in terms of some abstract concepts like eyes, legs, ears etc.&lt;br /&gt;&lt;br /&gt;Now enough of messing your brain.. Go back to work and start thinking about the designs you have done earlier and how you could have done it better [not that what you did earlier was wrong].</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/6030984251897397901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/6030984251897397901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/6030984251897397901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/6030984251897397901'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/04/dog-is-not-cat.html' title='Dog is not Cat'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-8220837191461674206</id><published>2010-01-30T12:33:00.000-08:00</published><updated>2010-01-30T12:43:46.584-08:00</updated><title type='text'>Hacking search suggestions</title><content type='html'>Opensearch specification has extension for &lt;a href=&quot;http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.1&quot;&gt;search suggestions&lt;/a&gt;. Major search providers have their own search suggestion entry points. After looking doing a search of my own, I found the entry points for the 3 major search providers&lt;br /&gt;&lt;br /&gt;Bing - http://api.search.live.com/osjson.aspx?query={Search Term}&lt;br /&gt;Google - http://suggestqueries.google.com/complete/search?q={Search Term}&amp;client=firefox&lt;br /&gt;Yahoo - http://ff.search.yahoo.com/gossip?output=fxjson&amp;command={searchTerms}&lt;br /&gt;&lt;br /&gt;For Google entry point, removing client parameter will also provide the number of results in the response. This format is not as per the Opensearch standards.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/8220837191461674206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/8220837191461674206' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/8220837191461674206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/8220837191461674206'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/01/hacking-search-suggestions.html' title='Hacking search suggestions'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-4316316884402013485</id><published>2010-01-30T12:01:00.000-08:00</published><updated>2010-01-30T12:06:18.581-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="atom"/><category scheme="http://www.blogger.com/atom/ns#" term="auto-discovery"/><category scheme="http://www.blogger.com/atom/ns#" term="bing"/><category scheme="http://www.blogger.com/atom/ns#" term="feed"/><category scheme="http://www.blogger.com/atom/ns#" term="google"/><category scheme="http://www.blogger.com/atom/ns#" term="microsoft"/><category scheme="http://www.blogger.com/atom/ns#" term="open standards"/><category scheme="http://www.blogger.com/atom/ns#" term="rss"/><category scheme="http://www.blogger.com/atom/ns#" term="search"/><category scheme="http://www.blogger.com/atom/ns#" term="yahoo"/><title type='text'>Who is more open? Google or Yahoo or Bing?</title><content type='html'>While looking at the search result page HTML from Google, Yahoo and Bing, I discovered that Google does not add &lt;a href=&quot;http://jeremy.zawodny.com/blog/archives/000967.html&quot;&gt;auto discovery&lt;/a&gt; to its search result page. Where as Yahoo and Bing does. &lt;br /&gt;&lt;br /&gt;That makes me wonder why Yahoo and Bing does not get as much credit as Google for adopting the open technologies/standards?</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/4316316884402013485/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/4316316884402013485' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4316316884402013485'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4316316884402013485'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/01/who-is-more-open-google-or-yahoo-or.html' title='Who is more open? Google or Yahoo or Bing?'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-3786791321843353658</id><published>2010-01-22T15:34:00.000-08:00</published><updated>2010-01-22T18:04:41.459-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="howto"/><category scheme="http://www.blogger.com/atom/ns#" term="http"/><category scheme="http://www.blogger.com/atom/ns#" term="performance"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><title type='text'>http request pipeline in Erlang</title><content type='html'>I tried to use Erlang&#39;s http module for high concurrent requests. It was not performing well due to pipelining and persistent connection issues. This seems to be solved in R13 version. I figured out how to use the http profiles to do selective pipelining/persistent connections to one server but not for others [if application is sending requests to multiple hosts].&lt;br /&gt;&lt;br /&gt;First step in the process is to create a new http profile. It can be done in 2 ways. First one is to run a stand along http connection manager (httpc_manager).&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;{ok, Pid} = inets:start( httpc, [{profile, other}] ).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As per the documentation, this is not desirable as all benefits of OTP framework is lost.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Dynamically started services will not be handled by application takeover and failover behavior when inets is run as a distributed application. Nor will they be automatically restarted when the inets application is restarted, but as long as the inets application is up and running they will be supervised and may be soft code upgraded. Services started as stand_alone, e.i. the service is not started as part of the inets application, will lose all OTP application benefits such as soft upgrade. The &quot;stand_alone-service&quot; will be linked to the process that started it. In most cases some of the supervision functionality will still be in place and in some sense the calling process has now become the top supervisor&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;2nd method is to run it as a part of inets application via configuration file&lt;br /&gt;&lt;br /&gt;Have a config file with the following content (say inets.config)&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;[{inets, &lt;br /&gt;[{services,[{httpc,[{profile, server1}]},&lt;br /&gt;            {httpc, [{profile, server2}]}]}]&lt;br /&gt;}].&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Run the erlang shell as &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;erl -config inets.config&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will start 3 http profiles [server1, server2 and default]. &lt;br /&gt;&lt;br /&gt;Now the question is how to use the newly created profiles. Let&#39;s say the application is using 2 web services hosted at foo1.example.com and foo2.example.com. Web service hosted at foo1.example.com is hosted on a web server which can support lot of persistent connections [keep alive connections]. Web service hosted foo2.example.com is hosted on a normal web server which is not optimized for large number of persistent connectinons.&lt;br /&gt;&lt;br /&gt;In the application set the profile for server1 for the connections to foo1.example.com. This can be done by changing the http options  listed &lt;a href=&quot;http://www.erlang.org/doc/man/http.html#set_options-1&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;http:set_options([{max_sessions, 20}, {pipeline_timeout, 20000}], server1).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;NOTE:&lt;/span&gt;It is required to set the pipeline timeout in order to enable &lt;a href=&quot;http://en.wikipedia.org/wiki/HTTP_pipelining&quot;&gt;http pipelining&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Profile can be specified during the request time.&lt;br /&gt;&lt;br /&gt;&lt;pre class=&quot;code&quot; name=&quot;erl&quot;&gt;&lt;br /&gt;http:request( &quot;http://foo1.example.com/v1/get_info/dudefrommangalore&quot;, server1).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There is no interface provided by httpc_manager or inets to get the info on the number of sessions open to a server.  But good news is that the session information is kept in the ets table. One can query the ets table to get the list of persistent connections.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;ets:tab2list(httpc_manager_server1_session_db).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Output is something like&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;{tcp_session,{{&quot;fo11.example.com&quot;,80},&lt;br /&gt;               &lt;0.103.0&gt;},&lt;br /&gt;              false,http,#Port&lt;0.1032&gt;,...}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;0.103.0&gt; is a Pid of httpc_handler gen server process. It is possible to get the status of this process via standard OTP sys module.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;sys:get_status(erlang:list_to_pid(&quot;&lt;0.103.0&gt;&quot;)).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It is also possible to get all the pipelined requests on each persistent connections. For that it is necessary to get the pid of the httpc_manager via inets:services_info(). This call will return the pid of the httpc_manager.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;[{httpc,&lt;0.52.0&gt;,[{profile,server1}]},&lt;br /&gt; {httpc,&lt;0.53.0&gt;,[{profile,server2}]},&lt;br /&gt; {httpc,&lt;0.41.0&gt;,[{profile,default}]}]&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;From the pid, get the status of httpc_manager gen server process.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;sys:get_status(erlang:list_to_pid( &quot;&lt;0.52.0&gt;&quot;)).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ets table name is in bold here.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;15&gt; sys:get_status(erlang:list_to_pid(&quot;&lt;0.52.0&gt;&quot;)).&lt;br /&gt;{status,&lt;0.52.0&gt;,&lt;br /&gt;        {module,gen_server},&lt;br /&gt;        [[{&#39;$ancestors&#39;,[httpc_profile_sup,httpc_sup,inets_sup,&lt;br /&gt;                         &lt;0.36.0&gt;]},&lt;br /&gt;          {&#39;$initial_call&#39;,{httpc_manager,init,1}}],&lt;br /&gt;         running,&lt;0.40.0&gt;,[],&lt;br /&gt;         [httpc_manager_server1,&lt;br /&gt;          {state,[],&lt;span style=&quot;font-weight:bold;&quot;&gt;24596&lt;/span&gt;,&lt;br /&gt;                 {undefined,28693},&lt;br /&gt;                 httpc_manager_server1_session_db,httpc_manager_server1,&lt;br /&gt;                 {options,{undefined,[]},&lt;br /&gt;                          0,2,5,120000,2,disabled,false,inet,default,...}},&lt;br /&gt;          httpc_manager,infinity]]}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Get the content of the ets table to get the pipelined connection&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;ets:tab2list(24596).&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Application can tune the http options to utilize the network bandwidth better, get the most of the machine and network.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/3786791321843353658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/3786791321843353658' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/3786791321843353658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/3786791321843353658'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/01/http-request-pipeline-in-erlang.html' title='http request pipeline in Erlang'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-4696605595262363909</id><published>2010-01-19T16:22:00.000-08:00</published><updated>2010-01-19T16:29:47.096-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="performance"/><title type='text'>Erlang process mailbox performance</title><content type='html'>I came across this performance issue in Erlang while doing the pattern matching against the mailbox [a.k.a. selective message processing]. Here is the orignal code:&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;-module (perf).&lt;br /&gt;&lt;br /&gt;-export( [start/0] ).&lt;br /&gt;&lt;br /&gt;start() -&gt;&lt;br /&gt;  S = erlang:now(),&lt;br /&gt;  Pids = spawn_n(fun test/1, 10000, []),&lt;br /&gt;  wait(Pids),&lt;br /&gt;  E = erlang:now(),&lt;br /&gt;  io:format( &quot;Total time: ~p~n&quot;, [timer:now_diff(E, S)/1000] ).&lt;br /&gt;&lt;br /&gt;spawn_n(_F, 0, Acc) -&gt; Acc;&lt;br /&gt;spawn_n(F, N, Acc) -&gt; &lt;br /&gt;  Me = self(),&lt;br /&gt;  Pid = spawn(fun() -&gt; F(Me) end),&lt;br /&gt;  spawn_n(F, N-1, [Pid|Acc]).&lt;br /&gt;&lt;br /&gt;test(Pid) -&gt; Pid ! {self(), ok}.&lt;br /&gt;&lt;br /&gt;wait([]) -&gt; ok;&lt;br /&gt;wait([Pid|Pids]) -&gt; &lt;br /&gt;    receive {Pid, ok} -&gt; ok end,&lt;br /&gt;    wait(Pids).&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Run time for perf:start() was 1.3 seconds&lt;br /&gt;&lt;br /&gt;Erlang (BEAM) emulator version 5.6.5 [source] [smp:2] [async-threads:0] [hipe] [kernel-poll:false]&lt;br /&gt;&lt;br /&gt;Eshell V5.6.5  (abort with ^G)&lt;br /&gt;1&gt; perf:start().&lt;br /&gt;Total time: 1368.038&lt;br /&gt;ok&lt;br /&gt;2&gt; &lt;br /&gt;&lt;br /&gt;Now I changed &lt;span style=&quot;font-weight:bold;&quot;&gt;wait(Pids)&lt;/span&gt; to &lt;span style=&quot;font-weight:bold;&quot;&gt;wait(lists:reverse(Pids))&lt;/span&gt;. After this change, run time for perf:start() was 83 milliseconds.&lt;br /&gt;&lt;br /&gt;1&gt; perf:start().&lt;br /&gt;Total time: 83.037&lt;br /&gt;ok&lt;br /&gt;&lt;br /&gt;15x improvement just by changing the way mailbox scan is done. &lt;br /&gt;&lt;br /&gt;Little things like this are usually overlooked and the language is blamed for the performance issues.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/4696605595262363909/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/4696605595262363909' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4696605595262363909'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4696605595262363909'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/01/erlang-process-mailbox-performance.html' title='Erlang process mailbox performance'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-8111177393862212969</id><published>2010-01-18T13:54:00.000-08:00</published><updated>2010-01-29T19:15:28.976-08:00</updated><title type='text'>Concurrency in Java - Part 2</title><content type='html'>In the &lt;a href=&quot;http://dudefrommangalore.blogspot.com/2010/01/concurrency-in-java.html&quot;&gt;earlier post&lt;/a&gt; I covered the basic cached thread pool. &lt;br /&gt;&lt;br /&gt;Another facility offered by Java&#39;s concurrency framework is to schedule a thread after certain time or at regular interval (like standard unix cron job). There are 2 ways to schedule the thread at regular interval. First one is to run a task at regular interval regardless of the previous job. Second one is to run a task and wait for the certain interval after the previous job is done.&lt;br /&gt;&lt;br /&gt;Second one is helpful in situation like crawlers. It is necessary to download the pages with some politeness factor [wait for sometime before downloading a page from the same website].&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;ScheduledExecutorService executionService = Executors.newScheduledThreadPool(2);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Above code snippet create a pool of 2 threads. This service can schedule the threads at regular interval.&lt;br /&gt;&lt;br /&gt;ScheduledExecutorService provide a method schedule&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;Runnable task = new Runnable() {&lt;br /&gt;   public void run() {&lt;br /&gt;      System.out.println( &quot;I am responsible for downloading a page&quot; );&lt;br /&gt;      return;&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;/* TimeUnit is defined within java.util.concurrent package */&lt;br /&gt;Future&lt;?&gt; future = executionService.schedule(task, 2000, TimeUnit.MILLISECONDS);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above code schedule a task to run after 2 seconds [2000 milliseconds]. schedule method return a future object. This future object can be used to check the status of the task [isDone method] or to cancel the task [cancel method]. Read more about the future object and the methods available &lt;a href=&quot;http://java.sun.com/javase/6/docs/api/java/util/concurrent/Future.html&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;ScheduledExecutorService also support repeated execution of a task via scheduleAtFixedRate and scheduleWithFixedDelay.&lt;br /&gt;&lt;br /&gt;scheduleAtFixedRate method schedule the task at regular interval. This method does not check if the previously scheduled task is finshed or not.&lt;br /&gt;&lt;br /&gt;scheduleWithFixedDelay method is similar to scheduleAtFixedRate except that this method wait for the previous execution to finish, wait for the fixed interval and then schedule the task again.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/8111177393862212969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/8111177393862212969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/8111177393862212969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/8111177393862212969'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/01/concurrency-in-java-part-2.html' title='Concurrency in Java - Part 2'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-2098405236247038522</id><published>2010-01-17T19:03:00.000-08:00</published><updated>2010-01-18T00:05:10.389-08:00</updated><title type='text'>Concurrency in Java</title><content type='html'>Java 5.x introduced the concurrency framework. It make the life of developer easier to run multiple threads. This framework also take care of thread caching this reducing the number of spawned threads in the system.&lt;br /&gt;&lt;br /&gt;When the concepts of thread was introduced in the operating systems, it was considered light-weight processes. As the clock speed of the CPU is increasing dramatically and also number of CPU cores available for the programs are increasing, even this light-weight processes are deemed to costly to start. Thus introduced the concept of cached threads. Erlang solve this problem by introducing ultra-light-weight processes. Millions of such processes can be spawned within few seconds. This is not the case in kernel threads. Even when kernel threads are used, there is a cost of context switching to schedule those threads from wait state to run state.&lt;br /&gt;&lt;br /&gt;I am new to Java concurrency framework. So I am taking baby steps to learn to use the classes available in Java 5.x. All the concurrency related classes are in &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/package-summary.html&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;java.util.concurrent&lt;/span&gt;&lt;/a&gt; package.&lt;br /&gt;&lt;br /&gt;First step in start using these classes is to introduce Executors class. This class has several class methods to create thread pools.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;import java.util.concurrent.Executors;&lt;br /&gt;import java.util.concurrent.ExecutorService;&lt;br /&gt;&lt;br /&gt;ExecutorService threadPool = Executors.newCachedThreadPool();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The above code create a cached thread pool. Behavior of this thread pool is documented &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Executors.html#newCachedThreadPool()&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;here&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources. Note that pools with similar properties but different details (for example, timeout parameters) may be created using ThreadPoolExecutor constructors&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;A task can be submitted to the newly created thread pool for execution. A task must be an instance of Runnable interface. Submitting a task to the ExecutorService will return an instance of &lt;a href=&quot;http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/Future.html&quot;&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;Future&lt;/span&gt;&lt;/a&gt; interface. This is a wrapper around the task submitted. This instance can be used to query the submitted task for completion, as well as to cancel the task.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;&lt;br /&gt;Future&lt;?&gt; task = threadPool.submit( new Runnable() {&lt;br /&gt;       public void run() {&lt;br /&gt;          System.out.println( &quot;Hello world from within the thread pool&quot; );&lt;br /&gt;       }&lt;br /&gt;  });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally wait for the task to be completed&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;  while ( !task.isDone() ) {&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once the task is completed and thread pool is no-longer necessary, send shutdown message to the thread pool to terminate all the threads created.&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;java&quot;&gt;&lt;br /&gt;  threadPool.shutdown();&lt;br /&gt;  while (!thread.isTerminated()) {&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There it is. First Hello world code using the Concurrent Thread Pool in Java. As and when I learn new methods in this framework, I will write about that here.&lt;br /&gt;&lt;br /&gt;&lt;script src=&quot;http://gist.github.com/279874.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;&lt;br /&gt;Until then, happy thread pooling and utilizing all the cores on the system.&lt;br /&gt;&lt;br /&gt;Update: Download the source from &lt;span style=&quot;font-weight:bold;&quot;&gt;&lt;a href=&quot;http://github.com/dudefrommangalore/Java-Concurrency/raw/master/src/org/baliga/java/concurrency/CachedThreads.java&quot;&gt;here&lt;/a&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/2098405236247038522/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/2098405236247038522' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/2098405236247038522'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/2098405236247038522'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2010/01/concurrency-in-java.html' title='Concurrency in Java'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-260061481956214398</id><published>2009-10-08T15:33:00.000-07:00</published><updated>2009-10-08T15:34:21.091-07:00</updated><title type='text'>What do you mean by giving more than 100%?</title><content type='html'>Here is a little something someone sent me that is _indisputable_ mathematical logic. (It also made me Laugh Out Loud.) &lt;br /&gt;&lt;br /&gt;Remember, this is a strictly mathematical viewpoint. It goes like this: &lt;br /&gt;&lt;br /&gt;What Makes 100%? What does it mean to give MORE than 100%? Ever wonder about those people who say they are giving more than 100%? We have all been to those meetings where someone wants you to give over 100%. How about achieving 103%? What makes up 100% in life? &lt;br /&gt;&lt;br /&gt;Here&#39;s a little mathematical formula that might help you answer these questions: &lt;br /&gt;&lt;br /&gt;If: &lt;br /&gt;A B C D E F G H I J K L M N O P Q R S T U V W X Y Z &lt;br /&gt;&lt;br /&gt;is represented as: &lt;br /&gt;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26. &lt;br /&gt;&lt;br /&gt;Then: &lt;br /&gt;&lt;br /&gt;H-A-R-D-W-O-R-K &lt;br /&gt;8+1+18+4+23+15+18+11 = 98%* &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;K-N-O-W-L-E-D-G-E &lt;br /&gt;11+14+15+23+12+5+4+7+5= 96% &lt;br /&gt;&lt;br /&gt;But,* &lt;br /&gt;&lt;br /&gt;A-T-T-I-T-U-D-E &lt;br /&gt;1+20+20+9+20+21+4+5 = 100% &lt;br /&gt;&lt;br /&gt;And, &lt;br /&gt;&lt;br /&gt;B-U-L-L-S-H-I-T &lt;br /&gt;2+21+12+12+19+8+9+20 = 103% &lt;br /&gt;&lt;br /&gt;AND, look how far ass kissing will take you. &lt;br /&gt;&lt;br /&gt;A-S-S-K-I-S-S-I-N-G &lt;br /&gt;1+19+19+11+9+19+19+9+14+7 = 118% &lt;br /&gt;So, one can conclude with _mathematical certainty_, that while* Hardwork* and *Knowledge *will get you close, and* Attitude *will get you there, its the *Bullshit*  and *Ass kissing* that will put you over the top.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/260061481956214398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/260061481956214398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/260061481956214398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/260061481956214398'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/10/what-do-you-mean-by-giving-more-than.html' title='What do you mean by giving more than 100%?'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-912704702600616446</id><published>2009-09-29T17:25:00.000-07:00</published><updated>2009-11-18T08:56:41.616-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="etop"/><title type='text'>How to see the running processes in erlang shell</title><content type='html'>Erlang provides a built-in utility called etop, that is same as standard top utility on Unix. Instead of monitoring processes on the operating system, etop show the current running/active Erlang processes. By default it starts a GUI window to show the processes running. Sometimes GUI is not desirable especially when the Erlang shell is running on production servers. Documentation does not show any way to start etop in text mode. Here is how to run it&lt;br /&gt;&lt;br /&gt;&lt;pre name=&quot;code&quot; class=&quot;erl&quot;&gt;&lt;br /&gt;etop:start([{output, text}]).&lt;br /&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/912704702600616446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/912704702600616446' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/912704702600616446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/912704702600616446'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/09/how-to-see-running-processes-in-erlang.html' title='How to see the running processes in erlang shell'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-8528700944715941703</id><published>2009-09-29T16:14:00.000-07:00</published><updated>2009-09-29T16:24:49.531-07:00</updated><title type='text'>Detecting rejected file upload in PHP code</title><content type='html'>PHP can be configured to reject the file uploads exceeding some limit via upload_max_filesize server configuration parameter (in php.ini). As per the documentation &lt;a href=&quot;http://www.php.net/manual/en/features.file-upload.post-method.php&quot;&gt;here&lt;/a&gt;, even though the file upload is rejected, an entry is made in $_FILES array with error code set to UPLOAD_ERR_INI_SIZE. This is documented &lt;a href=&quot;http://us3.php.net/manual/en/features.file-upload.errors.php&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Practically speaking this is not the case. When the uploaded content size exceed &lt;span style=&quot;font-weight:bold;&quot;&gt;upload_max_filesize&lt;/span&gt;, $_FILES array is empty. This array cannot be inspected to find the reason for the error. I found a hack to do this. &lt;br /&gt;&lt;br /&gt;   * For file uploads, $_SERVER[&#39;CONTENT_TYPE&#39;] is always set to &lt;span style=&quot;font-weight:bold;&quot;&gt;multipart/form-data&lt;/span&gt; followed by the multipart boundary string.&lt;br /&gt;   * $_SERVER[&#39;CONTENT_LENGTH&#39;] will be set to the content-length in the http header.&lt;br /&gt;&lt;br /&gt;Combination of above 2 can be used to detect the file upload exceeding &lt;span style=&quot;font-weight:bold;&quot;&gt;upload_max_filesize&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;if ( stripos( $_SERVER[&#39;CONTENT_TYPE&#39;], &#39;multipart/form-data&#39;) === 0 &amp;&amp; intval($_SERVER[&#39;CONTENT_LENGTH&#39;]) &gt; 0 &amp;&amp;&lt;br /&gt;        count($_FILES) == 0) {&lt;br /&gt;   error_log( &#39;File upload rejected due to file size exceeding upload_max_filesize limit&#39; );&lt;br /&gt;}</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/8528700944715941703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/8528700944715941703' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/8528700944715941703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/8528700944715941703'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/09/detecting-rejected-file-upload-in-php.html' title='Detecting rejected file upload in PHP code'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-707538970903765304</id><published>2009-09-26T13:45:00.000-07:00</published><updated>2009-09-26T13:48:30.920-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="function programming"/><title type='text'>Load balancing in Erlang using pg2 process groups</title><content type='html'>While working with some project @ my current workplace, we came across a situation where we are using pg2 process group. Apparently pg2 does not load balance across processes registered in the pg2 group. It usually done in round robin way. So it may happen that even though many processes are registered under same group, but all messages will get queues in single process. &lt;br /&gt;&lt;br /&gt;My co-worker and I came with an algorithm to solve this. It is describe &lt;a href=&quot;http://lethain.com/entry/2009/sep/12/load-balancing-across-erlang-process-groups/&quot;&gt;here&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/707538970903765304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/707538970903765304' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/707538970903765304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/707538970903765304'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/09/load-balancing-in-erlang-using-pg2.html' title='Load balancing in Erlang using pg2 process groups'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-4887266209145611080</id><published>2009-08-21T19:09:00.001-07:00</published><updated>2009-08-21T19:39:58.390-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="clustering"/><category scheme="http://www.blogger.com/atom/ns#" term="erlang"/><category scheme="http://www.blogger.com/atom/ns#" term="highavailability"/><category scheme="http://www.blogger.com/atom/ns#" term="messagequeue"/><category scheme="http://www.blogger.com/atom/ns#" term="rabbitmq"/><title type='text'>Clustering RabbitMQ servers for High Availability</title><content type='html'>&lt;a href=&quot;http://www.rabbitmq.com/clustering.html&quot;&gt;Clustering guide&lt;/a&gt; on rabbitmq website is a good start. But it does not seem to work out of the box.&lt;br /&gt;&lt;br /&gt;Default rabbitmq-server script uses -sname (short node name) option on the erlang shell command line. This makes it impossible to setup the cluster as it is not possible to put a node into the cluster when short name is given. So first step is remove that line from the rabbitmq-server script&lt;br /&gt;&lt;br /&gt;By default erlang shell generate a random cookie and save that in the .erlang.cookie file in the home directory. Since the cookie generated is random, unless the same cookie file copied onto the other nodes, it is not possible to setup the cluster. Better idea is to set the cookie on the command line itself. This can done via the environment variable RABBITMQ_SERVER_START_ARGS.&lt;br /&gt;&lt;br /&gt;Also by default, rabbitmq-server do not set the full node name. One need to specify that on the command line argument. Better place is to set the environment variable RABBITMQ_SERVER_START_ARGS (same as the one used to set the cookie)&lt;br /&gt;&lt;br /&gt;Erlang&#39;s DNS lookup is done via inet module. By default it uses /etc/hosts as the first one to resolve the hostname. Therefore in some environments (at least in my environment), short name does not resolve to long name when I use inet:gethostbyname(Shortname) function. I get short name back in hostent structure. Workaround for this is to force the use of native library for dns lookup. This can be done via inetrc file. By default Erlang uses $HOME/.inetrc file (if exists). Non-standard location can be specified via ERL_INETRC environment variable. Don&#39;t forget to set the full path name.&lt;br /&gt;&lt;br /&gt;Content of the inetrc file will look like&lt;br /&gt;&lt;br /&gt;{lookup, [native]}.&lt;br /&gt;&lt;br /&gt;Other possible options are file,yp,dns.&lt;br /&gt;&lt;br /&gt;It is good to know some other environment variables.&lt;br /&gt;&lt;br /&gt;RABBITMQ_LOG_BASE -&gt; log location (default /var/log/rabbitmq)&lt;br /&gt;RABBITMQ_NODENAME -&gt; node name to be used (default rabbit)&lt;br /&gt;RABBITMQ_MNESIA_BASE -&gt; location for mnesia database (default /var/lib/rabbitmq/mnesia)&lt;br /&gt;&lt;br /&gt;If your machine has multiple network interfaces, by default RabbitMQ binds to all the network interfaces. In some cases it is not desirable. One can force it to bind to only one network interface by setting the environment varaible RABBITMQ_NODE_IP_ADDRESS to the ip address of the network interface.&lt;br /&gt;&lt;br /&gt;Here is a summary of all environment variables required&lt;br /&gt;&lt;br /&gt;RABBITMQ_SERVER_START_ARGS=&quot;-name rabbit@`hostname` -setcookie rabbit&quot;&lt;br /&gt;RABBITMQ_LOG_BASE=/home/baliga/rabbit&lt;br /&gt;RABBITMQ_NODENAME=rabbit&lt;br /&gt;RABBITMQ_MNESIA_BASE=/home/baliga/rabbit&lt;br /&gt;ERL_INETRC=/home/baliga/inetrc&lt;br /&gt;&lt;br /&gt;Now it is time to start rabbitmq server on all the nodes.&lt;br /&gt;&lt;br /&gt;rabbitmq-server -detached&lt;br /&gt;&lt;br /&gt;To setup the cluster rabbitmqctl script is used. By default this script too has -sname option setup on the command line. Delete this line from rabbitmqctl file. In order for this script to communicate with the node, long name and cookie required. Set this via RABBITMQ_CTL_ERL_ARGS environment variable&lt;br /&gt;&lt;br /&gt;export RABBITMQ_CTL_ERL_ARGS=&quot;-name rabbitmqctl@`hostname` -setcookie rabbit&quot;&lt;br /&gt;&lt;br /&gt;Note that the cookie should be same as that of the rabbitmq-server instance.&lt;br /&gt;&lt;br /&gt;Now you can run the rabbitmqctl to setup the cluster.&lt;br /&gt;&lt;br /&gt;On each of the node, run the following command&lt;br /&gt;&lt;br /&gt;   1. rabbitmqctl stop_app&lt;br /&gt;   2. rabbitmqctl reset&lt;br /&gt;   3. rabbitmqctl cluster &lt;long name of node&gt;&lt;br /&gt;   4. Repeat step 3 for all nodes in the cluster except for itself.&lt;br /&gt;   4. rabbitmqctl start_app&lt;br /&gt;&lt;br /&gt;Now the cluster is ready to be used.&lt;br /&gt;&lt;br /&gt;Some questions are not answered here like how the clustering works when nodes are behind separate firewalls. What ports need to be opened in firewall for clustering to work. I am still doing the research on it. Will post the findings soon.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/4887266209145611080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/4887266209145611080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4887266209145611080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/4887266209145611080'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/08/clustering-rabbitmq-servers-for-high.html' title='Clustering RabbitMQ servers for High Availability'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-1983433909105326002</id><published>2009-08-13T19:14:00.001-07:00</published><updated>2010-08-24T10:01:54.420-07:00</updated><title type='text'>Is parallel computing/concurrency  hard to get?</title><content type='html'>Regarding this subject, first question I would like to ask is why one need concurrency? My one line answer would be &quot;As we go into the future, number of cores available on even desktops will increase dramatically&quot;. That&#39;s why one need to think in terms of parallel operations instead of serial operations. Many libraries are already there to achieive this like MPM. &lt;br /&gt;&lt;br /&gt;In my opinion, these libraries are hard to use and still need to deal with the underlying network architecture. But it is not necessary. It can be achieved without getting into the low level functions. Only thing is require is &quot;changing the way we think of designing the system&quot;. &lt;br /&gt;&lt;br /&gt;Functional is my answer to this problem. Just thinking functional is not enough. But one should get the real feel of it. One need to forget everything he/she knows and start thinking like a child. Start to learn things from the begining. &lt;br /&gt;&lt;br /&gt;When I started thinking functional, even though I was thinking functional but that functional always turned out to be serial. Then I got introduced to this wonderful language called &quot;Erlang&quot;. This really force one to think and do things not only in functional but do things in concurrency.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/1983433909105326002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/1983433909105326002' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/1983433909105326002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/1983433909105326002'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/08/is-parallel-computingconcurrency-hard.html' title='Is parallel computing/concurrency  hard to get?'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-1429287163014210535</id><published>2009-08-11T23:15:00.001-07:00</published><updated>2009-08-11T23:16:40.353-07:00</updated><title type='text'>Nice photography!</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;http://mail.google.com/mail/?ui=2&amp;ik=6812c99797&amp;view=att&amp;th=121aa5759d8cb2f2&amp;attid=0.1&amp;disp=emb&amp;realattid=0.1.1&amp;zw&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 399px; height: 255px;&quot; src=&quot;http://mail.google.com/mail/?ui=2&amp;ik=6812c99797&amp;view=att&amp;th=121aa5759d8cb2f2&amp;attid=0.1&amp;disp=emb&amp;realattid=0.1.1&amp;zw&quot; border=&quot;0&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/1429287163014210535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/1429287163014210535' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/1429287163014210535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/1429287163014210535'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/08/nice-photography.html' title='Nice photography!'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-970528744702948483.post-6611371158485066969</id><published>2009-08-04T08:51:00.000-07:00</published><updated>2009-08-04T08:56:01.992-07:00</updated><title type='text'>New and improved delicious released</title><content type='html'>Today Yahoo! Delicious released a new cool features.&lt;br /&gt;&lt;br /&gt;   * Integration with Twitter. See the related tweets.&lt;br /&gt;   * Share interesting links not just with delicious users, but also with your friends via &lt;span style=&quot;font-weight:bold;&quot;&gt;email&lt;/span&gt;.&lt;br /&gt;   * Search is ever more improved now. You can see the search results on timeline. Find the activity for your search terms over time (even though it is not done with Yahoo! Search)&lt;br /&gt;   * You can watch youtube and other  videos inline now. No need to leave delicious search page.&lt;br /&gt;   * Flickr images are also displayed inline.&lt;br /&gt;&lt;br /&gt;Congratulations to delicious team.</content><link rel='replies' type='application/atom+xml' href='http://dudefrommangalore.blogspot.com/feeds/6611371158485066969/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/970528744702948483/6611371158485066969' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/6611371158485066969'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/970528744702948483/posts/default/6611371158485066969'/><link rel='alternate' type='text/html' href='http://dudefrommangalore.blogspot.com/2009/08/new-and-improved-delicious-released.html' title='New and improved delicious released'/><author><name>Dude From Mangalore</name><uri>http://www.blogger.com/profile/11648794788677197501</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>