Concurrent requests overwrite each other's instrumentation data
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 35/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Ferma
- Stack tecnologico
- ruby
- Ambito
- backend, observability
Direzione di ricerca
Start with lib/mcp/instrumentation.rb, especially instrument_call and add_instrumentation_data, then read the concurrent shared server test in test/mcp/server_test.rb and the tool call instrumentation in lib/mcp/server.rb. Reproduce the interleaving described in the issue and check how request data reaches the callback; done when concurrent requests produce separate records with the correct tool names. An open pull request (#668) is already addressing this issue.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Instrumentation#instrument_call keeps the per-request record in @instrumentation_data, an instance variable on the shared Server (instrumentation.rb:8). When two requests run at the same time on one server, for example Streamable HTTP on a threaded Rack server, the second request replaces the hash.
The first request then writes its later fields (client, error, duration) into the second request's hash and passes that hash to instrumentation_callback (instrumentation.rb:43, :48). The first request's own record, with its tool_name and tool_arguments (server.rb:1408), is never sent to the callback. around_request gets the original hash (instrumentation.rb:17) but misses the fields written after the swap.
Concurrent use of one server is supported (see test "#handle concurrent requests on a shared server report exceptions independently" in test/mcp/server_test.rb).
Repro
Run from the repository root with bundle exec ruby -I lib repro.rb:
require "mcp"
entered = Queue.new
release = Queue.new
slow_tool = MCP::Tool.define(name: "slow_tool") do
entered << true
release.pop
MCP::Tool::Response.new([{ type: "text", text: "slow" }])
end
fast_tool = MCP::Tool.define(name: "fast_tool") do
MCP::Tool::Response.new([{ type: "text", text: "fast" }])
end
records = Queue.new
configuration = MCP::Configuration.new
configuration.instrumentation_callback = ->(data) { records << data.dup }
server = MCP::Server.new(name: "example", tools: [slow_tool, fast_tool], configuration: configuration)
call = ->(id, name) { server.handle({ jsonrpc: "2.0", id: id, method: "tools/call", params: { name: name, arguments: {} } }) }
thread = Thread.new { call.call(1, "slow_tool") }
entered.pop
call.call(2, "fast_tool")
release << true
thread.join
p(2.times.map { records.pop[:tool_name] })
Expected: ["fast_tool", "slow_tool"]
Actual: ["fast_tool", "fast_tool"]
Suggested fix
Keep the record local to the request instead of on the shared server. For example, create the hash in instrument_call and pass it to add_instrumentation_data, or keep it in a fiber-local value that instrument_call sets and restores.
- Lingua principale
- Ruby
- Stelle
- 940
- Fork
- 143
- Merge medio
- 1g 5h
- PR unite (30g)
- 48
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di modelcontextprotocol/ruby-sdk
-
Invalid UTF-8 in `MCP-Protocol-Version`, `Mcp-Method` or `Mcp-Name` gives 500 instead of 400Forse già presa @koic l’ha presa 1 giorno fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
modelcontextprotocol/ruby-sdk#663 ·
I maintainer di solito rispondono entro 1 giorno
-
`Client::Stdio` passes the whole parent environment to the server processForse già presa @atesgoral l’ha presa 1 giorno fa. Apertabug
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
modelcontextprotocol/ruby-sdk#662 ·
I maintainer di solito rispondono entro 1 giorno
-
Elicitation results are not checked against `requested_schema`, but the docs say they match itForse già presa @atesgoral l’ha presa 1 giorno fa. Apertabug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
modelcontextprotocol/ruby-sdk#661 ·
I maintainer di solito rispondono entro 1 giorno
-
`JWTVerifier` answers 500 instead of 401 for a PS256 token when it verifies with an EC key (jwt < 3.3.0)Forse già presa @atesgoral l’ha presa 1 giorno fa. Apertabug
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
modelcontextprotocol/ruby-sdk#659 ·
I maintainer di solito rispondono entro 1 giorno
-
`logging/setLevel` from one session changes the log level of other sessionsForse già presa @atesgoral l’ha presa 1 giorno fa. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
modelcontextprotocol/ruby-sdk#658 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di modelcontextprotocol/ruby-sdk
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
rubys/roundhouse#1917 ·
-
test_rescues_connection_reset_on_issue_comments_lookup fails on master and blocks every pull requestAperta
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 91/100
zerocracy/judges-action#3142 ·
I maintainer di solito rispondono entro 2 giorni
-
Malformed encoded_filters causes a 500, and keeps failing with session persistenceForse già presa @officialasishkumar l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
avo-hq/avo#4986 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 88/100