Doug,
I see. I understood what you say. I think additional threads or pooled threads
are required for each I/Os, so Future should be RunnableFuture like following:
Client c1 = new Client("server1:1010");
Client c2 = new Client("server2:1010");
Client c3 = new Client("server3:1010");
// sends queries to each servers.
RunnableFuture<ResultChunk> f1 = c1.DoIt(query1, data1); // Since the data
is rather large,
RunnableFuture<ResultChunk> f2 = c2.DoIt(query2, data2); // asynchronous
(parallel) sending
RunnableFuture<ResultChunk> f3 = c3.DoIt(query3, data3); // and receiving
are wished.
// does I/Os on thread pool
ExecutorService pool = Executors.newFixedThreadPool(3);
pool.submit(f1);
pool.submit(f2);
pool.submit(f3);
try {
// gathers results.
ResultChunk result1 = f1.get();
ResultChunk result2 = f2.get();
ResultChunk result3 = f3.get();
// merges the results into one object.
Result result = new Result.merge(result1, result2, result3);
} finally {
pool.shutdown();
}
Although it will be acceptable on many cases, threads spend more resources.
Single-threaded event-driven I/O will be better as a client library. Codes will
be like following for that:
// sends queries to each servers.
FutureWithIO<ResultChunk> f1 = c1.DoIt(query1, data1); // Since the data
is rather large,
FutureWithIO<ResultChunk> f2 = c2.DoIt(query2, data2); // asynchronous
(parallel) sending
FutureWithIO<ResultChunk> f3 = c3.DoIt(query3, data3); // and receiving
are wished.
// introduces FutureWithIO class and IOMultiplexer class for event-driven
parallel I/O.
IOMultiplexer multiplexer = new IOMultiplexer();
multiplexer.add(f1);
multiplexer.add(f2);
multiplexer.add(f3);
// proceeds I/Os using Selector.
multiplexer.run();
// gathers results.
ResultChunk result1 = f1.get();
ResultChunk result2 = f2.get();
ResultChunk result3 = f3.get();
Thanks,
Sadayuki
On 2010/06/15, at 16:10, Doug Cutting wrote:
> Sadayuki,
>
> Couldn't a Transciever implementation return a Future immediately, so that
> the requests could be sent in parallel?
>
> Doug
>
> On 06/15/2010 03:39 PM, FURUHASHI Sadayuki wrote:
>> Doug,
>>
>> Thank you for your reply. I read codes and found that provided idea seems
>> good.
>> But I guess that I/Os on f2 and f3 don't proceed while proceeding I/O on f1.
>> As a result, it might not utilize maximum network bandwidth of the servers
>> thus latency will increase.
>> I mean, I/Os seem not to run in parallel. Here is the picture:
>>
>> provided idea will become like:
>> request 1 --send--> --receive--> // Sending and
>> receiving won't proceed in parallel.
>> request 2 --send--> --receive-->
>> request 3 --send--> --receive-->
>> server 1 ---doit-->
>> server 2 ---doit-->
>> server 3 ---doit-->
>>
>> ideal sequence is:
>> request 1 --send--> --receive--> // Because the
>> network bandwidth of client is
>> request 2 -----send-----> ----receive---> // limited,
>> paralleled sending and receiving take
>> request 3 -------send--------> ----receive----> // longer time
>> compared with non-paralleled one.
>> server 1 ---doit-->
>> server 2 ---doit--> | |
>> server 3 ---doit--> +-------------+
>> | | latency increases
>> +------------------------------------+
>> I/O in parallel
>>
>> This becomes problem only when data is large, and there are many active
>> clients than servers. I found that asynchronous calls of Thrift has similar
>> design.
>> I'll try to test how much performance changes in actuality using another
>> system.
>>
>> Thanks,
>> Sadayuki
>>
>> --
>> Sadayuki Furuhashi
>> [email protected]
>> http://msgpack.sourceforge.net/
>> http://kumofs.sourceforge.net/
>>
>> On 2010/06/15, at 11:51, Doug Cutting wrote:
>>
>>> Sadayuki,
>>>
>>> Avro does not currently support such an API, but it might not be difficult
>>> to add one and it would be very useful to have.
>>>
>>> The Transciever API might to be extended with a method like:
>>>
>>> Future<List<ByteBuffer>> transceiveFuture(List<ByteBuffer>);
>>>
>>> and the Requestor API might add a method like:
>>>
>>> Future<Object> requestFuture(...)
>>>
>>> If you are interested in pursuing this, please file an issue in Jira.
>>>
>>> Thanks,
>>>
>>> Doug
>>>
>>> On 06/13/2010 09:35 PM, FURUHASHI Sadayuki wrote:
>>>> Hi,
>>>>
>>>> I'm working on distributed systems and looking for flexible RPC system,
>>>> then I found Protocol Buffers, Thrift and Avro.
>>>> I'd like to compare and test these recently proposed systems.
>>>>
>>>> Our system requires clients to communicate with other multiple servers in
>>>> parallel.
>>>> Here is the picture:
>>>>
>>>> +----> Server 1 \
>>>> |
>>>> Client<----+----> Server 2 -- Servers proceed requirests in
>>>> parallel,
>>>> | then the Client gathers the results.
>>>> +----> Server 3 /
>>>>
>>>> The codes will be like following:
>>>>
>>>> Client c1 = new Client("server1:1010");
>>>> Client c2 = new Client("server2:1010");
>>>> Client c3 = new Client("server3:1010");
>>>>
>>>> // sends queries to each servers.
>>>> Future<ResultChunk> f1 = c1.DoIt(query1, data1); // Since the data
>>>> is rather large,
>>>> Future<ResultChunk> f2 = c2.DoIt(query2, data2); // asynchronous
>>>> (parallel) sending
>>>> Future<ResultChunk> f3 = c3.DoIt(query3, data3); // and receiving
>>>> are wished.
>>>>
>>>> // gatehrs results.
>>>> ResultChunk result1 = f1.get();
>>>> ResultChunk result2 = f2.get();
>>>> ResultChunk result3 = f3.get();
>>>>
>>>> // merges the results into one object.
>>>> Result result = new Result.merge(result1, result2, result3);
>>>>
>>>> My question is that Avro supports these feature? Or is there plan to
>>>> implement it?
>>>> I couldn't find them on the source code. Design of RPC is still in under
>>>> construction?
>>>>
>>>> Thanks for any pointers,
>>>> Sadayuki
>>>>
>>>> --
>>>> Sadayuki Furuhashi
>>>> [email protected]
>>