Merge pull request #6475 from grpc/release-0_14

Upmerge from 0.14.0
pull/6508/head
Nicolas Noble 9 years ago
commit fac1b4d220
  1. 32
      include/grpc/impl/codegen/port_platform.h
  2. 40
      setup.py
  3. 4
      src/compiler/csharp_generator.cc
  4. 16
      src/csharp/Grpc.Examples/MathGrpc.cs
  5. 4
      src/csharp/Grpc.HealthCheck/HealthGrpc.cs
  6. 8
      src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
  7. 24
      src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
  8. 36
      src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
  9. 114
      src/python/grpcio/precompiled.py
  10. 2
      src/ruby/ext/grpc/rb_grpc.c
  11. 70
      src/ruby/ext/grpc/rb_signal.c
  12. 39
      src/ruby/ext/grpc/rb_signal.h
  13. 3
      src/ruby/lib/grpc.rb
  14. 6
      src/ruby/lib/grpc/generic/active_call.rb
  15. 63
      src/ruby/lib/grpc/generic/rpc_server.rb
  16. 16
      src/ruby/lib/grpc/generic/service.rb
  17. 69
      src/ruby/lib/grpc/signals.rb
  18. 23
      src/ruby/spec/generic/rpc_server_spec.rb
  19. 69
      src/ruby/spec/generic/service_spec.rb
  20. 7
      test/distrib/python/run_distrib_test.sh
  21. 2
      tools/distrib/python/grpcio_tools/MANIFEST.in
  22. 128
      tools/distrib/python/grpcio_tools/README.rst
  23. 0
      tools/distrib/python/grpcio_tools/grpc/tools/__init__.py
  24. 2
      tools/distrib/python/grpcio_tools/grpc/tools/main.cc
  25. 0
      tools/distrib/python/grpcio_tools/grpc/tools/main.h
  26. 2
      tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
  27. 2
      tools/distrib/python/grpcio_tools/grpc/tools/protoc_compiler.pyx
  28. 22
      tools/distrib/python/grpcio_tools/setup.py
  29. 32
      tools/run_tests/artifact_targets.py
  30. 6
      tools/run_tests/build_artifact_node.bat
  31. 2
      tools/run_tests/build_artifact_node.sh
  32. 22
      tools/run_tests/build_artifact_python.bat
  33. 6
      tools/run_tests/build_artifact_python.sh

@ -114,6 +114,38 @@
#define GPR_WIN32_ATOMIC 1 #define GPR_WIN32_ATOMIC 1
#define GPR_MSVC_TLS 1 #define GPR_MSVC_TLS 1
#endif #endif
#elif defined(GPR_MANYLINUX1)
// TODO(atash): manylinux1 is just another __linux__ but with ancient
// libraries; it should be integrated with the `__linux__` definitions below.
#define GPR_PLATFORM_STRING "manylinux"
#define GPR_POSIX_CRASH_HANDLER 1
#define GPR_CPU_LINUX 1
#define GPR_GCC_ATOMIC 1
#define GPR_GCC_TLS 1
#define GPR_LINUX 1
#define GPR_LINUX_LOG 1
#define GPR_POSIX_SOCKET 1
#define GPR_POSIX_WAKEUP_FD 1
#define GPR_POSIX_SOCKETADDR 1
#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
#define GPR_POSIX_SOCKETUTILS 1
#define GPR_HAVE_UNIX_SOCKET 1
#define GPR_HAVE_IP_PKTINFO 1
#define GPR_HAVE_IPV6_RECVPKTINFO 1
#define GPR_LINUX_ENV 1
#define GPR_POSIX_FILE 1
#define GPR_POSIX_TMPFILE 1
#define GPR_POSIX_STRING 1
#define GPR_POSIX_SUBPROCESS 1
#define GPR_POSIX_SYNC 1
#define GPR_POSIX_TIME 1
#define GPR_GETPID_IN_UNISTD_H 1
#define GPR_HAVE_MSG_NOSIGNAL 1
#ifdef _LP64
#define GPR_ARCH_64 1
#else /* _LP64 */
#define GPR_ARCH_32 1
#endif /* _LP64 */
#elif defined(ANDROID) || defined(__ANDROID__) #elif defined(ANDROID) || defined(__ANDROID__)
#define GPR_PLATFORM_STRING "android" #define GPR_PLATFORM_STRING "android"
#define GPR_ANDROID 1 #define GPR_ANDROID 1

@ -54,7 +54,6 @@ sys.path.insert(0, os.path.abspath(PYTHON_STEM))
# Break import-style to ensure we can actually find our in-repo dependencies. # Break import-style to ensure we can actually find our in-repo dependencies.
import commands import commands
import precompiled
import grpc_core_dependencies import grpc_core_dependencies
import grpc_version import grpc_version
@ -173,7 +172,6 @@ COMMAND_CLASS = {
'build_project_metadata': commands.BuildProjectMetadata, 'build_project_metadata': commands.BuildProjectMetadata,
'build_py': commands.BuildPy, 'build_py': commands.BuildPy,
'build_ext': commands.BuildExt, 'build_ext': commands.BuildExt,
'build_tagged_ext': precompiled.BuildTaggedExt,
'gather': commands.Gather, 'gather': commands.Gather,
'run_interop': commands.RunInterop, 'run_interop': commands.RunInterop,
'test_lite': commands.TestLite 'test_lite': commands.TestLite
@ -229,25 +227,21 @@ else:
PACKAGES = setuptools.find_packages( PACKAGES = setuptools.find_packages(
PYTHON_STEM, exclude=['tests', 'tests.*']) PYTHON_STEM, exclude=['tests', 'tests.*'])
setup_arguments = { setuptools.setup(
'name': 'grpcio', name='grpcio',
'version': grpc_version.VERSION, version=grpc_version.VERSION,
'license': LICENSE, license=LICENSE,
'ext_modules': CYTHON_EXTENSION_MODULES, ext_modules=CYTHON_EXTENSION_MODULES,
'packages': list(PACKAGES), packages=list(PACKAGES),
'package_dir': PACKAGE_DIRECTORIES, package_dir=PACKAGE_DIRECTORIES,
# TODO(atash): Figure out why auditwheel doesn't like namespace packages. # TODO(atash): Figure out why auditwheel doesn't like namespace packages.
#'namespace_packages': ['grpc'], #namespace_packages=['grpc'],
'package_data': PACKAGE_DATA, package_data=PACKAGE_DATA,
'install_requires': INSTALL_REQUIRES, install_requires=INSTALL_REQUIRES,
'setup_requires': SETUP_REQUIRES, setup_requires=SETUP_REQUIRES,
'cmdclass': COMMAND_CLASS, cmdclass=COMMAND_CLASS,
'tests_require': TESTS_REQUIRE, tests_require=TESTS_REQUIRE,
'test_suite': TEST_SUITE, test_suite=TEST_SUITE,
'test_loader': TEST_LOADER, test_loader=TEST_LOADER,
'test_runner': TEST_RUNNER, test_runner=TEST_RUNNER,
} )
precompiled.update_setup_arguments(setup_arguments)
setuptools.setup(**setup_arguments)

@ -214,10 +214,10 @@ std::string GetMethodReturnTypeServer(const MethodDescriptor *method) {
switch (GetMethodType(method)) { switch (GetMethodType(method)) {
case METHODTYPE_NO_STREAMING: case METHODTYPE_NO_STREAMING:
case METHODTYPE_CLIENT_STREAMING: case METHODTYPE_CLIENT_STREAMING:
return "Task<" + GetClassName(method->output_type()) + ">"; return "global::System.Threading.Tasks.Task<" + GetClassName(method->output_type()) + ">";
case METHODTYPE_SERVER_STREAMING: case METHODTYPE_SERVER_STREAMING:
case METHODTYPE_BIDI_STREAMING: case METHODTYPE_BIDI_STREAMING:
return "Task"; return "global::System.Threading.Tasks.Task";
} }
GOOGLE_LOG(FATAL)<< "Can't get here."; GOOGLE_LOG(FATAL)<< "Can't get here.";
return ""; return "";

@ -151,25 +151,25 @@ namespace Math {
/// Div divides args.dividend by args.divisor and returns the quotient and /// Div divides args.dividend by args.divisor and returns the quotient and
/// remainder. /// remainder.
/// </summary> /// </summary>
Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context);
/// <summary> /// <summary>
/// DivMany accepts an arbitrary number of division args from the client stream /// DivMany accepts an arbitrary number of division args from the client stream
/// and sends back the results in the reply stream. The stream continues until /// and sends back the results in the reply stream. The stream continues until
/// the client closes its end; the server does the same after sending all the /// the client closes its end; the server does the same after sending all the
/// replies. The stream ends immediately if either end aborts. /// replies. The stream ends immediately if either end aborts.
/// </summary> /// </summary>
Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context);
/// <summary> /// <summary>
/// Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib /// Fib generates numbers in the Fibonacci sequence. If args.limit > 0, Fib
/// generates up to limit numbers; otherwise it continues until the call is /// generates up to limit numbers; otherwise it continues until the call is
/// canceled. Unlike Fib above, Fib has no final FibReply. /// canceled. Unlike Fib above, Fib has no final FibReply.
/// </summary> /// </summary>
Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context);
/// <summary> /// <summary>
/// Sum sums a stream of numbers, returning the final result once the stream /// Sum sums a stream of numbers, returning the final result once the stream
/// is closed. /// is closed.
/// </summary> /// </summary>
Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context); global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of Math</summary> /// <summary>Base class for server-side implementations of Math</summary>
@ -179,7 +179,7 @@ namespace Math {
/// Div divides args.dividend by args.divisor and returns the quotient and /// Div divides args.dividend by args.divisor and returns the quotient and
/// remainder. /// remainder.
/// </summary> /// </summary>
public virtual Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -190,7 +190,7 @@ namespace Math {
/// the client closes its end; the server does the same after sending all the /// the client closes its end; the server does the same after sending all the
/// replies. The stream ends immediately if either end aborts. /// replies. The stream ends immediately if either end aborts.
/// </summary> /// </summary>
public virtual Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -200,7 +200,7 @@ namespace Math {
/// generates up to limit numbers; otherwise it continues until the call is /// generates up to limit numbers; otherwise it continues until the call is
/// canceled. Unlike Fib above, Fib has no final FibReply. /// canceled. Unlike Fib above, Fib has no final FibReply.
/// </summary> /// </summary>
public virtual Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -209,7 +209,7 @@ namespace Math {
/// Sum sums a stream of numbers, returning the final result once the stream /// Sum sums a stream of numbers, returning the final result once the stream
/// is closed. /// is closed.
/// </summary> /// </summary>
public virtual Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }

@ -72,13 +72,13 @@ namespace Grpc.Health.V1 {
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")] [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IHealth public interface IHealth
{ {
Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of Health</summary> /// <summary>Base class for server-side implementations of Health</summary>
public abstract class HealthBase public abstract class HealthBase
{ {
public virtual Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }

@ -112,11 +112,11 @@ namespace Grpc.Testing {
/// Returns the values of all the gauges that are currently being maintained by /// Returns the values of all the gauges that are currently being maintained by
/// the service /// the service
/// </summary> /// </summary>
Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context);
/// <summary> /// <summary>
/// Returns the value of one gauge /// Returns the value of one gauge
/// </summary> /// </summary>
Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of MetricsService</summary> /// <summary>Base class for server-side implementations of MetricsService</summary>
@ -126,7 +126,7 @@ namespace Grpc.Testing {
/// Returns the values of all the gauges that are currently being maintained by /// Returns the values of all the gauges that are currently being maintained by
/// the service /// the service
/// </summary> /// </summary>
public virtual Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -134,7 +134,7 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// Returns the value of one gauge /// Returns the value of one gauge
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }

@ -111,12 +111,12 @@ namespace Grpc.Testing {
/// One request followed by one response. /// One request followed by one response.
/// The server returns the client payload as-is. /// The server returns the client payload as-is.
/// </summary> /// </summary>
Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
/// <summary> /// <summary>
/// One request followed by one response. /// One request followed by one response.
/// The server returns the client payload as-is. /// The server returns the client payload as-is.
/// </summary> /// </summary>
Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of BenchmarkService</summary> /// <summary>Base class for server-side implementations of BenchmarkService</summary>
@ -126,7 +126,7 @@ namespace Grpc.Testing {
/// One request followed by one response. /// One request followed by one response.
/// The server returns the client payload as-is. /// The server returns the client payload as-is.
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -135,7 +135,7 @@ namespace Grpc.Testing {
/// One request followed by one response. /// One request followed by one response.
/// The server returns the client payload as-is. /// The server returns the client payload as-is.
/// </summary> /// </summary>
public virtual Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -375,7 +375,7 @@ namespace Grpc.Testing {
/// and once the shutdown has finished, the OK status is sent to terminate /// and once the shutdown has finished, the OK status is sent to terminate
/// this RPC. /// this RPC.
/// </summary> /// </summary>
Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context);
/// <summary> /// <summary>
/// Start client with specified workload. /// Start client with specified workload.
/// First request sent specifies the ClientConfig followed by ClientStatus /// First request sent specifies the ClientConfig followed by ClientStatus
@ -384,15 +384,15 @@ namespace Grpc.Testing {
/// and once the shutdown has finished, the OK status is sent to terminate /// and once the shutdown has finished, the OK status is sent to terminate
/// this RPC. /// this RPC.
/// </summary> /// </summary>
Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context);
/// <summary> /// <summary>
/// Just return the core count - unary call /// Just return the core count - unary call
/// </summary> /// </summary>
Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context);
/// <summary> /// <summary>
/// Quit this worker /// Quit this worker
/// </summary> /// </summary>
Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of WorkerService</summary> /// <summary>Base class for server-side implementations of WorkerService</summary>
@ -406,7 +406,7 @@ namespace Grpc.Testing {
/// and once the shutdown has finished, the OK status is sent to terminate /// and once the shutdown has finished, the OK status is sent to terminate
/// this RPC. /// this RPC.
/// </summary> /// </summary>
public virtual Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -419,7 +419,7 @@ namespace Grpc.Testing {
/// and once the shutdown has finished, the OK status is sent to terminate /// and once the shutdown has finished, the OK status is sent to terminate
/// this RPC. /// this RPC.
/// </summary> /// </summary>
public virtual Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -427,7 +427,7 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// Just return the core count - unary call /// Just return the core count - unary call
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -435,7 +435,7 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// Quit this worker /// Quit this worker
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }

@ -196,34 +196,34 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// One empty request followed by one empty response. /// One empty request followed by one empty response.
/// </summary> /// </summary>
Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context);
/// <summary> /// <summary>
/// One request followed by one response. /// One request followed by one response.
/// </summary> /// </summary>
Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
/// <summary> /// <summary>
/// One request followed by a sequence of responses (streamed download). /// One request followed by a sequence of responses (streamed download).
/// The server returns the payload with client desired type and sizes. /// The server returns the payload with client desired type and sizes.
/// </summary> /// </summary>
Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
/// <summary> /// <summary>
/// A sequence of requests followed by one response (streamed upload). /// A sequence of requests followed by one response (streamed upload).
/// The server returns the aggregated size of client payload as the result. /// The server returns the aggregated size of client payload as the result.
/// </summary> /// </summary>
Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context);
/// <summary> /// <summary>
/// A sequence of requests with each request served by the server immediately. /// A sequence of requests with each request served by the server immediately.
/// As one request could lead to multiple responses, this interface /// As one request could lead to multiple responses, this interface
/// demonstrates the idea of full duplexing. /// demonstrates the idea of full duplexing.
/// </summary> /// </summary>
Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
/// <summary> /// <summary>
/// A sequence of requests followed by a sequence of responses. /// A sequence of requests followed by a sequence of responses.
/// The server buffers all the client requests and then serves them in order. A /// The server buffers all the client requests and then serves them in order. A
/// stream of responses are returned to the client when the server starts with /// stream of responses are returned to the client when the server starts with
/// first request. /// first request.
/// </summary> /// </summary>
Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context); global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of TestService</summary> /// <summary>Base class for server-side implementations of TestService</summary>
@ -232,7 +232,7 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// One empty request followed by one empty response. /// One empty request followed by one empty response.
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -240,7 +240,7 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// One request followed by one response. /// One request followed by one response.
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -249,7 +249,7 @@ namespace Grpc.Testing {
/// One request followed by a sequence of responses (streamed download). /// One request followed by a sequence of responses (streamed download).
/// The server returns the payload with client desired type and sizes. /// The server returns the payload with client desired type and sizes.
/// </summary> /// </summary>
public virtual Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -258,7 +258,7 @@ namespace Grpc.Testing {
/// A sequence of requests followed by one response (streamed upload). /// A sequence of requests followed by one response (streamed upload).
/// The server returns the aggregated size of client payload as the result. /// The server returns the aggregated size of client payload as the result.
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -268,7 +268,7 @@ namespace Grpc.Testing {
/// As one request could lead to multiple responses, this interface /// As one request could lead to multiple responses, this interface
/// demonstrates the idea of full duplexing. /// demonstrates the idea of full duplexing.
/// </summary> /// </summary>
public virtual Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -279,7 +279,7 @@ namespace Grpc.Testing {
/// stream of responses are returned to the client when the server starts with /// stream of responses are returned to the client when the server starts with
/// first request. /// first request.
/// </summary> /// </summary>
public virtual Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context) public virtual global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -525,7 +525,7 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// A call that no server should implement /// A call that no server should implement
/// </summary> /// </summary>
Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of UnimplementedService</summary> /// <summary>Base class for server-side implementations of UnimplementedService</summary>
@ -534,7 +534,7 @@ namespace Grpc.Testing {
/// <summary> /// <summary>
/// A call that no server should implement /// A call that no server should implement
/// </summary> /// </summary>
public virtual Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
@ -669,19 +669,19 @@ namespace Grpc.Testing {
[System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")] [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
public interface IReconnectService public interface IReconnectService
{ {
Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context);
Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context); global::System.Threading.Tasks.Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context);
} }
/// <summary>Base class for server-side implementations of ReconnectService</summary> /// <summary>Base class for server-side implementations of ReconnectService</summary>
public abstract class ReconnectServiceBase public abstract class ReconnectServiceBase
{ {
public virtual Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }
public virtual Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context) public virtual global::System.Threading.Tasks.Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context)
{ {
throw new RpcException(new Status(StatusCode.Unimplemented, "")); throw new RpcException(new Status(StatusCode.Unimplemented, ""));
} }

@ -1,114 +0,0 @@
# 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.
import os
import platform
import shutil
import sys
import sysconfig
import setuptools
import commands
import grpc_version
try:
from urllib2 import urlopen
except ImportError:
from urllib.request import urlopen
PYTHON_STEM = os.path.dirname(os.path.abspath(__file__))
BINARIES_REPOSITORY = os.environ.get(
'GRPC_PYTHON_BINARIES_REPOSITORY',
'https://storage.googleapis.com/grpc-precompiled-binaries/python')
USE_PRECOMPILED_BINARIES = bool(int(os.environ.get(
'GRPC_PYTHON_USE_PRECOMPILED_BINARIES', '1')))
def _tagged_ext_name(base):
uname = platform.uname()
tags = (
grpc_version.VERSION,
'py{}'.format(sysconfig.get_python_version()),
uname[0],
uname[4],
)
ucs = 'ucs{}'.format(sysconfig.get_config_var('Py_UNICODE_SIZE'))
return '{base}-{tags}-{ucs}'.format(
base=base, tags='-'.join(tags), ucs=ucs)
class BuildTaggedExt(setuptools.Command):
description = 'build the gRPC tagged extensions'
user_options = []
def initialize_options(self):
# distutils requires this override.
pass
def finalize_options(self):
# distutils requires this override.
pass
def run(self):
if 'linux' in sys.platform:
self.run_command('build_ext')
try:
os.makedirs('dist/')
except OSError:
pass
shutil.copyfile(
os.path.join(PYTHON_STEM, 'grpc/_cython/cygrpc.so'),
'dist/{}.so'.format(_tagged_ext_name('cygrpc')))
else:
sys.stderr.write('nothing to do for build_tagged_ext\n')
def update_setup_arguments(setup_arguments):
if not USE_PRECOMPILED_BINARIES:
sys.stderr.write('not using precompiled extension')
return
url = '{}/{}.so'.format(BINARIES_REPOSITORY, _tagged_ext_name('cygrpc'))
target_path = os.path.join(PYTHON_STEM, 'grpc/_cython/cygrpc.so')
try:
extension = urlopen(url).read()
except:
sys.stderr.write(
'could not download precompiled extension: {}\n'.format(url))
return
try:
with open(target_path, 'w') as target:
target.write(extension)
setup_arguments['ext_modules'] = []
except:
sys.stderr.write(
'could not write precompiled extension to directory: {} -> {}\n'
.format(url, target_path))
return
setup_arguments['package_data']['grpc._cython'].append('cygrpc.so')

@ -50,6 +50,7 @@
#include "rb_loader.h" #include "rb_loader.h"
#include "rb_server.h" #include "rb_server.h"
#include "rb_server_credentials.h" #include "rb_server_credentials.h"
#include "rb_signal.h"
static VALUE grpc_rb_cTimeVal = Qnil; static VALUE grpc_rb_cTimeVal = Qnil;
@ -332,6 +333,7 @@ void Init_grpc_c() {
Init_grpc_channel_credentials(); Init_grpc_channel_credentials();
Init_grpc_server(); Init_grpc_server();
Init_grpc_server_credentials(); Init_grpc_server_credentials();
Init_grpc_signals();
Init_grpc_status_codes(); Init_grpc_status_codes();
Init_grpc_time_consts(); Init_grpc_time_consts();
} }

@ -0,0 +1,70 @@
/*
*
* Copyright 2016, 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 <ruby/ruby.h>
#include <signal.h>
#include <stdbool.h>
#include <grpc/support/log.h>
#include "rb_grpc.h"
static void (*old_sigint_handler)(int);
static void (*old_sigterm_handler)(int);
static volatile bool signal_received = false;
/* This has to be handled at the C level instead of Ruby, because Ruby signal
* handlers are constrained to run in the main interpreter thread. If that main
* thread is blocked on grpc_completion_queue_pluck, the signal handlers will
* never run */
static void handle_signal(int signum) {
signal_received = true;
if (signum == SIGINT) {
old_sigint_handler(signum);
} else if (signum == SIGTERM) {
old_sigterm_handler(signum);
}
}
static VALUE grpc_rb_signal_received(VALUE self) {
(void)self;
return signal_received ? Qtrue : Qfalse;
}
void Init_grpc_signals() {
old_sigint_handler = signal(SIGINT, handle_signal);
old_sigterm_handler = signal(SIGTERM, handle_signal);
rb_define_singleton_method(grpc_rb_mGrpcCore, "signal_received?",
grpc_rb_signal_received, 0);
}

@ -0,0 +1,39 @@
/*
*
* Copyright 2016, 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_RB_SIGNAL_H_
#define GRPC_RB_SIGNAL_H_
void Init_grpc_signals();
#endif /* GRPC_RB_SIGNAL_H_ */

@ -33,6 +33,7 @@ require_relative 'grpc/errors'
require_relative 'grpc/grpc' require_relative 'grpc/grpc'
require_relative 'grpc/logconfig' require_relative 'grpc/logconfig'
require_relative 'grpc/notifier' require_relative 'grpc/notifier'
require_relative 'grpc/signals'
require_relative 'grpc/version' require_relative 'grpc/version'
require_relative 'grpc/core/time_consts' require_relative 'grpc/core/time_consts'
require_relative 'grpc/generic/active_call' require_relative 'grpc/generic/active_call'
@ -47,3 +48,5 @@ begin
ensure ensure
file.close file.close
end end
GRPC::Signals.wait_for_signals

@ -28,7 +28,9 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require 'forwardable' require 'forwardable'
require 'weakref'
require_relative 'bidi_call' require_relative 'bidi_call'
require_relative '../signals'
class Struct class Struct
# BatchResult is the struct returned by calls to call#start_batch. # BatchResult is the struct returned by calls to call#start_batch.
@ -121,6 +123,10 @@ module GRPC
@unmarshal = unmarshal @unmarshal = unmarshal
@metadata_tag = metadata_tag @metadata_tag = metadata_tag
@op_notifier = nil @op_notifier = nil
weak_self = WeakRef.new(self)
remove_handler = GRPC::Signals.register_handler(&weak_self
.method(:cancel))
ObjectSpace.define_finalizer(self, remove_handler)
end end
# output_metadata are provides access to hash that can be used to # output_metadata are provides access to hash that can be used to

@ -28,46 +28,13 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require_relative '../grpc' require_relative '../grpc'
require_relative '../signals'
require_relative 'active_call' require_relative 'active_call'
require_relative 'service' require_relative 'service'
require 'thread' require 'thread'
# A global that contains signals the gRPC servers should respond to.
$grpc_signals = []
# GRPC contains the General RPC module. # GRPC contains the General RPC module.
module GRPC module GRPC
# Handles the signals in $grpc_signals.
#
# @return false if the server should exit, true if not.
def handle_signals
loop do
sig = $grpc_signals.shift
case sig
when 'INT'
return false
when 'TERM'
return false
when nil
return true
end
end
true
end
module_function :handle_signals
# Sets up a signal handler that adds signals to the signal handling global.
#
# Signal handlers should do as little as humanly possible.
# Here, they just add themselves to $grpc_signals
#
# RpcServer (and later other parts of gRPC) monitors the signals
# $grpc_signals in its own non-signal context.
def trap_signals
%w(INT TERM).each { |sig| trap(sig) { $grpc_signals << sig } }
end
module_function :trap_signals
# Pool is a simple thread pool. # Pool is a simple thread pool.
class Pool class Pool
# Default keep alive period is 1s # Default keep alive period is 1s
@ -328,23 +295,6 @@ module GRPC
end end
end end
# Runs the server in its own thread, then waits for signal INT or TERM on
# the current thread to terminate it.
def run_till_terminated
GRPC.trap_signals
t = Thread.new do
run
end
t.abort_on_exception = true
wait_till_running
until running_state == :stopped
sleep SIGNAL_CHECK_PERIOD
break unless GRPC.handle_signals
end
stop
t.join
end
# handle registration of classes # handle registration of classes
# #
# service is either a class that includes GRPC::GenericService and whose # service is either a class that includes GRPC::GenericService and whose
@ -403,9 +353,14 @@ module GRPC
transition_running_state(:running) transition_running_state(:running)
@run_cond.broadcast @run_cond.broadcast
end end
remove_signal_handler = GRPC::Signals.register_handler { stop }
loop_handle_server_calls loop_handle_server_calls
# Remove signal handler when server stops
remove_signal_handler.call
end end
alias_method :run_till_terminated, :run
# Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs # Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs
def available?(an_rpc) def available?(an_rpc)
jobs_count, max = @pool.jobs_waiting, @max_waiting_requests jobs_count, max = @pool.jobs_waiting, @max_waiting_requests
@ -503,10 +458,8 @@ module GRPC
unless cls.include?(GenericService) unless cls.include?(GenericService)
fail "#{cls} must 'include GenericService'" fail "#{cls} must 'include GenericService'"
end end
if cls.rpc_descs.size.zero? fail "#{cls} should specify some rpc descriptions" if
fail "#{cls} should specify some rpc descriptions" cls.rpc_descs.size.zero?
end
cls.assert_rpc_descs_have_methods
end end
# This should be called while holding @run_mutex # This should be called while holding @run_mutex

@ -110,6 +110,9 @@ module GRPC
rpc_descs[name] = RpcDesc.new(name, input, output, rpc_descs[name] = RpcDesc.new(name, input, output,
marshal_class_method, marshal_class_method,
unmarshal_class_method) unmarshal_class_method)
define_method(name) do
fail GRPC::BadStatus, GRPC::Core::StatusCodes::UNIMPLEMENTED
end
end end
def inherited(subclass) def inherited(subclass)
@ -199,19 +202,6 @@ module GRPC
end end
end end
end end
# Asserts that the appropriate methods are defined for each added rpc
# spec. Is intended to aid verifying that server classes are correctly
# implemented.
def assert_rpc_descs_have_methods
rpc_descs.each_pair do |m, spec|
mth_name = GenericService.underscore(m.to_s).to_sym
unless instance_methods.include?(mth_name)
fail "#{self} does not provide instance method '#{mth_name}'"
end
spec.assert_arity_matches(instance_method(mth_name))
end
end
end end
def self.included(o) def self.included(o)

@ -0,0 +1,69 @@
# Copyright 2016, 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.
require 'thread'
require_relative 'grpc'
# GRPC contains the General RPC module.
module GRPC
# Signals contains gRPC functions related to signal handling
module Signals
@interpreter_exiting = false
@signal_handlers = []
@handlers_mutex = Mutex.new
def register_handler(&handler)
@handlers_mutex.synchronize do
@signal_handlers.push(handler)
handler.call if @exit_signal_received
end
# Returns a function to remove the handler
lambda do
@handlers_mutex.synchronize { @signal_handlers.delete(handler) }
end
end
module_function :register_handler
def wait_for_signals
t = Thread.new do
sleep 0.1 until GRPC::Core.signal_received? || @interpreter_exiting
unless @interpreter_exiting
@handlers_mutex.synchronize do
@signal_handlers.each(&:call)
end
end
end
at_exit do
@interpreter_exiting = true
t.join
end
end
module_function :wait_for_signals
end
end

@ -308,10 +308,6 @@ describe GRPC::RpcServer do
expect { @srv.handle(EmptyService) }.to raise_error expect { @srv.handle(EmptyService) }.to raise_error
end end
it 'raises if the service does not define its rpc methods' do
expect { @srv.handle(NoRpcImplementation) }.to raise_error
end
it 'raises if a handler method is already registered' do it 'raises if a handler method is already registered' do
@srv.handle(EchoService) @srv.handle(EchoService)
expect { r.handle(EchoService) }.to raise_error expect { r.handle(EchoService) }.to raise_error
@ -349,6 +345,25 @@ describe GRPC::RpcServer do
t.join t.join
end end
it 'should return UNIMPLEMENTED on unimplemented methods', server: true do
@srv.handle(NoRpcImplementation)
t = Thread.new { @srv.run }
@srv.wait_till_running
req = EchoMsg.new
blk = proc do
cq = GRPC::Core::CompletionQueue.new
stub = GRPC::ClientStub.new(@host, cq, :this_channel_is_insecure,
**client_opts)
stub.request_response('/an_rpc', req, marshal, unmarshal)
end
expect(&blk).to raise_error do |error|
expect(error).to be_a(GRPC::BadStatus)
expect(error.code).to be(GRPC::Core::StatusCodes::UNIMPLEMENTED)
end
@srv.stop
t.join
end
it 'should handle multiple sequential requests', server: true do it 'should handle multiple sequential requests', server: true do
@srv.handle(EchoService) @srv.handle(EchoService)
t = Thread.new { @srv.run } t = Thread.new { @srv.run }

@ -273,73 +273,4 @@ describe GenericService do
end end
end end
end end
describe '#assert_rpc_descs_have_methods' do
it 'fails if there is no instance method for an rpc descriptor' do
c1 = Class.new do
include GenericService
rpc :AnRpc, GoodMsg, GoodMsg
end
expect { c1.assert_rpc_descs_have_methods }.to raise_error
c2 = Class.new do
include GenericService
rpc :AnRpc, GoodMsg, GoodMsg
rpc :AnotherRpc, GoodMsg, GoodMsg
def an_rpc
end
end
expect { c2.assert_rpc_descs_have_methods }.to raise_error
end
it 'passes if there are corresponding methods for each descriptor' do
c = Class.new do
include GenericService
rpc :AnRpc, GoodMsg, GoodMsg
rpc :AServerStreamer, GoodMsg, stream(GoodMsg)
rpc :AClientStreamer, stream(GoodMsg), GoodMsg
rpc :ABidiStreamer, stream(GoodMsg), stream(GoodMsg)
def an_rpc(_req, _call)
end
def a_server_streamer(_req, _call)
end
def a_client_streamer(_call)
end
def a_bidi_streamer(_call)
end
end
expect { c.assert_rpc_descs_have_methods }.to_not raise_error
end
it 'passes for subclasses of that include GenericService' do
base = Class.new do
include GenericService
rpc :AnRpc, GoodMsg, GoodMsg
def an_rpc(_req, _call)
end
end
c = Class.new(base)
expect { c.assert_rpc_descs_have_methods }.to_not raise_error
expect(c.include?(GenericService)).to be(true)
end
it 'passes if subclasses define the rpc methods' do
base = Class.new do
include GenericService
rpc :AnRpc, GoodMsg, GoodMsg
end
c = Class.new(base) do
def an_rpc(_req, _call)
end
end
expect { c.assert_rpc_descs_have_methods }.to_not raise_error
expect(c.include?(GenericService)).to be(true)
end
end
end end

@ -48,7 +48,10 @@ which $PYTHON || PYTHON=python
which $PIP || PIP=pip which $PIP || PIP=pip
# TODO(jtattermusch): this shouldn't be required # TODO(jtattermusch): this shouldn't be required
${PIP} install --upgrade six pip # TODO(jtattermusch): run the command twice to workaround docker-on-overlay
# issue https://github.com/docker/docker/issues/12327
# (first attempt will fail when using docker with overlayFS)
${PIP} install --upgrade six pip || ${PIP} install --upgrade six pip
# At least one of the bdist packages has to succeed (whichever one matches the # At least one of the bdist packages has to succeed (whichever one matches the
# test machine, anyway). # test machine, anyway).
@ -58,6 +61,6 @@ done
# TODO(jtattermusch): add a .proto file to the distribtest, generate python # TODO(jtattermusch): add a .proto file to the distribtest, generate python
# code from it and then use the generated code from distribtest.py # code from it and then use the generated code from distribtest.py
$PYTHON -m grpc.protoc.compiler $PYTHON -m grpc.tools.protoc
$PYTHON distribtest.py $PYTHON distribtest.py

@ -1,5 +1,7 @@
include grpc_version.py
include protoc_deps.py include protoc_deps.py
include protoc_lib_deps.py include protoc_lib_deps.py
include README.rst
graft grpc graft grpc
graft grpc_root graft grpc_root
graft third_party graft third_party

@ -0,0 +1,128 @@
gRPC Python Tools
=================
Package for gRPC Python tools.
Installation
------------
The gRPC Python tools package is available for Linux, Mac OS X, and Windows
running Python 2.7.
From PyPI
~~~~~~~~~
If you are installing locally...
::
$ pip install grpcio-tools
Else system wide (on Ubuntu)...
::
$ sudo pip install grpcio-tools
If you're on Windows make sure that you installed the :code:`pip.exe` component
when you installed Python (if not go back and install it!) then invoke:
::
$ pip.exe install grpcio-tools
Windows users may need to invoke :code:`pip.exe` from a command line ran as
administrator.
n.b. On Windows and on Mac OS X one *must* have a recent release of :code:`pip`
to retrieve the proper wheel from PyPI. Be sure to upgrade to the latest
version!
You might also need to install Cython to handle installation via the source
distribution if gRPC Python's system coverage with wheels does not happen to
include your system.
From Source
~~~~~~~~~~~
Building from source requires that you have the Python headers (usually a
package named :code:`python-dev`) and Cython installed. It further requires a
GCC-like compiler to go smoothly; you can probably get it to work without
GCC-like stuff, but you may end up having a bad time.
::
$ export REPO_ROOT=grpc # REPO_ROOT can be any directory of your choice
$ git clone https://github.com/grpc/grpc.git $REPO_ROOT
$ cd $REPO_ROOT
$ git submodule update --init
$ cd tools/distrib/python/grpcio_tools
$ python ../make_grpcio_tools.py
# For the next command do `sudo pip install` if you get permission-denied errors
$ pip install .
You cannot currently install Python from source on Windows. Things might work
out for you in MSYS2 (follow the Linux instructions), but it isn't officially
supported at the moment.
Troubleshooting
~~~~~~~~~~~~~~~
Help, I ...
* **... see a** :code:`pkg_resources.VersionConflict` **when I try to install
grpc**
This is likely because :code:`pip` doesn't own the offending dependency,
which in turn is likely because your operating system's package manager owns
it. You'll need to force the installation of the dependency:
:code:`pip install --ignore-installed $OFFENDING_DEPENDENCY`
For example, if you get an error like the following:
::
Traceback (most recent call last):
File "<string>", line 17, in <module>
...
File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 509, in find
raise VersionConflict(dist, req)
pkg_resources.VersionConflict: (six 1.8.0 (/usr/lib/python2.7/dist-packages), Requirement.parse('six>=1.10'))
You can fix it by doing:
::
sudo pip install --ignore-installed six
* **... see compiler errors on some platforms when either installing from source or from the source distribution**
If you see
::
/tmp/pip-build-U8pSsr/cython/Cython/Plex/Scanners.c:4:20: fatal error: Python.h: No such file or directory
#include "Python.h"
^
compilation terminated.
You can fix it by installing `python-dev` package. i.e
::
sudo apt-get install python-dev
If you see something similar to:
::
third_party/protobuf/src/google/protobuf/stubs/mathlimits.h:173:31: note: in expansion of macro 'SIGNED_INT_MAX'
static const Type kPosMax = SIGNED_INT_MAX(Type); \\
^
And your toolchain is GCC (at the time of this writing, up through at least
GCC 6.0), this is probably a bug where GCC chokes on constant expressions
when the :code:`-fwrapv` flag is specified. You should consider setting your
environment with :code:`CFLAGS=-fno-wrapv` or using clang (:code:`CC=clang`).

@ -32,7 +32,7 @@
#include "src/compiler/python_generator.h" #include "src/compiler/python_generator.h"
#include "grpc/protoc/main.h" #include "grpc/tools/main.h"
int protoc_main(int argc, char* argv[]) { int protoc_main(int argc, char* argv[]) {
google::protobuf::compiler::CommandLineInterface cli; google::protobuf::compiler::CommandLineInterface cli;

@ -31,7 +31,7 @@
import sys import sys
from grpc.protoc import protoc_compiler from grpc.tools import protoc_compiler
if __name__ == '__main__': if __name__ == '__main__':

@ -29,7 +29,7 @@
from libc cimport stdlib from libc cimport stdlib
cdef extern from "grpc/protoc/main.h": cdef extern from "grpc/tools/main.h":
int protoc_main(int argc, char *argv[]) int protoc_main(int argc, char *argv[])
def run_main(list args not None): def run_main(list args not None):

@ -30,6 +30,7 @@
from distutils import extension from distutils import extension
import os import os
import os.path import os.path
import shlex
import sys import sys
import setuptools import setuptools
@ -40,18 +41,28 @@ from setuptools.command import build_ext
os.chdir(os.path.dirname(os.path.abspath(__file__))) os.chdir(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, os.path.abspath('.'))
# There are some situations (like on Windows) where CC, CFLAGS, and LDFLAGS are
# entirely ignored/dropped/forgotten by distutils and its Cygwin/MinGW support.
# We use these environment variables to thus get around that without locking
# ourselves in w.r.t. the multitude of operating systems this ought to build on.
# By default we assume a GCC-like compiler.
EXTRA_COMPILE_ARGS = shlex.split(os.environ.get('GRPC_PYTHON_CFLAGS',
'-frtti -std=c++11'))
EXTRA_LINK_ARGS = shlex.split(os.environ.get('GRPC_PYTHON_LDFLAGS',
'-lpthread'))
import protoc_lib_deps import protoc_lib_deps
import grpc_version import grpc_version
def protoc_ext_module(): def protoc_ext_module():
plugin_sources = [ plugin_sources = [
'grpc/protoc/main.cc', 'grpc/tools/main.cc',
'grpc_root/src/compiler/python_generator.cc'] + [ 'grpc_root/src/compiler/python_generator.cc'] + [
os.path.join('third_party/protobuf/src', cc_file) os.path.join('third_party/protobuf/src', cc_file)
for cc_file in protoc_lib_deps.CC_FILES] for cc_file in protoc_lib_deps.CC_FILES]
plugin_ext = extension.Extension( plugin_ext = extension.Extension(
name='grpc.protoc.protoc_compiler', name='grpc.tools.protoc_compiler',
sources=['grpc/protoc/protoc_compiler.pyx'] + plugin_sources, sources=['grpc/tools/protoc_compiler.pyx'] + plugin_sources,
include_dirs=[ include_dirs=[
'.', '.',
'grpc_root', 'grpc_root',
@ -60,7 +71,8 @@ def protoc_ext_module():
], ],
language='c++', language='c++',
define_macros=[('HAVE_PTHREAD', 1)], define_macros=[('HAVE_PTHREAD', 1)],
extra_compile_args=['-lpthread', '-frtti', '-std=c++11'], extra_compile_args=EXTRA_COMPILE_ARGS,
extra_link_args=EXTRA_LINK_ARGS,
) )
return plugin_ext return plugin_ext
@ -71,7 +83,7 @@ def maybe_cythonize(exts):
setuptools.setup( setuptools.setup(
name='grpcio_tools', name='grpcio_tools',
version=grpc_version.VERSION, version=grpc_version.VERSION,
license='', license='3-clause BSD',
ext_modules=maybe_cythonize([ ext_modules=maybe_cythonize([
protoc_ext_module(), protoc_ext_module(),
]), ]),

@ -113,37 +113,7 @@ class PythonArtifact:
# defines ourselves. # defines ourselves.
# TODO(atash) get better platform-detection support in core so we don't # TODO(atash) get better platform-detection support in core so we don't
# need to do this manually... # need to do this manually...
environ['CFLAGS'] = " ".join([ environ['CFLAGS'] = '-DGPR_MANYLINUX1=1'
'-DGPR_NO_AUTODETECT_PLATFORM',
'-DGPR_PLATFORM_STRING=\\"manylinux\\"',
'-DGPR_POSIX_CRASH_HANDLER=1',
'-DGPR_CPU_LINUX=1',
'-DGPR_GCC_ATOMIC=1',
'-DGPR_GCC_TLS=1',
'-DGPR_LINUX=1',
'-DGPR_LINUX_LOG=1',
#'-DGPR_LINUX_MULTIPOLL_WITH_EPOLL=1',
'-DGPR_POSIX_SOCKET=1',
'-DGPR_POSIX_WAKEUP_FD=1',
'-DGPR_POSIX_SOCKETADDR=1',
#'-DGPR_LINUX_EVENTFD=1',
'-DGPR_POSIX_NO_SPECIAL_WAKEUP_FD=1',
#'-DGPR_LINUX_SOCKETUTILS=1',
'-DGPR_POSIX_SOCKETUTILS=1',
'-DGPR_HAVE_UNIX_SOCKET=1',
'-DGPR_HAVE_IP_PKTINFO=1',
'-DGPR_HAVE_IPV6_RECVPKTINFO=1',
'-DGPR_LINUX_ENV=1',
'-DGPR_POSIX_FILE=1',
'-DGPR_POSIX_TMPFILE=1',
'-DGPR_POSIX_STRING=1',
'-DGPR_POSIX_SUBPROCESS=1',
'-DGPR_POSIX_SYNC=1',
'-DGPR_POSIX_TIME=1',
'-DGPR_GETPID_IN_UNISTD_H=1',
'-DGPR_HAVE_MSG_NOSIGNAL=1',
'-DGPR_ARCH_{arch}=1'.format(arch=('32' if self.arch == 'x86' else '64')),
])
return create_docker_jobspec(self.name, return create_docker_jobspec(self.name,
'tools/dockerfile/grpc_artifact_python_manylinux_%s' % self.arch, 'tools/dockerfile/grpc_artifact_python_manylinux_%s' % self.arch,
'tools/run_tests/build_artifact_python.sh', 'tools/run_tests/build_artifact_python.sh',

@ -27,7 +27,7 @@
@rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE @rem (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
@rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. @rem OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 set node_versions=0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0
set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm set PATH=%PATH%;C:\Program Files\nodejs\;%APPDATA%\npm
@ -38,12 +38,12 @@ call npm update || goto :error
mkdir artifacts mkdir artifacts
for %%v in (%node_versions%) do ( for %%v in (%node_versions%) do (
call node-pre-gyp configure build --target=%%v --target_arch=%1 call .\node_modules\.bin\node-pre-gyp.cmd configure build --target=%%v --target_arch=%1
@rem Try again after removing openssl headers @rem Try again after removing openssl headers
rmdir "%HOMEDRIVE%%HOMEPATH%\.node-gyp\%%v\include\node\openssl" /S /Q rmdir "%HOMEDRIVE%%HOMEPATH%\.node-gyp\%%v\include\node\openssl" /S /Q
rmdir "%HOMEDRIVE%%HOMEPATH%\.node-gyp\iojs-%%v\include\node\openssl" /S /Q rmdir "%HOMEDRIVE%%HOMEPATH%\.node-gyp\iojs-%%v\include\node\openssl" /S /Q
call node-pre-gyp build package testpackage --target=%%v --target_arch=%1 || goto :error call .\node_modules\.bin\node-pre-gyp.cmd build package testpackage --target=%%v --target_arch=%1 || goto :error
xcopy /Y /I /S build\stage\* artifacts\ || goto :error xcopy /Y /I /S build\stage\* artifacts\ || goto :error
) )

@ -42,7 +42,7 @@ mkdir -p artifacts
npm update npm update
node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 ) node_versions=( 0.12.0 1.0.0 1.1.0 2.0.0 3.0.0 4.0.0 5.0.0 6.0.0 )
for version in ${node_versions[@]} for version in ${node_versions[@]}
do do

@ -41,7 +41,7 @@ copy /Y vsprojects\Release\grpc_dll.dll src\python\grpcio\grpc\_cython\_windows\
copy /Y vsprojects\x64\Release\grpc_dll.dll src\python\grpcio\grpc\_cython\_windows\grpc_c.64.python || goto :error copy /Y vsprojects\x64\Release\grpc_dll.dll src\python\grpcio\grpc\_cython\_windows\grpc_c.64.python || goto :error
set PATH=C:\%1;C:\%1\scripts;%PATH% set PATH=C:\%1;C:\%1\scripts;C:\msys64\mingw%2\bin;%PATH%
pip install --upgrade six pip install --upgrade six
pip install --upgrade setuptools pip install --upgrade setuptools
@ -50,12 +50,26 @@ pip install -rrequirements.txt
set GRPC_PYTHON_USE_CUSTOM_BDIST=0 set GRPC_PYTHON_USE_CUSTOM_BDIST=0
set GRPC_PYTHON_BUILD_WITH_CYTHON=1 set GRPC_PYTHON_BUILD_WITH_CYTHON=1
@rem TODO(atash): maybe we could avoid the grpc_c.(32|64).python shim above if
@rem this used the right python build?
python setup.py bdist_wheel python setup.py bdist_wheel
@rem Build gRPC Python tools @rem Build gRPC Python tools
set PATH=C:\msys64\mingw%2\bin;%PATH% @rem
set CC=C:\msys64\mingw%2\bin\g++.exe @rem Because this is windows and *everything seems to hate Windows* we have to
set CFLAGS=-fno-wrapv @rem set all of these flags ourselves because Python won't help us (see the
@rem setup.py of the grpcio_tools project).
set GRPC_PYTHON_CFLAGS=-fno-wrapv -frtti -std=c++11
@rem Further confusing things, MSYS2's mingw64 tries to dynamically link
@rem libgcc, libstdc++, and winpthreads. We have to override this or our
@rem extensions end up linking to MSYS2 DLLs, which the normal Python on
@rem Windows user won't have... and ON TOP OF THIS, there's MinGW's GCC default
@rem behavior of linking msvcrt.dll as the C runtime library, which we need to
@rem override so that Python's distutils doesn't link us against multiple C
@rem runtimes.
python -c "from distutils.cygwinccompiler import get_msvcr; print(get_msvcr()[0])" > temp.txt
set /p PYTHON_MSVCR=<temp.txt
set GRPC_PYTHON_LDFLAGS=-static-libgcc -static-libstdc++ -mcrtdll=%PYTHON_MSVCR% -static -lpthread
python tools\distrib\python\make_grpcio_tools.py python tools\distrib\python\make_grpcio_tools.py
if %2 == 32 ( if %2 == 32 (
python tools\distrib\python\grpcio_tools\setup.py build_ext -c mingw32 python tools\distrib\python\grpcio_tools\setup.py build_ext -c mingw32

@ -59,7 +59,11 @@ ${SETARCH_CMD} ${PYTHON} setup.py \
${SETARCH_CMD} ${PYTHON} setup.py \ ${SETARCH_CMD} ${PYTHON} setup.py \
bdist_wheel bdist_wheel
# Build gRPC tools package # Build gRPC tools package source distribution
${SETARCH_CMD} ${PYTHON} tools/distrib/python/grpcio_tools/setup.py \
sdist
# Build gRPC tools package binary distribution
${PYTHON} tools/distrib/python/make_grpcio_tools.py ${PYTHON} tools/distrib/python/make_grpcio_tools.py
CFLAGS="$CFLAGS -fno-wrapv" ${SETARCH_CMD} \ CFLAGS="$CFLAGS -fno-wrapv" ${SETARCH_CMD} \
${PYTHON} tools/distrib/python/grpcio_tools/setup.py bdist_wheel ${PYTHON} tools/distrib/python/grpcio_tools/setup.py bdist_wheel

Loading…
Cancel
Save