Terminating NodeJs requests.

Okay,

This one is for nodejs programmers. I figured something the hardway, Let me get right to the point. Often you are going to be making requests other than creating servers for whatever reason (Proxy servers, REST calls).

The way to do it is briefly :

var request = http.request (options, function (response) {  …..}) ;

request.end();

Now here is the messed up part, request.end() doesn’t actually terminate the request explicitly. Its upto the other server to terminate it once all the data has been sent. I learnt it the hardway when I was experimenting with a streaming proxy. my request header had a “connection : keep-alive” part to it which means that request.end() would never work since the connection is kept alive by the other end.

You’d have to explicitly terminate the connection by  request.connection.destroy();

I learn’t it after a couple of hours of googling and I found these links

http://stackoverflow.com/questions/7339640/with-node-js-http-how-does-res-end-guarantee-a-disconnection-of-the-socket

http://stackoverflow.com/questions/5263716/graceful-shutdown-of-a-node-js-http-server

Now i need some beer.

-rohit

Neo4j CodeIgniter library

Phewf,

Finally finished up a simple curl->request based CodeIgniter library that acts as a wrapper for the Neo4j Graph Database Server. Its barebone and fairly simple and its up on GitHub at https://github.com/rohitm/Neo4j-Codeigniter-REST-Library

Getting the Neo4j Graph Database to work with PHP.

Okay, For those of you who don’t know what Neo4j is, it’s a graph database server. You should probably research graph databases or read up on Neo4j on http://neo4j.org/ .  Neo4j is written on java and installs in a few quick command line steps on a Mac. If you are using pesky Linux or screwy Windows, you ought to follow the installation instructions as these boxes don’t come pre-installed with Java unlike osX.

Neo4j doesn’t support PHP straight away so therefore I tried using the php API recommended by them. This one is at https://github.com/onewheelgood/Neo4J-REST-PHP-API-client . The GuitHub repo says the last date it was updated was in 2010 and I couldn’t get the API to work. After a few annoying php errors, I gave up on the whole API idea. I decided to  look through the documentation and figured that Neo4j supports REST calls elegantly through json objects and the curl examples seemed pretty self-explanatory.

I decided to write a small Neo4j json friendly Curl Request() function that communicates with the API and put it up in a test.php function. Got it to work the way I wanted with a few tweaks and everything seemed fine so far. If you’re satisfied with what you’ve read so far and you just want the function and the REST API reference, I’ll spare you the trouble of the rest of my post.

The REST API documentation is here at : http://components.neo4j.org/neo4j-server/snapshot/rest.html

And my simple function is here :

function string_begins_with($string, $search)
{
	return (strncmp($string, $search, strlen($search)) == 0);
}	

function request($service, $data, $return_type="array")
{
	if (!string_begins_with ($service, 'http://'))
		$url = 'http://localhost:7474/'.$service ;
	else
		$url = $service ;

	$fields = $data ;

	$fields_string = '' ;

	//url-ify the data for the POST
	if ($data != NULL)
		$post_data = json_encode($data) ;

	//open connection
	$ch = curl_init();

	//set the url
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_HEADER, 0);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);

	if ($data != NULL) {
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
		curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

		$headers = array(
					'Content-Length: ' . strlen($post_data),
					'Content-Type: application/json',
					'Accept: application/json'
					);
		curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	} else {
		curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
	}
	curl_setopt($ch,CURLOPT_RETURNTRANSFER, true) ;

	//execute post
	$result = curl_exec($ch);
	//close connection
	curl_close($ch);	

	if ($result)
	{
		if ($return_type == "array")
			return (json_decode($result, true)) ;
		else
			return (json_decode($result)) ;
	}
}

In the example that I’m using below, I’ve created a social network between 10 famous people and I attempt to trace the path between two people from within that network. All this is done using the request method from above so therefore paste your code accordingly. We now create the models of the 10 people with their name and their ages.

// Create the nodes
$response = request('db/data/node', array ('name'=> 'Jennifer Connely', 'age' => '33')) ;
$jenniferConnelyNode = $response ;
$response = request('db/data/node', array ('name'=> 'Mark Walberg', 'age' => '30')) ;
$markWalbergNode = $response ;
$response = request('db/data/node', array ('name'=> 'Owen Wilson', 'age' => '38')) ;
$owenWilsonNode = $response ;
$response = request('db/data/node', array ('name'=> 'George Lucas', 'age' => '56')) ;
$georgeLucasNode = $response ;
$response = request('db/data/node', array ('name'=> 'kevin spacy', 'age' => '48')) ;
$kevinSpaceyNode = $response ;
$response = request('db/data/node', array ('name'=> 'Quentin tarantino', 'age' => '36')) ;
$QuentinTarantinoNode = $response ;
$response = request('db/data/node', array ('name'=> 'Ashlee Simpson', 'age' => '24')) ;
$ashleeSimpsonNode = $response ;
$response = request('db/data/node', array ('name'=> 'Guy Ritchie', 'age' => '45')) ;
$guyRitchieNode = $response ;
$response = request('db/data/node', array ('name'=> 'George Clooney', 'age' => '52')) ;
$georgeClooneyNode = $response ;
$response = request('db/data/node', array ('name'=> 'Lewis Hamilton', 'age' => '28')) ;
$lewisHamiltonNode = $response ;

We store the node addresses from the $response variable, If you wish you see what the REST Server responds, you could always var_dump ($response) and do your stuff. We use these node addresses to map relationships between these people. Therefore I make one way relationships such as “Jennifer Connelly” Knows “Mark Walberg” and so on.

// Create Relationship between nodes
request ($jenniferConnelyNode['self']."/relationships/", array ("to"=> $markWalbergNode['self'], "type"=>"knows")) ;
request ($jenniferConnelyNode['self']."/relationships/", array ("to"=> $owenWilsonNode['self'], "type"=>"knows")) ;

request ($markWalbergNode['self']."/relationships/", array ("to"=> $owenWilsonNode['self'], "type"=>"knows")) ;
request ($markWalbergNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;

request ($owenWilsonNode['self']."/relationships/", array ("to"=> $markWalbergNode['self'], "type"=>"knows")) ;
request ($owenWilsonNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;
request ($owenWilsonNode['self']."/relationships/", array ("to"=> $georgeLucasNode['self'], "type"=>"knows")) ;

request ($georgeLucasNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;
request ($georgeLucasNode['self']."/relationships/", array ("to"=> $QuentinTarantinoNode['self'], "type"=>"knows")) ;
request ($georgeLucasNode['self']."/relationships/", array ("to"=> $guyRitchieNode['self'], "type"=>"knows")) ;

request ($kevinSpaceyNode['self']."/relationships/", array ("to"=> $ashleeSimpsonNode['self'], "type"=>"knows")) ;

request ($QuentinTarantinoNode['self']."/relationships/", array ("to"=> $guyRitchieNode['self'], "type"=>"knows")) ;
request ($QuentinTarantinoNode['self']."/relationships/", array ("to"=> $jenniferConnelyNode['self'], "type"=>"knows")) ;	

request ($ashleeSimpsonNode['self']."/relationships/", array ("to"=> $georgeLucasNode['self'], "type"=>"knows")) ;
request ($ashleeSimpsonNode['self']."/relationships/", array ("to"=> $lewisHamiltonNode['self'], "type"=>"knows")) ;

request ($guyRitchieNode['self']."/relationships/", array ("to"=> $georgeClooneyNode['self'], "type"=>"knows")) ;

request ($georgeClooneyNode['self']."/relationships/", array ("to"=> $georgeLucasNode['self'], "type"=>"knows")) ;
request ($georgeClooneyNode['self']."/relationships/", array ("to"=> $ashleeSimpsonNode['self'], "type"=>"knows")) ;
request ($georgeClooneyNode['self']."/relationships/", array ("to"=> $lewisHamiltonNode['self'], "type"=>"knows")) ;		

request ($lewisHamiltonNode['self']."/relationships/", array ("to"=> $kevinSpaceyNode['self'], "type"=>"knows")) ;

Once I have the relationships mapped, I can trace the path between any two people with another REST call. For more information on any of the parameters that I’m passing to the REST Server. Refer the Neo4j REST documentation from the link way up above. Neo4j can return the intermediate nodes between two nodes and therefore I can see how “Lewis Hamilton” knows “Mark Walberg”. If you’ve joined up all the pieces of code and put it together on a test.php with a successfully running Neo4j server, You should see the result on your browser.

// Find path between two nodes
$response = request ($lewisHamiltonNode['self']."/path", array ("to"	=> $markWalbergNode['self'],
				"algorithm"=>"shortestPath",
				"max_depth"=>6,
				"relationships"	=>array ('type'=> 'knows', 'direction'=>'out')
			)) ;		

if (isset ($response['nodes'])) {
	$i = 0;
	$len = count($response['nodes']);		

	foreach ($response['nodes'] as $node) {
		$response = request ($node, NULL) ;

		if (isset ($response['data'])) {
			$data = $response['data'] ;
			if ($i == 0)
				echo "".$data['name']." knows " ;
			else if ($i == $len - 1)
				echo "".$data['name']."" ;
			else
				echo "".$data['name']." who knows " ;

			$i++;
		}
	}
} else {
	echo "Cant find a relationship" ;
}

I hope the above code helped

Rohit. Manohar

Follow

Get every new post delivered to your Inbox.