zerocaffe.in Blog of Uncaffeinated Experiences on Entrepreneurship and Everything Else

4Oct/082

Linux commands output in PHP

My friend Rahul was giving me a demo of their Web UI and a small but nifty feature caught my eye. They had a feature of being able to configure their systems using the Web UI (which is pretty cool in itself!) and the console output from the configuration command in turn would be displayed in a html iFrame. My company has a similar internal tool which does the same but then showing the output in a step-by-step manner would really be a huge help.

Anyways, so cooked up a quick php function for our system. Hope someone finds this snippet useful.

< ?php
/**
 * @func: Executes the command passed to it as argument and prints the
 * command console output line by line onto the html output stream hence
 * giving the illusion of having the command executing in the html window itself.
 */
function html_exec_cmd($cmd)	{
	$proc = popen("($cmd)2>&1", "r");
	echo '<pre>';
	while(!feof($proc))	{
		$result = fgets($proc, 100);
		echo htmlspecialchars($result);
		flush();
	}
	pclose($proc);
	echo '</pre>';
}

html_exec_cmd('wget yahoo.com'); # sample command.
?>
10Jul/081

Erlang Ring Code

Erlang Ring Benchmark Problem:
In the Programming Erlang book by Joe Armstrong, we find this problem at the end of the Concurrent Programming chapter.

Write a ring benchmark. Create N processes in a ring. Send a message round the ring M times so that a total of N * M messages get sent. Time how long this takes for different values of N and M. Write a similar program in some other programming language you are familiar with. Compare the results. Write a blog, and publish the results on the Internet!

My contribution to the already growing list of Erlang Ring Benchmark problem. However this is just the code for the Erlang, a N ring setup and M messages moving around the ring in parallel.

-module(ring).
-export([benchmark/2]).
 
%% run benchmark for N processes and M messages.
benchmark(N, M) ->
        Pids = makering(N),
        for(1, M, fun() -> spawn(fun() -> start(message, Pids) end) end).
 
%% setting up the process ring for sending
%% messages & return the Pids array
makering(M)     ->
        %% create the processes
        Pids = for(1, M, fun() -> spawn(fun() -> loop() end) end),
        [Head | _T] = Pids,
        %% now setup the ring. one simple init loop to make each
        %% each process aware of its next process in the ring
        %% we need to pass Head head here as we want to connect
        %% the last process back to the head.
        connect(Head, Pids),
        %% return the Pids
        Pids.
 
%% If only two elements are left in the list just point
%% the first process to the next process. And point the
%% the last process to the first process.
connect(Head, [H, N])   ->
        H ! {next, N},
        N ! {next, Head};
%% Connect the head and the next element and move to the
%% next elements
connect(Head, [H, N | T])       ->
        H ! {next, N},
        connect(Head, [N | T]).
 
%% send message from the beggining of the 
%% ring.
start(Mesg, Pids)	->
	[Head|T] = Pids,
	Head ! {lists:last(T), Mesg, length(Pids)}.
 
%% order a mass suicide for all process nodes	
killall(Pids)	->
	lists:foreach(fun(Pid) -> Pid ! die end, Pids).
 
%% message waiting loop. waits for message and sends 
%% it to the next process node. commits sepukku if 
%% it is ordered to die.
loop()	->
	receive
		%% now that we have the next pid, we move into the
		%% the listening loop for that function. remember
		%% the loop/1 will share the same Pid as this, so
		%% no worries.
		{next, NextPid} ->
			io:format("Set next for ~p as ~p~n", [self(), NextPid]),
			wait(NextPid)
	end.
 
wait(NextPid)	->
	receive
		{From, Mesg, NumHops}	when NumHops >= 0 ->
			io:format("~w from ~p to ~p~n", [Mesg, From, self()]),
			NextPid ! {self(), Mesg, NumHops - 1},
			wait(NextPid);
		die -> void
	end.
 
%% custom for loops
for(N,N,F)	->	[F()];
for(M,N,F)	->  [F()|for(M + 1, N, F)].
13Jun/082

Moved to WP 2.5.1

Finally moved the site to WordPress 2.5.1. My own personal blog has been on wordpress.com and that UI was quite inspiring. Now I stand inspired. And definitely the ease with which WP upgrades is quite awesome. However it would have been even greater if I could just upgrade by clicking on a button without even having to download, upload files!

14May/087

Multiuser Chat using Flex and Ruby

For the last few days I had been googling for some good help for coding networked flash applications for a pet project of mine. Mostly using Flex & Ruby. There have been quite a few I saw - made with flash and using Java; but nothing to my personal liking. And hence I set to build a prototype of my own.

Being a coder and a poor (financially & aesthetically & skillfully :D ) visual designer, I am totally in love with Flex for the visual quality it brings to the flash applications i can build.

Ruby for the beauty it brings to the code; but then the code is only as good as the coder. And for cooking up a quick prototype, no language has been so good of course except for Perl (for me ofcourse).

Multiplayer - thats a tricky question. Flash cannot support P2P (peer-to-peer) applications as yet. So the best choice available is to use a client-server architecture - the good ole' sockets.

Hence using the code from a lot of different places and porting them from other languages, I managed to quickly cook up a Flex multiuser chat application with a ruby backend. Without further ado, into the code.

The server right now runs on the 9999 port of the localhost and the client connects to the same host and port. If you plan to test it on a hosting server, make sure you change the host and the port.

Note: My wordpress code plugin is fucking up the mxml code. For this part you may just download the zip file and use the client.mxml.

The Flex client:

< ?xml version="1.0"?>
<mx :Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
	</mx><mx :Script>
		< ![CDATA[
			import flash.display.Sprite;
 
			import flash.net.XMLSocket;
			import flash.events.Event;
			import flash.events.DataEvent;
			import flash.events.IOErrorEvent;
			import mx.events.CloseEvent;
			import mx.controls.Alert;
 
			public var socket:XMLSocket = new XMLSocket();
			private var host:String     = "localhost";
			private var port:int        = 9999;
 
			public function init():void	{
				socket.connect(host, port);
 
				socket.addEventListener(DataEvent.DATA, onData);
				socket.addEventListener(Event.CONNECT, onConnect);
				socket.addEventListener(Event.CLOSE, onClose);
				socket.addEventListener(IOErrorEvent.IO_ERROR, onEvent);
			}
 
			private function onConnect(event:Event):void	{
				board.htmlText += "<i>Client: Connected to server" + "<br />";
			}
 
			private function ReconnectHandler(event:CloseEvent):void	{
				if (event.detail == Alert.YES)
					init();
			}
 
			private function onClose(event:Event):void	{
				board.htmlText += "<i>Disconnected from server</i>" + "<br />";
				Alert.show("Reconnect to the chat?", "Reconnect?", (Alert.YES | Alert.NO), this, ReconnectHandler);
			}
 
			private function onEvent(event:Event):void {
				board.htmlText += "Error" + "<br />";
				trace(event);
			}
 
			private function onData(event:DataEvent):void {
				board.htmlText += event.text;
			}
 
			private function sendMesg():void	{
				socket.send(username.text+ ': <font color="#' + cp.selectedColor.toString(16) + '">' + mesg.text + "</font>\n");
				mesg.text = "";
			}
 
		]]>
	</mx>
 
	<mx :Style>
		.marginstyle {
			paddingTop:12; 
			paddingBottom:12; 
			paddingLeft: 12; 
			paddingRight: 12;
		}
 
		.spacestyle {
			paddingTop:2; 
			paddingBottom:2; 
			paddingLeft: 2; 
			paddingRight: 2;
		}
	</mx>
 
	<mx :Panel title="chatterbox" styleName="marginstyle">
		<mx :TextArea editable="false" id="board" text="" height="400" width="600" color="#0000FF" styleName="spacestyle"/>
     </mx><mx :HBox>
			<mx :TextArea id="username" text="guest" height="20" width="50%"/>
			<mx :ColorPicker id="cp" height="20" width="20"/>    
		</mx>
		<mx :HBox>
			<mx :TextArea id="mesg" height="50" width="500" styleName="spacestyle"/>
			<mx :Button label="Send" click="sendMesg()"/>	
		</mx>

To compile it to a swf
Assuming you already have the free Flex SDK just use
$> mxmlc client.mxml
which will create a client.swf file for you.

Multiuser Ruby chat server:

#!/usr/bin/ruby
require 'socket'
 
MSGS = {"init"    => "Server started. Waiting for connections...",
        "welcome" => "Welcome! type EXIT to quit",
        "byebye"  => "Disconnected from server"}
 
EOF     = "\000"
HOST		= "localhost"
PORT		= 9999
 
server	= TCPServer.new(HOST, PORT)
puts MSGS["init"] 
 
# array to store all the active connections
sessions = []
while (session = server.accept)
  # push the current session(socket) in the array
  sessions < < session
  # initialize a new thead for each connection
  Thread.new(session) do |local_session|
		local_session.puts "<i>#{MSGS["welcome"]}" + EOF
 
    # each time a client sends some data send it to all the connections
    while(true)
      data = local_session.gets
 
			if !data.nil?
				delim_pos = data.index(":")
				name      = data[0..delim_pos-1]
				data      = data[delim_pos+1..-1]
 
				if data[0] == EOF
					data = data[1..-1] 
				elsif data.chomp == "EXIT"
					sessions.delete(local_session)
					local_session.puts "<i>#{MSGS["byebye"]}</i>" + EOF
					local_session.close
 
					data = "<i>#{name} disconnected from the server</i>" + EOF
				end
			end
 
      sessions.each do |s| 
        begin
          s.puts "<b>#{name}</b>: #{data.chomp}" + EOF
        rescue Errno::ECONNRESET
          # an exception is raised, that means the connection to the client is broken
          sessions.delete(s)
        end
      end
    end
  end
end

To Run
User ruby chat_server.rb

Source Code: Download here. It contains a simple single user server - java & ruby versions [simpleServer.java & server.rb], a multiuser server [chat_server.rb] and the client [client.mxml].

Anyone, any doubts can leave a comment.

Filed under: chat, code, flex, ruby 7 Comments
16Apr/083

Recursively creating a set of directories in Ruby

class Dir
  def self.mkdirs(p)
     return if File.exists?
     dir, file = File.split(p)
     Dir.mkdirs(dir) if !File.exists?(dir)
     Dir.mkdir(p)
  end
end

#sample usage: Dir.mkdirs('test/tmp/tempest')

Filed under: code, ruby 3 Comments