mirror of https://github.com/grpc/grpc.git
commit
9869cd3c7a
394 changed files with 26276 additions and 24195 deletions
@ -0,0 +1,53 @@ |
|||||||
|
# How to contribute |
||||||
|
|
||||||
|
We definitely welcome patches and contribution to grpc! Here is some guideline |
||||||
|
and information about how to do so. |
||||||
|
|
||||||
|
## Getting started |
||||||
|
|
||||||
|
### Legal requirements |
||||||
|
|
||||||
|
In order to protect both you and ourselves, you will need to sign the |
||||||
|
[Contributor License Agreement](https://cla.developers.google.com/clas). |
||||||
|
|
||||||
|
### Technical requirements |
||||||
|
|
||||||
|
You will need several tools to work with this repository. In addition to all of |
||||||
|
the packages described in the [INSTALL](INSTALL) file, you will also need |
||||||
|
python, and the mako template renderer. To install the latter, using pip, one |
||||||
|
should simply be able to do `pip install mako`. |
||||||
|
|
||||||
|
In order to run all of the tests we provide, you will need valgrind and clang. |
||||||
|
More specifically, under debian, you will need the package libc++-dev to |
||||||
|
properly run all the tests. |
||||||
|
|
||||||
|
If you are planning to work on any of the languages other than C and C++, you |
||||||
|
will also need their appropriate development environments. |
||||||
|
|
||||||
|
If you want to work under Windows, we recommend you to use Visual Studio 2013. |
||||||
|
The [Community or Express editions](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx) |
||||||
|
are free and suitable for developing with grpc. Note however that our test |
||||||
|
environment and tools are available for Unix environments only at the moment. |
||||||
|
|
||||||
|
## Testing your changes |
||||||
|
|
||||||
|
We provide a tool to help you run our suite of tests in various environments. |
||||||
|
In order to run most of the available tests, one would need to run: |
||||||
|
|
||||||
|
`./tools/run_tests/run_tests.py` |
||||||
|
|
||||||
|
If you want to run all the possible tests for all possible languages, do this: |
||||||
|
|
||||||
|
`./tools/run_tests/run_tests.py -lall -call` |
||||||
|
|
||||||
|
## Adding or removing source code |
||||||
|
|
||||||
|
Each language uses its own build system to work. Currently, the root's Makefile |
||||||
|
and the Visual Studio project files are building the C and C++ source code only |
||||||
|
at the moment. In order to ease the maintenance of these files, we have a |
||||||
|
template system. Please do not contribute manual changes to any of the generated |
||||||
|
files. Instead, modify the template files, or the build.json file, and |
||||||
|
re-generate the project files using the following command: |
||||||
|
|
||||||
|
`./tools/buildgen/generate_projects.sh` |
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,330 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <cassert> |
||||||
|
#include <cctype> |
||||||
|
#include <map> |
||||||
|
#include <ostream> |
||||||
|
#include <sstream> |
||||||
|
|
||||||
|
#include "src/compiler/python_generator.h" |
||||||
|
#include <google/protobuf/io/printer.h> |
||||||
|
#include <google/protobuf/io/zero_copy_stream_impl_lite.h> |
||||||
|
#include <google/protobuf/descriptor.pb.h> |
||||||
|
#include <google/protobuf/descriptor.h> |
||||||
|
|
||||||
|
using google::protobuf::FileDescriptor; |
||||||
|
using google::protobuf::ServiceDescriptor; |
||||||
|
using google::protobuf::MethodDescriptor; |
||||||
|
using google::protobuf::io::Printer; |
||||||
|
using google::protobuf::io::StringOutputStream; |
||||||
|
using std::initializer_list; |
||||||
|
using std::map; |
||||||
|
using std::string; |
||||||
|
|
||||||
|
namespace grpc_python_generator { |
||||||
|
namespace { |
||||||
|
//////////////////////////////////
|
||||||
|
// BEGIN FORMATTING BOILERPLATE //
|
||||||
|
//////////////////////////////////
|
||||||
|
|
||||||
|
// Converts an initializer list of the form { key0, value0, key1, value1, ... }
|
||||||
|
// into a map of key* to value*. Is merely a readability helper for later code.
|
||||||
|
map<string, string> ListToDict(const initializer_list<string>& values) { |
||||||
|
assert(values.size() % 2 == 0); |
||||||
|
map<string, string> value_map; |
||||||
|
auto value_iter = values.begin(); |
||||||
|
for (unsigned i = 0; i < values.size()/2; ++i) { |
||||||
|
string key = *value_iter; |
||||||
|
++value_iter; |
||||||
|
string value = *value_iter; |
||||||
|
value_map[key] = value; |
||||||
|
++value_iter; |
||||||
|
} |
||||||
|
return value_map; |
||||||
|
} |
||||||
|
|
||||||
|
// Provides RAII indentation handling. Use as:
|
||||||
|
// {
|
||||||
|
// IndentScope raii_my_indent_var_name_here(my_py_printer);
|
||||||
|
// // constructor indented my_py_printer
|
||||||
|
// ...
|
||||||
|
// // destructor called at end of scope, un-indenting my_py_printer
|
||||||
|
// }
|
||||||
|
class IndentScope { |
||||||
|
public: |
||||||
|
explicit IndentScope(Printer* printer) : printer_(printer) { |
||||||
|
printer_->Indent(); |
||||||
|
} |
||||||
|
|
||||||
|
~IndentScope() { |
||||||
|
printer_->Outdent(); |
||||||
|
} |
||||||
|
|
||||||
|
private: |
||||||
|
Printer* printer_; |
||||||
|
}; |
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
// END FORMATTING BOILERPLATE //
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
void PrintService(const ServiceDescriptor* service, |
||||||
|
Printer* out) { |
||||||
|
string doc = "<fill me in later!>"; |
||||||
|
map<string, string> dict = ListToDict({ |
||||||
|
"Service", service->name(), |
||||||
|
"Documentation", doc, |
||||||
|
}); |
||||||
|
out->Print(dict, "class $Service$Service(object):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_class_indent(out); |
||||||
|
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); |
||||||
|
out->Print("def __init__(self):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_method_indent(out); |
||||||
|
out->Print("pass\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void PrintServicer(const ServiceDescriptor* service, |
||||||
|
Printer* out) { |
||||||
|
string doc = "<fill me in later!>"; |
||||||
|
map<string, string> dict = ListToDict({ |
||||||
|
"Service", service->name(), |
||||||
|
"Documentation", doc, |
||||||
|
}); |
||||||
|
out->Print(dict, "class $Service$Servicer(object):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_class_indent(out); |
||||||
|
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); |
||||||
|
for (int i = 0; i < service->method_count(); ++i) { |
||||||
|
auto meth = service->method(i); |
||||||
|
out->Print("def $Method$(self, arg):\n", "Method", meth->name()); |
||||||
|
{ |
||||||
|
IndentScope raii_method_indent(out); |
||||||
|
out->Print("raise NotImplementedError()\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void PrintStub(const ServiceDescriptor* service, |
||||||
|
Printer* out) { |
||||||
|
string doc = "<fill me in later!>"; |
||||||
|
map<string, string> dict = ListToDict({ |
||||||
|
"Service", service->name(), |
||||||
|
"Documentation", doc, |
||||||
|
}); |
||||||
|
out->Print(dict, "class $Service$Stub(object):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_class_indent(out); |
||||||
|
out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); |
||||||
|
for (int i = 0; i < service->method_count(); ++i) { |
||||||
|
const MethodDescriptor* meth = service->method(i); |
||||||
|
auto methdict = ListToDict({"Method", meth->name()}); |
||||||
|
out->Print(methdict, "def $Method$(self, arg):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_method_indent(out); |
||||||
|
out->Print("raise NotImplementedError()\n"); |
||||||
|
} |
||||||
|
out->Print(methdict, "$Method$.async = None\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void PrintStubImpl(const ServiceDescriptor* service, |
||||||
|
Printer* out) { |
||||||
|
map<string, string> dict = ListToDict({ |
||||||
|
"Service", service->name(), |
||||||
|
}); |
||||||
|
out->Print(dict, "class _$Service$Stub($Service$Stub):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_class_indent(out); |
||||||
|
out->Print("def __init__(self, face_stub, default_timeout):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_method_indent(out); |
||||||
|
out->Print("self._face_stub = face_stub\n" |
||||||
|
"self._default_timeout = default_timeout\n" |
||||||
|
"stub_self = self\n"); |
||||||
|
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) { |
||||||
|
const MethodDescriptor* meth = service->method(i); |
||||||
|
bool server_streaming = meth->server_streaming(); |
||||||
|
bool client_streaming = meth->client_streaming(); |
||||||
|
std::string blocking_call, future_call; |
||||||
|
if (server_streaming) { |
||||||
|
if (client_streaming) { |
||||||
|
blocking_call = "stub_self._face_stub.inline_stream_in_stream_out"; |
||||||
|
future_call = blocking_call; |
||||||
|
} else { |
||||||
|
blocking_call = "stub_self._face_stub.inline_value_in_stream_out"; |
||||||
|
future_call = blocking_call; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (client_streaming) { |
||||||
|
blocking_call = "stub_self._face_stub.blocking_stream_in_value_out"; |
||||||
|
future_call = "stub_self._face_stub.future_stream_in_value_out"; |
||||||
|
} else { |
||||||
|
blocking_call = "stub_self._face_stub.blocking_value_in_value_out"; |
||||||
|
future_call = "stub_self._face_stub.future_value_in_value_out"; |
||||||
|
} |
||||||
|
} |
||||||
|
// TODO(atash): use the solution described at
|
||||||
|
// http://stackoverflow.com/a/2982 to bind 'async' attribute
|
||||||
|
// functions to def'd functions instead of using callable attributes.
|
||||||
|
auto methdict = ListToDict({ |
||||||
|
"Method", meth->name(), |
||||||
|
"BlockingCall", blocking_call, |
||||||
|
"FutureCall", future_call |
||||||
|
}); |
||||||
|
out->Print(methdict, "class $Method$(object):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_callable_indent(out); |
||||||
|
out->Print("def __call__(self, arg):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_callable_call_indent(out); |
||||||
|
out->Print(methdict, |
||||||
|
"return $BlockingCall$(\"$Method$\", arg, " |
||||||
|
"stub_self._default_timeout)\n"); |
||||||
|
} |
||||||
|
out->Print("def async(self, arg):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_callable_async_indent(out); |
||||||
|
out->Print(methdict, |
||||||
|
"return $FutureCall$(\"$Method$\", arg, " |
||||||
|
"stub_self._default_timeout)\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
out->Print(methdict, "self.$Method$ = $Method$()\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void PrintStubGenerators(const ServiceDescriptor* service, Printer* out) { |
||||||
|
map<string, string> dict = ListToDict({ |
||||||
|
"Service", service->name(), |
||||||
|
}); |
||||||
|
// Write out a generator of linked pairs of Server/Stub
|
||||||
|
out->Print(dict, "def mock_$Service$(servicer, default_timeout):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_mock_indent(out); |
||||||
|
out->Print("value_in_value_out = {}\n" |
||||||
|
"value_in_stream_out = {}\n" |
||||||
|
"stream_in_value_out = {}\n" |
||||||
|
"stream_in_stream_out = {}\n"); |
||||||
|
for (int i = 0; i < service->method_count(); ++i) { |
||||||
|
const MethodDescriptor* meth = service->method(i); |
||||||
|
std::string super_interface, meth_dict; |
||||||
|
bool server_streaming = meth->server_streaming(); |
||||||
|
bool client_streaming = meth->client_streaming(); |
||||||
|
if (server_streaming) { |
||||||
|
if (client_streaming) { |
||||||
|
super_interface = "InlineStreamInStreamOutMethod"; |
||||||
|
meth_dict = "stream_in_stream_out"; |
||||||
|
} else { |
||||||
|
super_interface = "InlineValueInStreamOutMethod"; |
||||||
|
meth_dict = "value_in_stream_out"; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (client_streaming) { |
||||||
|
super_interface = "InlineStreamInValueOutMethod"; |
||||||
|
meth_dict = "stream_in_value_out"; |
||||||
|
} else { |
||||||
|
super_interface = "InlineValueInValueOutMethod"; |
||||||
|
meth_dict = "value_in_value_out"; |
||||||
|
} |
||||||
|
} |
||||||
|
map<string, string> methdict = ListToDict({ |
||||||
|
"Method", meth->name(), |
||||||
|
"SuperInterface", super_interface, |
||||||
|
"MethodDict", meth_dict |
||||||
|
}); |
||||||
|
out->Print( |
||||||
|
methdict, "class $Method$(_face_interfaces.$SuperInterface$):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_inline_class_indent(out); |
||||||
|
out->Print("def service(self, request, context):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_inline_class_fn_indent(out); |
||||||
|
out->Print(methdict, "return servicer.$Method$(request)\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
out->Print(methdict, "$MethodDict$['$Method$'] = $Method$()\n"); |
||||||
|
} |
||||||
|
out->Print( |
||||||
|
"face_linked_pair = _face_testing.server_and_stub(default_timeout," |
||||||
|
"inline_value_in_value_out_methods=value_in_value_out," |
||||||
|
"inline_value_in_stream_out_methods=value_in_stream_out," |
||||||
|
"inline_stream_in_value_out_methods=stream_in_value_out," |
||||||
|
"inline_stream_in_stream_out_methods=stream_in_stream_out)\n"); |
||||||
|
out->Print("class LinkedPair(object):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_linked_pair(out); |
||||||
|
out->Print("def __init__(self, server, stub):\n"); |
||||||
|
{ |
||||||
|
IndentScope raii_linked_pair_init(out); |
||||||
|
out->Print("self.server = server\n" |
||||||
|
"self.stub = stub\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
out->Print( |
||||||
|
dict, |
||||||
|
"stub = _$Service$Stub(face_linked_pair.stub, default_timeout)\n"); |
||||||
|
out->Print("return LinkedPair(None, stub)\n"); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
string GetServices(const FileDescriptor* file) { |
||||||
|
string output; |
||||||
|
StringOutputStream output_stream(&output); |
||||||
|
Printer out(&output_stream, '$'); |
||||||
|
out.Print("from grpc.framework.face import demonstration as _face_testing\n"); |
||||||
|
out.Print("from grpc.framework.face import interfaces as _face_interfaces\n"); |
||||||
|
|
||||||
|
for (int i = 0; i < file->service_count(); ++i) { |
||||||
|
auto service = file->service(i); |
||||||
|
PrintService(service, &out); |
||||||
|
PrintServicer(service, &out); |
||||||
|
PrintStub(service, &out); |
||||||
|
PrintStubImpl(service, &out); |
||||||
|
PrintStubGenerators(service, &out); |
||||||
|
} |
||||||
|
return output; |
||||||
|
} |
||||||
|
|
||||||
|
} // namespace grpc_python_generator
|
@ -0,0 +1,51 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef __GRPC_COMPILER_PYTHON_GENERATOR_H__ |
||||||
|
#define __GRPC_COMPILER_PYTHON_GENERATOR_H__ |
||||||
|
|
||||||
|
#include <string> |
||||||
|
|
||||||
|
namespace google { |
||||||
|
namespace protobuf { |
||||||
|
class FileDescriptor; |
||||||
|
} // namespace protobuf
|
||||||
|
} // namespace google
|
||||||
|
|
||||||
|
namespace grpc_python_generator { |
||||||
|
|
||||||
|
std::string GetServices(const google::protobuf::FileDescriptor* file); |
||||||
|
|
||||||
|
} // namespace grpc_python_generator
|
||||||
|
|
||||||
|
#endif // __GRPC_COMPILER_PYTHON_GENERATOR_H__
|
@ -0,0 +1,87 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
// Generates a Python gRPC service interface out of Protobuf IDL.
|
||||||
|
|
||||||
|
#include <memory> |
||||||
|
#include <string> |
||||||
|
|
||||||
|
#include "src/compiler/python_generator.h" |
||||||
|
#include <google/protobuf/compiler/code_generator.h> |
||||||
|
#include <google/protobuf/compiler/plugin.h> |
||||||
|
#include <google/protobuf/io/coded_stream.h> |
||||||
|
#include <google/protobuf/io/zero_copy_stream.h> |
||||||
|
#include <google/protobuf/descriptor.h> |
||||||
|
|
||||||
|
using google::protobuf::FileDescriptor; |
||||||
|
using google::protobuf::compiler::CodeGenerator; |
||||||
|
using google::protobuf::compiler::GeneratorContext; |
||||||
|
using google::protobuf::compiler::PluginMain; |
||||||
|
using google::protobuf::io::CodedOutputStream; |
||||||
|
using google::protobuf::io::ZeroCopyOutputStream; |
||||||
|
using std::string; |
||||||
|
|
||||||
|
class PythonGrpcGenerator : public CodeGenerator { |
||||||
|
public: |
||||||
|
PythonGrpcGenerator() {} |
||||||
|
~PythonGrpcGenerator() override {} |
||||||
|
|
||||||
|
bool Generate(const FileDescriptor* file, |
||||||
|
const string& parameter, |
||||||
|
GeneratorContext* context, |
||||||
|
string* error) const override { |
||||||
|
// Get output file name.
|
||||||
|
string file_name; |
||||||
|
static const int proto_suffix_length = 6; // length of ".proto"
|
||||||
|
if (file->name().size() > static_cast<size_t>(proto_suffix_length) && |
||||||
|
file->name().find_last_of(".proto") == file->name().size() - 1) { |
||||||
|
file_name = file->name().substr( |
||||||
|
0, file->name().size() - proto_suffix_length) + "_pb2.py"; |
||||||
|
} else { |
||||||
|
*error = "Invalid proto file name. Proto file must end with .proto"; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
std::unique_ptr<ZeroCopyOutputStream> output( |
||||||
|
context->OpenForInsert(file_name, "module_scope")); |
||||||
|
CodedOutputStream coded_out(output.get()); |
||||||
|
string code = grpc_python_generator::GetServices(file); |
||||||
|
coded_out.WriteRaw(code.data(), code.size()); |
||||||
|
return true; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
int main(int argc, char* argv[]) { |
||||||
|
PythonGrpcGenerator generator; |
||||||
|
return PluginMain(argc, argv, &generator); |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
#Overview |
||||||
|
|
||||||
|
This directory contains source code for shared C library. Libraries in other languages in this repository (C++, Ruby, |
||||||
|
Python, PHP, NodeJS, Objective-C) are layered on top of this library. |
||||||
|
|
||||||
|
#Status |
||||||
|
|
||||||
|
Alpha : Ready for early adopters |
||||||
|
|
@ -0,0 +1,110 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "src/core/debug/trace.h" |
||||||
|
|
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include "src/core/support/env.h" |
||||||
|
|
||||||
|
#if GRPC_ENABLE_TRACING |
||||||
|
gpr_uint32 grpc_trace_bits = 0; |
||||||
|
|
||||||
|
static void add(const char *beg, const char *end, char ***ss, size_t *ns) { |
||||||
|
size_t n = *ns; |
||||||
|
size_t np = n + 1; |
||||||
|
char *s = gpr_malloc(end - beg + 1); |
||||||
|
memcpy(s, beg, end - beg); |
||||||
|
s[end-beg] = 0; |
||||||
|
*ss = gpr_realloc(*ss, sizeof(char**) * np); |
||||||
|
(*ss)[n] = s; |
||||||
|
*ns = np; |
||||||
|
} |
||||||
|
|
||||||
|
static void split(const char *s, char ***ss, size_t *ns) { |
||||||
|
const char *c = strchr(s, ','); |
||||||
|
if (c == NULL) { |
||||||
|
add(s, s + strlen(s), ss, ns); |
||||||
|
} else { |
||||||
|
add(s, c, ss, ns); |
||||||
|
split(c+1, ss, ns); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void parse(const char *s) { |
||||||
|
char **strings = NULL; |
||||||
|
size_t nstrings = 0; |
||||||
|
size_t i; |
||||||
|
split(s, &strings, &nstrings); |
||||||
|
|
||||||
|
grpc_trace_bits = 0; |
||||||
|
|
||||||
|
for (i = 0; i < nstrings; i++) { |
||||||
|
const char *s = strings[i]; |
||||||
|
if (0 == strcmp(s, "surface")) { |
||||||
|
grpc_trace_bits |= GRPC_TRACE_SURFACE; |
||||||
|
} else if (0 == strcmp(s, "channel")) { |
||||||
|
grpc_trace_bits |= GRPC_TRACE_CHANNEL; |
||||||
|
} else if (0 == strcmp(s, "tcp")) { |
||||||
|
grpc_trace_bits |= GRPC_TRACE_TCP; |
||||||
|
} else if (0 == strcmp(s, "secure_endpoint")) { |
||||||
|
grpc_trace_bits |= GRPC_TRACE_SECURE_ENDPOINT; |
||||||
|
} else if (0 == strcmp(s, "all")) { |
||||||
|
grpc_trace_bits = -1; |
||||||
|
} else { |
||||||
|
gpr_log(GPR_ERROR, "Unknown trace var: '%s'", s); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (i = 0; i < nstrings; i++) { |
||||||
|
gpr_free(strings[i]); |
||||||
|
} |
||||||
|
gpr_free(strings); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_init_trace_bits() { |
||||||
|
char *e = gpr_getenv("GRPC_TRACE"); |
||||||
|
if (e == NULL) { |
||||||
|
grpc_trace_bits = 0; |
||||||
|
} else { |
||||||
|
parse(e); |
||||||
|
gpr_free(e); |
||||||
|
} |
||||||
|
} |
||||||
|
#else |
||||||
|
void grpc_init_trace_bits() { |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
@ -0,0 +1,60 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef GRPC_CORE_DEBUG_TRACE_H |
||||||
|
#define GRPC_CORE_DEBUG_TRACE_H |
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
|
||||||
|
/* set to zero to remove all debug trace code */ |
||||||
|
#ifndef GRPC_ENABLE_TRACING |
||||||
|
# define GRPC_ENABLE_TRACING 1 |
||||||
|
#endif |
||||||
|
|
||||||
|
typedef enum { |
||||||
|
GRPC_TRACE_SURFACE = 1 << 0, |
||||||
|
GRPC_TRACE_CHANNEL = 1 << 1, |
||||||
|
GRPC_TRACE_TCP = 1 << 2, |
||||||
|
GRPC_TRACE_SECURE_ENDPOINT = 1 << 3 |
||||||
|
} grpc_trace_bit_value; |
||||||
|
|
||||||
|
#if GRPC_ENABLE_TRACING |
||||||
|
extern gpr_uint32 grpc_trace_bits; |
||||||
|
#else |
||||||
|
# define grpc_trace_bits 0 |
||||||
|
#endif |
||||||
|
|
||||||
|
void grpc_init_trace_bits(); |
||||||
|
|
||||||
|
#endif |
||||||
|
|
@ -0,0 +1,166 @@ |
|||||||
|
/*
|
||||||
|
* |
||||||
|
* Copyright 2015, Google Inc. |
||||||
|
* All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are |
||||||
|
* met: |
||||||
|
* |
||||||
|
* * Redistributions of source code must retain the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer. |
||||||
|
* * Redistributions in binary form must reproduce the above |
||||||
|
* copyright notice, this list of conditions and the following disclaimer |
||||||
|
* in the documentation and/or other materials provided with the |
||||||
|
* distribution. |
||||||
|
* * Neither the name of Google Inc. nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* |
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||||
|
* |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h> |
||||||
|
#ifdef GPR_WINSOCK_SOCKET |
||||||
|
|
||||||
|
#include "src/core/iomgr/sockaddr.h" |
||||||
|
#include "src/core/iomgr/resolve_address.h" |
||||||
|
|
||||||
|
#include <sys/types.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include "src/core/iomgr/iomgr_internal.h" |
||||||
|
#include "src/core/iomgr/sockaddr_utils.h" |
||||||
|
#include "src/core/support/string.h" |
||||||
|
#include <grpc/support/alloc.h> |
||||||
|
#include <grpc/support/host_port.h> |
||||||
|
#include <grpc/support/log.h> |
||||||
|
#include <grpc/support/thd.h> |
||||||
|
#include <grpc/support/time.h> |
||||||
|
|
||||||
|
typedef struct { |
||||||
|
char *name; |
||||||
|
char *default_port; |
||||||
|
grpc_resolve_cb cb; |
||||||
|
void *arg; |
||||||
|
} request; |
||||||
|
|
||||||
|
grpc_resolved_addresses *grpc_blocking_resolve_address( |
||||||
|
const char *name, const char *default_port) { |
||||||
|
struct addrinfo hints; |
||||||
|
struct addrinfo *result = NULL, *resp; |
||||||
|
char *host; |
||||||
|
char *port; |
||||||
|
int s; |
||||||
|
size_t i; |
||||||
|
grpc_resolved_addresses *addrs = NULL; |
||||||
|
const gpr_timespec start_time = gpr_now(); |
||||||
|
|
||||||
|
/* parse name, splitting it into host and port parts */ |
||||||
|
gpr_split_host_port(name, &host, &port); |
||||||
|
if (host == NULL) { |
||||||
|
gpr_log(GPR_ERROR, "unparseable host:port: '%s'", name); |
||||||
|
goto done; |
||||||
|
} |
||||||
|
if (port == NULL) { |
||||||
|
if (default_port == NULL) { |
||||||
|
gpr_log(GPR_ERROR, "no port in name '%s'", name); |
||||||
|
goto done; |
||||||
|
} |
||||||
|
port = gpr_strdup(default_port); |
||||||
|
} |
||||||
|
|
||||||
|
/* Call getaddrinfo */ |
||||||
|
memset(&hints, 0, sizeof(hints)); |
||||||
|
hints.ai_family = AF_UNSPEC; /* ipv4 or ipv6 */ |
||||||
|
hints.ai_socktype = SOCK_STREAM; /* stream socket */ |
||||||
|
hints.ai_flags = AI_PASSIVE; /* for wildcard IP address */ |
||||||
|
|
||||||
|
s = getaddrinfo(host, port, &hints, &result); |
||||||
|
if (s != 0) { |
||||||
|
gpr_log(GPR_ERROR, "getaddrinfo: %s", gai_strerror(s)); |
||||||
|
goto done; |
||||||
|
} |
||||||
|
|
||||||
|
/* Success path: set addrs non-NULL, fill it in */ |
||||||
|
addrs = gpr_malloc(sizeof(grpc_resolved_addresses)); |
||||||
|
addrs->naddrs = 0; |
||||||
|
for (resp = result; resp != NULL; resp = resp->ai_next) { |
||||||
|
addrs->naddrs++; |
||||||
|
} |
||||||
|
addrs->addrs = gpr_malloc(sizeof(grpc_resolved_address) * addrs->naddrs); |
||||||
|
i = 0; |
||||||
|
for (resp = result; resp != NULL; resp = resp->ai_next) { |
||||||
|
memcpy(&addrs->addrs[i].addr, resp->ai_addr, resp->ai_addrlen); |
||||||
|
addrs->addrs[i].len = resp->ai_addrlen; |
||||||
|
i++; |
||||||
|
} |
||||||
|
|
||||||
|
/* Temporary logging, to help identify flakiness in dualstack_socket_test. */ |
||||||
|
{ |
||||||
|
const gpr_timespec delay = gpr_time_sub(gpr_now(), start_time); |
||||||
|
const int delay_ms = |
||||||
|
delay.tv_sec * GPR_MS_PER_SEC + delay.tv_nsec / GPR_NS_PER_MS; |
||||||
|
gpr_log(GPR_INFO, "logspam: getaddrinfo(%s, %s) resolved %d addrs in %dms:", |
||||||
|
host, port, addrs->naddrs, delay_ms); |
||||||
|
for (i = 0; i < addrs->naddrs; i++) { |
||||||
|
char *buf; |
||||||
|
grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr, |
||||||
|
0); |
||||||
|
gpr_log(GPR_INFO, "logspam: [%d] %s", i, buf); |
||||||
|
gpr_free(buf); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
done: |
||||||
|
gpr_free(host); |
||||||
|
gpr_free(port); |
||||||
|
if (result) { |
||||||
|
freeaddrinfo(result); |
||||||
|
} |
||||||
|
return addrs; |
||||||
|
} |
||||||
|
|
||||||
|
/* Thread function to asynch-ify grpc_blocking_resolve_address */ |
||||||
|
static void do_request(void *rp) { |
||||||
|
request *r = rp; |
||||||
|
grpc_resolved_addresses *resolved = |
||||||
|
grpc_blocking_resolve_address(r->name, r->default_port); |
||||||
|
void *arg = r->arg; |
||||||
|
grpc_resolve_cb cb = r->cb; |
||||||
|
gpr_free(r->name); |
||||||
|
gpr_free(r->default_port); |
||||||
|
gpr_free(r); |
||||||
|
cb(arg, resolved); |
||||||
|
grpc_iomgr_unref(); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_resolved_addresses_destroy(grpc_resolved_addresses *addrs) { |
||||||
|
gpr_free(addrs->addrs); |
||||||
|
gpr_free(addrs); |
||||||
|
} |
||||||
|
|
||||||
|
void grpc_resolve_address(const char *name, const char *default_port, |
||||||
|
grpc_resolve_cb cb, void *arg) { |
||||||
|
request *r = gpr_malloc(sizeof(request)); |
||||||
|
gpr_thd_id id; |
||||||
|
grpc_iomgr_ref(); |
||||||
|
r->name = gpr_strdup(name); |
||||||
|
r->default_port = gpr_strdup(default_port); |
||||||
|
r->cb = cb; |
||||||
|
r->arg = arg; |
||||||
|
gpr_thd_new(&id, do_request, r, NULL); |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,9 @@ |
|||||||
|
|
||||||
|
#Overview |
||||||
|
|
||||||
|
This directory contains source code for C++ implementation of gRPC. |
||||||
|
|
||||||
|
#Status |
||||||
|
|
||||||
|
Alpha : Ready for early adopters |
||||||
|
|
@ -0,0 +1 @@ |
|||||||
|
gRPC C# is work-in-progress and is not intended to be used. See README. |
@ -0,0 +1,23 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<package > |
||||||
|
<metadata> |
||||||
|
<id>Grpc.Core</id> |
||||||
|
<title>gRPC Core</title> |
||||||
|
<summary>Core C# implementation of gRPC - an RPC library and framework</summary> |
||||||
|
<description>Core C# implementation of gRPC - an RPC library and framework. See project site for more info. |
||||||
|
This is an experimental release, not ready to use. |
||||||
|
</description> |
||||||
|
<version>0.1.0</version> |
||||||
|
<authors>Google Inc.</authors> |
||||||
|
<owners>jtattermusch</owners> |
||||||
|
<licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl> |
||||||
|
<projectUrl>https://github.com/grpc/grpc</projectUrl> |
||||||
|
<requireLicenseAcceptance>false</requireLicenseAcceptance> |
||||||
|
<releaseNotes>The first experimental release. Not ready to use.</releaseNotes> |
||||||
|
<copyright>Copyright 2015, Google Inc.</copyright> |
||||||
|
<tags>gRPC RPC Protocol HTTP/2</tags> |
||||||
|
</metadata> |
||||||
|
<files> |
||||||
|
<file src="bin/Release/Grpc.Core.dll" target="lib/net45" /> |
||||||
|
</files> |
||||||
|
</package> |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue