aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Craig Tiller <craig.tiller@gmail.com>2015-05-28 07:36:07 -0700
committerGravatar Craig Tiller <craig.tiller@gmail.com>2015-05-28 07:36:07 -0700
commitd1369aa134e8eaab1bde6a5ea36a8ba655c79a57 (patch)
treec1cdc85da9e4a01371edee5dcb99a6069f0c5be8 /src
parentfe46136721acc3298a2949a7321d043180daed92 (diff)
parenta3c9fb08136d6a3875b8e400ef4b4137357d6b4a (diff)
Merge github.com:grpc/grpc into scalable-poll
Diffstat (limited to 'src')
-rw-r--r--src/compiler/cpp_generator.cc221
-rw-r--r--src/compiler/csharp_generator.cc56
-rw-r--r--src/compiler/objective_c_generator.cc108
-rw-r--r--src/compiler/ruby_generator.cc87
-rw-r--r--src/core/iomgr/pollset_posix.c7
-rw-r--r--src/core/surface/call.h13
-rw-r--r--src/core/surface/call_log_batch.c16
-rw-r--r--src/core/surface/server.c12
-rw-r--r--src/core/surface/server.h2
-rw-r--r--src/core/transport/chttp2/alpn.c3
-rw-r--r--src/core/tsi/ssl_transport_security.c10
-rw-r--r--src/csharp/README.md77
-rw-r--r--src/node/examples/math_server.js2
-rw-r--r--src/node/examples/stock_server.js2
-rw-r--r--src/node/package.json2
-rw-r--r--src/objective-c/ProtoRPC/ProtoRPC.m4
-rw-r--r--src/objective-c/README.md119
-rw-r--r--src/objective-c/examples/Sample/Sample/ViewController.m2
-rw-r--r--src/objective-c/examples/Sample/SampleTests/RemoteTests.m2
-rw-r--r--src/objective-c/examples/Sample/SampleTests/SampleTests.m2
-rw-r--r--src/python/src/setup.py2
-rw-r--r--src/ruby/.rubocop_todo.yml6
-rw-r--r--src/ruby/ext/grpc/rb_server.c4
-rw-r--r--src/ruby/lib/grpc/generic/rpc_server.rb60
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/spec/generic/rpc_server_pool_spec.rb4
-rw-r--r--src/ruby/spec/generic/rpc_server_spec.rb42
27 files changed, 550 insertions, 317 deletions
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index acac1475f7..b0d2b5d229 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -86,23 +86,25 @@ grpc::string FilenameIdentifier(const grpc::string &filename) {
grpc::string GetHeaderPrologue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
- std::map<grpc::string, grpc::string> vars;
-
- vars["filename"] = file->name();
- vars["filename_identifier"] = FilenameIdentifier(file->name());
- vars["filename_base"] = grpc_generator::StripProto(file->name());
-
- printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
- printer.Print(vars, "// If you make any local change, they will be lost.\n");
- printer.Print(vars, "// source: $filename$\n");
- printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
- printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
- printer.Print(vars, "\n");
- printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
- printer.Print(vars, "\n");
-
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_identifier"] = FilenameIdentifier(file->name());
+ vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+ printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+ printer.Print(vars, "// If you make any local change, they will be lost.\n");
+ printer.Print(vars, "// source: $filename$\n");
+ printer.Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
+ printer.Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
+ printer.Print(vars, "\n");
+ printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+ printer.Print(vars, "\n");
+ }
return output;
}
@@ -626,100 +628,108 @@ void PrintHeaderService(grpc::protobuf::io::Printer *printer,
grpc::string GetHeaderServices(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
- std::map<grpc::string, grpc::string> vars;
-
- if (!params.services_namespace.empty()) {
- vars["services_namespace"] = params.services_namespace;
- printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
- }
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ if (!params.services_namespace.empty()) {
+ vars["services_namespace"] = params.services_namespace;
+ printer.Print(vars, "\nnamespace $services_namespace$ {\n\n");
+ }
- for (int i = 0; i < file->service_count(); ++i) {
- PrintHeaderService(&printer, file->service(i), &vars);
- printer.Print("\n");
- }
+ for (int i = 0; i < file->service_count(); ++i) {
+ PrintHeaderService(&printer, file->service(i), &vars);
+ printer.Print("\n");
+ }
- if (!params.services_namespace.empty()) {
- printer.Print(vars, "} // namespace $services_namespace$\n\n");
+ if (!params.services_namespace.empty()) {
+ printer.Print(vars, "} // namespace $services_namespace$\n\n");
+ }
}
-
return output;
}
grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
- std::map<grpc::string, grpc::string> vars;
-
- vars["filename"] = file->name();
- vars["filename_identifier"] = FilenameIdentifier(file->name());
-
- if (!file->package().empty()) {
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
-
- for (auto part = parts.rbegin(); part != parts.rend(); part++) {
- vars["part"] = *part;
- printer.Print(vars, "} // namespace $part$\n");
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_identifier"] = FilenameIdentifier(file->name());
+
+ if (!file->package().empty()) {
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "} // namespace $part$\n");
+ }
+ printer.Print(vars, "\n");
}
+
printer.Print(vars, "\n");
+ printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
}
-
- printer.Print(vars, "\n");
- printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
-
return output;
}
grpc::string GetSourcePrologue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
- std::map<grpc::string, grpc::string> vars;
-
- vars["filename"] = file->name();
- vars["filename_base"] = grpc_generator::StripProto(file->name());
-
- printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
- printer.Print(vars, "// If you make any local change, they will be lost.\n");
- printer.Print(vars, "// source: $filename$\n\n");
- printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
- printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
- printer.Print(vars, "\n");
-
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ vars["filename"] = file->name();
+ vars["filename_base"] = grpc_generator::StripProto(file->name());
+
+ printer.Print(vars, "// Generated by the gRPC protobuf plugin.\n");
+ printer.Print(vars, "// If you make any local change, they will be lost.\n");
+ printer.Print(vars, "// source: $filename$\n\n");
+ printer.Print(vars, "#include \"$filename_base$.pb.h\"\n");
+ printer.Print(vars, "#include \"$filename_base$.grpc.pb.h\"\n");
+ printer.Print(vars, "\n");
+ }
return output;
}
grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
const Parameters &param) {
grpc::string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
- std::map<grpc::string, grpc::string> vars;
-
- printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
- printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
- printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
- printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
- printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
- printer.Print(vars, "#include <grpc++/stream.h>\n");
-
- if (!file->package().empty()) {
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
-
- for (auto part = parts.begin(); part != parts.end(); part++) {
- vars["part"] = *part;
- printer.Print(vars, "namespace $part$ {\n");
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+
+ printer.Print(vars, "#include <grpc++/async_unary_call.h>\n");
+ printer.Print(vars, "#include <grpc++/channel_interface.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/client_unary_call.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/rpc_service_method.h>\n");
+ printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
+ printer.Print(vars, "#include <grpc++/stream.h>\n");
+
+ if (!file->package().empty()) {
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
+
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "namespace $part$ {\n");
+ }
}
- }
-
- printer.Print(vars, "\n");
+ printer.Print(vars, "\n");
+ }
return output;
}
@@ -1077,26 +1087,29 @@ void PrintSourceService(grpc::protobuf::io::Printer *printer,
grpc::string GetSourceServices(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- grpc::protobuf::io::Printer printer(&output_stream, '$');
- std::map<grpc::string, grpc::string> vars;
- // Package string is empty or ends with a dot. It is used to fully qualify
- // method names.
- vars["Package"] = file->package();
- if (!file->package().empty()) {
- vars["Package"].append(".");
- }
- if (!params.services_namespace.empty()) {
- vars["ns"] = params.services_namespace + "::";
- vars["prefix"] = params.services_namespace;
- } else {
- vars["ns"] = "";
- vars["prefix"] = "";
- }
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ grpc::protobuf::io::Printer printer(&output_stream, '$');
+ std::map<grpc::string, grpc::string> vars;
+ // Package string is empty or ends with a dot. It is used to fully qualify
+ // method names.
+ vars["Package"] = file->package();
+ if (!file->package().empty()) {
+ vars["Package"].append(".");
+ }
+ if (!params.services_namespace.empty()) {
+ vars["ns"] = params.services_namespace + "::";
+ vars["prefix"] = params.services_namespace;
+ } else {
+ vars["ns"] = "";
+ vars["prefix"] = "";
+ }
- for (int i = 0; i < file->service_count(); ++i) {
- PrintSourceService(&printer, file->service(i), &vars);
- printer.Print("\n");
+ for (int i = 0; i < file->service_count(); ++i) {
+ PrintSourceService(&printer, file->service(i), &vars);
+ printer.Print("\n");
+ }
}
return output;
}
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 5dd078b303..ccb0b688b6 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -474,35 +474,39 @@ void GenerateService(Printer* out, const ServiceDescriptor *service) {
grpc::string GetServices(const FileDescriptor *file) {
grpc::string output;
- StringOutputStream output_stream(&output);
- Printer out(&output_stream, '$');
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
- // Don't write out any output if there no services, to avoid empty service
- // files being generated for proto files that don't declare any.
- if (file->service_count() == 0) {
- return output;
- }
+ StringOutputStream output_stream(&output);
+ Printer out(&output_stream, '$');
+
+ // Don't write out any output if there no services, to avoid empty service
+ // files being generated for proto files that don't declare any.
+ if (file->service_count() == 0) {
+ return output;
+ }
- // Write out a file header.
- out.Print("// Generated by the protocol buffer compiler. DO NOT EDIT!\n");
- out.Print("// source: $filename$\n", "filename", file->name());
- out.Print("#region Designer generated code\n");
- out.Print("\n");
- out.Print("using System;\n");
- out.Print("using System.Threading;\n");
- out.Print("using System.Threading.Tasks;\n");
- out.Print("using Grpc.Core;\n");
- // TODO(jtattermusch): add using for protobuf message classes
- out.Print("\n");
-
- out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
- out.Indent();
- for (int i = 0; i < file->service_count(); i++) {
- GenerateService(&out, file->service(i));
+ // Write out a file header.
+ out.Print("// Generated by the protocol buffer compiler. DO NOT EDIT!\n");
+ out.Print("// source: $filename$\n", "filename", file->name());
+ out.Print("#region Designer generated code\n");
+ out.Print("\n");
+ out.Print("using System;\n");
+ out.Print("using System.Threading;\n");
+ out.Print("using System.Threading.Tasks;\n");
+ out.Print("using Grpc.Core;\n");
+ // TODO(jtattermusch): add using for protobuf message classes
+ out.Print("\n");
+
+ out.Print("namespace $namespace$ {\n", "namespace", GetFileNamespace(file));
+ out.Indent();
+ for (int i = 0; i < file->service_count(); i++) {
+ GenerateService(&out, file->service(i));
+ }
+ out.Outdent();
+ out.Print("}\n");
+ out.Print("#endregion\n");
}
- out.Outdent();
- out.Print("}\n");
- out.Print("#endregion\n");
return output;
}
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index 8f35302bee..1bf0254f5b 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -176,65 +176,71 @@ void PrintMethodImplementations(Printer *printer,
string GetHeader(const ServiceDescriptor *service, const string prefix) {
string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- Printer printer(&output_stream, '$');
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ Printer printer(&output_stream, '$');
- printer.Print("@protocol GRXWriteable;\n");
- printer.Print("@protocol GRXWriter;\n\n");
-
- map<string, string> vars = {{"service_name", service->name()},
- {"prefix", prefix}};
- printer.Print(vars, "@protocol $prefix$$service_name$ <NSObject>\n\n");
-
- for (int i = 0; i < service->method_count(); i++) {
- PrintMethodDeclarations(&printer, service->method(i), vars);
+ printer.Print("@protocol GRXWriteable;\n");
+ printer.Print("@protocol GRXWriter;\n\n");
+
+ map<string, string> vars = {{"service_name", service->name()},
+ {"prefix", prefix}};
+ printer.Print(vars, "@protocol $prefix$$service_name$ <NSObject>\n\n");
+
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintMethodDeclarations(&printer, service->method(i), vars);
+ }
+ printer.Print("@end\n\n");
+
+ printer.Print("// Basic service implementation, over gRPC, that only does"
+ " marshalling and parsing.\n");
+ printer.Print(vars, "@interface $prefix$$service_name$ :"
+ " ProtoService<$prefix$$service_name$>\n");
+ printer.Print("- (instancetype)initWithHost:(NSString *)host"
+ " NS_DESIGNATED_INITIALIZER;\n");
+ printer.Print("@end\n");
}
- printer.Print("@end\n\n");
-
- printer.Print("// Basic service implementation, over gRPC, that only does"
- " marshalling and parsing.\n");
- printer.Print(vars, "@interface $prefix$$service_name$ :"
- " ProtoService<$prefix$$service_name$>\n");
- printer.Print("- (instancetype)initWithHost:(NSString *)host"
- " NS_DESIGNATED_INITIALIZER;\n");
- printer.Print("@end\n");
return output;
}
string GetSource(const ServiceDescriptor *service, const string prefix) {
string output;
- grpc::protobuf::io::StringOutputStream output_stream(&output);
- Printer printer(&output_stream, '$');
-
- map<string, string> vars = {{"service_name", service->name()},
- {"package", service->file()->package()},
- {"prefix", prefix}};
-
- printer.Print(vars,
- "static NSString *const kPackageName = @\"$package$\";\n");
- printer.Print(vars,
- "static NSString *const kServiceName = @\"$service_name$\";\n\n");
-
- printer.Print(vars, "@implementation $prefix$$service_name$\n\n");
-
- printer.Print("// Designated initializer\n");
- printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
- printer.Print(" return (self = [super initWithHost:host"
- " packageName:kPackageName serviceName:kServiceName]);\n");
- printer.Print("}\n\n");
- printer.Print("// Override superclass initializer to disallow different"
- " package and service names.\n");
- printer.Print("- (instancetype)initWithHost:(NSString *)host\n");
- printer.Print(" packageName:(NSString *)packageName\n");
- printer.Print(" serviceName:(NSString *)serviceName {\n");
- printer.Print(" return [self initWithHost:host];\n");
- printer.Print("}\n\n\n");
-
- for (int i = 0; i < service->method_count(); i++) {
- PrintMethodImplementations(&printer, service->method(i), vars);
- }
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+ grpc::protobuf::io::StringOutputStream output_stream(&output);
+ Printer printer(&output_stream, '$');
+
+ map<string, string> vars = {{"service_name", service->name()},
+ {"package", service->file()->package()},
+ {"prefix", prefix}};
- printer.Print("@end\n");
+ printer.Print(vars,
+ "static NSString *const kPackageName = @\"$package$\";\n");
+ printer.Print(vars,
+ "static NSString *const kServiceName = @\"$service_name$\";\n\n");
+
+ printer.Print(vars, "@implementation $prefix$$service_name$\n\n");
+
+ printer.Print("// Designated initializer\n");
+ printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
+ printer.Print(" return (self = [super initWithHost:host"
+ " packageName:kPackageName serviceName:kServiceName]);\n");
+ printer.Print("}\n\n");
+ printer.Print("// Override superclass initializer to disallow different"
+ " package and service names.\n");
+ printer.Print("- (instancetype)initWithHost:(NSString *)host\n");
+ printer.Print(" packageName:(NSString *)packageName\n");
+ printer.Print(" serviceName:(NSString *)serviceName {\n");
+ printer.Print(" return [self initWithHost:host];\n");
+ printer.Print("}\n\n\n");
+
+ for (int i = 0; i < service->method_count(); i++) {
+ PrintMethodImplementations(&printer, service->method(i), vars);
+ }
+
+ printer.Print("@end\n");
+ }
return output;
}
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index a0bb92848b..299137519f 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -119,49 +119,52 @@ void PrintService(const ServiceDescriptor *service, const grpc::string &package,
grpc::string GetServices(const FileDescriptor *file) {
grpc::string output;
- StringOutputStream output_stream(&output);
- Printer out(&output_stream, '$');
-
- // Don't write out any output if there no services, to avoid empty service
- // files being generated for proto files that don't declare any.
- if (file->service_count() == 0) {
- return output;
- }
-
- // Write out a file header.
- std::map<grpc::string, grpc::string> header_comment_vars = ListToDict(
- {"file.name", file->name(), "file.package", file->package(), });
- out.Print("# Generated by the protocol buffer compiler. DO NOT EDIT!\n");
- out.Print(header_comment_vars,
- "# Source: $file.name$ for package '$file.package$'\n");
-
- out.Print("\n");
- out.Print("require 'grpc'\n");
- // Write out require statemment to import the separately generated file
- // that defines the messages used by the service. This is generated by the
- // main ruby plugin.
- std::map<grpc::string, grpc::string> dep_vars =
- ListToDict({"dep.name", MessagesRequireName(file), });
- out.Print(dep_vars, "require '$dep.name$'\n");
-
- // Write out services within the modules
- out.Print("\n");
- std::vector<grpc::string> modules = Split(file->package(), '.');
- for (size_t i = 0; i < modules.size(); ++i) {
- std::map<grpc::string, grpc::string> module_vars =
- ListToDict({"module.name", CapitalizeFirst(modules[i]), });
- out.Print(module_vars, "module $module.name$\n");
- out.Indent();
+ {
+ // Scope the output stream so it closes and finalizes output to the string.
+
+ StringOutputStream output_stream(&output);
+ Printer out(&output_stream, '$');
+
+ // Don't write out any output if there no services, to avoid empty service
+ // files being generated for proto files that don't declare any.
+ if (file->service_count() == 0) {
+ return output;
+ }
+
+ // Write out a file header.
+ std::map<grpc::string, grpc::string> header_comment_vars = ListToDict(
+ {"file.name", file->name(), "file.package", file->package(), });
+ out.Print("# Generated by the protocol buffer compiler. DO NOT EDIT!\n");
+ out.Print(header_comment_vars,
+ "# Source: $file.name$ for package '$file.package$'\n");
+
+ out.Print("\n");
+ out.Print("require 'grpc'\n");
+ // Write out require statemment to import the separately generated file
+ // that defines the messages used by the service. This is generated by the
+ // main ruby plugin.
+ std::map<grpc::string, grpc::string> dep_vars =
+ ListToDict({"dep.name", MessagesRequireName(file), });
+ out.Print(dep_vars, "require '$dep.name$'\n");
+
+ // Write out services within the modules
+ out.Print("\n");
+ std::vector<grpc::string> modules = Split(file->package(), '.');
+ for (size_t i = 0; i < modules.size(); ++i) {
+ std::map<grpc::string, grpc::string> module_vars =
+ ListToDict({"module.name", CapitalizeFirst(modules[i]), });
+ out.Print(module_vars, "module $module.name$\n");
+ out.Indent();
+ }
+ for (int i = 0; i < file->service_count(); ++i) {
+ auto service = file->service(i);
+ PrintService(service, file->package(), &out);
+ }
+ for (size_t i = 0; i < modules.size(); ++i) {
+ out.Outdent();
+ out.Print("end\n");
+ }
}
- for (int i = 0; i < file->service_count(); ++i) {
- auto service = file->service(i);
- PrintService(service, file->package(), &out);
- }
- for (size_t i = 0; i < modules.size(); ++i) {
- out.Outdent();
- out.Print("end\n");
- }
-
return output;
}
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index bdfcba6e5d..a38517908d 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -174,6 +174,8 @@ void grpc_pollset_del_fd(grpc_pollset *pollset, grpc_fd *fd) {
int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) {
/* pollset->mu already held */
gpr_timespec now = gpr_now();
+ /* FIXME(ctiller): see below */
+ gpr_timespec maximum_deadline = gpr_time_add(now, gpr_time_from_seconds(1));
int r;
if (gpr_time_cmp(now, deadline) > 0) {
return 0;
@@ -184,6 +186,11 @@ int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) {
if (grpc_alarm_check(&pollset->mu, now, &deadline)) {
return 1;
}
+ /* FIXME(ctiller): we should not clamp deadline, however we have some
+ stuck at shutdown bugs that this resolves */
+ if (gpr_time_cmp(deadline, maximum_deadline) > 0) {
+ deadline = maximum_deadline;
+ }
gpr_tls_set(&g_current_thread_poller, (gpr_intptr)pollset);
r = pollset->vtable->maybe_work(pollset, deadline, now, 1);
gpr_tls_set(&g_current_thread_poller, 0);
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index 60222bf389..9116538948 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -122,6 +122,16 @@ void grpc_call_log_batch(char *file, int line, gpr_log_severity severity,
grpc_call *call, const grpc_op *ops, size_t nops,
void *tag);
+void grpc_server_log_request_call(char *file, int line,
+ gpr_log_severity severity,
+ grpc_server *server,
+ grpc_call **call,
+ grpc_call_details *details,
+ grpc_metadata_array *initial_metadata,
+ grpc_completion_queue *cq_bound_to_call,
+ grpc_completion_queue *cq_for_notification,
+ void *tag);
+
/* Set a context pointer.
No thread safety guarantees are made wrt this value. */
void grpc_call_context_set(grpc_call *call, grpc_context_index elem, void *value,
@@ -132,6 +142,9 @@ void *grpc_call_context_get(grpc_call *call, grpc_context_index elem);
#define GRPC_CALL_LOG_BATCH(sev, call, ops, nops, tag) \
if (grpc_trace_batch) grpc_call_log_batch(sev, call, ops, nops, tag)
+#define GRPC_SERVER_LOG_REQUEST_CALL(sev, server, call, details, initial_metadata, cq_bound_to_call, cq_for_notifications, tag) \
+ if (grpc_trace_batch) grpc_server_log_request_call(sev, server, call, details, initial_metadata, cq_bound_to_call, cq_for_notifications, tag)
+
gpr_uint8 grpc_call_is_client(grpc_call *call);
#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */
diff --git a/src/core/surface/call_log_batch.c b/src/core/surface/call_log_batch.c
index e3b3f75b45..9905401bee 100644
--- a/src/core/surface/call_log_batch.c
+++ b/src/core/surface/call_log_batch.c
@@ -119,3 +119,19 @@ void grpc_call_log_batch(char *file, int line, gpr_log_severity severity,
gpr_free(tmp);
}
}
+
+void grpc_server_log_request_call(char *file, int line,
+ gpr_log_severity severity,
+ grpc_server *server,
+ grpc_call **call,
+ grpc_call_details *details,
+ grpc_metadata_array *initial_metadata,
+ grpc_completion_queue *cq_bound_to_call,
+ grpc_completion_queue *cq_for_notification,
+ void *tag) {
+ gpr_log(file, line, severity,
+ "grpc_server_request_call(server=%p, call=%p, details=%p, "
+ "initial_metadata=%p, cq_bound_to_call=%p, cq_for_notification=%p, "
+ "tag=%p)", server, call, details, initial_metadata,
+ cq_bound_to_call, cq_for_notification, tag);
+}
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 24a23ae5c4..a60d5f7717 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -1010,6 +1010,9 @@ grpc_call_error grpc_server_request_call(
grpc_completion_queue *cq_bound_to_call,
grpc_completion_queue *cq_for_notification, void *tag) {
requested_call rc;
+ GRPC_SERVER_LOG_REQUEST_CALL(GPR_INFO, server, call, details,
+ initial_metadata, cq_bound_to_call,
+ cq_for_notification, tag);
grpc_cq_begin_op(cq_for_notification, NULL);
rc.type = BATCH_CALL;
rc.tag = tag;
@@ -1128,3 +1131,12 @@ static void publish_registered_or_batch(grpc_call *call, int success,
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server) {
return server->channel_args;
}
+
+int grpc_server_has_open_connections(grpc_server *server) {
+ int r;
+ gpr_mu_lock(&server->mu);
+ r = server->root_channel_data.next != &server->root_channel_data;
+ gpr_mu_unlock(&server->mu);
+ return r;
+}
+
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index c6331033e0..58f17272a4 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -62,4 +62,6 @@ grpc_transport_setup_result grpc_server_setup_transport(
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
+int grpc_server_has_open_connections(grpc_server *server);
+
#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
diff --git a/src/core/transport/chttp2/alpn.c b/src/core/transport/chttp2/alpn.c
index 11901a58a0..3ccd5796ba 100644
--- a/src/core/transport/chttp2/alpn.c
+++ b/src/core/transport/chttp2/alpn.c
@@ -36,7 +36,8 @@
#include <grpc/support/useful.h>
/* in order of preference */
-static const char *const supported_versions[] = {"h2-16", "h2-15", "h2-14"};
+static const char *const supported_versions[] = {"h2", "h2-17", "h2-16",
+ "h2-15", "h2-14"};
int grpc_chttp2_is_alpn_version_supported(const char *version, size_t size) {
size_t i;
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index 9718a0b048..63b4c42131 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -639,7 +639,7 @@ static tsi_result ssl_protector_protect(tsi_frame_protector* self,
tsi_result result = TSI_OK;
/* First see if we have some pending data in the SSL BIO. */
- size_t pending_in_ssl = BIO_ctrl_pending(impl->from_ssl);
+ size_t pending_in_ssl = BIO_pending(impl->from_ssl);
if (pending_in_ssl > 0) {
*unprotected_bytes_size = 0;
read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
@@ -694,7 +694,7 @@ static tsi_result ssl_protector_protect_flush(
impl->buffer_offset = 0;
}
- *still_pending_size = BIO_ctrl_pending(impl->from_ssl);
+ *still_pending_size = BIO_pending(impl->from_ssl);
if (*still_pending_size == 0) return TSI_OK;
read_from_ssl = BIO_read(impl->from_ssl, protected_output_frames,
@@ -704,7 +704,7 @@ static tsi_result ssl_protector_protect_flush(
return TSI_INTERNAL_ERROR;
}
*protected_output_frames_size = read_from_ssl;
- *still_pending_size = BIO_ctrl_pending(impl->from_ssl);
+ *still_pending_size = BIO_pending(impl->from_ssl);
return TSI_OK;
}
@@ -782,7 +782,7 @@ static tsi_result ssl_handshaker_get_bytes_to_send_to_peer(tsi_handshaker* self,
}
}
*bytes_size = (size_t)bytes_read_from_ssl;
- return BIO_ctrl_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
+ return BIO_pending(impl->from_ssl) == 0 ? TSI_OK : TSI_INCOMPLETE_DATA;
}
static tsi_result ssl_handshaker_get_result(tsi_handshaker* self) {
@@ -818,7 +818,7 @@ static tsi_result ssl_handshaker_process_bytes_from_peer(
ssl_result = SSL_get_error(impl->ssl, ssl_result);
switch (ssl_result) {
case SSL_ERROR_WANT_READ:
- if (BIO_ctrl_pending(impl->from_ssl) == 0) {
+ if (BIO_pending(impl->from_ssl) == 0) {
/* We need more data. */
return TSI_INCOMPLETE_DATA;
} else {
diff --git a/src/csharp/README.md b/src/csharp/README.md
index 37aa2ecddc..43d519349f 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -6,7 +6,7 @@ A C# implementation of gRPC.
Status
------
-Ready for early adopters.
+Alpha : Ready for early adopters.
Usage: Windows
--------------
@@ -19,22 +19,60 @@ Usage: Windows
That will also pull all the transitive dependencies (including the native libraries that
gRPC C# is internally using).
-- TODO: link to Helloworld example
+- Helloworld project example can be found in https://github.com/grpc/grpc-common/tree/master/csharp.
Usage: Linux (Mono)
--------------
-- Prerequisites: Mono framework, MonoDevelop 5.9 with NuGet add-in installed.
+- Prerequisites: Mono 3.2.8+, MonoDevelop 5.9 with NuGet add-in installed.
-- Install gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc
+- Install Linuxbrew and gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc
-- TODO: explain using LD_LIBRARY_PATH or installation to /usr/local
+- gRPC C# depends on native shared library libgrpc_csharp_ext.so (Unix flavor of grpc_csharp_ext.dll).
+ This library will be installed to `~/.linuxbrew/lib` by the previous step.
+ To make it visible to mono, you need to:
+
+ - (preferred approach) add `libgrpc_csharp_ext.so` to `/etc/ld.so.cache` by running:
+
+ ```sh
+ echo "$HOME/.linuxbrew/lib" | sudo tee /etc/ld.so.conf.d/zzz_brew_lib.conf
+ sudo ldconfig
+ ```
+
+ - (adhoc approach) set `LD_LIBRARY_PATH` environment variable to point to directory containing `libgrpc_csharp_ext.so`:
+
+ ```sh
+ export LD_LIBRARY_PATH=$HOME/.linuxbrew/lib:${LD_LIBRARY_PATH}
+ ```
- Open MonoDevelop and start a new project/solution.
- Add NuGet package `Grpc` as a dependency (Project -> Add NuGet packages).
-- TODO: link to Helloworld example
+- Helloworld project example can be found in https://github.com/grpc/grpc-common/tree/master/csharp.
+
+Usage: MacOS (Mono)
+--------------
+
+- WARNING: As of now gRPC C# only works on 64bit version of Mono (because we don't compile
+ the native extension for C# in 32bit mode yet). That means your development experience
+ with Xamarin Studio on MacOS will not be great, as you won't be able to run your
+ code directly from Xamarin Studio (which requires 32bit version of Mono).
+
+- Prerequisites: Xamarin Studio with NuGet add-in installed.
+
+- Install Homebrew and gRPC C Core using instructions in https://github.com/grpc/homebrew-grpc
+
+- Install 64-bit version of mono with command `brew install mono` (assumes you've already installed Homebrew).
+
+- Open Xamarin Studio and start a new project/solution.
+
+- Add NuGet package `Grpc` as a dependency (Project -> Add NuGet packages).
+
+- *You will be able to build your project in Xamarin Studio, but to run or test it,
+ you will need to run it under 64-bit version of Mono.*
+
+- Helloworld project example can be found in https://github.com/grpc/grpc-common/tree/master/csharp.
Building: Windows
-----------------
@@ -47,9 +85,10 @@ If you are a user of gRPC C#, go to Usage section above.
- The grpc_csharp_ext native library needs to be built so you can build the Grpc C# solution. You can
either build the native solution in `vsprojects/grpc.sln` from Visual Studio manually, or you can use
a convenience batch script that builds everything for you.
-```
-buildall.bat
-```
+
+ ```
+ buildall.bat
+ ```
- Open Grpc.sln using Visual Studio 2013. NuGet dependencies will be restored
upon build (you need to have NuGet add-in installed).
@@ -61,11 +100,12 @@ Building: Linux & Mono
You only need to go through these steps if you are planning to develop gRPC C#.
If you are a user of gRPC C#, go to Usage section above.
-- Prerequisites for development: Mono framework, MonoDevelop 5.9 with NuGet and Nunit add-ins installed.
-```
-sudo apt-get install mono-devel
-sudo apt-get install nunit nunit-console
-```
+- Prerequisites for development: Mono 3.2.8+, MonoDevelop 5.9 with NuGet and NUnit add-ins installed.
+
+ ```sh
+ sudo apt-get install mono-devel
+ sudo apt-get install nunit nunit-console
+ ```
You can use older versions of MonoDevelop, but then you might need to restore
NuGet dependencies manually (by `nuget restore`), because older versions of MonoDevelop
@@ -73,10 +113,10 @@ don't support NuGet add-in.
- Compile and install the gRPC C# extension library (that will be used via
P/Invoke from C#).
-```
-make grpc_csharp_ext
-sudo make install_grpc_csharp_ext
-```
+ ```sh
+ make grpc_csharp_ext
+ sudo make install_grpc_csharp_ext
+ ```
- Use MonoDevelop to open the solution Grpc.sln
@@ -95,7 +135,6 @@ Then you should be able to run all the test from the Test View.
After building the solution, you can also run the tests from command line
using nunit-console tool.
-
```
# from Grpc.Core.Test/bin/Debug directory
nunit-console Grpc.Core.Tests.dll
diff --git a/src/node/examples/math_server.js b/src/node/examples/math_server.js
index 3fac193d64..0a86e7eaff 100644
--- a/src/node/examples/math_server.js
+++ b/src/node/examples/math_server.js
@@ -119,7 +119,7 @@ var server = new Server({
});
if (require.main === module) {
- server.bind('0.0.0.0:7070');
+ server.bind('0.0.0.0:50051');
server.listen();
}
diff --git a/src/node/examples/stock_server.js b/src/node/examples/stock_server.js
index e475c9cb4c..8c22af147e 100644
--- a/src/node/examples/stock_server.js
+++ b/src/node/examples/stock_server.js
@@ -83,7 +83,7 @@ var stockServer = new StockServer({
});
if (require.main === module) {
- stockServer.bind('0.0.0.0:8080');
+ stockServer.bind('0.0.0.0:50051');
stockServer.listen();
}
diff --git a/src/node/package.json b/src/node/package.json
index 3f31ba49ff..d7e9af07bd 100644
--- a/src/node/package.json
+++ b/src/node/package.json
@@ -1,6 +1,6 @@
{
"name": "grpc",
- "version": "0.8.0",
+ "version": "0.9.0",
"author": "Google Inc.",
"description": "gRPC Library for Node",
"homepage": "http://www.grpc.io/",
diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m
index 96608f2898..b8f8008422 100644
--- a/src/objective-c/ProtoRPC/ProtoRPC.m
+++ b/src/objective-c/ProtoRPC/ProtoRPC.m
@@ -59,7 +59,7 @@
responseClass:(Class)responseClass
responsesWriteable:(id<GRXWriteable>)responsesWriteable {
// Because we can't tell the type system to constrain the class, we need to check at runtime:
- if (![responseClass respondsToSelector:@selector(parseFromData:)]) {
+ if (![responseClass respondsToSelector:@selector(parseFromData:error:)]) {
[NSException raise:NSInvalidArgumentException
format:@"A protobuf class to parse the responses must be provided."];
}
@@ -71,7 +71,7 @@
if ((self = [super initWithHost:host method:method requestsWriter:bytesWriter])) {
// A writeable that parses the proto messages received.
_responseWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- [responsesWriteable writeValue:[responseClass parseFromData:value]];
+ [responsesWriteable writeValue:[responseClass parseFromData:value error:NULL]];
} completionHandler:^(NSError *errorOrNil) {
[responsesWriteable writesFinishedWithError:errorOrNil];
}];
diff --git a/src/objective-c/README.md b/src/objective-c/README.md
index 49d7f43882..167016cc2c 100644
--- a/src/objective-c/README.md
+++ b/src/objective-c/README.md
@@ -1,43 +1,119 @@
# gRPC for Objective-C
-## How to generate a client library from a Protocol Buffers definition
+- [Install protoc with the gRPC plugin](#install)
+- [Use protoc to generate a gRPC library](#protoc)
+- [Integrate the generated gRPC library in your project](#cocoapods)
+- [Use the generated library in your code](#use)
+- [Alternative methods](#alternatives)
+ - [Install protoc and the gRPC plugin without using Homebrew](#nohomebrew)
+ - [Integrate the generated gRPC library without using Cocoapods](#nococoapods)
-First install v3 of the Protocol Buffers compiler (_protoc_), by cloning [its Git repository](https://github.com/google/protobuf) and following these [installation instructions](https://github.com/google/protobuf#c-installation---unix) (the ones titled C++; don't miss the note for Mac users).
+<a name="install"></a>
+## Install protoc with the gRPC plugin
-Then clone this repository and execute the following commands from the root directory where it was cloned.
+On Mac OS X, install [homebrew][]. On Linux, install [linuxbrew][].
-Compile the gRPC plugins for _protoc_:
+Run the following command to install the Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin:
```sh
-make plugins
+$ curl -fsSL https://goo.gl/getgrpc | bash -
```
+This will download and run the [gRPC install script][]. After the command completes, you're ready to proceed.
+
+<a name="protoc"></a>
+## Use protoc to generate a gRPC library
+
+Run _protoc_ with the following flags to generate the client library for your `.proto` files:
-Create a symbolic link to the compiled plugin binary somewhere in your `$PATH`:
```sh
-ln -s `pwd`/bins/opt/grpc_objective_c_plugin /usr/local/bin/protoc-gen-objcgrpc
+protoc --objc_out=. --objcgrpc_out=. *.proto
```
-(Notice that the name of the created link must begin with "protoc-gen-" for _protoc_ to recognize it as a plugin).
-If you don't want to create the symbolic link, you can alternatively copy the binary (with the appropriate name). Or you might prefer instead to specify the plugin's path as a flag when invoking _protoc_, in which case no system modification nor renaming is necessary.
+This will generate a pair of `.pbobjc.h`/`.pbobjc.m` files for each `.proto` file, with the messages and enums defined in them. And a pair of `.pbrpc.h`/`.pbrpc.m` files for each `.proto` file with services defined. The latter contains the code to make remote calls to the specified API.
-Finally, run _protoc_ with the following flags to generate the client library for your `.proto` files:
+<a name="cocoapods"></a>
+## Integrate the generated gRPC library in your project
+
+Install [Cocoapods](https://cocoapods.org/#install).
+
+You need to create a Podspec file for the generated library. You may simply copy the following example to the directory where the source files were generated, updating the name and other metadata of the Podspec as necessary:
+
+```ruby
+Pod::Spec.new do |s|
+ s.name = '<Podspec file name>'
+ s.version = '...'
+ s.summary = 'Client library to make RPCs to <my proto API>'
+ s.homepage = '...'
+ s.license = '...'
+ s.authors = { '<my name>' => '<my email>' }
+
+ s.ios.deployment_target = '6.0'
+ s.osx.deployment_target = '10.8'
+
+ s.subspec 'Messages' do |ms|
+ ms.source_files = '*.pbobjc.{h,m}'
+ ms.requires_arc = false
+ ms.dependency 'Protobuf', '~> 3.0'
+ end
+
+ s.subspec 'Services' do |ss|
+ ss.source_files = '*.pbrpc.{h,m}'
+ ss.requires_arc = true
+ ss.dependency 'gRPC', '~> 0.0'
+ ss.dependency '<Podspec file name>/Messages'
+ end
+end
+```
+
+The file should be named `<Podspec file name>.podspec`. You can refer to this [example Podspec][]. Once your library has a Podspec, Cocoapods can install it into any XCode project. For that, go into your project's directory and create a Podfile by running:
```sh
-protoc --objc_out=. --objcgrpc_out=. *.proto
+pod init
```
-This will generate a pair of `.pbobjc.h`/`.pbobjc.m` files for each `.proto` file, with the messages and enums defined in them. And a pair of `.pbrpc.h`/`.pbrpc.m` files for each `.proto` file with services defined. The latter contains the code to make remote calls to the specified API.
+Next add a line to your Podfile to refer to your library's Podspec. Use `:path` as described [here](https://guides.cocoapods.org/using/the-podfile.html#using-the-files-from-a-folder-local-to-the-machine):
+
+```ruby
+pod '<Podspec file name>', :path => 'path/to/the/directory/of/your/podspec'
+```
+
+You can look at this [example Podfile][].
+
+Finally, in your project's directory, run:
-## How to integrate a generated gRPC library in your project
+```sh
+pod install
+```
+
+<a name="use"></a>
+## Use the generated library in your code
+
+Please check this [sample app][] for examples of how to use a generated gRPC library.
+
+<a name="alternatives"></a>
+## Alternative methods
-### If you use Cocoapods
+<a name="nohomebrew"></a>
+### Install protoc and the gRPC plugin without using Homebrew
-This is the recommended approach.
+First install v3 of the Protocol Buffers compiler (_protoc_), by cloning [its Git repository](https://github.com/google/protobuf) and following these [installation instructions](https://github.com/google/protobuf#c-installation---unix) (the ones titled C++; don't miss the note for Mac users).
+
+Then clone this repository and execute the following commands from the root directory where it was cloned.
+
+Compile the gRPC plugins for _protoc_:
+```sh
+make plugins
+```
-You need to create a Podspec file for the generated library. This is simply a matter of copying an example like [this one](https://github.com/grpc/grpc/blob/master/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec) to the directory where the source files were generated. Update the name and other metadata of the Podspec as suitable.
+Create a symbolic link to the compiled plugin binary somewhere in your `$PATH`:
+```sh
+ln -s `pwd`/bins/opt/grpc_objective_c_plugin /usr/local/bin/protoc-gen-objcgrpc
+```
+(Notice that the name of the created link must begin with "protoc-gen-" for _protoc_ to recognize it as a plugin).
-Once your library has a Podspec, refer to it from your Podfile using `:path` as described [here](https://guides.cocoapods.org/using/the-podfile.html#using-the-files-from-a-folder-local-to-the-machine).
+If you don't want to create the symbolic link, you can alternatively copy the binary (with the appropriate name). Or you might prefer instead to specify the plugin's path as a flag when invoking _protoc_, in which case no system modification nor renaming is necessary.
-### If you don't use Cocoapods
+<a name="nococoapods"></a>
+### Integrate the generated gRPC library without using Cocoapods
You need to compile the generated `.pbpbjc.*` files (the enums and messages) without ARC support, and the generated `.pbrpc.*` files (the services) with ARC support. The generated code depends on v0.3+ of the Objective-C gRPC runtime library and v3.0+ of the Objective-C Protobuf runtime library.
@@ -45,3 +121,10 @@ These libraries need to be integrated into your project as described in their re
* [Podspec](https://github.com/grpc/grpc/blob/master/gRPC.podspec) for the Objective-C gRPC runtime library. This can be tedious to configure manually.
* [Podspec](https://github.com/jcanizales/protobuf/blob/add-podspec/Protobuf.podspec) for the Objective-C Protobuf runtime library.
+
+[homebrew]:http://brew.sh
+[linuxbrew]:https://github.com/Homebrew/linuxbrew
+[gRPC install script]:https://raw.githubusercontent.com/grpc/homebrew-grpc/master/scripts/install
+[example Podspec]:https://github.com/grpc/grpc/blob/master/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec
+[example Podfile]:https://github.com/grpc/grpc/blob/master/src/objective-c/examples/Sample/Podfile
+[sample app]: https://github.com/grpc/grpc/tree/master/src/objective-c/examples/Sample
diff --git a/src/objective-c/examples/Sample/Sample/ViewController.m b/src/objective-c/examples/Sample/Sample/ViewController.m
index 1c866babec..9b331fe43f 100644
--- a/src/objective-c/examples/Sample/Sample/ViewController.m
+++ b/src/objective-c/examples/Sample/Sample/ViewController.m
@@ -80,7 +80,7 @@
requestsWriter:requestsWriter];
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
- RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value];
+ RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value error:NULL];
NSLog(@"Received response:\n%@", response);
} completionHandler:^(NSError *errorOrNil) {
if (errorOrNil) {
diff --git a/src/objective-c/examples/Sample/SampleTests/RemoteTests.m b/src/objective-c/examples/Sample/SampleTests/RemoteTests.m
index 553c813b0b..ceb72cfaec 100644
--- a/src/objective-c/examples/Sample/SampleTests/RemoteTests.m
+++ b/src/objective-c/examples/Sample/SampleTests/RemoteTests.m
@@ -125,7 +125,7 @@
XCTAssertNotNil(value, @"nil value received as response.");
[response fulfill];
XCTAssertGreaterThan(value.length, 0, @"Empty response received.");
- RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value];
+ RMTSimpleResponse *response = [RMTSimpleResponse parseFromData:value error:NULL];
// We expect empty strings, not nil:
XCTAssertNotNil(response.username, @"Response's username is nil.");
XCTAssertNotNil(response.oauthScope, @"Response's OAuth scope is nil.");
diff --git a/src/objective-c/examples/Sample/SampleTests/SampleTests.m b/src/objective-c/examples/Sample/SampleTests/SampleTests.m
index b1a0f78a01..83cfd8c1b5 100644
--- a/src/objective-c/examples/Sample/SampleTests/SampleTests.m
+++ b/src/objective-c/examples/Sample/SampleTests/SampleTests.m
@@ -123,7 +123,7 @@
id<GRXWriteable> responsesWriteable = [[GRXWriteable alloc] initWithValueHandler:^(NSData *value) {
XCTAssertNotNil(value, @"nil value received as response.");
- RGDFeature *feature = [RGDFeature parseFromData:value];
+ RGDFeature *feature = [RGDFeature parseFromData:value error:NULL];
XCTAssertEqualObjects(point, feature.location);
XCTAssertNotNil(feature.name, @"Response's name is nil.");
[response fulfill];
diff --git a/src/python/src/setup.py b/src/python/src/setup.py
index e936913cfd..d0f4791a1e 100644
--- a/src/python/src/setup.py
+++ b/src/python/src/setup.py
@@ -86,7 +86,7 @@ _PACKAGE_DIRECTORIES = {
setuptools.setup(
name='grpcio',
- version='0.5.0a2',
+ version='0.9.0a0',
ext_modules=[_EXTENSION_MODULE],
packages=list(_PACKAGES),
package_dir=_PACKAGE_DIRECTORIES,
diff --git a/src/ruby/.rubocop_todo.yml b/src/ruby/.rubocop_todo.yml
index ed4a4438b3..c35e970df6 100644
--- a/src/ruby/.rubocop_todo.yml
+++ b/src/ruby/.rubocop_todo.yml
@@ -1,5 +1,5 @@
# This configuration was generated by `rubocop --auto-gen-config`
-# on 2015-04-17 14:43:27 -0700 using RuboCop version 0.30.0.
+# on 2015-05-22 13:23:34 -0700 using RuboCop version 0.30.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@@ -7,12 +7,12 @@
# Offense count: 30
Metrics/AbcSize:
- Max: 40
+ Max: 38
# Offense count: 3
# Configuration parameters: CountComments.
Metrics/ClassLength:
- Max: 184
+ Max: 192
# Offense count: 35
# Configuration parameters: CountComments.
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index 3182d03fab..837ca3b5e8 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -282,12 +282,12 @@ static VALUE grpc_rb_server_destroy(VALUE self) {
call-seq:
// insecure port
insecure_server = Server.new(cq, {'arg1': 'value1'})
- insecure_server.add_http2_port('mydomain:7575')
+ insecure_server.add_http2_port('mydomain:50051')
// secure port
server_creds = ...
secure_server = Server.new(cq, {'arg1': 'value1'})
- secure_server.add_http_port('mydomain:7575', server_creds)
+ secure_server.add_http_port('mydomain:50051', server_creds)
Adds a http2 port to server */
static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) {
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 665c144432..dcb11bfbef 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -76,7 +76,7 @@ module GRPC
@jobs = Queue.new
@size = size
@stopped = false
- @stop_mutex = Mutex.new
+ @stop_mutex = Mutex.new # needs to be held when accessing @stopped
@stop_cond = ConditionVariable.new
@workers = []
@keep_alive = keep_alive
@@ -92,10 +92,15 @@ module GRPC
# @param args the args passed blk when it is called
# @param blk the block to call
def schedule(*args, &blk)
- fail 'already stopped' if @stopped
return if blk.nil?
- GRPC.logger.info('schedule another job')
- @jobs << [blk, args]
+ @stop_mutex.synchronize do
+ if @stopped
+ GRPC.logger.warn('did not schedule job, already stopped')
+ return
+ end
+ GRPC.logger.info('schedule another job')
+ @jobs << [blk, args]
+ end
end
# Starts running the jobs in the thread pool.
@@ -116,8 +121,8 @@ module GRPC
def stop
GRPC.logger.info('stopping, will wait for all the workers to exit')
@workers.size.times { schedule { throw :exit } }
- @stopped = true
@stop_mutex.synchronize do # wait @keep_alive for works to stop
+ @stopped = true
@stop_cond.wait(@stop_mutex, @keep_alive) if @workers.size > 0
end
forcibly_stop_workers
@@ -249,15 +254,18 @@ module GRPC
server_override:nil,
connect_md_proc:nil,
**kw)
- @cq = RpcServer.setup_cq(completion_queue_override)
- @server = RpcServer.setup_srv(server_override, @cq, **kw)
@connect_md_proc = RpcServer.setup_connect_md_proc(connect_md_proc)
- @pool_size = pool_size
+ @cq = RpcServer.setup_cq(completion_queue_override)
@max_waiting_requests = max_waiting_requests
@poll_period = poll_period
- @run_mutex = Mutex.new
- @run_cond = ConditionVariable.new
+ @pool_size = pool_size
@pool = Pool.new(@pool_size)
+ @run_cond = ConditionVariable.new
+ @run_mutex = Mutex.new
+ @running = false
+ @server = RpcServer.setup_srv(server_override, @cq, **kw)
+ @stopped = false
+ @stop_mutex = Mutex.new
end
# stops a running server
@@ -266,20 +274,23 @@ module GRPC
# server's current call loop is it's last.
def stop
return unless @running
- @stopped = true
+ @stop_mutex.synchronize do
+ @stopped = true
+ end
@pool.stop
+ @server.close
+ end
- # TODO: uncomment this:
- #
- # This segfaults in the c layer, so its commented out for now. Shutdown
- # still occurs, but the c layer has to do the cleanup.
- #
- # @server.close
+ # determines if the server has been stopped
+ def stopped?
+ @stop_mutex.synchronize do
+ return @stopped
+ end
end
# determines if the server is currently running
def running?
- @running ||= false
+ @running
end
# Is called from other threads to wait for #run to start up the server.
@@ -311,11 +322,6 @@ module GRPC
t.join
end
- # Determines if the server is currently stopped
- def stopped?
- @stopped ||= false
- end
-
# handle registration of classes
#
# service is either a class that includes GRPC::GenericService and whose
@@ -407,7 +413,13 @@ module GRPC
request_call_tag = Object.new
until stopped?
deadline = from_relative_time(@poll_period)
- an_rpc = @server.request_call(@cq, request_call_tag, deadline)
+ begin
+ an_rpc = @server.request_call(@cq, request_call_tag, deadline)
+ rescue Core::CallError, RuntimeError => e
+ # can happen during server shutdown
+ GRPC.logger.warn("server call failed: #{e}")
+ next
+ end
c = new_active_server_call(an_rpc)
unless c.nil?
mth = an_rpc.method.to_sym
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 072fb9b1aa..40b6df9a2b 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -29,5 +29,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '0.6.1'
+ VERSION = '0.9.0'
end
diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb
index aae3a7d7cb..b67008de48 100644
--- a/src/ruby/spec/generic/rpc_server_pool_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_pool_spec.rb
@@ -74,11 +74,11 @@ describe GRPC::Pool do
end
describe '#schedule' do
- it 'throws if the pool is already stopped' do
+ it 'return if the pool is already stopped' do
p = Pool.new(1)
p.stop
job = proc {}
- expect { p.schedule(&job) }.to raise_error
+ expect { p.schedule(&job) }.to_not raise_error
end
it 'adds jobs that get run by the pool' do
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index 640b0f656c..e60a8b27c3 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -212,10 +212,14 @@ describe GRPC::RpcServer do
describe '#stopped?' do
before(:each) do
- opts = { a_channel_arg: 'an_arg', poll_period: 1 }
+ opts = { a_channel_arg: 'an_arg', poll_period: 1.5 }
@srv = RpcServer.new(**opts)
end
+ after(:each) do
+ @srv.stop
+ end
+
it 'starts out false' do
expect(@srv.stopped?).to be(false)
end
@@ -225,7 +229,7 @@ describe GRPC::RpcServer do
expect(@srv.stopped?).to be(false)
end
- it 'stays false after the server starts running' do
+ it 'stays false after the server starts running', server: true do
@srv.handle(EchoService)
t = Thread.new { @srv.run }
@srv.wait_till_running
@@ -234,7 +238,7 @@ describe GRPC::RpcServer do
t.join
end
- it 'is true after a running server is stopped' do
+ it 'is true after a running server is stopped', server: true do
@srv.handle(EchoService)
t = Thread.new { @srv.run }
@srv.wait_till_running
@@ -251,21 +255,22 @@ describe GRPC::RpcServer do
expect(r.running?).to be(false)
end
- it 'is false after run is called with no services registered' do
+ it 'is false if run is called with no services registered', server: true do
opts = {
a_channel_arg: 'an_arg',
- poll_period: 1,
+ poll_period: 2,
server_override: @server
}
r = RpcServer.new(**opts)
r.run
expect(r.running?).to be(false)
+ r.stop
end
it 'is true after run is called with a registered service' do
opts = {
a_channel_arg: 'an_arg',
- poll_period: 1,
+ poll_period: 2.5,
server_override: @server
}
r = RpcServer.new(**opts)
@@ -284,6 +289,10 @@ describe GRPC::RpcServer do
@srv = RpcServer.new(**@opts)
end
+ after(:each) do
+ @srv.stop
+ end
+
it 'raises if #run has already been called' do
@srv.handle(EchoService)
t = Thread.new { @srv.run }
@@ -335,6 +344,10 @@ describe GRPC::RpcServer do
@srv = RpcServer.new(**server_opts)
end
+ after(:each) do
+ @srv.stop
+ end
+
it 'should return NOT_FOUND status on unknown methods', server: true do
@srv.handle(EchoService)
t = Thread.new { @srv.run }
@@ -376,7 +389,7 @@ describe GRPC::RpcServer do
t.join
end
- it 'should receive metadata when a deadline is specified', server: true do
+ it 'should receive metadata if a deadline is specified', server: true do
service = SlowService.new
@srv.handle(service)
t = Thread.new { @srv.run }
@@ -445,11 +458,11 @@ describe GRPC::RpcServer do
it 'should handle multiple parallel requests', server: true do
@srv.handle(EchoService)
- Thread.new { @srv.run }
+ t = Thread.new { @srv.run }
@srv.wait_till_running
req, q = EchoMsg.new, Queue.new
n = 5 # arbitrary
- threads = []
+ threads = [t]
n.times do
threads << Thread.new do
stub = EchoStub.new(@host, **client_opts)
@@ -472,7 +485,7 @@ describe GRPC::RpcServer do
}
alt_srv = RpcServer.new(**opts)
alt_srv.handle(SlowService)
- Thread.new { alt_srv.run }
+ t = Thread.new { alt_srv.run }
alt_srv.wait_till_running
req = EchoMsg.new
n = 5 # arbitrary, use as many to ensure the server pool is exceeded
@@ -490,6 +503,7 @@ describe GRPC::RpcServer do
end
threads.each(&:join)
alt_srv.stop
+ t.join
expect(one_failed_as_unavailable).to be(true)
end
end
@@ -513,6 +527,10 @@ describe GRPC::RpcServer do
@srv = RpcServer.new(**server_opts)
end
+ after(:each) do
+ @srv.stop
+ end
+
it 'should send connect metadata to the client', server: true do
service = EchoService.new
@srv.handle(service)
@@ -545,6 +563,10 @@ describe GRPC::RpcServer do
@srv = RpcServer.new(**server_opts)
end
+ after(:each) do
+ @srv.stop
+ end
+
it 'should be added to BadStatus when requests fail', server: true do
service = FailingService.new
@srv.handle(service)