New website of MessagePack Project

New website of MessagePack Project is opened!

URL is: http://msgpack.org/

New website of MessagePack Project

New website of MessagePack Project

Now it describes about our RPC – MessagePack-RPC. It is the next-generation RPC system that supports ALL of following features:

Twitter hash tag is #msgpack. Please tweet me.
There are also mailing lists at google groups.

Detailed information is available at MessagePack Wiki.
enjoy!

Posted in Uncategorized | 2 Comments

Architecture of MessagePack

Posted in MessagePack, MessagePack-RPC | 1 Comment

MessagePack-RPC for Java 0.3.0 is released!

Today, I just released the MessagePack-RPC for Java version 0.3.0!

The main change is, supporting the UDP protocol. The following is the example codes.

UDPClient

        EventLoop loop = new EventLoop();
        try {
            Client c = new UDPClient("localhost", 19850, loop);
            try {
                Object o = c.call("intFunc1", 1);
                int val = ((Number)c).intValue();
            } finally {
                c.close();
            }
        } finally {
            loop.shutdown();
        }

UDPServer

class ServerTest {
    public int intFunc1(int a) { return a; }

    public static void main(String[] args) {
        Server s = new UDPServer("0.0.0.0", 19850, this);
        s.serve();
    }
}

Replacing “UDP” with “TCP” will work for the TCP Client/Server. Thanks to JBoss netty, it was really easy to support two different transports.

The next tasks are running the more serious stress test for the stability. And also, thrift-compatible IDL support is under development!

Looking forward to integrate into the real applications:-)

Posted in Java, MessagePack-RPC | 2 Comments

Streaming Serialization/Deserialization with MessagePack

Streaming feature of MessagePack

Streaming serialization/deserialization is one of the key features of MessagePack.
It enables you to store and load multiple objects to/from a stream (like files or network connections). It is easy to use and fast.

I’ll introduce the streaming features with Ruby codes.

Storing objects to a file

Now I want to store structured objects to a log file.
I can serialize objects with MessagePack and store them to a file. And then, I can take from the file objects out one after another.

Here is the code:

require 'msgpack'  # gem install msgpack

# Open the log file for write.
File.open("log.mpac", "w") do |f|
  # Serialize and store 3 objects.
  {'name'=>'msgpack'}.to_msgpack(f)
  {'name'=>'kumofs' }.to_msgpack(f)
  {'name'=>'frsyuki'}.to_msgpack(f)
end

# Open the log file for read.
File.open("log.mpac") do |f|
  # Create a instance of "MessagePack::Unpacker"
  pac = MessagePack::Unpacker.new(f)

  begin

    # Load the stored objects with "each" method.
    pac.each do |obj|
      # Do something with the deserialized object.
      on_message(obj)
    end

  rescue EOFError
    # EOF reached.
  end
end

Compression

Next, the size of the log file becams a big problem. Compression is very effective to reduce the size. MessagePack::Unpacker#feed method is useful to deal with special stream like Zlib::Inflate.

Here is the code:

require 'msgpack'  # gem install msgpack
require 'zlib'  # zlib is a standard library

# Open the log file for write.
File.open("log.zmpac", "w") do |f|
  # Serialize, compress and store the objects.
  zd = Zlib::Deflate.new
  zd << {'name'=>'msgpack'}.to_msgpack && f.write(zd.flush)
  zd << {'name'=>'kumofs' }.to_msgpack && f.write(zd.flush)
  zd << {'name'=>'frsyuki'}.to_msgpack && f.write(zd.flush)
  zd.close
end

# Open the log file for read.
File.open("log.zmpac") do |f|
  # Create instance of "Zlib::Inflate" and "MesasgePack::Unpacker"
  zi = Zlib::Inflate.new
  pac = MessagePack::Unpacker.new

  begin

    buffer = ''
    while f.sysread(1024, buffer)
      # Use "feed" method to append the inflated buffer.
      pac.feed zi.inflate(buffer)

      # Then, call each method.
      pac.each do |obj|
        # Do something with the deserialized object.
        on_message(obj)
      end
    end

  rescue EOFError
    # eof reached.
  end

  zi.close
end

Streaming on network connection

MessagePack::Unpacker#feed method is also useful to receive objects from other hosts via network connection.
In the following code, I use an event-processing library EventMacnie with MessagePack.

require 'msgpack'      # gem install msgpack
require 'eventmachine' # gem install eventmachine
require 'json'

# This server program receives objects serialized with MessagePack and convert them to JSON.
class MessagePackToJsonServer < EventMachine::Connection
  def initialize
    # Create the streaming deserializer of MessagePack.
    @pac = MessagePack::Unpacker.new
  end

  def receive_data(data)
    # Feed the recived data to the deserializer.
    @pac.feed data

    # Streaming deserialize.
    @pac.each do |obj|
      message_received(obj)
    end
  end

  def message_received(obj)
    # Do something with the deserialized object.
    send_data obj.to_json
  end
end

# Start the server.
EventMachine::run do
  host = '0.0.0.0'
  port = 8080
  EventMachine::start_server host, port, MessagePackToJsonServer
end

The streaming feature is available on other languages. It is very important feature to implement MessagePack-RPC.

Posted in MessagePack, MessagePack-RPC, Ruby | 1 Comment

MessagePack-RPC for C++

What’s MessagePack-RPC?

MessagePack-RPC is a inter-process messaging system that is similar to Facebook’s thrift, Apache avro or Google’s Protocol Buffers. It uses MessagePack format for object serialization and passes serialized object across network connection.

MessagePack is cross-language serialization format and MessagePack-RPC enables you to exchange messages between programs implemented in heterogeneous languages.

Today, I want to introduce the C++ implementation of MessagePack-RPC. Its most important characteristics are (1) High-performance, (2) concept of “Future” and (3) Thread-safe connection pool.

(1) High-Performance

One of the most important factors of the performance is parallel processing because even cheap machines have multiple cores today. MessagePack-RPC for C++ has an intelligent parallel processing mechanism that other libraries (Thrift, Avro, Protocol Buffers, etc.) don’t have.

It processes all messages in parallel even if the messages are reached on single connection.

This characteristic is particularly effective in the cluster application that servers communicate mutually.

The following graph shows you the effectiveness of the parallel processing.

(2) Future and Asynchronous call

MessagePack-RPC for C++ provides flexible asynchronous processing model supported by concept of Future. Future describes an object that acts as a proxy for a result that is initially not known (Wikipedia).

The following code shows the example.

#include <msgpack/rpc/client.h>
#include <string>
#include <iostream>

using namespace std;
using namespace msgpack::rpc;

int main(void)
{
    // create an client instance
    client c("127.0.0.1", 9090);
    std::string text = ...;

    // send some heavy request and receives its future result.
    future f1 = c.call("analyze", text);
    // the server starts to process this request.

    // send other requests.
    future f2 = c.call("count", text);
    // the server starts to process this request on another CPU core.

    // receive actual result of request that will be finished first.
    int result2 = f2.get<int>();

    // you can do some calcuation while server processing first heavy request ...

    // then receive result of the heavy request.
    string result1 = f1.get<string>();

    std::cout << result1 << std::endl;
    std::cout << result2 << std::endl;
}

(3) Thread-safe connection pool

MessagePack-RPC for C++ has connection pooling feature. Its peculiar advantage is thread safety. You can share one pooled connection with multiple threads.

The following multithreaded client program is valid and it establishes only one connection.

#include <msgpack/rpc/client.h>
#include <msgpack/rpc/session_pool.h>
#include <mp/pthread.h>

void thread_1(session_pool* sp) {
    // do RPC on pooled connection
    msgpack::rpc::session s = sp->get_session("127.0.0.1", 9090);
    int result = s.call("add", 1, 2).get<int>();
}

void thread_2(msgpack::rpc::session_pool* sp) {
    // do RPC on pooled connection
    msgpack::rpc::session s = sp->get_session("127.0.0.1", 9090);
    int result = s.call("add", 2, 3).get<int>();
}

int main(void) {
    // create thread-safe connection pool
    msgpack::rpc::session_pool sp;
    sp.start(4);  // run 4 worker threads

    // run 2 client threads for example
    mp::pthread_thread t1;
    mp::pthread_thread t2;
    t1.run( mp::bind(thread_1, &sp) );
    t2.run( mp::bind(thread_2, &sp) );

    t1.join();
    t2.join();
    sp.end();
}

Starting with MessagePack-RPC

The Ruby implementation is good for first. It’s very easy to use and suitable for prototyping, while it is full-featured that has concept of Future and connection pool.

There are simple implementation of distributed key-value storage on my simple-kvs repository at github. Though it has replication and load-balancing features, it is implemented in only 54 lines.

Question

If you have any question, please contact with @frsyuki_ha or @kzk_mover with #msgpack hash tag, or #msgpack on freenode.net, or project mailing list. See also the project web site.

Posted in C++, MessagePack-RPC | 6 Comments

Introduction to MessagePack-RPC

The official MessagePack blog is here! Today I want to introduce recent progress at the MessagePack project. It’s a extremely efficient object serialization library like JSON, but very fast and small.

Why MessagePack?

There’re some projects in the same area. Google’s protocol buffer, Facebook’s thrift, Apache avro, etc. Why another one?

Two important points. For speed, and tight integration with each language.

(1) Speed

For speed, MessagePack has zero copy serialization + streaming deserialization. Please look at Introduction to MessagePack. We also compared with other libraries in the view point of speed and size. Please look at here.

(2) Tight Integration with the language

Actually “MessagePack” itself is the name of the format, like JSON. And many libraries handling it were written by many languages. Currently, C, C++, Java, Ruby, Python, Perl, PHP, Haskell, Lua, D implementations are available.

Some implementations provide the easy packaging. For example, Ruby version is provided as Ruby gem.

$ gem install msgpack

Same for other languages (Maven2 for Java, PyPI for Python, CPAN for Perl, Hackage for Haskell).

The library API is basically the same across languages but provides the convenient way for the language. Here’s the deselialization with for loop in Python version. Really cool!

>>> unpacker = msgpack.Unpacker()
>>> buf = b'¥x93¥x01¥x02¥x03' * 5
>>> len(buf)
20
>>> unpacker.feed(buf[:9])
>>> for o in unpacker:
...     print o
...
[1, 2, 3]
[1, 2, 3]
>>> unpacker.feed(buf[9:])
>>> for o in unpacker:
...     print o
...
[1, 2, 3]
[1, 2, 3]
[1, 2, 3]

MessagePack-RPC

The next move of our project is developing MessagePack-RPC, RPC library using MessagePack for object serialization. It’s fast, and achieves cross language object exchange.

The repository is available here.

Currently, only C++/Java/Ruby implementations are available. The nice thing is that, each implementation depends on nice event loop libraries for the languages. Ruby version uses Rev, C++ version uses mpio, Java version uses JBoss netty.

And also, please remember MessagePack supports “Streaming Deserializer”. When you got the data from the network, the server/client are able to deserialize in a streaming way.

By using them, MessagePack-RPC provides high-performance RPC. And also provide asynchronous call at the client-side.

Let’s look at the example. Most users use script language at the client-side, and C++/Java program at the server side.

Ruby client

It’s provided as ruby gem. Please install with “gem install msgpack-rpc”. Following is the example of calling “hello” function with some arguments.

require 'rubygems'
gem 'msgpack'
gem 'msgpack-rpc'
require 'msgpack'
require 'msgpack/rpc'

begin
  cli = MessagePack::RPC::Client.new("127.0.0.1", 1985)
  cli.timeout = 5
  v = cli.call(:hello0)
  v = cli.call(:hello1, 1)
  v = cli.call(:hello2, 1, 2)
  cli.close
rescue MessagePack::RPC::TimeoutError
  p $!
end

It also supports asynchronous call. It’s really useful when you call multiple services at the same time.

client = new Client(...);
future = client.send(...) # asynchronous call returns
future.join() # waiting the completion
result = future.result();

futures = []
futures << client.send(...)
futures << client.send(...)
futures.each { |f| f.join() }

Of course, you can use custom data structure. Example code is here.

Java server

The following code implements high-performance Java server. The Java version uses netty, Java NIO Socket Framework by JBoss community. netty provides multithread + event model. It’s really FAST, and extensible.

package org.msgpack.rpc;

import java.io.IOException;

import org.msgpack.rpc.client.Client;
import org.msgpack.rpc.server.*;

public class App 
{
    public int hello0() {
    	System.out.println("hello0");
        return 0;
    }
    public int hello1(int a) {
    	System.out.println("hello1");
        return 1;
    }
    public int hello2(int a, int b) {
    	System.out.println("hello2");
        return 2;
    }
    
    public static void main( String[] args )
    {
        Server s = new TCPServer();
        try {
        	System.out.println("listen!");
        	s.listen(1985, new App());
        } catch (IOException e) {
        	e.printStackTrace();
        }
    }
}

Difference between MessagePack-RPC and Thrift

Way faster. The following graph shows the performance difference between C++ MessagePack-RPC v.s C++ Thrift v.s. Sun-RPC.

Tight integration with each language.

Release management per language bindings, not by whole project. Formerly, I submitted to the bug fix patch to the PHP binding. But Thrift release cycle is decided by all language bindings. Then, they couldn’t release as soon as possible.

We’re developing actively. Many languages don’t support RPC yet, but ongoing.

And also note that, we’re now developing Thrift compatible IDL (Interface Definition Language) compiler for MessagePack. If you use the Thrift, the move to MessagePack-RPC will be really easy :-)

Question

If you have any question, please contact with @frsyuki or @kzk_mover with #msgpack hash tag, or #msgpack on freenode.net, or project mailing list.

Add to FacebookAdd to DiggAdd to Del.icio.usAdd to StumbleuponAdd to RedditAdd to BlinklistAdd to TwitterAdd to TechnoratiAdd to Yahoo BuzzAdd to Newsvine Like This!

Posted in MessagePack-RPC | 9 Comments