My Favorite Ted Talks

I’ve been going through some of my favorite Ted Talks, here’s the list.

1. Sir Ken Robinson on Creativity.

2. Simon Sinek, People don’t buy what you do, they buy why you do it

I love this talk just for that one line which just resonates with everything I believe in.

3. Dan Ariely

Lastly, to my favorite speaker Dan Ariely. I’ve been a big fan of his books and talks. I strongly recommend you read Predictably Irrational. Here are his talks

I can’t believe I missed this the first time around.

4. Derek Sivers – How to start a movement.

Tagged , ,

Async Responses in Thin and a Simple Long Polling Server

I’ve been playing with Thin, the Ruby web server which packages the awesomeness of Rack, Mongrel and Eventmachine (\m/). However, the thing that blew me away completely was the James Tucker’s Async Rack that was integrated to Thin. The combination opens a whole new world of realtime responses, something that I’ve been constantly switching to NodeJS and SocketIO for.

Async Rack

A simple rack application would look like this


# my_rack_app.ru

class MyRackApp
  def call(env)
    [200, {'Content-Type' => 'text/html'}, ["Hello World"]]
  end
end

run MyRackApp.new

# thin start -R my_rack_app.ru -D -p3000

This simple rack app on hitting port 3000 responds with the a status code (200), the content-type and some body. Nothing special. With async rack we’d be able to send the response head back while we build the response. Once the response is built we send the body and close the connection.

A quick glance at Patrick’s Blog (apologies for not being able to find the last name of the author of this blog) should give you an excellent understanding of what I’m trying to explain

A simple async app


# my_async_app.ru

AsyncResponse = [-1, {}, []].freeze

class MyAsyncApp
  def call(env)
    Thread.new do
      sleep(10)
      body = [200, {"Content-Type" => "text/html"}, ["<em > This is Async </em >"]]
      env['async.callback'].call(body)
    end

    AsyncResponse
  end
end


The AsyncResponse is a constant which returns a -1 status which tells the server that the response will be coming later asynchronously. It, as defined in the examples provided in thin an “Async Template” Async Template

On a request the code initially returns an AsyncResponse while the thread waits on the sleep request. Once the thread is active again it builds the response and sends the response keeping the connection alive.

An async app where we build the response and close the connection

From here on, it would really help to have the thin code open in your text editor. We would be looking at the request.rb, response.rb and the connection.rb methods from /thin folder.


require 'rubygems'

class DeferrableBody
	include EventMachine::Deferrable

	def each &blk
		puts "Blocks: #{blk.inspect}"
		@callback_blk = blk
	end

	def append(data)
		puts " -- appending data --"
		data.each do |data_chunk|
			puts " -- triggering callback --"
			puts @callback_blk.call(data_chunk)
		end
	end	
end

class AsyncLife
	AsyncResponse = [-1, {}, []].freeze
	
	def call(env)
		body = DeferrableBody.new

		EM.next_tick {
			puts "Next tick before async"
			sleep(3)
			puts "#{env['async.callback']}"
			env['async.callback'].call([200, {'Content-Type' => 'text/plain'}, body])
			sleep(5)
		}

		puts "-- activated 5 second timer --"
		EM.add_timer(5) {
			puts "--5 second timer done --"
			body.append(['Mary had a little lamb'])

			puts "-- activated 2 second timer --"
			EM.add_timer(2){
				puts "--7 second timer done --"
				body.append(['This is the house that jack built'])
				puts "-- succeed called -- "
				body.succeed
			}

		}


		AsyncResponse
	end
end

run AsyncLife.new

This example uses Eventmachine Deferrable which allow us to determine when we’re done building our response. But the tricky part I struggled to get my head around was the strangle looking each method and how it uses the append method to build our responses.

Walking through the code

When the request comes in from the browser the application renders the AsyncResponse constant which tells the server that the response body is going to be built over time. Now on request eventmachine’s ( checkout thin/connection.rb ) post_init method creates a @request and @response object. This triggers a post_process method which on the first call returns without setting the header, status or body and prepares for the asynchronous response.

On next_tick we begin to create our header. We initialize a EM::Deferrable object which is assigned as the response body and this ensures the header is sent ahead of the body (because we don’t have anything to iterate over in the each block where the response is sent) The env['async.callback'] is a closure for the method post_process which is created by method(:post_process) checkout the pre_process method in the thin/connection.rb

The each method in our Deferrable class overrides the default each implementation defined by the response object. So now our each block is saved in an instance variable @callback_blk which is call ed when we call the append method. So essentially we are calling send_data on each of the data blocks we’re sending back when we call the append method.

Once that’s done we call succeed which tells Eventmachine to trigger the callback to denote we’re done building the body. It ensures the request response connection is closed.

The default each implementation


 # Send the response      
      @response.each do |chunk|        
        trace { chunk }
        send_data chunk
      end

Thats pretty much what I gathered by going through the code on async response with thin and rack. Another useful module is the thin_async bit written by the creator of thin @macournoyer available here . This pretty much abstracts the trouble of overriding the each block.

Here’s an example of a simple long polling server I built using thin available here

Hope this is helpful

Tagged , , ,

Tagging with Redis

Its been a long time since my last post and this one is about Redis. So I’ve been working on this project for a bit now and I had this story to implement where I had to associate posts with other posts which were identified to be similar based on a tagging system that already existed. The trouble here was that the existing tagging system was closely tied to a lot of other functionalities and couldn’t be easily (quickly) re-written. The feature needed to be rolled out quickly for several reasons which I won’t get into.

The Problem

The tags associated to each posts were poorly organized where one record in the Tag model would hold all the tags associated to the post as a whitespace separated string (ouch!)


posts.tags.first.name # business money finance investment

So to find posts that had 2 tags in common from a database of approximately 2000 posts with at least 4 tags each took a significant amount of time. Here is a basic benchmark of just finding the matches on each request.


Benchmark.measure do
 similar_posts = []
 Post.tagged_posts.each do |post|
   similar_tags = (post.tags.first.name.split & current_post.tags.first.name.split)
   similar_posts << post if similar_tags.size >= 2
  end
end

Here is what benchmark returns


 => #Benchmark::Tms:0x111fd8cb8 @cstime=0.0, @total=2.25, 
@cutime=0.0, @label="", @stime=0.19, @real=4.79089307785034, @utime=2.06

Not Great.

So the next option was to pre-populate the related posts for every post and store it in the database as similar_posts. So all that was required was to fetch the post with its ‘similar_posts’ at runtime. This seemed like an acceptable solution considering the tags were not changed on a regular basis but if changed it would require the similar_posts table to be rebuilt again(which took a long time). Here is the benchmark for fetching the pre-populated data from the database


Benchmark.measure { p.similar_posts }
=> #Benchmark::Tms:0x104d153f8 @cstime=0.0, @total=0.0100000000000007, 
@cutime=0.0, @label="", @stime=0.0, @real=0.0333230495452881, @utime=0.0100000000000007

Nice! But this came at the cost of having to rebuild the similar_videos every time something had to be changed with tags or videos.

Redis

Redis is this awesome in memory key-value, data-structure store which is really fast. Though it would be wrong to think of it as a silver bullet it does a lot things which are really awesome. One is the ability to store data structures and perform operations on them, PubSub and a lot of other cool stuff. It even allows you to persist the information using a snapshotting technique which takes periodic snapshots of the dataset or by “append only file” where it appends to a file all the operations that take place and recreates the dataset in case of failure.

In my case I didn’t need to persist the data but maintain a snapshot of it in memory. So assuming some basic understanding of Redis and the redis gem I’ll describe the approach.

We created a SET with each tag name as key in REDIS so that every tag contains a set of the post_ids of all posts that have that tag. Inorder to identify a post having two tags in common all that was needed was the intersection of tags sets and REDIS provides built methods for these operations. Thats it!

 
{"communication" => ['12','219', .. , '1027']}  #sample SET

Fetching the similar posts


def find_similar_posts 
  similar_posts = []
  if self.tags.present? && self.tags.first.present?
    tags = self.tags.first.name.split
    tags_clone = tags.clone
    tags_clone.shift
    tags.each do |tag| 
      tags_clone.each do |tag_clone|  
        similar_posts << REDIS_API.sinter(tag.to_s, tag_clone.to_s)
      end
      tags_clone.shift        
     end
  else
    puts "No matching posts."
   end                          
 similar_posts -= [self.id.to_s]
 Post.find(similar_posts)  

Benchmark


 >> Benchmark.measure { p.find_similar_posts }
Benchmark::Tms:0x1100636f8 @cstime=0.0, @total=0.0100000000000007, @cutime=0.0, @label="",
@stime=0.0, @real=0.163993120193481, @utime=0.0100000000000007
 

Which is pretty good considering that we do all the computation within this request and nothing is pre-populated.

Tagged , ,

MongoDB with Mysql and ActiveRecord.

I’ve been playing with mongodb for a little while now and here some basic issues that I faced and some setup help.

Setting up mongo is really straight forward in OS X. You may either download it from here or use homebrew to install it. If your using brew

brew install mongodb

should do it.

Skip over to the bin folder and launch it with

./mongod

You’ll now see that the console is available for access. It can be launched by

./mongo

and you should see a irb like shell.

Using MongoDB with Mysql while continuing to use Mysql as the primary datastore.

I have been looking into Mongo purely because I was told its highly performant but I still need my primary datastore to be mysql because I see the need for transactions in the future. I decided to go with mongoid (was recommended because its maintained and is unlikely to vanish soon) which only require you to add the gems to the Gemfile.

gem "mongoid", "~> 2.3"
gem "bson_ext", "~> 1.4"

# Run bundle install

If you decide to use Mongoid with MongoDB as your primary datastore you would have to follow these steps completely. However, since I needed to still retain my mysql configuration I only ran this step

 rails g mongoid:config

This should generate a mongoid.yml file similar to your database.yml file in the config folder. A very well written blog post on how to setup users on mongodb and maintain it with mongoid is provided here and I strongly recommend reading it.

Running the generator now makes mongo your default datastore and using the generator would build models using mogoid and not ActiveRecord. To ensure that active record remains your primary orm add the following config to your application.rb

config.generators do |gen|
        gen.orm :active_record
    end

Source :http://stackoverflow.com/questions/6372626/using-active-record-generators-after-mongoid-installation

Now you have ActiveRecord as your primary ORM and you may generate models with mongoid when you need it.

Errors when installing MongoDb on Ubuntu

As before you can find the tar ball at the Mongodb downloads page but on installing and running mongo, I encountered this error.

 exception in initAndListen std::exception: dbpath (/data/db/) does not exist, terminating
  dbexit:
 	 shutdown: going to close listening sockets...
 	 shutdown: going to flush oplog...
 	 shutdown: going to close sockets...
 	 shutdown: waiting for fs preallocator...
 	 shutdown: closing all files...
     closeAllFiles() finished
  dbexit: really exiting now

The error says that it can’t find the /data/db folder. So just create with the right user permissions and you should be good to go

Source : http://ronaldbradford.com/blog/mongodb-experience-getting-started-2010-06-09/

Tagged ,

Improving on the original AMQP chat application

Continuing from where my earlier post on AMQP left off, this post describes the changes introduced to make the application more object oriented, shifting from the fanout exchange to direct exchanges and new problems on long polling.

My initial example of the amqp_server would make most Ruby developers cringe. So a quick glance at the AMQP documentation (which is awesome) revealed a simple approach on how to structure the code. The complete source is available here

Here is the revised amqp_server

require 'rubygems'
require 'amqp'
require 'mongo'
require 'em-websocket'
require 'json'
require 'evma_httpserver'
require File.expand_path('../message_parser.rb', __FILE__)
require File.expand_path('../producer.rb', __FILE__)
require File.expand_path('../worker.rb', __FILE__)
require File.expand_path('../consumer.rb', __FILE__)
require File.expand_path('../http_server.rb', __FILE__)
require File.expand_path('../setup.rb', __FILE__)
require File.expand_path('../socket_manager', __FILE__)


# start the run loop
EventMachine.run do
  connection = AMQP.connect(:host => '127.0.0.1', :port => 5672)
  channel = AMQP::Channel.new(connection)

  socket_manager = SocketManager.new
  EventMachine.start_server('127.0.0.1', 8082, Setup, [socket_manager, channel])
# EventMachine.start_server('127.0.0.1', 8081, HttpServer, channel)

  puts "---- Server started on 8081 -----"


   EventMachine::WebSocket.start(:host => '127.0.0.1', :port => 9000) do |ws|

    ws.onopen do
      puts "EStaiblished......"
      ws.send('Connection open')

     puts ">>>>>>>>#{ws.request["query"]} <<<<<<<<< message[:roomname])
    end

    ws.onclose do
      puts " socket connection closed."
      roomname = ws.request["query"]["roomname"]
      username = ws.request["query"]["username"]
      SocketManager.new().remove_socket(roomname, ws)
    end
  end
end

Switching from Fanout to Direct Exchanges

The most significant change is switching from fanout exchanges to direct exchanges. This identifies the room to have a unique queue and is bound to an exchange with a routing_key = room_name. All new messages that arrive are published via the exchange with the same routing key. This works like a charm when working with websockets but won’t be a wise approach when using long polling or simple polling.

Why this works with sockets but is not the best design for polling

In this post we consider each room to have a queue and all messages directed to this room and available from this queue. With websockets its easy to keep track of users connected to this room and on arrival of a message its easy to broadcast this to all the websockets connected on that room.

Keeping track of websockets for a room. socket_manager.rb

class SocketAPI
  def self.api
    @sockets ||= {}
  end
end

class SocketManager
  attr_accessor :sockets

  def initialize
    @sockets = SocketAPI.api
  end

  def add_socket(roomname, sock)
    puts "=#{roomname}" * 50
    puts  "IN ADD SOCKET"
    puts "=" * 50
    puts "SOCKETS #{SocketAPI.api.inspect}"
    @sockets = SocketAPI.api
    if @sockets["#{roomname}"]
      puts "=" * 50
      puts "SOCKET HASH Exists"
      puts "=" * 50
      socket_array = @sockets["#{roomname}"]
      socket_array.push(sock)
    else
      #puts "=#{roomname.blank?}" * 50
      puts "SOCKET HASH DOES NOT Exists"
      puts "=" * 50
      @sockets[roomname.to_s] = []
      socket_array = @sockets["#{roomname}"]
      socket_array.push(sock)
    end
  end

  def remove_socket(roomname, sock)
    sockets = SocketAPI.api
    sockets["#{roomname}"].delete sock
  end
end

So all that is needed is identify the associated sockets for a room and push messages from the consumer to the browser. With polling however we would need to use the ‘pull api’ for queues. Heres an example


require "rubygems"
require "amqp"

EventMachine.run do
  connection = AMQP.connect(:host => '127.0.0.1')
  puts "Connected to AMQP broker. Running #{AMQP::VERSION} version of the gem..."

  channel  = AMQP::Channel.new(connection)
  queue    = channel.queue("c", :auto_delete => true)
  exchange = channel.direct("cexchange")

#  queue.subscribe do |payload|
#    puts "Received a message: #{payload}. Disconnecting..."
#    connection.close { EventMachine.stop }
#  end

  queue.bind(exchange, :routing_key => "cratos")


  exchange.publish "Hello, world!", :routing_key => "cratos"
  exchange.publish "Goodbye world", :routing_key => "cratos"

  exchange.publish "Goodbye world", :routing_key => queue.name


  q = channel.queue("c", :auto_delete => true)


  q.status do |message_count, consumer_count|
    messages = message_count
    consumers = consumer_count

    if messages > 0
      0.upto(messages - 1) do
        q.pop { |m, p| puts "#{m} Payload #{p}" }
      end
    end
  end
end

So we pop off messages from the queue one by one, but in this case we have no information about all the logged in users. So the messages are wiped out from the queue by the first poll that arrives from the members of the room. What this means is that the queue is wiped clean with the first poll updating one user’s browser window with the latest messages while the others see the old messages.

What are the alternatives

Right now it seems like “topic exchanges” would work. Every user could have a queue for each room. So the routing key could be something like “sid.harry_potter” where the period separates the username and the roomname. Maybe this is not the best alternative but the first one I could think of.

Ugly hack

One part of the code which seems like a horribly ugly hack to me is the Setup class which creates our queues. Setup.rb simply defines a basic EventMachine Server which listens on port 8082 for incoming requests. This request arrives when the user creates a new room (in our rails app).

The incoming requests triggers a call to the worker.rb which creates the queues. The other change aren’t that significant other than moving chunks to respective classes.

I still continue to use Websockets but using websockets for production wouldn’t be wise considering its limited adoption. Hence I dabbled with SocketIO and simple XHR-polling.

Though my current link to the source does not contain my experiments with Long Polling I would like to briefly go into the problems I faced.

Some of the basic issues would be violating the same origin policy and the easiest solution that I could come up with was to use Apache proxying.



   ServerName localhost
   DocumentRoot /etc/apache2/www/trackertalk/public/    
   ErrorLog "/private/var/log/apache2/dummy-host.example.com-error_log"
   CustomLog "/private/var/log/apache2/dummy-host.example.com-access_log" common
   ProxyPass /poll http://a.localhost:8081
   ProxyPassReverse	/poll http://a.localhost:8081
   RailsEnv development	



   ServerName a.localhost
   ProxyRequests Off
   ProxyPass / http://localhost:8081
   ProxyPassReverse / http://localhost:8081


All that is needed is to forward all requests that arrive to localhost/poll to a.localhost:8081 where our http_server would live. The http_server is another http_server that uses EM::Http_Server on port 8082 to handle incoming requests. It would need to be able to handle incoming requests (like a poll to check for messages in the relevant queue and forward it back to the client or a new message and add it to the correct queue.) and provide
the required reponse.

If you know or have built applications using AMQP and Ruby, I would love to know more about how production ready applications are structured and built. Any suggestions, corrections or feedback on my code would be awesome

Tagged , , , ,

RabbitMQ and Rails. Why my chat application failed.

Over the last few weeks I’ve been playing with RabbitMQ and Rails have been completely blown away by how awesome it is.

I started out to build a simple chat application which would allow users to create a room and log into the room and post messages to multiple users who were logged in. Though, this is probably not the best use case for using AMQP but it helped me understand how AMQP worked and maybe I’ll get to use somewhere more apt.

RabbitMQ

What is RabbitMQ
RabbitMQ is an open source, highly scalable messaging system which provides support for STOMP, SMTP and HTTP messaging. [www.rabbitmq.com]

It’s built using the Advanced Message Queuing protocol (AMQP) which provides APIs in Ruby and several other programming languages.

Installation

The easiest way to install RabbitMQ on the Mac is using homebrew. The Macports installation has many issues and I would recommend going with HomeBrew. It also takes care of all dependencies like the correct Erlang installation etc.

You can test your installation by moving into the installation ‘bin’ directory and running rabbitmq-server

If you end up seeing something like

 ...
 starting error log relay                                              ...done
 starting networking                                                   ...done
 starting direct_client                                                ...done
 starting notify cluster nodes 
 broker running

your good to go.

Creating our AMQP server

In Ruby we could run our AMQP server using the ‘amqp gem’ along with EventMachine.

The AMQP server code.

require 'rubygems'
require 'amqp'
require 'mongo'
require 'em-websocket'
require 'json'

....


@sockets = []
EventMachine.run do
  connection  = AMQP.connect(:host => '127.0.0.1')
  channel = AMQP::Channel.new(connection)
  puts "Connected to AMQP broker. #{AMQP::VERSION} "
  mongo = MongoManager.establish_connection("trackertalk_development")

  EventMachine::WebSocket.start(:host => '127.0.0.1', :port => 8080) do |ws|
    socket_detail = {:socket => ws}
    ws.onopen do
      @sockets < true)
        #AMQP::Consumer.new(channel, queue)

      elsif status[:status] == 'MESSAGE'
        full_message = " #{status[:username]} :  #{status[:message]}"
        exchange.publish(full_message)
      end
    end

    ws.onclose do
      @sockets.delete ws
    end
  end

end

The code snippet contains most of the amqp server code. The entire code lives inside the EM.run loop. Ignore the Mongo bit as it doesn’t play a part in our area of interest.

@sockets = []
EventMachine.run do
  connection  = AMQP.connect(:host => '127.0.0.1')
  channel = AMQP::Channel.new(connection)
...
 

In this snippet I created a new AMQP connection to localhost. When not provided with any other parameter the default port used by AMQP is 5672 with the username: guest and password :guest. Since the RabbitMQ installation will never (in most cases) have to be accessed from outside the server its safe to run the installation with the defaults.

The second line creates a new channel.

Once the channel is established the EM::Websocket block is used to allow modern browsers to connect to our server on port 8080

EventMachine::WebSocket.start(:host => '127.0.0.1', :port => 8080) do |ws|
    socket_detail = {:socket => ws}
    ws.onopen do
      @sockets < true)
        #AMQP::Consumer.new(channel, queue)

      elsif status[:status] == 'MESSAGE'
        full_message = " #{status[:username]} :  #{status[:message]}"
        exchange.publish(full_message)
      end
    end

    ws.onclose do
      @sockets.delete ws
    end

This is where the core logic lies. On the socket connect block I store the current socket in an array to use it later.

The ‘onmessage’ block is called when a new message arrives from the browser. Since I needed to dynamically create new exchanges and queues I used a very amateurish system. The message sent from the browser arrives with the following parameters in the JSON format

The following snippet is not a part of AMQP but a feature borrowed from XMPP to get my application working

{status:'status', username:'someusername', roomname:'someroomname', message:'somemessage'}

Status could have values from ['status', 'message', 'presence']
Username contains the ‘current_user’ name
Roomname indicates the ‘room’ the user has been logged into.

Status messages indicate that some kind of chore needs to be performed like subscribing to queues, binding exchanges etc.

Messages indicate that the message needs to be pushed to an exchange. When a message is published to an exchange, subscribing queues push the message to the browser using Websockets.

Presence messages indicate the users presence.

Why the entire application was a failure

The most important aspect while using AMQP is identifying the type of exchanges needed. In this case my assumptions on identifying rooms to be exchanges and users to have individual queues proved to be the reason for failure.

The reason why this assumption would fail is if a user queue would bind to multiple exchanges with each user having a unique queue assigned to him, a simple fanout exchange would push messages from different rooms to the user’s logged in chat room which is not what we want. This way users would end up receiving messages that are not relevant.

A ideal approach would have multiple users subscribe to a room (assumed to be the queue in this case) via a topic exchange or direct exchange.

I also believe that it would be logical to dynamically create queues and exchanges using the EM.periodic timer to check a NoSQL database or key-value store for new requests rather than using Websockets.

The AMQP server code is available here

Tagged , ,

window.unload, synchronous ajax and page loads

I’ve been working on a project that had me work with javascript based timers and required me to ensure certain data was updated before the user left the page. The obvious solution in this case was to handle the data updating on the window.unload event.

Now the task at hand was to ensure that on unload the quiz status (the object i was working with) needed to be updated to ‘DONE’ or something to that effect and the next object that was in the ‘NEW’ state needed to be fetched.

Synchronous AJAX (or whatever synchronous XMLHttpRequests are called)
The problem with using asynchronous ajax in such a situation would be that one cannot guarantee if the page refresh or a new request would wait long enough to see through the ajax request. Chances are the page may unload much before you receive confirmation that the request was completed. The advantage with synchronous ajax is that the page waits in a frozen state awaiting a confirmation before it loads the next request. Sync ajax in jquery

In most scenarios you would not need to have that confirmation but heres one valuable detail that I overlooked and may come in handy:

When you wait on a response the next request (which could have been caused by clicking a link or a refresh) to the server has already loaded and is waiting to be rendered while you wait on the unload event to display the confirmation of your cleanup action. In my case this was updating the state of the quiz object from new to done.

What I failed to acknowledge was that the new request is processed before the server actually receives the message from your ajax call. So if your next request depends upon the clean up action performed by your ajax call, the data that is waiting to be rendered is already stale (as it was fetched by working on data before the ajax updation took place)

Just to drive the point home, here are the sequence of events
1. Click Link/Refresh
2. Request for refresh or click fired
3. window.unload event fired (Response from the earlier request waiting to be rendered)
4. ajax call to update data on the server (Response from the earlier request waiting to be rendered)
5. ajax callback received
6. Data for click link/refresh rendered.

* the sequence is purely to illustrate the point.

A optimal solution would be to use filters if your using Rails.

This may sound trivial for most experienced developers but in case you overlooked this I hope this post saves you some time.

Tagged ,

EventMachine: Deferring Time consuming tasks to a separate thread

A small update on my last post which focuses on building a sample twitter feed application using eventmachine and the twitter gem. If you’ve already gone through the documentation and references, especially the introduction to eventmachine PDF, you would have noticed that the reactor is single threaded and the EM methods aren’t thread safe. It also describes a simple example on how to use EM.defer to run time consuming tasks on a separate thread as a background process by using a thread from the thread pool.

Though there isn’t significant benefit in running our twitter feed application’s ‘update fetch’ operation as a background process but for purely illustrative purposes lets make our server perform updates on a separate thread. EM.defer provides a callback option that allows us to fetch values returned by the background thread and return it to the user in the main thread.

Update your event_machine_server.rb file with the following changes and run both the client and server.

The code is also available here

 
require 'rubygems'
require 'eventmachine'
require 'socket'
require 'json'
require 'hashie'
require File.expand_path("twitter_lib.rb", __FILE__ + "/..")
require File.expand_path("tweet_Fetcher.rb", __FILE__ + "/..")

class Echo < EM::Connection

 attr_reader :data, :response, :status, :fetcher   
 
 def post_init   
   @status = :inactive 
    ip, port = Socket.unpack_sockaddr_in( get_peername) #peer.methods.inspect
    puts  "Connection Established from #{ip} #{port}"
  end

  def receive_data(data)
    puts "[LOGGING: RECEIVED] #{data}"
    @data = JSON.parse(data)
    puts "[LOGGING: PARSED DATA ] #{@data} #{@data.class.to_s}"
    initialize_fetcher
    execute_request
    
  end

  def unbind
    puts "Connection Lost" + self.inspect
  end
  
  def respond
    send_data(@response)
  end
  
  def execute_request
    if @data["op"] == "fetch"
      puts "Please wait while we fetch the data ..."
      @status = :active
      response = @fetcher.fetch      
      send_data(response.to_json)
      Echo.activate_periodic_timer(self)    
    elsif @data["op"] == "update"
      puts "Fetching update . . ."
      response = @fetcher.fetch_update
    #  send_data(response.to_json)      
    end
  end
  
  def self.activate_event_machine(this = nil)
    EM.run do 
        puts "Starting echo server . . . ."
        EM.start_server('0.0.0.0', 6789, Echo)
        puts "STARTED "
    end    
  end
  
  def self.activate_periodic_timer(this = nil)
    response = nil
    operations = Proc.new do     
      this.update_operation
      response = this.execute_request
    end
    
    callback = Proc.new{ this.send_data(response.to_json)}
    
    EM.add_periodic_timer(2) do
      EM.defer(operations, callback)      
    end    
  end
  
  def update_operation
    @data["op"] = "update"
  end
  
  private  

  def initialize_fetcher
    @fetcher =  Fetcher.new({ :consumer_key => "xxxxxxxxxxxxxxxx",
                     :consumer_secret => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                     :o auth_token => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
                     :o auth_token_secret => "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" 
                    })
                    
   # puts "[LOGGING FETCHER INITIALIZED] #{@fetcher.inspect}"                
  end
  
end

Echo.activate_event_machine

=begin
  EM.run do 
      puts "Starting echo server . . . ."
      EM.start_server('0.0.0.0', 6789, Echo)
      puts "STARTED "
    
      EM.add_periodic_timer(5) do
        puts "Timer activated"
      end    
  end
=end




Tagged , , ,

Event Machine: A sample application to learn about event machine

I have been playing around with event machine for a couple of days now and have been trying to work out a basic (quick and ugly) example to understand how it could be used for simple applications.

Though my understanding of the subject is still very superficial here is a sample application that you could try to get yourself going. There are a lot of tutorials available for this and I guess this would be a good starting point

To get a quick idea of the working app try changing the value of the ‘timeline’ key in the tweet_fetcher file to :public.

Further bulletins as events warrant.

Tagged ,

Javacript: Binding, call and apply methods

Continuing my interest in Javascript this would be second in the series of Posts revisiting the basics of Javascript.

One of the many things that I have been ignorant about when it comes to Javascript is the existence of bindings. Like Ruby ( and other languages) Javascript uses bindings to allow functions to be called with reference to a specific object.

I like to think of this as something similar to instance_eval in Ruby or the binding method.

Instance_eval evaluates an object in the context of an object its called with so lets take a simple example in Ruby


class Cat
def speak
 "miaow"
end
end

class Dog
def speak
"Bark"
end
end

d = Dog.new
=> #
>> c = Cat.new
=> #
>> c.instance_eval{ speak }
=> "miaow"

All this describes is that the speak method is invoked with reference to the instance c (Cat Object)

Similarly the binding method

class Person
  def bind
   @var = "Person Object"
  binding
 end
end

>> p= Person.new
=> #
>> b = p.bind
=> #
>> eval("@var", b)
=> "Person Object"

“binding” which is a kernel method provides us with a binding or snapshot of the context at a particular place in the code where it retains the execution context such as the variable values (@var in this example) which can be used at a later point. With eval we evaluate the value of the @var variable with respect to the binding generated earlier.

Similary Javascript provides us with the apply and call methods. Based on Christophe Porteneuve’s example on the listapart blog here is a simple example to illustrate the use of apply
and call methods


function Song(band, album, song){
	this.band = band;
	this.album = album;
	this.song = song;
	
	this.info = function(other){
		console.log(this);
			alert( 'Did you know '  + other.band + " covered " + this.band + "\'s " + this.song ); 
		}
		
	
	
}



var korn = new Song('Korn','Another Brick in the Wall', 'Another Brick in the Wall' );
var pink = new Song('Pink Floyd', 'The Wall', 'Another Brick in the Wall');

pink.info(korn);

In this case we see a message that says “Did you know Korn covered Pink Floyd’s Another Brick in the Wall”. So thats cool.

The problem occurs when the reference is lost (binding loss: when you assign a method to a variable or pass it as an argument). So lets append this to our earlier example

function display_info(fn, args){
	
		fn(args);
	
}

display_info(pink.info, korn);

Now we see “Did you know Korn covered undefined’s undefined”. The logger statement in the info method will show you that “this” actually is pointing to the window object and not Object of type Song. This is because the minute the binding it lost “this” starts referring to the default binding that is the window object.

So we solve the problem using call or apply. Add this to the bottom of the display_info method

	fn.apply(pink, [korn]);
	fn.call(pink, korn);

Now we see it works again. All we do here with the call and apply method is specify explicitly that we would be invoking the fn i.e. pink.info with reference to the pink object with the korn object as an argument.

So whats the difference between call an apply then? Nothing except that call expects individual arguments to be passed while apply accepts an array

        fn.apply(BindingObject, ArrayArgument);
	fn.call(BindingObject, Argument1, Argument2...);

The inferences drawn in this post have been learned from Christophe Porteneuve’s post titled Getting Out of Binding Situations in JavaScript from the ListApart Blog. Its an awesome post and definitely a must read if your interested in Javascript.

Tagged , , ,
Follow

Get every new post delivered to your Inbox.