You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
brpc is built on Protobuf Generic Services, which are deprecated #3287
As part of our overall efforts to reduce tech debt in our code, we would like to remove generic services from our code generator. These have been marked as deprecated since 2010, both in the docs and in several places in the code (descriptor.proto, service.h, service.py, etc.).
We noticed that bRPC is built on generic services. Because these APIs are exposed directly to your users, a sudden removal on our end would cause significant disruption to the bRPC ecosystem. We want to avoid that and work together to manage this transition as smoothly as possible.
To move forward, the sustainable path is for bRPC to transition to its own custom code generator (a protoc plugin) to generate these service APIs, rather than relying on the built-in generic services option in protoc. This is the standard approach modern RPC frameworks (like gRPC) use to generate their stubs.
We want to give your team ample runway to design, implement, and distribute this migration.
Timeline: We are targeting Q1 2028 to disable the xx_generic_services options (making them into no-ops). Prior to this, we will begin emitting warnings and possibly require that a special codegen flag be set to continue using generic services.
Our Support: We are happy to provide guidance on how to structure a custom generator plugin, share references from how other frameworks achieved this, or review migration designs to make this process easier for you.
Please let us know your thoughts on this timeline and how we can best support the Apache bRPC community during this transition.
Thanks for the heads-up and the offer to help with the migration. After surveying the codebase, here's the planned proposal.
Scope
39 .proto files in the repo enable cc_generic_services (7 in brpc's own builtin services, 23 in examples, 7 in tests, 1 in tools). We plan to migrate all of
them to a brpc-owned protoc plugin before xx_generic_services becomes a no-op.
Plan
New protoc-gen-brpc C++ plugin, modeled after the existing protoc-gen-mcpack plugin we already ship (src/mcpack2pb/generator.cpp). Single binary, standard PluginMain entry point.
Inject into the stock *.pb.h / *.pb.cc via OpenForInsert (namespace_scope for declarations, global_scope for definitions). This keeps #include "foo.pb.h" working unchanged — zero source-code changes
for users. Since the plugin is only active on protobuf versions where cc_generic_services is already a no-op, there's no risk of duplicate-symbol collisions with the legacy stubs.
Generated output is source-compatible with what cc_generic_services produces today: same class names, same namespaces, same virtual signatures, same _Stub(RpcChannel*) constructor. We're aiming for
source-level compatibility only — old/new outputs never coexist in the same binary, so byte-level ABI alignment isn't required.
No dependency on protobuf private symbols. Instead of internal::AssignDescriptors + descriptor_table_xxx + file_level_service_descriptors_xxx, we resolve descriptors via the public
DescriptorPool::generated_pool()->FindServiceByName(...) API, cached at module-init time into file-scope pointers — runtime cost is a single load, no call_once check on the hot path.
Misuse detection — to catch users who forget to remove option cc_generic_services from their .proto or forget to wire the plugin into their build:
- Compile-time: generated classes embed a BrpcGeneratedTag typedef; Server::AddService does a static_assert on it.
- Runtime: each generated service registers its full name in a global set at static init; AddServiceInternal rejects services not produced by the plugin, with an actionable error message.
- Hand-written google::protobuf::Service subclasses (we have one — BaiduMasterService) can declare the tag manually or go through an AddServiceUnchecked escape hatch.
@haberman I would be grateful for any feedback or suggestions you may have on my proposal.
Really appreciate your productive reply here; I'll stress the context is basically that some of these features were ~never used for Google's direct business needs. They've been on life support forever since we want to support people in the community who adopt them and not pull the rug out on people, but for some of these things the ongoing toil starts to look dubious on some time horizon (toil tends to be low level but sometimes spurty in cost when they intersect poorly with something else that we're touching).
Protobuf unfortunately under-communicated that that certain things were considered regretted so many good faith open source projects couldn't have reasonably known sooner about some of these dark corners being considered dark corners.
Unfortunately the insertion point capability that you pointed to are also somewhat of a dubious/regretted feature as well. We're not touching it immediately but it also is forseeably a future conversation which looks pretty similar to this one, so I think if brpc has to move it would be best if we could get y'all onto something that is fully green today instead.
In general our main RPC systems including gRPC and Stubby (which is internal to Google and predates gRPC) more follow the path that Josh was describing and have the service code be wholly separate from the gencode that protoc generators would emit, and create service classes which don't extend any base classes which are part of the protobuf library.
Do you think there's a viable path there that would still minimize breakages for your users? Or perhaps there's incremental steps of insertion points to try to smooth a transition but where it gets off after that?
Activity
chenBright commentedon May 27, 2026
Thanks for the heads-up and the offer to help with the migration. After surveying the codebase, here's the planned proposal.
Scope
39 .proto files in the repo enable cc_generic_services (7 in brpc's own builtin services, 23 in examples, 7 in tests, 1 in tools). We plan to migrate all of
them to a brpc-owned protoc plugin before xx_generic_services becomes a no-op.
Plan
for users. Since the plugin is only active on protobuf versions where cc_generic_services is already a no-op, there's no risk of duplicate-symbol collisions with the legacy stubs.
source-level compatibility only — old/new outputs never coexist in the same binary, so byte-level ABI alignment isn't required.
DescriptorPool::generated_pool()->FindServiceByName(...) API, cached at module-init time into file-scope pointers — runtime cost is a single load, no call_once check on the hot path.
- Compile-time: generated classes embed a BrpcGeneratedTag typedef; Server::AddService does a static_assert on it.
- Runtime: each generated service registers its full name in a global set at static init; AddServiceInternal rejects services not produced by the plugin, with an actionable error message.
- Hand-written google::protobuf::Service subclasses (we have one — BaiduMasterService) can declare the tag manually or go through an AddServiceUnchecked escape hatch.
@haberman I would be grateful for any feedback or suggestions you may have on my proposal.
esrauchg commentedon Jun 3, 2026
(Another protobuf team member from Google here.)
Really appreciate your productive reply here; I'll stress the context is basically that some of these features were ~never used for Google's direct business needs. They've been on life support forever since we want to support people in the community who adopt them and not pull the rug out on people, but for some of these things the ongoing toil starts to look dubious on some time horizon (toil tends to be low level but sometimes spurty in cost when they intersect poorly with something else that we're touching).
Protobuf unfortunately under-communicated that that certain things were considered regretted so many good faith open source projects couldn't have reasonably known sooner about some of these dark corners being considered dark corners.
Unfortunately the insertion point capability that you pointed to are also somewhat of a dubious/regretted feature as well. We're not touching it immediately but it also is forseeably a future conversation which looks pretty similar to this one, so I think if brpc has to move it would be best if we could get y'all onto something that is fully green today instead.
In general our main RPC systems including gRPC and Stubby (which is internal to Google and predates gRPC) more follow the path that Josh was describing and have the service code be wholly separate from the gencode that protoc generators would emit, and create service classes which don't extend any base classes which are part of the protobuf library.
Do you think there's a viable path there that would still minimize breakages for your users? Or perhaps there's incremental steps of insertion points to try to smooth a transition but where it gets off after that?
Thanks!
chenBright commentedon Jun 10, 2026
@esrauchg Hi, appreciate your productive reply. I need to research how gRPC is used before I can determine a viable path.