Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an IPC transport implementation for Thrift ? or low latency SOA solutions

I want to introduce SOA to a low latency system without the overhead of TCP communication(even on the same machine). Thirft seems like a great fit as I have both Java and php processes. Is there an IPC transport implementation for thrift, or any other good idea that could help in this scenario?

like image 520
Assaf Karmon Avatar asked May 15 '12 20:05

Assaf Karmon


2 Answers

You could use Thrift to serialize your objects and then use IPC method of your liking(named pipe,message queues etc). The following is a simple example using pipes

  1. We have a an object of type Message which contains some information
  2. Php process is the producer of the message
  3. Java process is the consumer

Thrift model

struct Message {
  1: i32 uid,
  2: string information,
}

generate thrift sources

thrift --gen java message.thrift
thrift --gen php message.thrift

PHP producer

<?php
$GLOBALS['THRIFT_ROOT'] = 'src';
require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php';
require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinarySerializer.php'; // this generates serialized string from our obect
require_once $GLOBALS['THRIFT_ROOT'].'/packages/message/message_types.php'; //from generated thrift sources
//create new message
$message = new Message();
$message->uid = '1';
$message->information = 'Some info';
var_dump($message);

//serialize
$serializer = new TBinarySerializer(); 
$serialized_message = $serializer->serialize($message);
var_dump($serialized_message);

//write to a pipe
if (pcntl_fork() == 0) {
$namedPipe = '/tmp/pipe';
if (! file_exists($namedPipe)) {
   posix_mkfifo($namedPipe, 0600);
}

$fifo = fopen($namedPipe, 'w');

fwrite($fifo, $serialized_message);
exit(0);
}
?>

Java Consumer

        //read from pipe
    FileInputStream fileInputStream = new FileInputStream(new File("/tmp/pipe"));
    int availableBytes = fileInputStream.available();

    byte[] b = new byte[availableBytes]; 
        fileInputStream.read(b , 0, availableBytes);
        //deserialize
    TDeserializer tDeserializer = new TDeserializer();
    Message deserMessage = new Message();
    tDeserializer.deserialize(deserMessage, b);
    System.out.println(deserMessage.getInformation());
    //prints "Some info"
like image 142
gt5050 Avatar answered Nov 15 '22 17:11

gt5050


See here regarding a cross-platform pipe transport for the Thrift C++ library. This should be straight-forward to port to the other languages. If you only need to support *NIX, you could use domain sockets which is already supported by TSocket. Simply pass in (name) instead of (host, port) to its constructor.

like image 41
pmont Avatar answered Nov 15 '22 17:11

pmont