Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 21 additions & 12 deletions lib/ruby_lsp/base_server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def start
# The following requests need to be executed in the main thread directly to avoid concurrency issues. Everything
# else is pushed into the incoming queue
case method
when "initialize", "initialized", "rubyLsp/diagnoseState"
when "initialize", "initialized", "rubyLsp/diagnoseState", "$/cancelRequest"
process_message(message)
when "shutdown"
@global_state.synchronize do
Expand Down Expand Up @@ -154,20 +154,29 @@ def fail_request_and_notify(id, message, type: Constant::MessageType::INFO)
def new_worker
Thread.new do
while (message = @incoming_queue.pop)
id = message[:id]

# Check if the request was cancelled before trying to process it
@global_state.synchronize do
if id && @cancelled_requests.include?(id)
send_message(Result.new(id: id, response: nil))
@cancelled_requests.delete(id)
next
end
end
handle_incoming_message(message)
end
end
end

process_message(message)
#: (Hash[Symbol, untyped]) -> void
def handle_incoming_message(message)
id = message[:id]

# Check if the request was cancelled before trying to process it
@global_state.synchronize do
if id && @cancelled_requests.include?(id)
send_message(Error.new(
id: id,
code: Constant::ErrorCodes::REQUEST_CANCELLED,
message: "Request #{id} was cancelled",
))
@cancelled_requests.delete(id)
return
end
end

process_message(message)
end

#: ((Result | Error | Notification | Request) message) -> void
Expand Down
7 changes: 4 additions & 3 deletions test/server_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ def handle_window_show_message_response(title)
end
end

def test_cancelling_requests_returns_nil
def test_cancelling_requests_returns_expected_error_code
uri = URI("file:///foo.rb")

@server.process_message({
Expand Down Expand Up @@ -868,8 +868,9 @@ def test_cancelling_requests_returns_nil
mutex.unlock
thread.join

result = find_message(RubyLsp::Result)
assert_nil(result.response)
error = find_message(RubyLsp::Error)
assert_equal(RubyLsp::Constant::ErrorCodes::REQUEST_CANCELLED, error.code)
assert_equal("Request 1 was cancelled", error.message)
end

def test_unsaved_changes_are_indexed_when_computing_automatic_features
Expand Down