<?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>ByteLion</title>
	<atom:link href="http://bytelion.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://bytelion.com</link>
	<description></description>
	<lastBuildDate>Sun, 05 Feb 2012 20:47:23 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Rails app with HTML5 Websockets</title>
		<link>http://bytelion.com/blog/rails-app-with-html5-websockets/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=rails-app-with-html5-websockets</link>
		<comments>http://bytelion.com/blog/rails-app-with-html5-websockets/#comments</comments>
		<pubDate>Wed, 01 Feb 2012 07:39:15 +0000</pubDate>
		<dc:creator>m4risu</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://bytelion.com/?p=637</guid>
		<description><![CDATA[Reasoning: Recently on the project I have run into a requirement of delivering the results to the client browser in an instant that some delayed job has been completed. The architecture itself was pretty complex and the job sometimes took more than 3 seconds. Polling was taking too much of the resources and the delay [...]]]></description>
			<content:encoded><![CDATA[<h3>Reasoning:</h3>
<p>Recently on the project I have run into a requirement of delivering the results to the client browser in an instant that some delayed job has been completed.<br />
The architecture itself was pretty complex and the job sometimes took more than 3 seconds.<br />
Polling was taking too much of the resources and the delay was still high.</p>
<p>The decision was to switch to the <strong>html5</strong> websockets.</p>
<p>To send the message to the listening service there is a nice implementation of ruby websocket client<a href="https://github.com/gimite/web-socket-ruby"></p>
<p>https://github.com/gimite/web-socket-ruby</a></p>
<p>Then in the resque worker I was able to use following</p>
<pre>WebSocket.new("ws://example.com:9090/").send("expected message")</pre>
<p>Now it does not matter it is the Controller, model or resque worker.</p>
<h3>The websocket broadcaster:</h3>
<pre>require 'em-websocket'

EventMachine.run {
  @channel = EM::Channel.new
  EventMachine::WebSocket.start(:host =&gt; "0.0.0.0", :port =&gt; 9090) do |ws|
    ws.onopen {
      sid = @channel.subscribe { |msg| ws.send msg }

      ws.onmessage { |msg|
        @channel.push msg
      }

      ws.onclose {
        @channel.unsubscribe(sid)
      }
    }
  end
}</pre>
<p>It works like a hub so it repeats message to everyone connected listener.</p>
<h3>Tricky part</h3>
<p>The most tricky here was how to run the websocket service on production machine.</p>
<p>I gave a &#8216;<a title="daemons github repository" href="https://github.com/ghazel/daemons" target="_blank">daemons</a>&#8216; gem a try.</p>
<pre>#!/usr/bin/env ruby

APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__) + '/..'))
APP_ENV =  ENV["APP_ENV"] || "development"
$LOAD_PATH.unshift(APP_ROOT + '/lib') unless $LOAD_PATH.include?(APP_ROOT + '/lib')

require 'rubygems'
require 'daemons'

def stop_and_exit
  # Do something useful here....
  exit 0
end

Signal.trap('INT') { stop_and_exit }
Signal.trap('TERM'){ stop_and_exit }

options = {
  :app_name =&gt; 'Websocket',
  :multiple =&gt; false,
  :log_output =&gt; true,
  :dir_mode =&gt; :normal,
  :dir =&gt; File.join(APP_ROOT, 'log')
}
Daemons.run(File.join(APP_ROOT, 'websocket.rb'), options)</pre>
<h3>Receiving the message (in Javascript):</h3>
<pre>var socket = new MozWebSocket("ws://example.com:9090);
socket.onopen = function(){
  // something can be done here
};
socket.onmessage = function(event){
  if(event.data.indexOf("expected message") != -1){
    // do the call since job has finished and results are ready to be displayed</pre>
<pre>    // close if connection is not needed anymore
    socket.close();
  }
};</pre>
<p>Receiving the message is the easiest task. This js code just wait for &#8220;expected message&#8221; to be received, then some work can be done.</p>
<h3>Conclusion</h3>
<p>Eventmachine and HTML5 Websockets create nice glue to scattered architecture when latency is the key.</p>
]]></content:encoded>
			<wfw:commentRss>http://bytelion.com/blog/rails-app-with-html5-websockets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Finish Bad Work</title>
		<link>http://bytelion.com/blog/how-to-finish-bad-work/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=how-to-finish-bad-work</link>
		<comments>http://bytelion.com/blog/how-to-finish-bad-work/#comments</comments>
		<pubDate>Sat, 12 Nov 2011 08:57:50 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://bytelion.com/?p=244</guid>
		<description><![CDATA[&#160; I was recently given a very complicated task:  installing a highly dependent project in a complex environment ( one of 30 different configurable environments) without VMs or root privledges.   Now, to complicate things, image that you don&#8217;t have any guidance, not one thing written.   All you have is a poorly documented configuration [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.codinghorror.com"><img class="size-full wp-image-437 alignleft" title="coding horror" src="http://bytelion.com/wp-content/uploads/coding-horror.jpg" alt="" width="170" height="170" /></a></p>
<p>&nbsp;</p>
<p>I was recently given a very complicated task:  installing a highly dependent project in a complex environment ( one of 30 different configurable environments) without VMs or root privledges.   Now, to complicate things, image that you don&#8217;t have any guidance, not one thing written.   All you have is a poorly documented configuration file known in Maven as the POM, 10 sets of property files, and a git directory.   To make matters even worse if possible, you have never touched this code and you can&#8217;t write any of it.  You can only compile, build, configure, install, and troubleshoot.   Oh, the developers who wrote the code are in remote offices  and you are installing this complex software in a remote network, without access to the internet.  Number of external services requires for integration = 10+ rest based with encrypted services.</p>
<p>The challenge is daunting.</p>
<p>&nbsp;</p>
<p>These are the steps that I took to overcome:</p>
<p>1. Procrastinate.  That&#8217;s right, I said it.   I solved a few other issues knowing that this task was looming   Is this healthy?  I am not sure, but this posting is part of that procrastination.  Who knows, maybe someone will cancel the task and I wouldn&#8217;t have to do it , right?  Wrong.</p>
<p>2.  Control It  -  Create a teaching aid to teach someone else.  When you teach something, you must learn the material better.  It it only through teaching that you really learn.  I turn to documentation as not only a helper for those that follow, but more as a motivator.    Face it, compiling and configuring someone else&#8217;s work is  just about the worst job out there.  When you think of the benefits and value you have by building training material, just about any task is bearable.   If you have control, you are going to be much happier.</p>
<p>3.  Acknowldge your Pain &#8211; When doing something very difficult, remind yourself&#8230; it is going to suck at first, bad.  Then,  it will get easier.   It always does, provided you have the prerequisite knowledge to complete the task.  If you find yourself without the basic fundamentals in place,  you will always struggle until your foundation is correct.  You are human and this cycle is natural.  I acknowledge the pain by swearing at my computer some times, if you choose this option, make sure you do it quietly. :- )</p>
<p>4. Don&#8217;t give up &#8211; work through the pain and don&#8217;t give up.   Grab a coworker and talk through a problem you are having.  Even if  they don&#8217;t know how to solve it, it can feel better or help you work through something.</p>
<p>5. Celebrate &#8211; By now, maybe is it 1 day or 5 days later, you will have solved the problem and become that much sharper for it.  Realize that when you can do hard jobs, other people around you will value that skill, even if they don&#8217;t say it.</p>
<p>6. Do it again.  As soon as possible, volunteer for the same job.   Taking the hard jobs means that you are typically going to grow your skill set.   Even if this boss doesn&#8217;t realize how valuable these skills are, remember, that one day, you will find someone who does appreciate them.</p>
<p>7.  Expand Your Influence &#8211; If you can influence the work so that it is easier to do, then that is even better.</p>
<ul>
<li>Train a coworker &#8211; grab someone and help them through the steps that you just completed.</li>
<li>Take the time to work with the remote developers building your code to make the task easier to complete.   Your customer will thank you for it!</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://bytelion.com/blog/how-to-finish-bad-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

