Giter Site home page Giter Site logo

linecode / easy_grpc Goto Github PK

View Code? Open in Web Editor NEW

This project forked from francoischabot/easy_grpc

0.0 1.0 0.0 1.04 MB

An easier way to write asynchronous c++ grpc clients/servers.

License: Apache License 2.0

CMake 0.84% Dockerfile 0.04% C++ 99.06% C 0.05%

easy_grpc's Introduction

CircleCI Join the chat at https://gitter.im/easy_grpc/community

easy_grpc

A future-based gRPC API for C++.

This project is an attempt to create a wrapper around gRPC to make writing asynchronous servers and clients as straightforward as possible. It may not be quite as optimal as a fully-customized server working on raw completion queues, but every effort is being made to get as close as possible while maintaining as sane and modern an API as possible.

Who is this for?

If you want to make gRPC services in C++ that contain methods that have to wait on external conditions before completing, then this is for you.

The Goal

With easy_grpc, writing asynchronous rpc servers is simple. This is especially true for servers that need to send rpcs to other services during the handling of a rpc.

class MyService_impl {
public:
  MyService_impl(pkg::MyService2::Stub_interface* stub2, 
                 pkg::MyService3::Stub_interface* stub3) 
      : stub2_(stub2)
      , stub3_(stub3) {}

  rpc::Future<pkg::Reply> MyMethod(pkg::Request req) {
    pkg::MyRequest2 stub2_request;
    pkg::MyRequest3 stub3_request;

    // These requests are sent in parallel.
    auto rep_2f = stub_2->Method2(stub2_request);
    auto rep_3f = stub_3->Method3(stub3_request);

    // Wait for the completion of both requests:
    return join(rep_2f, rep_3f).then(
      [](auto rep_2, auto rep_3) {
        pkg::Reply reply;
        return reply;
      });
    )
  }

private:
  pkg::MyService2::Stub_interface* stub2_;
  pkg::MyService3::Stub_interface* stub3_;
};

Key points:

  • The handling thread is freed while the child rpcs are in progess
  • If either of the child rpcs fail, the failure is propagated to the parent RPC.
  • The lambda will be executed directly in the receiving thread of the last response that comes in (this can be changed easily).

Requirements

All you need is a compliant C++17 compiler, and grpc itself. It should be possible to back-port this library to C++14 if there is enough demand for it.

Futures

A lot of heavy lifting is done through a dedicated Futures library. It's powerful, fast and straightforward to use. Please refer to that project for the API details of these objects.

The Dockerfile contained in this project contains an image that should have everything you need.

Current State

  • protoc plugin
  • Client Unary-Unary calls
  • Server Unary-Unary handling
  • Client Unary-stream calls
  • Client Stream-Unary calls
  • Client Stream-Stream calls
  • Server Unary-stream handling
  • Server Stream-Unary handling
  • Server Stream-Stream handling
  • Reflection
  • credentials

Next steps:

  • Big cleanup and documentation pass.
  • Tests, lots of tests.
  • Secure credentials

Examples:

Initializing the library and calling a method on a server.

#include "easy_grpc/easy_grpc.h"
#include "generated/data.egrpc.pb.h"

namespace rpc = easy_grpc;
namespace client = rpc::client;

int main() {
  // Library initialization.
  rpc::Environment grpc_env;

  // Completion queue + single handling thread
  rpc::Completion_queue cq;
  
  // Connection to server, with a default completion queue.
  client::Unsecure_channel channel("localhost:12345", &cq);

  // Connection to service.
  pkg::MyService::Stub stub(&channel);

  // Call method.
  auto done = stub.MyMethod({})
    .then([](auto rep) {
      std::cout << "MyMethod returned: " << rep.DebugString() << "\n";
    });


  // Wait until the result is done
  done.get();
  
  return 0;
}

Synchronously calling a method on the server:

int main() {
  // ...
  
  // This converts the rpc::Future<Reply> to a std::future<Reply>, and calls get() on it.
  auto rep = stub.MyMethod({}).get();
  
  return 0;

Chaining calls:

int main() {
  // ...
  
  auto reply_3 = stub.MyMethod({})
    .then([&](auto rep) {
      return stub.MyMethod2({});
    })
    .then([&](auto rep2) {
      return stub.MyMethod3({});
    });
  
  return 0;

Waiting on multiple calls:

int main() {
  //...

  auto reply_1 = stub.MyMethod({});
  auto reply_2 = stub.MyMethod2({});

  join(reply_1, reply_2).then_finally([](auto rep_1, auto rep_2) {
    std::cerr << "1 and 2 are both done!\n";
  });


  return 0;

Server sending rpcs during handling:

class MyService_impl : public pkg::MyService {
public:
  MyService_impl(pkg::MyService2::Stub_interface* stub) : stub_(stub) {}

  rpc::Future<pkg::Reply> MyMethod(pkg::Request) {
    pkg::MyRequest2 stub_request;

    return stub_->MyMethod2(stub_request)
      .then([](auto sub_reply) {
        pkg::Reply result;
        return result;
      });
  }

private:
  pkg::MyService2::Stub_interface* stub_;
};

Design philosophy

  • Simple yet flexible: The library imposes as few restrictions as possible.
  • Asynchronous by default: In fact, the library only exposes asynchronous interfaces.

easy_grpc's People

Contributors

francoischabot avatar gitter-badger avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.