I want to (re)create a project I did in my time at AOL. It was a data pipeline for collecting system stats. The pipeline is an Agent per host to collect the stats, a Message Routing infrastructure, and a data storage end point. Currently my Idea is to do all this in Ruby, 0MQ, and MySQL. Maybe later I will keep the timeseries data stored in something other than MySQL.
Mostly I want to play with 0MQ.
I am exploring two new languages and a Distributed VCS. Go and Node.js. Go has Goroutines (sorta evented, sorta threaded) and Node.js is intrinsically event driven. Git is a VCS born of Linus Torvalds mind (tried Mercuria[hg] but git has won me and the majority over).
Thursday, April 14, 2011
Sunday, April 3, 2011
Detecting remote connection closed
Normally you see read(2) return 0 bytes and errno set to ECONNRESET (on MacOS X) to detect that the peer of the socket closed the socket. But I have not figured out how EventMachine notifies the user of a peer disconnect.
EM (EventMachine) calls unbind on a socket close. But that is for a client close via close_connection or a peer close with no means to detect the difference.
EM (EventMachine) calls unbind on a socket close. But that is for a client close via close_connection or a peer close with no means to detect the difference.
Saturday, April 2, 2011
Simple Chat Server
Uses EM::Channel to communicate between two Server ports.
A simple `nc localhost 7000` to talk to the server
Learned a bunch of little things. More about transliterating things from Perl to Ruby.
Spent too much time trying to get /^(\w+)(?:\s+(\w+))*/ to do what I thought it would do. Doesn't even do what I think in perl. Of course the obvious
Then "
A simple `nc localhost 7000` to talk to the server
Learned a bunch of little things. More about transliterating things from Perl to Ruby.
Spent too much time trying to get /^(\w+)(?:\s+(\w+))*/ to do what I thought it would do. Doesn't even do what I think in perl. Of course the obvious
str.split(' ')
didn't work till I "gave up" and thought of a programatic way to do that hypothetical regex.Then "
chan_sid = ...
" didn't work, but "self.chan_sid = ...
" did. I have to figure that out.#!/usr/bin/env ruby -w require 'rubygems' require 'eventmachine' class CmdExecutor < EM::Connection include EM::P::LineText2 attr_reader :port attr_reader :cmd_prompt attr_reader :rsp_prefix attr_reader :greetings attr_reader :chan attr_accessor :chan_sid def initialize port, chan, *args p port, chan, args @port = port @chan = chan @cmd_prompt = "[#{port}]> " @rsp_prefix = "[#{port}]# " @greetings = "Hello how may I be of assistance?" console "Setting port=#{@port}" console "Setting prompt=#{@cmd_prompt}" console "#{self.class} initialized" end def console *args puts "[#{port}] #{args.join(' ')}" end def send_line line send_data(line+"\n") end def post_init console "\"post_init\" for port=#{port}" self.chan_sid = chan.subscribe { |msg| receive_chan msg } console "channel sid = ##{chan_sid}" send_line greetings send_data cmd_prompt end def receive_chan msg (port, cmd, *args) = *msg; console "FROM CHANNEL(#{chan_sid}): #{cmd} #{args.join ' '}" send_line rsp_prefix + "#{cmd} #{args.join ' '}" end def receive_line line (cmd, *args) = line.split(' ') cmd = cmd.downcase console "RECIEVED CMD: #{cmd} #{args.join(' ')}" case cmd when "close" console "\"close\" command called" console "close_connection will be issued" send_line rsp_prefix + cmd close_connection_after_writing when "quit" console "\"quit\" command called" console "EM.stop will be issued" send_line rsp_prefix + cmd EM.next_tick { EM.stop } else chan.push([port, cmd, *args]) console "sent to chan (#{chan_sid}) \"#{cmd} #{args.join ' '}\"" send_data cmd_prompt end #case data end #end def recieve_data def unbind console "connection closed" chan.unsubscribe(chan_sid) end #private end EM.run { chan = EM::Channel.new EM.start_server("0.0.0.0", 7000, CmdExecutor, 7000, chan) EM.start_server("0.0.0.0", 7001, CmdExecutor, 7001, chan) }
Subscribe to:
Posts (Atom)