Skip to content

Commit 05630e3

Browse files
authored
Merge pull request #2685 from Amosel/amos/grpc-relay-fix
Amos/grpc relay fix
2 parents 2ffc800 + 5997552 commit 05630e3

4 files changed

Lines changed: 325 additions & 135 deletions

File tree

pylons-grpc-relay/README.md

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,4 +214,52 @@ The relay server handles the conversion between:
214214
```
215215

216216
## Testing
217-
See [INCIDENT_REPORT.md](INCIDENT_REPORT.md) for detailed testing procedures and data contracts.
217+
See [INCIDENT_REPORT.md](INCIDENT_REPORT.md) for detailed testing procedures and data contracts.
218+
219+
## Enhanced Diagnostics and Patching (May 2025)
220+
221+
The gRPC relay has been significantly enhanced to aid in diagnosing and incrementally fixing issues with gRPC calls, particularly those originating from clients that might not correctly wrap messages in the `google.protobuf.Any` type as expected by the target Pylons node.
222+
223+
### Key Features:
224+
225+
1. **Detailed Logging**:
226+
* The relay now produces verbose logs (to `grpc_relay.log` and stdout) for each gRPC call.
227+
* **`[MSG_FLOW]`**: Traces messages at various stages:
228+
* `request_received_by_relay`: Initial incoming request with metadata.
229+
* `client_msg_raw_unpacked`: After the relay receives a message from the client, showing its raw `TypeUrl` and a snippet of its `Value`. This is crucial for seeing what the client actually sent.
230+
* `client_msg_patched_pre_send` / `client_msg_unpatched_pre_send`: Shows the message just before it's sent to the target, indicating if a patch was applied.
231+
* `target_msg_sent_successfully`: Confirmation of successful send to target.
232+
* `target_response_received_by_relay`: Response received from the target.
233+
* `target_response_sent_to_client`: Confirmation of successful send of target's response back to the client.
234+
* **`[ERROR_DETAIL]`**: Provides detailed context when an error occurs, including:
235+
* `Method`: The gRPC method name.
236+
* `Stage`: Where in the relay's processing the error happened (e.g., `client_recv_error`, `target_send_error`, `patch_application_error`).
237+
* `MsgTypeURL`, `MsgValueLen`, `MsgValueSnippet`: Details of the message being processed when the error occurred.
238+
* `Metadata`: Incoming request metadata.
239+
* **`PatchInfo`**: Both `[MSG_FLOW]` and `[ERROR_DETAIL]` logs include patch information:
240+
* `PatchNotAttempted`: No patch was tried for this message.
241+
* `PatchAttempted(Name:..., Success:false, ...)`: A patch was tried but was not successful (e.g., conditions for patching weren't fully met, or the patch logic itself had an issue).
242+
* `PatchApplied(Name:..., Success:true, OriginalURL:..., PatchedURL:...)`: A patch was successfully applied, showing the original and new `TypeUrl`.
243+
244+
2. **Message Patching (`attemptToApplyFix` function)**:
245+
* The relay now includes a mechanism to "patch" incoming messages before forwarding them to the target gRPC server.
246+
* Currently, the primary patch (`any_typeurl_rewrap`) focuses on fixing issues where client messages are not correctly wrapped in `google.protobuf.Any`.
247+
* It uses a predefined map `knownRequestPayloadTypeURLs` in `relay.go`. This map links gRPC method names (e.g., `/pylons.pylons.Query/ListItemByOwner`) to their expected `TypeUrl` (e.g., `type.googleapis.com/pylons.pylons.QueryListItemByOwnerRequest`).
248+
* **How it works**:
249+
1. If an incoming message's `TypeUrl` is empty or different from the `expectedTypeURL` for that method, AND the message `Value` is not empty:
250+
* The relay assumes `Value` contains the raw protobuf bytes of the actual request.
251+
* It creates a new `anypb.Any` message, setting its `TypeUrl` to the `expectedTypeURL` and its `Value` to the original message's `Value`.
252+
2. If the incoming message's `TypeUrl` already matches the expected one, or if no specific mapping exists for the method, the message is passed through as-is (or with minimal intervention).
253+
* **Adding New Patches/Mappings**: To support fixing new methods or refining existing ones, update the `knownRequestPayloadTypeURLs` map in `relay.go`.
254+
255+
3. **Identifying Incorrect Calls**:
256+
* Look for `[ERROR_DETAIL]` logs, especially "target_send_error" with "failed to marshal" messages.
257+
* Examine the preceding `[MSG_FLOW]` logs for that method, particularly the `client_msg_raw_unpacked` stage. This will show the `TypeUrl` and `Value` snippet sent by the client.
258+
* If `TypeUrl` is empty or incorrect, and `Value` seems to contain the actual payload, this method is a candidate for adding/updating its entry in `knownRequestPayloadTypeURLs`.
259+
260+
### Environment Variables:
261+
262+
* `TARGET_ADDRESS`: The address (host:port) of the target gRPC server (e.g., `pylons.api.m.stavr.tech:443`). Do NOT include `http://` or `https://`.
263+
* `PORT`: The port on which this relay server will listen (e.g., `50051`).
264+
265+
This enhanced relay aims to simplify debugging and allow for rapid, iterative fixes to client-server gRPC communication issues without requiring immediate client-side code changes.

pylons-grpc-relay/go.mod

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
module pylons-relay
1+
module pylons-grpc-relay
22

3-
go 1.23.3
3+
go 1.24
44

55
require (
6-
golang.org/x/net v0.35.0 // indirect
7-
golang.org/x/sys v0.30.0 // indirect
8-
golang.org/x/text v0.22.0 // indirect
9-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
10-
google.golang.org/grpc v1.72.0 // indirect
11-
google.golang.org/protobuf v1.36.5 // indirect
6+
google.golang.org/grpc v1.62.0
7+
google.golang.org/protobuf v1.32.0
8+
)
9+
10+
require (
11+
github.com/golang/protobuf v1.5.3 // indirect
12+
golang.org/x/net v0.20.0 // indirect
13+
golang.org/x/sys v0.16.0 // indirect
14+
golang.org/x/text v0.14.0 // indirect
15+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 // indirect
1216
)

pylons-grpc-relay/go.sum

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
2-
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
3-
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
4-
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
5-
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
6-
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
7-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
8-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
9-
google.golang.org/grpc v1.72.0 h1:S7UkcVa60b5AAQTaO6ZKamFp1zMZSU0fGDK2WZLbBnM=
10-
google.golang.org/grpc v1.72.0/go.mod h1:wH5Aktxcg25y1I3w7H69nHfXdOG3UiadoBtjh3izSDM=
11-
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
12-
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
1+
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
2+
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
3+
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
4+
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
5+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
6+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
7+
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
8+
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
9+
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
10+
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
11+
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
12+
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
13+
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
14+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80 h1:AjyfHzEPEFp/NpvfN5g+KDla3EMojjhRVZc1i7cj+oM=
15+
google.golang.org/genproto/googleapis/rpc v0.0.0-20240123012728-ef4313101c80/go.mod h1:PAREbraiVEVGVdTZsVWjSbbTtSyGbAgIIvni8a8CD5s=
16+
google.golang.org/grpc v1.62.0 h1:HQKZ/fa1bXkX1oFOvSjmZEUL8wLSaZTjCcLAlmZRtdk=
17+
google.golang.org/grpc v1.62.0/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE=
18+
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
19+
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
20+
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
21+
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=

0 commit comments

Comments
 (0)