Skip to content

fix(q): harden response handling and encode dict results - #5

Open
belowzeroff wants to merge 3 commits into
RayforceDB:masterfrom
belowzeroff:fix/q-response-message-type
Open

fix(q): harden response handling and encode dict results#5
belowzeroff wants to merge 3 commits into
RayforceDB:masterfrom
belowzeroff:fix/q-response-message-type

Conversation

@belowzeroff

@belowzeroff belowzeroff commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • reject Q frames that are not response messages in q_exchange
  • encode native RAY_DICT results as Q XD dictionaries
  • decode Q identity (::, wire type 101 0) as Rayforce null
  • suppress SIGPIPE on client sends so closed peers return a normal send error
  • release RAY_ERROR objects with ray_error_free on decode/server cleanup paths
  • add server, socketpair, codec, client, and real-q interop regression coverage

User-visible bugs

A user querying the Rayfall-over-Q server could return ordinary scalar, vector, table, and error values successfully, but a query whose result was a native Rayforce dictionary failed at the Q wire boundary. From the user side this looks like a transport/server response failure instead of receiving the expected dictionary value.

Example shape:

.q.send h "(dict [a b] [1 2])"

Expected: the client receives the dictionary result.

Before this fix: the server could not serialize the native RAY_DICT result because q.c only decoded dictionaries and did not encode them, so the request failed when the response was being prepared.

A real q server can also return identity/null (::). Before this fix, .q.send h "::" reached the client as wire type 101 0, but q_decode did not handle that type and surfaced an unsupported-wire-type failure instead of a null result.

If the remote peer closed the socket before .q.send wrote the request, the POSIX send(..., 0) path could raise SIGPIPE and terminate the embedding process. The client send helper now uses MSG_NOSIGNAL where available and SO_NOSIGPIPE where supported, so closed peers fail cleanly as send errors.

The branch also keeps the earlier response-frame hardening: if a peer sends a sync/request frame where the client is waiting for a response, .q.send now fails clearly with an expected response message type error instead of decoding the wrong frame shape.

Tests

  • make recheck

@belowzeroff belowzeroff changed the title fix(q): reject non-response frames fix(q): harden response handling and encode dict results Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant