<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Blogs at Near Infinity</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/" />
    <link rel="self" type="application/atom+xml" href="http://www.nearinfinity.com/blogs/atom.xml" />
    <id>tag:www.nearinfinity.com,2007-12-20:/blogs/7</id>
    <updated>2012-01-26T20:28:33Z</updated>
    <subtitle>Employee Blogs</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type 4.31-en</generator>

<entry>
    <title>Automatic Code Coverage Switching for Vows.js</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/jeff_kunkle/automatic_code_coverage_switch.html" />
    <id>tag:www.nearinfinity.com,2012:/blogs//7.1895</id>

    <published>2012-01-26T20:22:16Z</published>
    <updated>2012-01-26T20:28:33Z</updated>

    <summary>If you&apos;ve used Node.js lately you&apos;ve likely run across Vows, the asynchronous behavior driven development test framework for Node. Vows does a really nice job of forcing you to separate...</summary>
    <author>
        <name>Jeff Kunkle</name>
        
    </author>
    
        <category term="Node" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="nodejs" label="node.js" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>If you've used <a href="http://nodejs.org">Node.js</a> lately you've likely run across <a href="http://vowsjs.org/">Vows</a>, the asynchronous behavior driven development test framework for Node. Vows does a really nice job of forcing you to separate your setup logic from your assertions, but that's not what this post is about.</p>

<p>Vows can generate test coverage reports with its --cover-plain, --cover-html, and --cover-json options. Unfortunately, creating code coverage metrics isn't as straightforward as simply including these options in your call to vows. You need to</p>

<ol>
<li>Pre-instrument your code using <a href="https://github.com/visionmedia/node-jscoverage">node-jscoverage</a>.</li>
<li>Require the instrumented versions of your code from your tests.</li>
</ol>

<p>The first prerequisite is fairly easy to satisfy, although you need to remember to re-run node-jscoverage any time you change the source files you're interested in covering. Setting up a script using something like <a href="https://github.com/balupton/watchr">watchr</a> to re-instrument your files if anything changes might be a good option. Anyway, simply executing the following (assuming you've installed node-jscoverage and added it to your path) from the root of your node project will create the instrumented versions of the files in your lib directory:</p>

<pre class="prettyprint">
node-jscoverage lib lib-cov
</pre>

<p>The second prerequisite is not as straightforward to resolve as you might expect unless you want to generate the code coverage on every test run. Why? Because requiring the instrumented code from your test is not the same as requiring the un-instrumented versions. Consider</p>

<pre class="prettyprint lang-js">
// test/myfile_test.js
var fut = require('../lib/myfile.js'); // regular version
var fut = require('../lib-cov/myfile.js'); // instrumented version
</pre>

<p>Since the statement requiring the file under test is in every test you write, having to change it when you want to run the instrumented or un-instrumented files is, in my opinion, not an option. So, on my current project we wrote the following javascript to to serve as a replacement to requiring your files under test.</p>

<pre class="prettyprint lang-js">
// test/coverage.js
var covererageOn = process.argv.some(function(arg) {
  return /^--cover/.test(arg);  
});

if (covererageOn) {
  console.log('Code coverage on');

  exports.require = function(path) {
    var instrumentedPath = path.replace('/lib', '/lib-cov');

    try {
      require.resolve(instrumentedPath);
      return require(instrumentedPath);
    } catch (e) {
      console.log('Coverage on, but no instrumented file found at ' 
        + instrumentedPath);
      return require(path);
    }
  }
} else {
  console.log('Code coverage off');
  exports.require = require;
}
</pre>

<p>In essence, the script checks the process arguments to see if one of the vows --cover-* arguments were passed and changes its require method to substitute /lib-cov for any /lib references. If none of the coverage arguments are detected it simply requires the file as usual. Since your files under test normally use relative references to other files in your lib directory, they get covered too. Check out the example below to see how you would use the script in a test.</p>

<pre class="prettyprint lang-js">
// test/mytest.js
var vows = require('vows');
var assert = require('assert');
var coverage = require('coverage');
var fileUnderTest = coverage.require('../lib/myfile.js');

vows.describe('your test').addBatch({
    // do some testing
}).export(module);
</pre>
]]>
        

    </content>
</entry>

<entry>
    <title>Parsing pcap Files in Node.js with pcap-parser</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/jeff_kunkle/parsing_pcap_files_in_nodejs_w.html" />
    <id>tag:www.nearinfinity.com,2012:/blogs//7.1894</id>

    <published>2012-01-12T13:00:00Z</published>
    <updated>2012-01-12T13:13:49Z</updated>

    <summary>On my current project we&apos;ve been using Node.js for an app that does a lot of packet capture and processing. In the past we used node-pcap for packet capture but...</summary>
    <author>
        <name>Jeff Kunkle</name>
        
    </author>
    
        <category term="Node" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="javascript" label="javascript" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="node" label="node" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="pcap" label="pcap" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>On my current project we've been using <a href="http://nodejs.org">Node.js</a> for an app that does a lot of packet capture and processing. In the past we used <a href="https://github.com/mranney/node_pcap">node-pcap</a> for packet capture but were looking for an easier way to simply parse raw pcap files. It turns out the <a href="http://wiki.wireshark.org/Development/LibpcapFileFormat">pcap file format</a> is pretty simple as was writing a node module to parse it.</p>

<p>The module, called <a href="https://github.com/nearinfinity/node-pcap-parser">pcap-parser</a>, can be used to parse any pcap file or readable pcap stream, such as the piped output of <a href="http://www.tcpdump.org/">tcpdump</a>. As packets are parsed, pcap-parser emits relevant events to which your node program can listen. It's a really simple way to process a theoretically infinite stream of pcap data. The code below shows a basic example of it in action. Please check out the <a href="https://github.com/nearinfinity/node-pcap-parser">project page</a> for more details.</p>

<pre class="prettyprint">
var pcapp = require('pcap-parser');

var parser = new pcapp.Parser('/path/to/file.pcap');
// var parser = new pcapp.Parser(process.stdin);

parser.on('packet', function(packet) {
  console.log(packet.header);
  console.log(packet.data);
});

parser.parse(); // to kick things off
</pre> 
]]>
        

    </content>
</entry>

<entry>
    <title>How to use libwireshark to dissect a packet</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/joe_ferner/how_to_use_libwireshark_to_dis.html" />
    <id>tag:www.nearinfinity.com,2012:/blogs//7.1893</id>

    <published>2012-01-10T14:28:39Z</published>
    <updated>2012-01-25T21:01:27Z</updated>

    <summary> I&apos;ve been doing some programming in node.js and needed a way to parse network packets. node-pcap just wasn&apos;t cutting it anymore so I figured why not use the best...</summary>
    <author>
        <name>Joe Ferner</name>
        
    </author>
    
    <category term="c" label="c" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="c" label="c++" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="node" label="node" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="nodejs" label="node.js" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="wireshark" label="wireshark" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>
I've been doing some programming in <a href="http://nodejs.org/">node.js</a> and needed a way to parse network packets. <a href="https://github.com/mranney/node_pcap">node-pcap</a> just wasn't cutting it anymore so I figured why not use the best tool for the job, <a href="http://www.wireshark.org/">Wireshark</a>. Under the covers Wireshark uses libwireshark. In fact libwireshark is also used by tshark and rawshark to dissect network packets. When you download the source for Wireshark you won't find a libwireshark directory, what you will find is an epan directory. This directory contains most of what you need to dissect packets.
</p>

<p>
All of the code for this blog can be found in some shape or form in my node project <a href="https://github.com/nearinfinity/node-shark">Nodeshark</a>. This blog does not cover filters or other advanced features but you can always do what I did and study the Wireshark, tshark, or rawshark code. I'm going to try and preset what I believe to be the minimum amount of code to get packet dissection working.
</p>

<p>
The first thing you will need to do is initialize epan.

<pre class="prettyprint">
#include &lt;config.h&gt;
#include &lt;epan/epan.h&gt;

// setup permissions
init_process_policies();

// initialize GLib. GLib is used by Wireshark under the covers.
GLogLevelFlags log_flags = (GLogLevelFlags)(
  G_LOG_LEVEL_ERROR
  | G_LOG_LEVEL_CRITICAL
  | G_LOG_LEVEL_WARNING
  | G_LOG_LEVEL_MESSAGE
  | G_LOG_LEVEL_INFO
  | G_LOG_LEVEL_DEBUG
  | G_LOG_FLAG_FATAL
  | G_LOG_FLAG_RECURSION);

g_log_set_handler(NULL, log_flags, tshark_log_handler, NULL);
g_log_set_handler(
  LOG_DOMAIN_CAPTURE_CHILD,
  log_flags,
  tshark_log_handler,
  NULL);

// initialize timestamp info
timestamp_set_type(TS_RELATIVE);
timestamp_set_precision(TS_PREC_AUTO);
timestamp_set_seconds_type(TS_SECONDS_DEFAULT);

// initialize epan
epan_init(
  register_all_protocols,
  register_all_protocol_handoffs,
  NULL,
  NULL,
  failureMessage,
  openFailureMessage,
  readFailureMessage,
  writeFailureMessage);

// load all the modules
prefs_register_modules();

// set the locale
setlocale(LC_ALL, "");

// Cleanup all data structures used for dissection. I know
// we haven't done any dissection yet but epan complains
// if this isn't called.
cleanup_dissection();

// Initialize all data structures used for dissection.
// Magical epan function that initializes global variables.
init_dissection();

// functions to log epan_init errors
void openFailureMessage(
  const char *filename,
  int err,
  gboolean for_writing) {
  fprintf(stderr, "filename: %s, err: %d\n", filename, err);
}

void failureMessage(const char *msg_format, va_list ap) {
  vfprintf(stderr, msg_format, ap);
  fprintf(stderr, "\n");
}

void readFailureMessage(const char *filename, int err) {
  fprintf(
    stderr,
    "An error occurred while reading from the file \"%s\": %s.",
    filename,
    g_strerror(err));
}

void writeFailureMessage(
  const char *filename,
  int err) {
  fprintf(
    stderr,
    "An error occurred while writing to the file \"%s\": %s.",
    filename,
    g_strerror(err));
}
</pre>
</p>

<p>
After initialization you probably want to open a scope for your packets. Scoping your packets allows Wireshark to do dissection, such as HTTP, across packets. In Wireshark the scope is called a capture file. Here is how we initialize it.

<pre class="prettyprint">
capture_file cfile;
guint32 cum_bytes;
gint64 data_offset;

cap_file_init(&cfile);

// This will load or not load dissectors based on your
// wireshark preferences.
char *gpf_path, *pf_path;
int gpf_open_errno, gpf_read_errno;
int pf_open_errno, pf_read_errno;
e_prefs *prefs = read_prefs(
  &gpf_open_errno,
  &gpf_read_errno,
  &gpf_path,
  &pf_open_errno,
  &pf_read_errno,
  &pf_path);

// Build the column format array. I beleive this holds
// all the columns that Wireshark may return
build_column_format_array(&cfile.cinfo, prefs->num_cols, TRUE);

cfile.wth = NULL;
cfile.f_datalen = 0;
cfile.filename = g_strdup(""); // don't care about the filename
cfile.is_tempfile = FALSE;
cfile.user_saved = FALSE;
cfile.cd_t = WTAP_FILE_UNKNOWN;
cfile.count = 0;
cfile.drops_known = FALSE;
cfile.drops = 0;
cfile.has_snap = FALSE;
cfile.snap = WTAP_MAX_PACKET_SIZE;
nstime_set_zero(&cfile.elapsed_time);

// set the frame type. This will tell Wireshark
// what the top level frame type is.
int encap = wtap_pcap_encap_to_wtap_encap(1 /* ETHERNET */);

// clear the timestamps
nstime_t first_ts;
nstime_t prev_dis_ts;
nstime_t prev_cap_ts;
nstime_set_unset(&first_ts);
nstime_set_unset(&prev_dis_ts);
nstime_set_unset(&prev_cap_ts);
</pre>

</p>

<p>
Now we can dissect packets. To do this we initialize a frame, run the packet through epan, and cleanup.

<pre class="prettyprint">
struct wtap_pkthdr whdr;
whdr.pkt_encap = encap;
whdr.ts.secs = 0;
whdr.ts.nsecs = 0;
whdr.caplen = packetLength;
whdr.len = packetLength;

frame_data fdata;
epan_dissect_t edt;

cfile.count++; // increment the packet count

frame_data_init(
  &fdata,
  cfile.count,
  &whdr,
  data_offset,
  cum_bytes);
epan_dissect_init(
  &edt,
  TRUE,
  TRUE /* dissect the whole tree */);
frame_data_set_before_dissect(
  &fdata,
  &cfile.elapsed_time,
  &first_ts,
  &prev_dis_ts,
  &prev_cap_ts);

// run the dissection on "data"
epan_dissect_run(
  &edt,
  &cfile.pseudo_header,
  data,
  &fdata,
  &cfile.cinfo);

frame_data_set_after_dissect(
  &fdata,
  &cum_bytes,
  &prev_dis_ts);
data_offset += whdr.caplen;

// process packet information

// clean up
epan_dissect_cleanup(&edt);
frame_data_cleanup(&fdata);
</pre>

</p>

<p>
This isn't all that useful unless we do something with the packet data. Wireshark returns the data, pretty much just like you see it in the Wireshark GUI, as a tree. Here are some of the things you can do with the data.

<pre class="prettyprint">
// iterate the current nodes children
void iteratorFunction(proto_node *node, gpointer data) {
  // node = child node
  // data = the data you passed to proto_tree_children_foreach
  field_info *fi = PNODE_FINFO(node);

  // some nodes don't have field_info. You can still
  // iterate them if you want though
  if(fi == NULL) return;

  fi->length; // size of data in packet

  int posInPacket;
  if (node->parent && node->parent->finfo
    && (fi->start &lt; node->parent->finfo->start)) {
    posInPacket = node->parent->finfo->start + fi->start;
  } else {
    posInPacket = fi->start;
  }

  // abbreviation of node. This is the string you'll
  // see in display filters such as "tcp.srcport"
  fi->hfinfo->abbrev;
  
  // This is the string that you see in the Wireshark GUI,
  // not including the value
  fi->rep->representation;

  // This is the value string you see in the GUI
  char *showString =
    proto_construct_match_selected_string(fi, &edt);
}

proto_node *node = edt.tree; // grab the top level tree node

// data can be anything you want it just gets
// forwarded on to your iterator function.
proto_tree_children_foreach(node, iteratorFunction, &data);
</pre>

</p>]]>
        
    </content>
</entry>

<entry>
    <title>The Art of Searching</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/presentations/the_art_of_searching.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1892</id>

    <published>2011-12-16T15:59:45Z</published>
    <updated>2011-12-16T19:19:01Z</updated>

    <summary><![CDATA[ 28:30 Speaker:&nbsp;Tom Neumark, Senior Software Engineer, Near Infinity Conference: NIC-U Tech Talk Length of Video: 28 minutes, 30 seconds Reston, Virginia, Nov 2...]]></summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Presentations" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="video" label="video" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<div class="presentation-video">
<a href="http://www.youtube.com/v/yst6VQ7Lwpo?hd=1" class="lightwindow page-options play" params="lightwindow_width=480,lightwindow_height=295,lightwindow_loading_animation=false"></a><img src="http://img.youtube.com/vi/yst6VQ7Lwpo/1.jpg" />
<span class="video-time">28:30</span></div>

<div class="presentation-details">
<p><strong>Speaker:&nbsp;</strong>Tom Neumark, Senior Software Engineer, Near Infinity
<br /> 
<strong>Conference:</strong> NIC-U Tech Talk<br />
<strong>Length of <a href="http://www.youtube.com/v/yst6VQ7Lwpo?hd=1">Video</a>:</strong> 28 minutes, 30 seconds</p>
<ul><li>Reston, Virginia, Nov 2</li></ul></div>]]>
        <![CDATA[<p>Tom Neumark presents on searching.</p>

<p>Blur, which is based on Apache Lucene, is a search engine capable of searching billions of records quickly.  The underlying data structures and algorithms that make Lucene work are build from simple structures that are built up piece-by-piece to enable more sophisticated functionality such as comparing documents through cosine similarity.  In this talk, we'll start with a simple search example and build up to a vector space model and explain some of the underlying math needed normalize the weights used to make fair comparisons among documents.</p>]]>
    </content>
</entry>

<entry>
    <title>Near Infinity Celebrates its Second Year on the Inc 500 | 5000 List</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/awards/near_infinity_celebrates_its_s.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1878</id>

    <published>2011-12-15T16:18:26Z</published>
    <updated>2011-12-16T19:14:58Z</updated>

    <summary>For the second year in a row, Near Infinity has been named one of the nation&apos;s fastest-growing private companies by Inc Magazine. Near Infinity ranked 2946th, based on a three-year sales growth of 71 percent. The 2011 list is a...</summary>
    <author>
        <name>Will Brady</name>
        
    </author>
    
        <category term="Awards" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<p>For the second year in a row, Near Infinity has been named one of the nation's fastest-growing private companies by Inc Magazine. Near Infinity ranked 2946th, based on a three-year sales growth of 71 percent.</p>

<p>The 2011 list is a group of companies that Inc Magazine dubbed the "Engines of the Economy." Collectively, they were responsible for creating 370,592 new jobs over the past three years. <a href="http://www.inc.com/inc5000/profile/near-infinity">More on NIC and the INC 500 | 5000</a></p>]]>
        
    </content>
</entry>

<entry>
    <title>How To Get The Most From Twitter: Scoping Rules</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/how_to_get_the_most_from_twitt.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1891</id>

    <published>2011-11-29T15:36:04Z</published>
    <updated>2011-11-29T17:34:56Z</updated>

    <summary> Ever noticed a tweet disappear? As in someone else can&apos;t see something you posted? There&apos;s a common mistake even twitter pros make that causes this to occur. Are you...</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="twitter" label="twitter" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[ <p>Ever noticed a tweet disappear? As in someone else can't see something you posted?  There's a common mistake even twitter pros make that causes this to occur.</p>
<p>Are you sure you're seeing <i>all</i> of the replies to your tweets -- even from people you don't follow?  Do you ever find yourself missing important posts -- like those from your real life friends?  Do you know which will reach a wider audience: new style retweets vs old style retweets?</p>
<p>This article will answer these and other twitter related questions. It will help beginner to intermediate twitter users get the most out of the service.</p>

<p><b>#1 Standard #Tweets</b></p>
<p><a href="http://4.bp.blogspot.com/-e8CL3yKse4c/TtRbWzwGNlI/AAAAAAAAByI/lB9vEdwttes/s1600/1.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor:pointer; cursor:hand;width: 349px; height: 343px;" src="http://4.bp.blogspot.com/-e8CL3yKse4c/TtRbWzwGNlI/AAAAAAAAByI/lB9vEdwttes/s400/1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5680265477428229714" /></a></p>
<p>These appear simple.  These show up in the timeline of your followers (@admirer and @vet in the example above).  And they don't show up in the timeline of anyone who doesn't follow you (@effusive).  If this was all there was to twitter it would be a complete waste of time.</p>
<p>The subtlety with this type of tweet is that your content may show up to someone that doesn't follow you but that is following a hashtag or a topic you mention.  In the example above @hiro thows a hashtag onto the word aardvarks to indicate that it's special somehow.  His tweet is then picked up by @spca who runs a constant search in a twitter client for the word "#aardvark".</p>
<p>The first time I realized how powerful this could be I had was at a conference.  I was extremely bored by a terrible keynote.  With nothing else to do I discovered the conference hashtag on twitter and started watching it.  Suddenly I realized I wasn't alone.  I was in a huge room full of people making fun of the presenter!  It was like telepathy, or group consciousness or something.  I've never felt alone or bored at a conference since.</p>
<p>Interesting statistic: As of June 2010, about 65 million tweets were posted each day, equaling about 750 tweets sent each second. (<a href="http://en.wikipedia.org/wiki/Twitter">reference</a>)</p>
<p><b>#2 Replies</b></p>
<p><a href="http://3.bp.blogspot.com/-yg6C6yTNlfo/TtRbXFuUjsI/AAAAAAAAByU/Si6sfvHr-9c/s1600/2.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor:pointer; cursor:hand;width: 400px; height: 317px;" src="http://3.bp.blogspot.com/-yg6C6yTNlfo/TtRbXFuUjsI/AAAAAAAAByU/Si6sfvHr-9c/s400/2.png" border="0" alt="" id="Img1" /></a></p>
<p>Replies are more complicated.  In the example above the guy on the left, @vet, replies to @hiro by prefixing his tweet with "@hiro".  However, this probably doesn't work like you think.  The tweet obviously shows up in @hiro's timeline, but it also shows up in @admirer's timeline because she follows both people mentioned in the tweet (@hiro <i>and</i> @vet).  But the tweet does <i>not</i> show up to @effusive because, while he follows @vet, the author of the tweet, he doesn't follow @hiro, the person being mentioned.</p>
<p>Getting this scoping rule wrong is way too easy.  For instance you can't just announce that someone did something great.  If @hiro started a tweet with "@vet gave a great anti-aardvark presentation" then most of his followers (e.g. @effusive) wouldn't actually see the tweet!  I've seen seasoned twitter users make this mistake.</p>
<p>As an interesting aside twitter can help track conversations.  If you click a reply button in a twitter client or on the website twitter will keep track of which tweet you replied to and then help piece a conversation together.  But if you simply start a new tweet with "@somone" without clicking reply, the above scoping rules still apply, but twitter won't help anyone reconstruct the conversation.</p>
<p>Finally a word on notifications: If someone mentions you (via a reply or anywhere in their tweet) and you follow them then you will get an e-mail and possibly an SMS notification.  If someone that you do not follow replies to you, you <i>will not</i> get an email.  For this reason you must either frequently check the "mentions and more" section of the website or use a column based twitter client, discussed in the final section on lists.</p>
<p>Interesting statistic: On average only 23% of tweets get a reply. (<a href="http://www.sysomos.com/insidetwitter/engagement/">more</a>)</p>
<p>Another one: 38% of tweets are conversational.  In other words 38% of tweets start with an "@". If your percentage of replies is lower you probably aren't using twitter to its fullest. (<a href="http://www.pearanalytics.com/blog/wp-content/uploads/2010/05/Twitter-Study-August-2009.pdf">more</a>)</p>
<p><b>#3 Reply-All's</b></p>
<p><a href="http://3.bp.blogspot.com/-VBvIcRq5ANk/TtRbXahnI2I/AAAAAAAAByc/U1KHy4J3x0Q/s1600/3.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor:pointer; cursor:hand;width: 379px; height: 333px;" src="http://3.bp.blogspot.com/-VBvIcRq5ANk/TtRbXahnI2I/AAAAAAAAByc/U1KHy4J3x0Q/s400/3.png" border="0" alt="" id="Img2" /></a></p>
<p>So what happens if you want to reply to someone, but still have it show up in the timelines of <i>all</i> of your followers?  As long as your tweet doesn't start with an "@" symbol then you're fine.  So the convention that has grown up is to prefix your tweet with a "." and then the "@someone".  In the example above @effusive now sees the tweet where he didn't in a standard reply.</p>
<p>Interesting statistic: The highest usage rate of twitter to date occurred during the 2011 FIFA Women's World Cup Final between Japan and the United States when 7,196 tweets were published per second! (<a href="http://www.usatoday.com/tech/news/2011-07-18-world-cup-twitter-record_n.htm">more</a>)</p>
<p><b>#4 Old Style Retweet or "Retweet with Comment"</b></p>
<p><a href="http://4.bp.blogspot.com/-T2Z7KRpWud8/TtRbXh_DKuI/AAAAAAAABys/EHV8GHZIRrE/s1600/4.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor:pointer; cursor:hand;width: 400px; height: 282px;" src="http://4.bp.blogspot.com/-T2Z7KRpWud8/TtRbXh_DKuI/AAAAAAAABys/EHV8GHZIRrE/s400/4.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5680265489838975714" /></a></p>
<p>Prior to late 2009 if you saw a tweet you wanted to share with your followers you would retweet (RT) it by copy and pasting their tweet and prefixing it with "RT @author".  The problem from a scoping perspective was that people would get duplicates.  In the example above @admirer sees a duplicate from @vet when he retweets @hiro's tweet.</p>
<p>There are other problems with old style retweets unrelated to scoping.  One problem is that you get long chains of "RT @person1 RT @person2 ...".  Another problem is it was hard to follow a person but not all their retweets.  The biggest problem is old style retweets take valuable characters away from your available 140, and sometimes require mangling the original.</p>
<p>Old style retweeting is still in use today primarily from people wish to retweet but add a comment, but also because it allows people to reach a wider audience (since new style retweets won't show up in searches or lists, more on this later).</p>
<p>Interesting statistic: Only 6% of tweets get retweeted (<a href="http://socialtimes.com/report-71-percent-of-tweets-do-not-get-a-single-reply-or-retweet_b24365">more</a>)</p>
<p><b>#5 New Style Retweet</b></p>
<p><a href="http://2.bp.blogspot.com/-OfR_u71pkK8/TtRbYFzvYkI/AAAAAAAABy4/n_JlWBmX-3Q/s1600/5.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor:pointer; cursor:hand;width: 400px; height: 338px;" src="http://2.bp.blogspot.com/-OfR_u71pkK8/TtRbYFzvYkI/AAAAAAAABy4/n_JlWBmX-3Q/s400/5.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5680265499455218242" /></a></p>
<p>In November of 2009 twitter rolled out a new technique for retweeting aimed at solving the problems mentioned above.  It caused a lot of confusion, but did solve the problems.</p>
<p>The end result of new style retweets from a scoping perspective is that sometimes people see tweets from people they don't follow.  In the example above @effusive sees @hiro's tweet in his timeline even though he doesn't follow @hiro, because @vet performed a new-style retweet.</p>
<p>If you click the retweet button on the twitter website today it will perform a new style retweet.  Some twitter clients like TweetDeck give you the option.  The only way to perform an old style retweet or retweet with comment via the website is to copy and paste the message.</p>
<p>Interesting statistic: Less than half of tweets are posted using the web user interface.  By far the most common twitter client is Tweetdeck with 8.48% of the market. (<a href="http://www.sysomos.com/insidetwitter/clients/">more</a>)</p>
<p><b>#6 Direct Messages</b></p>
<p><a href="http://2.bp.blogspot.com/-hTvmYv4PA7k/TtRcUt8ld_I/AAAAAAAABzE/7gD3kRqy8Rc/s1600/6.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor:pointer; cursor:hand;width: 400px; height: 276px;" src="http://2.bp.blogspot.com/-hTvmYv4PA7k/TtRcUt8ld_I/AAAAAAAABzE/7gD3kRqy8Rc/s400/6.png" border="0" alt="" id="Img4" /></a></p>
<p>Direct messages are simple.  Prefix your tweet with "D somone" (no at symbol before the name) and they will be the only person that will see it.  Just like e-mail except the recipient will get an e-mail and a text message if they've set that up on their phone.  Note that neither people watching an included hashtag  (e.g. @spca) nor people mentioned will see direct messages unless they are the recipient.</p>
<p>Interesting statistic: Six percent of all tweets are sent via SMS. (<a href="http://www.quora.com/What-percentage-of-Twitter-users-get-their-Twitter-updates-predominately-from-direct-text-messages-as-opposed-to-the-website-or-3rd-party-Apps">more</a>)</p>
<p><b>#7 Lists</b></p>
<p>The last scoping topic worthy of mention is lists.  This fantastic feature was added by twitter in late 2009.  It allows you to organize the people you follow.  For instance I have a private "Infrequent Posters" list that I try very hard to never miss a tweet from.  Meanwhile I follow enough people that my main list is more like a stream that I dip into but don't get stressed out if I miss some of.</p>
<p>Lists work best when used in conjunction with a column based twitter clients (e.g. TweetDeck).  These types of twitter clients are the only way to go if you want to become a twitter pro.  If you've gotten to the point where you start missing content from important people (e.g. your real life friends), or you're missing responses to your tweets, or mentions from people you don't follow: then you probably need lists, but you absolutely need something like TweetDeck.</p>
<p><a href="http://3.bp.blogspot.com/-xyrC1APLTqM/TtRcU6p58_I/AAAAAAAABzQ/cUvaNcE8_zk/s1600/7.png" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}"><img style="cursor:pointer; cursor:hand;width: 368px; height: 321px;" src="http://3.bp.blogspot.com/-xyrC1APLTqM/TtRcU6p58_I/AAAAAAAABzQ/cUvaNcE8_zk/s400/7.png" border="0" alt="" id="Img3" /></a></p>
<p>In regards to scoping, lists contain one subtlety that you need to be aware of.  They do not support new style retweets.  In the example above @vet posts a normal tweet.  He then new-style retweets one of @hiro's tweets.  @effusive follows @vet and has also placed him into a list.  While the list helps @effusive not miss tweets from @vet, it does not end up displaying @hiro's tweet.  </p>
<p>Note that this rule applies both to people who maintain their own lists as well as to people who follow lists maintained by other people (e.g. your company may maintain a public list of its twitter enabled employees).</p>
<p>Interesting Statistic: Pointless babble is the most common type of content on twitter.  It represents 40.55% of all traffic. (<a href="http://www.pearanalytics.com/blog/wp-content/uploads/2010/05/Twitter-Study-August-2009.pdf">more</a>)</p>


<div style="float:right;padding:4px; text-align: center; width: 115px;">
<iframe src="http://platform.twitter.com/widgets/tweet_button.html#_=1322581831960&amp;count=horizontal&amp;id=twitter_tweet_button_0&amp;lang=en&amp;original_referer=http%3A%2F%2Frapidapplicationdevelopment.blogspot.com%2F2011%2F11%2Fhow-to-get-most-from-twitter.html&amp;related=lprichar%3ALee%20Richardson%20Blog&amp;text=RT%20%40lprichar%20How%20To%20Get%20The%20Most%20From%20Twitter%3A%20Understand%20Scoping%20Rules&amp;url=http%3A%2F%2Frapidapplicationdevelopment.blogspot.com%2F2011%2F11%2Fhow-to-get-most-from-twitter.html" allowtransparency="true" frameborder="0" scrolling="no" class="twitter-share-button twitter-count-horizontal" style="width: 110px; height: 20px; " title="Twitter For Websites: Tweet Button"></iframe>
<script type="text/javascript">
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2011/11/how-to-get-most-from-twitter.html';

        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);

        var div = document.createElement('div');
        div.appendChild(document.createElement('br'));
        div.appendChild(dotnetkicksLink);
        document.write(div.innerHTML);
    </script>
<p></p>
<div id="___plusone_0" style="height: 20px; width: 90px; display: inline-block; text-indent: 0px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; background-image: initial; background-attachment: initial; background-origin: initial; background-clip: initial; background-color: transparent; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; float: none; line-height: normal; font-size: 1px; vertical-align: baseline; background-position: initial initial; background-repeat: initial initial; "><iframe allowtransparency="true" frameborder="0" hspace="0" id="I1_1322581832741" marginheight="0" marginwidth="0" name="I1_1322581832741" scrolling="no" src="https://plusone.google.com/_/+1/fastbutton?url=http%3A%2F%2Frapidapplicationdevelopment.blogspot.com%2F2011%2F11%2Fhow-to-get-most-from-twitter.html&amp;size=medium&amp;count=true&amp;annotation=bubble&amp;hl=en-US&amp;jsh=m%3B%2F_%2Fapps-static%2F_%2Fjs%2Fwidget%2F__features__%2Frt%3Dj%2Fver%3DJJ_UMfXdHS0.en_US.%2Fsv%3D1%2Fam%3D!7cXxqVkrvlyIEO88iA%2Fd%3D1%2F#id=I1_1322581832741&amp;parent=http%3A%2F%2Frapidapplicationdevelopment.blogspot.com&amp;rpctoken=152461457&amp;_methods=onPlusOne%2C_ready%2C_close%2C_open%2C_resizeMe" style="width: 90px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; border-top-style: none; border-right-style: none; border-bottom-style: none; border-left-style: none; height: 20px; position: static; left: 0px; top: 0px; visibility: visible; " tabindex="-1" vspace="0" width="100%" title="+1"></iframe></div>
<script src="http://platform.twitter.com/widgets.js" type="text/javascript">
</script>
</div>

<p><b>Conclusion</b></p>
<p>Twitter may appear to be fairly simple at first glance.  In reality it has grown over the years to become very sophisticated.  Sophisticated and incredibly powerful.  But to fully tap that power you must understand the scoping rules and subtleties surrounding things like replies, retweets, and lists.  Hopefully you're closer now.</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Integral Image for Faster Image Processing</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/tom_neumark/integral_tables_for_faster_ima.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1887</id>

    <published>2011-11-28T02:29:12Z</published>
    <updated>2011-11-28T00:05:23Z</updated>

    <summary><![CDATA[Recently, I was looking into computer vision related technologies. &nbsp;One of the interesting techniques is known as the "integral image" which can enable more advanced techniques, most notably the Viola-Jones...]]></summary>
    <author>
        <name>Tom Neumark</name>
        
    </author>
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="image" label="image" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[Recently, I was looking into computer vision related technologies. &nbsp;One of the interesting techniques is known as the "integral image" which can enable more advanced techniques, most notably the <a href="http://en.wikipedia.org/wiki/Viola%E2%80%93Jones_object_detection_framework">Viola-Jones object detection framework</a>, which&nbsp;uses a series of simple, Haar-like features, which are rectangular areas with dark and light regions, to find areas that match patterns that correspond with the object you are trying to find.<div><br /></div><div>To do this computation, you search an image by sliding an imaginary window with the pattern &nbsp;at multiple scales over the entire image, looking for differences between the dark and light areas of the pattern that meet a threshold that is determined by the training algorithm. &nbsp;Doing this can require many computations, so how can we speed this up? Let's frame the question this way: Starting with a gray scale image in which each pixel has a value from 0-255, how can we quickly compute the average color value in a sub-region of an image?</div><div><br /></div><div>The conventional way would be to write a loop similar the following:


<pre class="prettyprint">private static int computeSum(BufferedImage image, int regionX1, int regionY1, int regionX2, int regionY2) {
   //Compute a sub-region of the image 
   int sum = 0;
   Raster data = image.getData();
   for (int x = regionX1; x &lt;= regionX2; x++) {
      for (int y = regionY1; y &lt;= regionY2; y++) {
         int value = data.getSample(y, x, 0);
         sum = sum + value;
      }
   }
   return sum;
}
</pre>
</div><div><br /></div><div>But we can do better than this, especially if we'll need to compute multiple regions and not constantly recompute the sums. &nbsp;To create an integral image, we make a single pass over the entire image and for each pixel in the original image compute the sum of all the pixels to the left and above of this pixel and add it to the value of the original pixel. &nbsp;The code for that is below.</div><div><br /></div><div><div><br /></div></div>

<pre class="prettyprint">public class IntegralImage {
   private int[][] integralImage = null;
	
   public IntegralImage(BufferedImage image) {
      int originalImageHeight = image.getHeight();
      int originalImageWidth = image.getWidth();
      integralImage = new int[originalImageHeight][originalImageWidth];
      Raster originalPixels = image.getData();

      int originalPixelValue = 0;
      for (int row = 0; row &lt; originalImageHeight; row++) {
         for (int column = 0; column &lt; originalImageWidth; column++) {
      originalPixelValue = originalPixels.getSample(column, row, 0); 

         //For the leftmost pixel, just copy value from original
         if (row == 0 &amp;&amp; column == 0) {
            integralImage[row][column] = originalPixelValue;
         }

        //For the first row, just add the value to the left of this pixel
         else if (row == 0) {
             integralImage[row][column] = originalPixelValue + integralImage[row][column - 1];
         }

        //For the first column, just add the value to the top of this pixel
         else if (column == 0) {
            integralImage[row][column] = originalPixelValue + integralImage[row - 1][column];      &nbsp;
         }

       //For a pixel that has pixels to its left, above it, and to the left and above diagonally, 
       //add the left and above values and subtract the value to the left and above diagonally
       else {
          integralImage[row][column] = originalPixelValue + integralImage[row][column - 1] + integralImage[row - 1][column] - integralImage[row - 1][column - 1];
       }
    }
}
</pre>

After this pass through the image, we can compute the sum of any region in constant time by doing the following:<div><br /><pre class="prettyprint">public int total(int x1, int y1, int x2, int y2) {
   int a = x1 &gt; 0 &amp;&amp; y1 &gt; 0 ? integralImage[x1-1][y1-1] : 0;
   int b = x1 &gt; 0 ? integralImage[x1-1][y2] : 0;
   int c = y1 &gt; 0 ? integralImage[x2][y1-1] : 0;
   int d = integralImage[x2][y2];
   return a + d - b - c;
}
</pre><div><br /></div>

And that's it!  We can now apply this faster computation to a number of interesting problems.  For a nice tutorial on this, you may want to check out <a href="http://computersciencesource.wordpress.com/2010/09/03/computer-vision-the-integral-image/">the following</a>.</div>]]>
        
    </content>
</entry>

<entry>
    <title>jQuery UI</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/presentations/jquery_ui.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1890</id>

    <published>2011-11-21T00:05:21Z</published>
    <updated>2011-11-21T15:21:27Z</updated>

    <summary><![CDATA[ 05:01 Speaker:&nbsp;Jennifer Newman, Software Engineer, Near Infinity Conference: NIC-U Fall Conference 2011 Length of Video: 5 minutes, 1 second Reston, Virginia, Nov 18...]]></summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Presentations" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="video" label="video" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[ <div class="presentation-video">
<a href="http://www.youtube.com/v/leRPsdDnOa0?hd=1" class="lightwindow page-options play" params="lightwindow_width=480,lightwindow_height=295,lightwindow_loading_animation=false"></a><img src="http://img.youtube.com/vi/leRPsdDnOa0/2.jpg" />
<span class="video-time">05:01</span></div>

<div class="presentation-details">
<p><strong>Speaker:&nbsp;</strong>Jennifer Newman, Software Engineer, Near Infinity
<br /> 
<strong>Conference:</strong> NIC-U Fall Conference 2011<br />
<strong>Length of <a href="http://www.youtube.com/v/leRPsdDnOa0?hd=1">Video</a>:</strong> 5 minutes, 1 second
</p>
<ul><li>Reston, Virginia, Nov 18</li></ul></div>]]>
        <![CDATA[<p>Jennifer Newman presents a lightning talk on jQuery UI.</p>
<p>jQuery UI is the official user interface library for jQuery, the most popular JavaScript library today. As a packaged set of widgets, animations, and other effects, it provides an easy way to clean up and spice up your UI, all while maintaining your current branding via themeable.  This presentation demos a few of the features of jQuery UI, from complex widgets such as date pickers and accordions to effects such as color animation. A few themes are also demonstrated to show the ease of integrating these tools into web sites with already-existing colors and styles.</p>]]>
    </content>
</entry>

<entry>
    <title>Promoting Software Craftsmanship</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/andrew_wagner/promoting_software_craftsmansh.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1888</id>

    <published>2011-11-18T18:09:45Z</published>
    <updated>2011-11-18T18:43:11Z</updated>

    <summary><![CDATA[Many people have tried to define software craftsmanship. Corey Haines&nbsp;likes to talk about&nbsp;being positive as part of your profession. Avdi Grimm, in the&nbsp;Confident Code&nbsp;talk he's been giving, talks similarly about...]]></summary>
    <author>
        <name>Andrew Wagner</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[Many people have tried to define software craftsmanship. Corey Haines&nbsp;<a href="http://programmingtour.blogspot.com/2011/03/my-talk-from-scna2010.html">likes to talk about</a>&nbsp;being positive as part of your profession. Avdi Grimm, in the&nbsp;<a href="http://avdi.org/talks/confident-code-rubymidwest-2011/confident-code.html">Confident Code</a>&nbsp;talk he's been giving, talks similarly about how clean code is more enjoyable to work with.&nbsp;Bob Martin points out that&nbsp;<a href="http://cleancoder.posterous.com/software-craftsmanship-things-wars-commandmen">nobody likes writing bad code</a>.&nbsp;<div><br /></div><div>So I think that a lot of the Software Craftsmanship is about enjoying writing code. It's about building something that you can be proud of. Generally, it's about being happy to be a developer.&nbsp;</div><div><br /></div><div>One of the keys to this is to learn a lot of different techniques, and to get good at the techniques that you do know. If you're using the right tools, and using them correctly, it will go a long way towards enjoying what you do. After all, would you rather cut wood by hand with a hacksaw, or with a circular saw?</div><div><br /></div><div>To that end, Near Infinity is sponsoring and hosting a local Code Retreat on&nbsp;<a href="http://blog.coderetreat.com/global-day-of-coderetreat">the upcoming Global Day of Code Retreat</a>, December 3rd. The idea behind the event is to work on the same programming problem, repeatedly, all day long. After each cycle of working on the problem, you throw away your code and start all over again. This has a really powerful effect - you no longer get attached to having your code, and finishing the problem. Instead, you focus on <i>how you&nbsp;</i>write the code. Plus, you're pairing with a different person each session, potentially with a different programming language. So you get to see a lot of different approaches - different tools - and how to use them, both well and poorly.</div><div><br /></div><div>So, if you're interested,&nbsp;<a href="http://www.eventbrite.com/event/1756063433">check out the details</a>, and sign up!</div><div><br /></div>]]>
        
    </content>
</entry>

<entry>
    <title>An Introduction to Blur</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/aaron_mccurry/an_introduction_to_blur.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1886</id>

    <published>2011-11-09T20:00:00Z</published>
    <updated>2011-11-10T15:22:12Z</updated>

    <summary>Blur is a new Apache 2.0 licensed software project that provides a search capability built on top of Hadoop and Lucene. Elastic Search and Solr already exist so why build...</summary>
    <author>
        <name>Aaron McCurry</name>
        
    </author>
    
        <category term="Hadoop" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Java" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Lucene" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="bigdata" label="Big Data" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="hadoop" label="Hadoop" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="java" label="Java" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="lucene" label="Lucene" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="mapreduce" label="MapReduce" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>Blur is a new Apache 2.0 licensed software project that provides a search capability built on top of Hadoop and Lucene.  Elastic Search and Solr already exist so why build something new?  While these projects work well, they didn't have a solid integration with the Hadoop ecosystem.  Blur was built specifically for Big Data, taking scalability, redundancy, and performance into consideration from the very start, while leveraging all the goodness that already exists in the Hadoop stack.  </p>

<p>A year and a half ago, my project began using Hadoop for data processing.  Very early on, we were having networking issues that would make our HDFS cluster network connectivity spotty at best.  Over one weekend in particular, we steadily lost network connection to 47 of the 90 data nodes in the cluster.  When we came in on Monday morning, I noticed that the MapReduce system was a little sluggish but still working.  When I checked HDFS I saw that our capacity had dropped by about 50%.  After running an fsck on the cluster I was amazed to find that what seemed like a catastrophic failure over the weekend resulted in a still healthy file system.  This experience left a lasting impression on me.  It was then that I got the idea to somehow leverage the redundancy and fault tolerance of HDFS for the next version of a search system that I was just beginning to (re)write.  </p>

<p>I had already written a custom sharded Lucene server that had been in a production system for a couple of years.  Lucene worked really well and did everything that we needed for search.  The issue that we faced was that it  was running on big iron that was not redundant and could not be easily expanded.  After seeing the resilient characteristics of Hadoop first hand, I decided to look into marrying the already mature and impressive feature set of Lucene with the built in redundancy and scalability of the Hadoop platform.  From this experiment Blur was created.</p>

<p>The biggest technical issues/features that Blur solves:</p>

<ul>
<li>Rapid mass indexing of entire datasets</li>
<li>Automatic Shard Server Failover</li>
<li>Near Real-time update compatibility via Lucene NRT</li>
<li>Compression of Lucene FDT files while maintaining random access performance</li>
<li>Lucene WAL (Write Ahead Log) to provide data reliability</li>
<li>Lucene R/W directly into HDFS (the seek on write problem)</li>
<li>Random access performance with block caching of the Lucene Directory</li>
</ul>

<h1>Data Model</h1>

<p>Data in Blur is stored in Tables that contain Rows.  Rows must have a unique row id and contain one or more Records.  Records have a unique record id (unique within the Row) and a column family for grouping columns that logically make up a single record.  Columns contain a name and a value, and a Record can contain multiple columns with the same name.</p>

<script src="https://gist.github.com/1349055.js?file=gistfile1.js"></script>

<h1>Architecture</h1>

<p>Blur uses Hadoop's MapReduce framework for indexing data, and Hadoop's HDFS filesystem for storing indexes.  Thrift is used for all inter-process communications and Zookeeper is used to know the state of the system and to store meta data.  The Blur architecture is made up of two types of server processes:</p>

<ul>
<li>Blur Controller Server</li>
<li>Blur Shard Server</li>
</ul>

<p>The shard server, serves 0 or more shards from all the currently online tables.  The calculation of the what shards are online in each shard server is done through the state information in Zookeeper.  If a shard server goes down, through interaction with Zookeeper the remaining shard servers detect the failure and determine which if any of the missing shards they need to serve from HDFS.  </p>

<p>The controller server provides a single point of entry (logically) to the cluster for spraying out queries, collecting the responses, and providing a single response.  Both the controller and shard servers expose the same Thrift API which helps to ease debugging.  It also allows developers to start a single shard server and interact with it the same way they would with a large cluster.  Many controller servers can be (and should be) run for redundancy. The controllers act as gateways to all of the data that is being served by the shard servers.</p>

<h1>Updating / Loading Data</h1>

<p>Currently there are two ways to load and update data.  The first is through a bulk load in MapReduce and the second is through mutation calls in Thrift.</p>

<h2>Bulk Load MapReduce Example</h2>

<script src="https://gist.github.com/1348788.js?file=BlurMapReduce.java"></script>

<h2>Data Mutation Thrift Example</h2>

<script src="https://gist.github.com/1348845.js?file=ThriftMutationExample.java"></script>

<h1>Searching Data</h1>

<p>Any element in the Blur data model is searchable through the normal Lucene semantics: analyzers. Analyzers are defined per Blur table.</p>

<p>The standard Lucene query syntax is the default way to search Blur.  If anything outside of the standard syntax is needed, you can create a Lucene query directly with Java objects, and submit them through the expert query API.</p>

<p>The column family grouping within Rows allows for results to be discovered across column families similar to what you would get with an inner join across two tables that share the same key (or in this case rowid).  For complicated data models that have multiple column families, this makes for a very powerful search capability.</p>

<p>The following example searches for "value" as a full text search.  If I had wanted to search for "value" in a single field like column "colA" in column family "famB" the query would look like "famB.colA:value".</p>

<script src="https://gist.github.com/1348874.js?file=ThriftSearchExample.java"></script>

<h1>Fetching Data</h1>

<p>Fetches can be done by row or by record.  This is done by creating a selector object in which you specify the rowid or recordid, and the specific column families or columns that you would like returned.  When not specified, the entire Row or Record is returned.</p>

<script src="https://gist.github.com/1348865.js?file=ThriftFetchExample.java"></script>

<h1>Current State</h1>

<p>Blur is nearing it's first release 0.1 and is relatively stable.  The first release candidate should be available for download within the next few weeks.  In the meantime you can check it out on github:</p>

<p><a href="https://github.com/nearinfinity/blur">https://github.com/nearinfinity/blur</a></p>

<p><a href="http://blur.io">http://blur.io</a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>Scott Leberknight Speaking at DevIgnition</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/speaking_engagements/scott_leberknight_speaking_at_10.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1889</id>

    <published>2011-11-05T18:16:27Z</published>
    <updated>2011-12-16T19:15:31Z</updated>

    <summary><![CDATA[Speaker:&nbsp;Scott Leberknight, Chief Architect, Near Infinity Conference:&nbsp;DevIgnition McLean, Virginia, Dec 2 Introduction to CoffeeScript&nbsp;»more...]]></summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Speaking Engagements" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="scottleberknight" label="scott leberknight" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<p><strong>Speaker:&nbsp;<a href="http://devignition.com/welcome/speakers#scott_leberknight" target="_blank">Scott Leberknight, Chief Architect, Near Infinity</a></strong>

<br /> 

<strong>Conference:&nbsp;<a href="http://devignition.com/" target="_blank">DevIgnition</a></strong></p>

<ul><li>McLean, Virginia, Dec 2</li></ul>

<strong>Introduction to CoffeeScript&nbsp;</strong><a href="http://devignition.com/welcome/speakers#scott_leberknight" target="_blank">»more</a>]]>
        <![CDATA[

<div><br /></div>
<p>CoffeeScript is a language that combines Ruby-ish and Python-esque flavors, and compiles directly to JavaScript. CoffeeScript's golden rule is "It's just JavaScript" so you can always see exactly what JavaScript is generated by the CoffeeScript compiler. In fact it will probably make you a better JavaSscript developer! It combines the best of JavaScript and its power in a clear, concise syntax that is easy to learn and use. You can also use it in your existing web applications with any JavaScript frameworks like jQuery, Prototype, and Scriptaculous. This session will present an overview of CoffeeScript and its features.</p>]]>
    </content>
</entry>

<entry>
    <title>Android : Browsing your PC from your Phone</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/stephen_mouring_jr/android_browsing_your_pc_hard.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1883</id>

    <published>2011-11-05T17:11:46Z</published>
    <updated>2011-11-09T22:30:37Z</updated>

    <summary>If you are like me and have a lot of music, videos, and pictures stored on an external hard drive that you want to browse from your Android smartphone than...</summary>
    <author>
        <name>Stephen Mouring Jr.</name>
        
    </author>
    
        <category term="General" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="android" label="Android" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[If you are like me and have a lot of music, videos, and pictures stored on an external hard drive that you want to browse from your Android smartphone than you have a couple options. Some are expensive (a WIFI hard drive such as <a href="http://www.seagate.com/www/en-us/products/network_storage/home-network-storage">this one</a>). Others require you to trust your data <a href="https://www.amazon.com/clouddrive/learnmore/">to the cloud</a> which you may or may not be comfortable with. And still others are needlessly complicated (setting up your own FTP server was one suggestion I got).<br /><br />After some searching I was able to compose a simple and free option, which, while a little primitive, certainly gets the job done.<br /><br />ES File Explorer is a free app available on the Android market:<br /><br />https://market.android.com/details?id=com.estrongs.android.pop<br /><br />Its primary goal is to let you to browse files on your phone. However it allows provides support for several other file sharing methods including share drives over a LAN using the simple sharing service available on Windows computers.<br /><br />From a Windows computer attached to your local network, simply right click on the drive or folder you want to share, and click "Sharing and Security" to open up the file sharing configuration. (More information <a href="http://support.microsoft.com/kb/304040">here</a>.)<br /><br />Now you can open ES File Explorer, and in the upper left corner select there is a drop down menu (defaults to "Local") that has a "LAN" option on it. Selecting LAN should display a list of shared folders on your local network.<br /><br />Now when I first did this it worked for folders on my laptop local drive, but did not work for the USB attached hard drive where I stored my file backups. I could see the share, but when I clicked on it in ES File Explorer <br /><br />Apparently there is some obscure registry setting that can prevent you from successfully sharing. Detailed instructions are <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;177078">here</a>.<br /><br />In summary: <br /><br /><ol><li>Open regedit.exe</li><li>Navigate to HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters</li><li>If the IRPStackSize value is present, double click on it. If it is not present, create it by right clicking in the Parameters window, selecting New, then DWord Value. Type IRPStackSize (it is case sensitive!)</li><li>Change the base to "decimal"</li><li>Choose a value that is larger than the existing value (or if you just created it, higher than the default value of 15.)</li><li>Restart your computer and try it now.</li><li>You may need to increase IRPStackSize a second time if it does not work. The maximum value you can enter is 50. <br /></li></ol>All done! Now you should be able to browse arbitrary content on your computer from your phone!<br />]]>
        
    </content>
</entry>

<entry>
    <title>Bryan Weber Speaking at Richmond Code Camp</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/speaking_engagements/bryan_weber_speaking_at_richmo.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1880</id>

    <published>2011-09-01T19:46:34Z</published>
    <updated>2011-10-17T19:12:39Z</updated>

    <summary><![CDATA[ Speaker: Bryan Weber, Software Developer, Near Infinity Conference:&nbsp;Richmond Code Camp Richmond, Virginia, Oct 8...]]></summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Speaking Engagements" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="bryanweber" label="bryan weber" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[ <p><strong>Speaker: Bryan Weber, Software Developer, Near Infinity</strong>

<br /> 

<strong>Conference:&nbsp;<a href="http://richmondcodecamp.org/" target="_blank">Richmond Code Camp</a></strong></p>

<ul><li>Richmond, Virginia, Oct 8</li></ul>]]>
        <![CDATA[<strong>Securing the Internet&nbsp;</strong><a href="http://richmondcodecamp.org/files/uploads/CodeCamp20112SessionList.pdf" target="_blank">»more</a>
<div><br /></div>
<p>The internet is constantly changing, but lately there have been significant updates with new and more secure protocols. We'll discuss the status of IPv4 and what is being done in an attempt to make the internet a safer place. This talk will cover changes to WHOIS, routing infrastructure and the introduction of DNSSEC and IPv6.</p>

<div><br /></div>

<strong>What makes Clojure special?&nbsp;</strong><a href="http://richmondcodecamp.org/files/uploads/CodeCamp20112SessionList.pdf" target="_blank">»more</a>
<div><br /></div>
<p>You've probably heard the buzz surrounding Clojure. You might even think that it is a fad that has peaked already. Maybe you've even written Hello World in it. But what really makes Clojure different from the other 100+ languages that run on the JVM? Come find out why Clojure is not a flash in the pan language, but one that will be around for a long time.</p>]]>
    </content>
</entry>

<entry>
    <title>Andrew Wagner Speaking at NovaRUG</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/speaking_engagements/andrew_wagner_speaking_at_nova.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1879</id>

    <published>2011-08-25T19:46:27Z</published>
    <updated>2011-09-23T19:22:43Z</updated>

    <summary><![CDATA[Speaker:&nbsp;Andrew Wagner, Software Developer, Near Infinity Usergroup:&nbsp;The Northern Virginia Ruby Meetup Group Reston, Virginia, September 22 Reek and Static Analysis of Ruby Code by Andrew Wagner&nbsp;»more...]]></summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Speaking Engagements" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="andrewwagner" label="andrew wagner" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<p><strong>Speaker:&nbsp;<a href="http://www.meetup.com/novarug/events/33444862/" target="_blank">Andrew Wagner, Software Developer, Near Infinity</a></strong>

<br /> 

<strong>Usergroup:&nbsp;<a href="http://www.meetup.com/novarug/" target="_blank">The Northern Virginia Ruby Meetup Group</a></strong></p>

<ul><li>Reston, Virginia, September 22</li></ul>

<strong>Reek and Static Analysis of Ruby Code by Andrew Wagner&nbsp;</strong><a href="http://www.meetup.com/novarug/events/33444862/" target="_blank">»more</a>]]>
        <![CDATA[<div><br /></div>
<p>Since ruby is such a dynamic language, how much can we tell about it statically? Can we get hints about parts of our design that need improving? We can, and reek is a great tool for this. Reek bills itself as the code smell detector for Ruby! We'll talk about its features, gotchas, future, and even its internals.</p>]]>
    </content>
</entry>

<entry>
    <title>Presentation Tips</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/presentations/presentation_tips.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1877</id>

    <published>2011-08-24T03:15:57Z</published>
    <updated>2011-08-24T18:32:12Z</updated>

    <summary><![CDATA[ 31:13 Speaker:&nbsp;Jeff Kunkle, Chief Technology Officer, Near Infinity Conference: NIC-U Tech Talk Length of Video: 31 minutes, 13 seconds Reston, Virginia, Jan 5...]]></summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Presentations" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="video" label="video" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<div class="presentation-video">
<a href="http://www.youtube.com/v/8l6dmfXovto?hd=1" class="lightwindow page-options play" params="lightwindow_width=480,lightwindow_height=295,lightwindow_loading_animation=false"></a><img src="http://img.youtube.com/vi/8l6dmfXovto/3.jpg" />
<span class="video-time">31:13</span>
</div>

<div class="presentation-details">
<p><strong>Speaker:&nbsp;</strong>Jeff Kunkle, Chief Technology Officer, Near Infinity
<br /> 
<strong>Conference:</strong> NIC-U Tech Talk<br />
<strong>Length of <a href="http://www.youtube.com/v/8l6dmfXovto?hd=1">Video</a>:</strong> 31 minutes, 13 seconds
</p>
<ul><li>Reston, Virginia, Jan 5</li></ul><p></p>
</div>
<br />]]>
        <![CDATA[<p>There's an endless supply of books, articles, blog posts, and videos
to help you improve your presentations. Most of them focus on the
organization and delivery aspects of presenting, which is obviously a
critical piece. This presentations is slightly different. It focuses
on some of the technical aspects surrounding your presentation, such
as making sure you have the right adapter for your projector,
preparing for screen-resolution shock, minimizing your external
distractions, and sixteen more. These tips are easy to implement and
will give your presentations an instant boost in effectiveness and
professionalism.</p>]]>
    </content>
</entry>

<entry>
    <title>Integrating JavaScript and C# with Script#</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/lee_richardson/integrating_javascript_and_c_w.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1876</id>

    <published>2011-08-24T03:09:48Z</published>
    <updated>2011-08-24T14:21:27Z</updated>

    <summary>Have you ever had an enum in your server code that you wanted to access in client side code? Or wanted the safety of compile time errors when there are...</summary>
    <author>
        <name>Lee Richardson</name>
        
    </author>
    
        <category term=".NET" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="JavaScript" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="script" label="script#" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>Have you ever had an enum in your server code that you wanted to access in client side code?  Or wanted the safety of compile time errors when there are discrepancies between your server-side and client-side code?  Or had a C# Data Transfer Object (DTO) that you wanted to enable Intellisense for in JavaScript?  I hadn't found a good solution either ... until now.</p>
<p><b>Compiling C# to What!?</b></p>

<div style="float:right; overflow: auto; margin-left:10px;">
<script type='text/javascript'> 
        var currentPageUrl = 'http://rapidapplicationdevelopment.blogspot.com/2011/08/integrating-javascript-and-c-with.html';
 
        /* Digg */
        var diggIframe = document.createElement('iframe');
        diggIframe.setAttribute('src', 'http://digg.com/tools/diggthis.php?u=' + currentPageUrl);
        diggIframe.setAttribute('height', '80');
        diggIframe.setAttribute('width', '52');
        diggIframe.setAttribute('frameborder', '0');
        diggIframe.setAttribute('scrolling', 'no');
        diggIframe.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
 
        /* DotNetKicks */
        var dotnetkicksLink = document.createElement('a');
        dotnetkicksLink.setAttribute('href', 'http://www.dotnetkicks.com/kick/?url=' + currentPageUrl);
        var dotnetkicksImg = document.createElement('img');
        dotnetkicksImg.setAttribute('src', 'http://www.dotnetkicks.com/Services/Images/KickItImageGenerator.ashx?url=' + currentPageUrl);
        dotnetkicksImg.setAttribute('alt', 'Kick this article (a good thing) on DotNetKicks');
        dotnetkicksImg.setAttribute('border', '0');
        dotnetkicksImg.setAttribute('style', 'margin-left:auto; margin-right:auto; display:block; text-align:center;');
        dotnetkicksLink.appendChild(dotnetkicksImg);
 
        var div = document.createElement('div');
        div.appendChild(dotnetkicksLink);
        div.appendChild(document.createElement('br'));
        div.appendChild(diggIframe);
 
        document.write(div.innerHTML);
    </script> 
</div>

<p>Compiling C# code into JavaScript may seem foreign, but <a href=" http://projects.nikhilk.net/ScriptSharp ">Script#</a> is a mature technology that is absolutely worth a look.  Our team has been using it very happily for about three months.  We've found a number of benefits  including:</p>

<ul>
<li>Consistently working Intellisense</li>
<li>Better encapsulation</li>
<li>Simpler Object Orientation</li>
<li>Easier deployment (Script# compiles multiple files to a single, optionally minified file)</li>
<li>Safer refactoring</li>
<li>Simpler unit testing</li>
<li>Type safety; and</li>
<li>Design time syntax checking (no more mistyping a variable and accidentally declaring it to the global scope)</li>
</ul>

<p>Scott Hanselman covered most of these topics in last month's Hanselminutes episode: <a href=" http://www.hanselminutes.com/default.aspx?showID=296">Script# Compiles to JavaScript</a>.  If you have a spare car ride I definitely recommend the listen.  But what wasn't covered were some additional benefits provided by an off the beaten path approach to this great technology.  The main benefit is tighter server side C# to client side JavaScript integration.  A secondary benefit is less of a dependency on Script#.</p>

<p><b>To the Command Line</b></p>

<p>Typically to get going with Script# you: </p>

<ol>
<li>Install the Script# Visual Studio plug-in</li>
<li>File -> New project</li>
<li>Select "Script Library" and</li>
<li>Compile to generate JavaScript</li>
</ol>

<p>Nice and easy.  The down side to this approach is you can't easily include files outside of your project.  Specifically, you can't include data transfer objects or enum's from your server side code.  Furthermore, all of your team members must install Script#.  If instead you compile with Script#'s "ssc.exe" command you obtain more control and get less dependency.</p>

<p><b>How-To</b></p>

<p>The how-to looks something like this:</p>

<ol>

<li><a href="http://projects.nikhilk.net/ScriptSharp">Download</a> and install Script#</li>
<li>Add a Class Library (not a Script# project)</li>
<li>Project properties -> Build -> Advanced -> "Do not reference mscorlib"<br />
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-u7QvzHOOfxE/TlRhVwoGyII/AAAAAAAABu8/Vonkzc8nNLc/s1600/mscorlib.png"><img style="cursor:pointer; cursor:hand;width: 400px; height: 235px;" src="http://4.bp.blogspot.com/-u7QvzHOOfxE/TlRhVwoGyII/AAAAAAAABu8/Vonkzc8nNLc/s400/mscorlib.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5644243259460339842" /></a>
</li>

<li>Ideally move the Script# files (C:\Program Files (x86)\ScriptSharp) locally to the solution and check them into source control to a Libs or something similar</li>

<li>Remove all references, but add: ScriptSharp.dll, ScriptSharp.Web.dll, Script.Jquery</li>
<li>Edit your .csproj to manually reference Script#'s mscorlib (right click, Unload project, Edit MyProject.csproj)<br />
    <br />
    <span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">&lt;</span><span style="font-size:9.5pt;line-height:
115%;font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:#A31515;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">Reference</span><span style="font-size:9.5pt;
line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;
mso-fareast-language:EN-US;mso-bidi-language:AR-SA"> </span>
    <span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;color:red;mso-ansi-language:EN-US;
mso-fareast-language:EN-US;mso-bidi-language:AR-SA">Include</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;color:blue;mso-ansi-language:EN-US;
mso-fareast-language:EN-US;mso-bidi-language:AR-SA">=</span><span style="font-size:9.5pt;line-height:115%;font-family:Consolas;mso-fareast-font-family:
Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA">&quot;<span style="color:blue">mscorlib, Version=0.7.0.0, 
    Culture=neutral, PublicKeyToken=8fc0e3af5abcb6c4, processorArchitecture=MSIL</span>&quot;<span 
        style="color:blue">&gt;<br />
    <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span style="color:#A31515">SpecificVersion</span><span 
        style="color:blue">&gt;</span>True<span style="color:blue">&lt;/</span><span 
        style="color:#A31515">SpecificVersion</span><span style="color:blue">&gt;<br />
    <span style="mso-spacerun:yes">&nbsp; </span>&lt;</span><span style="color:#A31515">HintPath</span><span 
        style="color:blue">&gt;</span>..\Libs\ScriptSharp\v1.0\mscorlib.dll<span 
        style="color:blue">&lt;/</span><span style="color:#A31515">HintPath</span><span 
        style="color:blue">&gt;<br />
    &lt;/</span><span style="color:#A31515">Reference</span><span style="color:
blue">&gt;</span></span><br /><br /></li>

<li>Modify AssemblyInfo.cs and remove the following lines:<br />
<br />
[assembly: ComVisible(false)]<br />
[assembly: Guid("b5e2449f-193c-46d1-9023-9143618d8491")]<br />
<br />
</li>

<li>Modify AssemblyInfo.cs and add the following:<br />
<br />
[assembly: ScriptAssembly("ScriptSharpDemoAssembly")<br />
<br />
</li>

<li>Ensure it compiles in Visual Studio</li>
<li>Create a batch script or PowerShell script that compiles using ssc.exe like this:<br />
<br />
..\Libs\ScriptSharp\v1.0\ssc.exe ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;/debug ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;/out:MyScriptSharp.js ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;/ref:"..\Libs\ScriptSharp\v1.0\Framework\mscorlib.dll" ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;.\Properties\AssemblyInfo.cs ^<br />
&nbsp;&nbsp;&nbsp;&nbsp;.\Class1.cs<br />
<br />

</li>
</ol>

<p>Notice the last two lines in the script are a list of the files that you want to include.  The point of this exercise is that you can now include files outside of your main Script# project in that list.</p>
<p>Now for completeness if you put a simple static method in Class1.cs, something like this:</p>
    <p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;color:blue;mso-ansi-language:EN-US;mso-fareast-language:EN-US;
mso-bidi-language:AR-SA">namespace</span><span style="font-size:9.5pt;
line-height:115%;font-family:Consolas;mso-fareast-font-family:Calibri;
mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:
EN-US;mso-bidi-language:AR-SA"> MyScriptSharp<br />
        {<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>
        <span style="color:blue">class</span> <span style="color:#2B91AF">Class1<br />
        </span><span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>{<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">public</span>
        <span style="color:blue">static</span> <span style="color:blue">string</span> 
        HelloWorld()<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="color:blue">
        return</span> <span style="color:#A31515">&quot;Hello World!&quot;</span>;<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}<br />
        <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span>}<br />
        }</span></p>

<p>Then run the batch file you should get something like this:</p>

<p><span style="font-size:9.5pt;line-height:115%;
font-family:Consolas;mso-fareast-font-family:Calibri;mso-fareast-theme-font:
minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:
AR-SA">Type.registerNamespace(<span style="color:maroon">&#39;MyScriptSharp&#39;</span>);<br />
    <br />
    <span style="color:darkgreen">
    ////////////////////////////////////////////////////////////////////////////////<br />
    // MyScriptSharp.Class1<br />
    <br />
    </span>MyScriptSharp.Class1 = <span style="color:blue">function</span> 
    MyScriptSharp_Class1() {<br />
    }<br />
    MyScriptSharp.Class1.helloWorld = <span style="color:blue">function</span> 
    MyScriptSharp_Class1$helloWorld() {<br />
    <span style="mso-spacerun:yes">&nbsp;&nbsp;&nbsp; </span><span style="color:blue">return</span>
    <span style="color:maroon">&#39;Hello World!&#39;</span>;<br />
    }<br />
    <br />
    MyScriptSharp.Class1.registerClass(<span style="color:maroon">&#39;MyScriptSharp.Class1&#39;</span>);</span></p>

<p>Obviously you could get these results faster with approach #1.  But now you have a lot more control.</p>

<p><b>Summary</b></p>

<p>The main downside to this approach is maintaining the batch file is a bit of a hassle.  But the upsides are that you can include any file from your server-side C# code.  And any changes in that server-side code are automatically reflected in your JavaScript.  And any breaking changes in your server-side code generate compile time errors in your client side code.  And furthermore none of your team members need to install Script#.  For our team it's an easy tradeoff.  What about for yours?  Please share your thoughts in the comments or on <a href="http://twitter.com/#!/lprichar">twitter</a>.</p>
]]>
        
    </content>
</entry>

<entry>
    <title>Scott Leberknight</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/published_works/scott_leberknight_nfjs_aug2011.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1874</id>

    <published>2011-08-23T15:24:56Z</published>
    <updated>2011-08-23T15:48:10Z</updated>

    <summary>Handling Big Data with HBasePublished by NFJS, the Magazine: August 2011...</summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Published Works" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="scottleberknight" label="scott leberknight" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<a target="_blank" href="http://www.nofluffjuststuff.com/home/magazine_subscribe?id=26"><b>Handling Big Data with HBase</b></a><br />Published by NFJS, the Magazine: August 2011<br />]]>
        <![CDATA[<p>
In the past few years we have seen a veritable explosion in various ways to store and retrieve data. The so-called NoSql databases have been leading the charge and creating all these new persistence choices. These alternatives have, in large part, become more popular due to the rise of Big Data led by companies such as Google, Amazon, Twitter, and Facebook as they have amassed vast amounts of data that must be stored, queried, and analyzed. But more and more companies are collecting massive amounts of data and they need to be able to effectively use all that data to fuel their business. For example social networks all need to be able to analyze large social graphs of people and make recommendations for who to link to next, while almost every large website out there now has a recommendation engine that tries to suggest ever more things you might want to purchase. As these businesses collect more data, they need a way to be able to easily scale-up without needing to re-write entire systems.
</p>]]>
    </content>
</entry>

<entry>
    <title>Rails 3 Performance Monitoring with System Metrics</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/jeff_kunkle/rails_3_performance_monitoring.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1873</id>

    <published>2011-08-22T13:42:18Z</published>
    <updated>2011-08-22T13:48:28Z</updated>

    <summary>System Metrics is a new Rails 3 Engine providing a clean web interface to the performance metrics instrumented with ActiveSupport::Notifications. It will collect and display the notifications baked into Rails...</summary>
    <author>
        <name>Jeff Kunkle</name>
        
    </author>
    
        <category term="Ruby" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>System Metrics is a new Rails 3 Engine providing a clean web interface to the performance metrics instrumented with <code>ActiveSupport::Notifications</code>. It will collect and display the notifications baked into Rails and any additional custom ones you add using <code>ActiveSupport::Notification#instrument</code>.</p>

<p>System Metrics is not intended to be a replacement for performance monitoring solutions such as New Relic. However, it is especially handy for quickly identifying performance problems in a development environment. It's also a great alternative for private networks disconnected from the Internet.</p>

<p>You can find more information about System Metrics on the <a href="http://nearinfinity.github.com/system-metrics">System Metrics site</a>. Please kick the tires and let us know what you think.</p>

<p><img src="/blogs/2011/08/22/system-metrics/smdetails.png" alt="System Metrics Detail View" title="" /></p>
]]>
        

    </content>
</entry>

<entry>
    <title>Near Infinity will be a Gigabyte Sponsor of the 2011 Run! Geek! Run! 8K Race</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/news/near_infinity_will_be_a_gigaby.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1872</id>

    <published>2011-08-01T18:01:48Z</published>
    <updated>2011-08-23T16:01:47Z</updated>

    <summary>Near Infinity will return for the third year as a sponsor of Run! Geek! Run!, an 8k race to be held on September 17 at West Potomac Park. The race supports Equal Footing Foundation, a Virginia-based nonprofit focused on getting...</summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="News" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<img alt="rungeekrun_logo.png" src="http://www.nearinfinity.com/news/assets/rungeekrun_logo.png" height="85" class="mt-image-left" style="float: right; margin: 0 0 10px -20px;" /><p>Near Infinity will return for the third year as a sponsor of Run!
Geek! Run!, an 8k race to be held on September 17 at West Potomac
Park. The race supports Equal Footing Foundation, a Virginia-based
nonprofit focused on getting technology into the hands of
underprivileged youth to "help them bring their ideas and creativity
to life." NIC will also field a team of runners in the corporate
competition.</p><div><br /></div>]]>
        
    </content>
</entry>

<entry>
    <title>Presenting Introduction to iOS development (iPhone/iPad) Sept 19-21</title>
    <link rel="alternate" type="text/html" href="https://www.nearinfinity.com/trainingcenter/coursecatalog/presenting_introduction_to_ios_development_iphoneipad_sept_19-21.html" />
    <id>tag:www.nearinfinity.com,2011:/trainingcenter//8.1871</id>

    <published>2011-07-25T18:01:53Z</published>
    <updated>2011-10-17T19:14:12Z</updated>

    <summary>Near Infinity is proud to announce our first home-grown public class offering, Introduction to iOS development (iPhone/iPad)! This class will be taught by Chris D&apos;Agostino. Chris has been teaching this class at George Mason and in various private offerings to...</summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Course Catalog" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Previous" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="https://www.nearinfinity.com/trainingcenter/">
        <![CDATA[<p>Near Infinity is proud to announce our first home-grown public class offering, Introduction to iOS development (iPhone/iPad)! This class will be taught by Chris D'Agostino. Chris has been teaching this class at George Mason and in various private offerings to our customers for a while. Now it is ready for prime time!</p>
]]>
        <![CDATA[<p>During the three day Introduction to iOS development (iPhone/iPad) class students will learn the fundamentals of building iPhone applications through a combination of lecture and hands-on labs. Each lab will build on the previous lab to demonstrate a range of capabilities for the iOS platform.</p>

<p>To learn more or to register please visit the <a href="http://www.eventbrite.com/event/1124211547/">Introduction to iOS development (iPhone/iPad) course registration</a> web page. But sign up soon because our amazingly affordable early bird rate ends after Aug 18th!</p>

<p>For information on other courses check out our <a href="../../trainingcenter/coursecatalog/upcoming/">Upcoming NIC-U Training Courses</a> page!</p>
]]>
    </content>
</entry>

<entry>
    <title>ExtJS 4 Bootcamp August 1-3 by Modus/Create</title>
    <link rel="alternate" type="text/html" href="https://www.nearinfinity.com/trainingcenter/coursecatalog/extjs_4_bootcamp_august_1-3_by_moduscreate.html" />
    <id>tag:www.nearinfinity.com,2011:/trainingcenter//8.1870</id>

    <published>2011-07-21T16:04:26Z</published>
    <updated>2011-10-17T19:16:34Z</updated>

    <summary>In August, the NIC Training Center will host an ExtJS 4 Bootcamp presented by Modus/Create. This class will be taught by Jay Garcia, the Author of ExtJS in Action. Jay has been working with ExtJS since its beginning, and is...</summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Course Catalog" scheme="http://www.sixapart.com/ns/types#category" />
    
        <category term="Previous" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="https://www.nearinfinity.com/trainingcenter/">
        <![CDATA[<p>In August, the NIC Training Center will host an ExtJS 4 Bootcamp presented by Modus/Create. This class will be taught by Jay Garcia, the Author of ExtJS in Action. Jay has been working with ExtJS since its beginning, and is a recognized expert on ExtJS.</p>
]]>
        <![CDATA[<p>The three day Ext JS 4.0 bootcamp is designed to give you essential knowledge on using this new framework focusing on real-world experience in the field.  With this course, you'll learn to master critical Ext JS 4.0 essentials, such as the new class system, and you'll get to exercise the newly updated grid and tree Panels.</p>

<p>To learn more please visit Modus/Create's <a href="http://moduscreate.com/training/extjs-4-training">ExtJS 4 Bootcamp</a> course description.</p>

<p>To register visit the <a href="http://extjs4training.eventbrite.com/">course registration</a> web page.</p>
]]>
    </content>
</entry>

<entry>
    <title>JRubyConf 2011</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/news/jrubyconf_2011.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1869</id>

    <published>2011-07-20T19:22:33Z</published>
    <updated>2011-07-20T19:30:21Z</updated>

    <summary>Near Infinity is one of the sponsors for JRubyConf 2011, Wednesday and Thursday, August 3-4 in Washington, D.C. Learn about a technology that is quickly changing the face of software development and hear from many companies who have implemented JRuby...</summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="News" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<p>Near Infinity is one of the sponsors for <a href="http://jrubyconf.com/" target="_blank">JRubyConf 2011</a>, Wednesday and Thursday, August 3-4 in Washington, D.C. Learn about a technology that is quickly changing the face of software development and hear from many companies who have implemented JRuby and found creative ways to harness its power.</p>]]>
        
    </content>
</entry>

<entry>
    <title>NovaRUG - CoffeeScript by Scott Leberknight</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/news/novarug_-_coffeescript_by_scot.html" />
    <id>tag:www.nearinfinity.com,2011:/news//4.1868</id>

    <published>2011-07-20T18:47:34Z</published>
    <updated>2011-07-20T19:20:35Z</updated>

    <summary><![CDATA[Near Infinity is hosting the July&nbsp;NovaRUG meeting, Thursday, July 21 6:30 p.m. in Reston, Virginia. Scott Leberknight will be presenting on&nbsp;CoffeeScript....]]></summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="News" scheme="http://www.sixapart.com/ns/types#category" />
    
    <category term="scottleberknight" label="scott leberknight" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[Near Infinity is hosting the July&nbsp;<a href="http://www.meetup.com/novarug/events/26214201/" target="_blank">NovaRUG</a> meeting, Thursday, July 21 6:30 p.m. in Reston, Virginia. <a href="http://www.nearinfinity.com/home/bios/scott_leberknight.html">Scott Leberknight</a> will be presenting on&nbsp;<i>CoffeeScript</i>.]]>
        Scott Leberknight will take a break from his recent immersions into the depths of Hadoop and Hive long enough to reprise his excellent CoffeeScript presentation, which he presented at NIC-U&apos;s Spring technical conference in April. Scott is the Chief Architect at Near Infinity Corporation.
    </content>
</entry>

<entry>
    <title>Near Infinity Named One of the Top 25 Best Small-Sized Companies to Work for in America</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/news/awards/near_infinity_named_one_of_the.html" />
    <id>tag:www.nearinfinity.com,2010:/news//4.1757</id>

    <published>2011-07-18T13:00:00Z</published>
    <updated>2011-07-20T18:45:59Z</updated>

    <summary> Near Infinity Corporation was named one of this year&apos;s 50 Best Small and Medium Companies to Work For by the Great Place to Work Institute, published by entrepreneur.com, which underscores employee trust in the workplace. Near Infinity was recognized...</summary>
    <author>
        <name>Fatimah Hoque</name>
        
    </author>
    
        <category term="Awards" scheme="http://www.sixapart.com/ns/types#category" />
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/news/">
        <![CDATA[<a href="http://www.greatplacetowork.com/what_we_do/lists-us-sme.htm" target="_blank"><img alt="entlogo-2009.gif" src="http://www.nearinfinity.com/news/images/sme_entrepreneur_list_logo.gif" class="mt-image-right" style="float: left; margin: 10px 20px 10px 0pt;" width="200" height="115" /></a>

<p><br />Near Infinity Corporation was named one of this year's 50 Best Small and Medium Companies to Work For by the Great Place to Work Institute, published by entrepreneur.com, which underscores employee trust in the workplace. Near Infinity was recognized in particular for its outstanding in-house training program and employee-managed software and training budgets.</p>]]>
        <![CDATA[<p>Near Infinity was chosen as a 2010 winner by participating in the Great Place to Work Institute's selection process, which includes a Trust Index© Employee Survey, a questionnaire filled out by NIC employees about programs and company practices, and an in-depth culture audit. The Great Place to Work Institute evaluated the company based on five areas: credibility, respect, fairness, pride and camaraderie. The Institute's unique methodology measures the level of trust that exists between employees and management, the pride employees express about the company and the camaraderie employees share.</p>

<p>Other 2010 winners include Shutterfly, Radio Flyer, and Near Infinity's partner, Atlassian. <a href="http://www.greatplacetowork.com/what_we_do/lists-us-sme.htm" target="_blank">See the full list of 2010 winners</a>. </p>

<h3>About Great Places to Work</h3>

<p>The Great Place to Work Institute has been studying and identifying best companies for more than 25 years. Great Place to Work Institute's proprietary methodology and assessment tools examine the level of trust at an organization. Visit <a href="http://cts.businesswire.com/ct/CT?id=smartlink&amp;url=http%3A%2F%2Fwww.greatplacetowork.com&amp;esheet=6421383&amp;lan=en-US&amp;anchor=www.greatplacetowork.com&amp;index=9&amp;md5=8e1e7eb7d0b0be62629f9650fe900a1c" target="_blank">www.greatplacetowork.com</a> to learn more about our trust assessments and Best Companies to Work For lists.</p>

<h3>About Entrepreneur.com</h3>

<p>Marking its 10-year anniversary in 2006, Entrepreneur.com has evolved into the most widely used website by entrepreneurs and leaders in business worldwide. As the leading small business website on the Internet, Entrepreneur.com serves its visitors' needs by creating the most satisfying experience with relevant content, logical information management and ease of access.</p>]]>
    </content>
</entry>

<entry>
    <title>Danger in the shadows of ruby...</title>
    <link rel="alternate" type="text/html" href="http://www.nearinfinity.com/blogs/andrew_wagner/danger_in_the_shadows_of_ruby.html" />
    <id>tag:www.nearinfinity.com,2011:/blogs//7.1866</id>

    <published>2011-07-14T20:40:32Z</published>
    <updated>2011-07-15T20:23:29Z</updated>

    <summary>Consider this seemingly innocuous bit of code, presumably on a User class somewhere: def manager manager = User.ceo User.all_managers.each do |manager| return manager if self.reports_to?(manager) end return manager end There...</summary>
    <author>
        <name>Andrew Wagner</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://www.nearinfinity.com/blogs/">
        <![CDATA[<p>Consider this seemingly innocuous bit of code, presumably on a User class somewhere:</p>

<pre>
 def manager
    manager = User.ceo
    User.all_managers.each do |manager| 
        return manager if self.reports_to?(manager)
    end
    return manager
  end
</pre>

<p>There are certainly other ways to write this code, but the idea is straightforward enough. This is a pretty small company, and if there are no manager-level employees to whom the user reports, then they report directly to the CEO.</p>

<p>However, as you might have guessed, it's not quite that simple. In fact, in ruby 1.8x, it will always return one of the managers, and <strong>never</strong> the CEO. The "manager" variable in the block overwrites the variable defined previously. Note, however, that both variables, in some sense, shadow the method name, yet that doesn't come into play at all.</p>

<p>Now in ruby 1.9.2, all is well. The "manager" variable in the block shadows the previous one, but doesn't interact with it. And, to boot, it warns you about what you're doing, if you turn warnings on <a href="http://avdi.org/devblog/2011/06/23/how-ruby-helps-you-fix-your-broken-code/">which of course you should</a>. </p>

<p>However, this unfortunately doesn't help you in the slightest in ruby 1.8. And, in fact, it's worse than that. Here's <a href="https://gist.github.com/1083428">a more complete implementation of the class, with some tests</a>. These tests pass. Not only that, but they show 100% code coverage! <strong>This is why you cannot trust code coverage in and of itself</strong>.</p>

<p>So, this is a simple snippet, which behaves in mysteriously different ways between 1.8 and 1.9, gives you no warning in 1.8, and even deceives your code coverage numbers. Here be dragons!</p>
]]>
        

    </content>
</entry>

</feed>

