diff --git a/doc/workarounds.md b/doc/workarounds.md new file mode 100644 index 0000000000000000000000000000000000000000..bc511860f870a9483a3f9ccbc458f90cf63cce92 --- /dev/null +++ b/doc/workarounds.md @@ -0,0 +1,19 @@ +# gRPC Server Backward Compatibility Issues and Workarounds Manageent + +## Introduction +This document lists the workarounds implemented on gRPC servers for record and reference when users need to enable a certain workaround. + +## Workaround List + +### Cronet Compression + +**Workaround ID:** WORKAROUND\_ID\_CRONET\_COMPRESSION + +**Date added:** May 06, 2017 + +**Status:** Implemented in C core and C++ + +**Issue:** Before version v1.3.0-dev, gRPC iOS client's Cronet transport did not implement compression. However the clients still claim to support compression. As a result, a client fails to parse received message when the message is compressed. +The problem above was resolved in gRPC v1.3.0-dev. For backward compatibility, a server must forcingly disable compression for gRPC clients of version lower than or equal to v1.3.0-dev. + +**Workaround Description:** Implemented as a server channel filter in C core. The filter identifies the version of peer client with incoming `user-agent` header of each call. If the client's gRPC version is lower that or equal to v1.3.x, a flag GRPC_WRITE_NO_COMPRESS is marked for all send_message ops which prevents compression of the messages to be sent out. diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index 5a8577659ab098890cb3aabeb78c29901f3f97f3..2185b283ac20b304581a0f40ddfcbcab5fe13c55 100644 --- a/include/grpc++/server_builder.h +++ b/include/grpc++/server_builder.h @@ -46,6 +46,7 @@ #include <grpc/compression.h> #include <grpc/support/cpu.h> #include <grpc/support/useful.h> +#include <grpc/support/workaround_list.h> struct grpc_resource_quota; @@ -184,6 +185,11 @@ class ServerBuilder { static void InternalAddPluginFactory( std::unique_ptr<ServerBuilderPlugin> (*CreatePlugin)()); + /// Enable a server workaround. Do not use unless you know what the workaround + /// does. For explanation and detailed descriptions of workarounds, see + /// doc/workarounds.md. + ServerBuilder& EnableWorkaround(grpc_workaround_list id); + private: friend class ::grpc::testing::ServerBuilderPluginTest; diff --git a/include/grpc/support/workaround_list.h b/include/grpc/support/workaround_list.h index 6a8aa1f9550171bc421201d235ba7b0aee78e94c..ec4766510f3e6ccc927731532052567f97941959 100644 --- a/include/grpc/support/workaround_list.h +++ b/include/grpc/support/workaround_list.h @@ -36,7 +36,7 @@ /* The list of IDs of server workarounds currently maintained by gRPC. For * explanation and detailed descriptions of workarounds, see - * /docs/workarounds.md + * /doc/workarounds.md */ typedef enum { GRPC_WORKAROUND_ID_CRONET_COMPRESSION = 0, diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 2ead048a1ff14901c99d715229d20d6b4199d619..6dca6a6862cc3b46b1e225f987f0d043d0711b34 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -358,4 +358,14 @@ void ServerBuilder::InternalAddPluginFactory( (*g_plugin_factory_list).push_back(CreatePlugin); } +ServerBuilder& ServerBuilder::EnableWorkaround(grpc_workaround_list id) { + switch (id) { + case GRPC_WORKAROUND_ID_CRONET_COMPRESSION: + return AddChannelArgument(GRPC_ARG_WORKAROUND_CRONET_COMPRESSION, 1); + default: + gpr_log(GPR_ERROR, "Workaround %u does not exist or is obsolete.", id); + return *this; + } +} + } // namespace grpc diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index b7531bc276f3c65c2a03369d91351463cb5f4f02..b6f2857b391d26e8745fd00af4c3dda883d9c544 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -794,6 +794,7 @@ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/unit_testing.md \ doc/wait-for-ready.md \ +doc/workarounds.md \ include/grpc++/alarm.h \ include/grpc++/channel.h \ include/grpc++/client_context.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c8ebb0dbcae2a2c2be761d0f1c2cf61392b58c0a..5242172f96d967c15f28acd1d67c96d590c51ca9 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -794,6 +794,7 @@ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/unit_testing.md \ doc/wait-for-ready.md \ +doc/workarounds.md \ include/grpc++/alarm.h \ include/grpc++/channel.h \ include/grpc++/client_context.h \ diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core index 74e76bfce9c3907f3d828a6794e116028d82a5f3..c5ae421d40ceeedeb8576ba9c594c98bdf9e8958 100644 --- a/tools/doxygen/Doxyfile.core +++ b/tools/doxygen/Doxyfile.core @@ -794,6 +794,7 @@ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/unit_testing.md \ doc/wait-for-ready.md \ +doc/workarounds.md \ include/grpc/byte_buffer.h \ include/grpc/byte_buffer_reader.h \ include/grpc/census.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index d5eeebed32c68658381e08027a018d41ec42478d..eb0883b7971b63b1231e9d2488a187189c1a2814 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -794,6 +794,7 @@ doc/statuscodes.md \ doc/stress_test_framework.md \ doc/unit_testing.md \ doc/wait-for-ready.md \ +doc/workarounds.md \ include/grpc/byte_buffer.h \ include/grpc/byte_buffer_reader.h \ include/grpc/census.h \