Add opt-in client/server mode to the rdx executable#869
Open
paracycle wants to merge 1 commit into
Open
Conversation
6967765 to
3bf6c65
Compare
49ed15d to
13f37ec
Compare
3bf6c65 to
59e9e4b
Compare
Introduce a resident, per-workspace server that keeps an indexed + resolved Rubydex::Graph in memory so repeated `--query` invocations skip the index/resolve cost. Server mode is opt-in via `--server`; without it (or on platforms lacking fork/UNIX sockets) `rdx` runs inline as before. - lib/rubydex/server/cache.rb: per-workspace runtime dir keyed by an app-id hashed from the workspace, Ruby/rubydex version and a native-ext fingerprint; pid/token/socket/version files with restrictive perms. - lib/rubydex/server/request.rb: length-prefixed JSON framing plus an IO.select handshake read timeout. - lib/rubydex/server/core.rb: UNIX socket accept loop with a version-line gate, constant-time token auth, mutex-guarded dispatch and per-request mtime-manifest staleness (reindex changed / delete removed / resolve). - lib/rubydex/server/client.rb: start-if-absent (fork + Process.daemon, flock single-start, spawn-and-poll readiness), version handshake, cold/warm recovery, graceful stop with SIGTERM fallback. - lib/rubydex/server/commands.rb: --start/stop/restart/server-status. - exe/rdx: new --[no-]server, --start/stop/restart-server, --server-status and --no-detach flags; queries route to the server when opted in, everything else stays inline. Binds/connects the socket via a relative name from its directory so long runtime paths stay under the sockaddr_un limit. Adds unit tests for the cache and framing plus integration tests that spawn a real server.
59e9e4b to
7a54996
Compare
2e6a202 to
bc2a231
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an opt-in resident, per-workspace server to the
rdxexecutable. The server keeps an indexed + resolvedRubydex::Graphin memory so repeatedrdx queryinvocations skip the index/resolve cost. Without--server(or on platforms lackingfork/UNIX sockets)rdx queryruns inline exactly as before.This is the first step of a larger effort to turn
rdxinto a client/server tool (similar in spirit to the RuboCop and Spring servers), so that the expensive indexing + resolution work is paid once and reused across commands. It is intentionally scoped to the foundations: the runtime/IPC plumbing and a working server for the read-only query path. It's pure Ruby on top of the existing gem API — no Rust/C changes.CLI surface
rdx query <CYPHER> [--server] [--format ...]— opt into the resident server for a query (otherwise runs inline).rdx server <start|stop|restart|status> [--no-detach]— manage the resident server for the current workspace.DISABLE_RDX_SERVER(force inline) andRDX_SERVER_DIR(override the runtime directory).How
lib/rubydex/cli.rb— extracts all command/option parsing and subcommand dispatch into aRubydex::CLIclass, keepingexe/rdxa thin shim. Heavyweight requires (rubydex,rubydex/server) stay deferred into the handlers so paths that don't need the native extension stay cheap to start.lib/rubydex/server/cache.rb— per-workspace runtime dir keyed by an app-id hashed from the workspace path, Ruby/rubydex version and a native-extension fingerprint (a gem upgrade forces a fresh server). Managespid/token/socket/versionfiles with0700/0600perms.lib/rubydex/server/request.rb— length-prefixed JSON framing + anIO.selecthandshake read timeout.lib/rubydex/server/core.rb— UNIX socket accept loop with a version-line gate, constant-time token auth, mutex-guarded dispatch (query/status/stop) and per-request mtime-manifest staleness (reindex changed /delete_documentremoved /resolve).lib/rubydex/server/client.rb— start-if-absent (fork+Process.daemon, flock single-start, spawn-and-poll readiness), version handshake, cold/warm recovery, graceful stop with SIGTERM fallback.lib/rubydex/server/commands.rb— implements therdx server start|stop|restart|statusactions.The socket is bound/connected via a relative name from its directory so long runtime paths stay under the
sockaddr_un~104-byte limit.What's coming next
This PR deliberately keeps the scope small. Follow-up PRs will build on this foundation:
rdx consolesessions served from the resident graph. An IRB session needs the client's real terminal, so this requires forking a per-session worker, passing the client's STDIN/STDOUT/STDERR file descriptors to it, and forwarding signals — landing a REPL that starts instantly against the already-built graph.Testing
Cache(app-id stability, perms, version compare, stale cleanup) and the request framing.bundle exec rake ruby_test— all Ruby tests pass; RuboCop clean.