jovany-wang / dousi Goto Github PK
View Code? Open in Web Editor NEWNative Multiple Languages RPC Framework.
Native Multiple Languages RPC Framework.
We have 3 P2P nodes, and every node has its code:
class Node implements EventBased {
void f1() {
// change my state
}
void f2() {
// change my state as well
}
}
Since there is no approach to assert the static errors such as protobufs or other IDLs, we should support the dynamic asserting
:
If the method signification doesn't match the real argument list, the server will return a exception to indicate that, and then the client will throw it in getting
.
service:
class VoidReturnService : public dousi::AbstractService {
public:
void Perform(const std::string &str) {
data_ = str;
}
std::string Get() {
return data_;
}
private:
std::string data_ = "123";
};
server:
// VoidReturnService
auto void_return = dousi::executor::CreateService<VoidReturnService>();
void_return.RegisterMethod(dousi::Remote(&VoidReturnService::Perform));
void_return.RegisterMethod(dousi::Remote(&VoidReturnService::Get));
The server could not pass the compiling with these words complaint:
In many distributed systems, such as Spark Flink, Ray, and other like YARN based systems, a local tenancy often boardcast to other ends like notifications. It's valuable that we support the P2P IPC to make the things simpler.
// remote methods definitions
void Heartbeat(int termId) {
// handle.
}
void AppendLogs(int termId, int logId, buffer log_data) {
// handle
}
// processor1
dousi::Grid grid = dousi::Grid::GetOrCreate(master_addr="127.0.0.1:10001", grid_name="my_grid_1");
grid.SubProcessorsChanged([](ProcessorsChangedType type, ProcessorsInfo before, ProcessorsInfo after) {
// Handle the processors changed.
});
grid.Sub(/*method_to_be_subscribed=*/dousi::Remote(&Heartbeat));
grid.Sub(/*method_to_be_subscribed=*/dousi::Remote(&AppendLogs));
// processor2
dousi::Grid grid = dousi::Grid::GetOrCreate(master_addr="127.0.0.1:10001", grid_name="my_grid_1");
grid.SubProcessorsChanged([](ProcessorsChangedType type, ProcessorsInfo before, ProcessorsInfo after) {
// Handle the processors changed.
});
grid.Sub(/*method_to_be_subscribed=*/dousi::Remote(&Heartbeat));
grid.Sub(/*method_to_be_subscribed=*/dousi::Remote(&AppendLogs));
// processor3
dousi::Grid grid = dousi::Grid::GetOrCreate(master_addr="127.0.0.1:10001", grid_name="my_grid_1");
grid.SubProcessorsChanged([](ProcessorsChangedType type, ProcessorsInfo before, ProcessorsInfo after) {
// Handle the processors changed.
});
grid.Pub(/*method_to_be_subscribed=*/dousi::Remote(&Heartbeat), /*termId=*/100);
grid.Pub(/*method_to_be_subscribed=*/dousi::Remote(&AppendLogs, 100, 200, “this log”));
It should noted that the Grid
is used to be the identifier to the local tenancy for processors discovery and networking.
Each processor holds an executor and a submitter for methods invoking and submitting.
This issue traces the performance optimizing tasks.
WaitAndPopBatch
for StdLockedQueue
to avoid locking time.dousi::Remote
annotation around a method not only a method pointer: dousi::Remote(Echoer::echo)
Init()
accepts the listening port or the connecting target address. #16DousiFuture<bool>
for void return method on client side.https://github.com/jovany-wang/dousi/blob/master/core/tests/basic_call_test.cc#L38
This line is not correct now, because in the server side, we pass the service instance by closure-object so the value will not be changed any more once binding.
@Test
public void testMultiCalls() throws ParserAddrException, InterruptedException {
DousiRpcClient client = new NettyRpcClient("127.0.0.1:10001");
AdderService service = client.newStub(AdderService.class);
int result1 = service.add(3, 4);
int result2 = service.add(1, 2);
Assert.assertEquals(7, result1);
Assert.assertEquals(3, result1);
client.shutdown();
}
The above test will be failed since we do not cache the read buffer if there is not enough a package in channelread.
AsnycRead()
, AsyncWrite
. #6The purpose of Dousi
RPC framework is to build a highly performance, multiple languages server and easy to use RPC framework for the distributed domain especially for modern distributed end-to-end system, such as online recommender system, search engine system, etc.
[Highly Performance] For internal remote method invocations, the highly performance should prefer being the low latency and high throughput to high concurrency. This is the biggest difference between Dousi
motivation and the motivations of other RPC frameworks like brpc
. The reason for this point is internal remote invocations has no high concurrency requirement like the RPC server which should provide the services to a big number of public clients.
[Multiple Languages Server] For a big end-to-end system, it is almost built in several languages, And it's usual that upstream uses language A and the downstream uses language B. In the traditional solution, It almost uses one protocol to be communicated between the upstream and downstream but uses different RPC framework in different sides. Dousi
aims to provides multiple languages server and client to solve this issue, so that users shouldn't know the protocol details between different RPC frameworks in one large system.
[Easy to Use Abstraction] For this motivation, we would like to try our best to provide a very easy to use abstraction. We
should not only provide the abstraction in the same language of server and client, but also provide the easy to use abstraction in the different languages of server and client.
The bottom layer is the core layer which provides the basic abilities. The middle layer is runtime, and it provides the runtimes of Dousi
. And the top layer is unified remote invocations API.
For the motivations mentioned above, we are designing the Dousi RPC framework to achieve the following goals:
There are some key points from the picture:
template
and function traits
for the remote method signification, the work threads have more information for the remote method signification.https://github.com/yedf/handy is a great library to help us build the highly performance RPC framework.
Add an abstraction to support the eventloop as an abstracted layer, so that we can switch them.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.