File tree Expand file tree Collapse file tree 2 files changed +58
-0
lines changed
lib/ruby_lsp/ruby_lsp_rails Expand file tree Collapse file tree 2 files changed +58
-0
lines changed Original file line number Diff line number Diff line change @@ -529,6 +529,32 @@ def database_supports_indexing?(model)
529
529
end
530
530
end
531
531
532
+ # Patch fork to name processes based on the caller's file path. This is useful for figuring out what is creating more
533
+ # child processes from the runtime server, so that we can optimize and more easily debug orphaned processes
534
+ # @requires_ancestor: Kernel
535
+ module ForkPatch
536
+ #: () ?{ () -> void } -> Integer?
537
+ def fork ( &block )
538
+ fork_caller = caller_locations ( 1 , 1 ) &.first
539
+
540
+ # If a block is given, set the child process name and call the original block
541
+ if block
542
+ return super do
543
+ $0 = "ruby-lsp-rails: #{ fork_caller &.path } "
544
+ block . call
545
+ end
546
+ end
547
+
548
+ # If no block is given, then only set the child process name (when `pid` is `nil`)
549
+ pid = super
550
+ $0 = "ruby-lsp-rails: #{ fork_caller &.path } " unless pid
551
+ pid
552
+ end
553
+
554
+ Kernel . prepend ( self )
555
+ Process . singleton_class . prepend ( self )
556
+ end
557
+
532
558
if ARGV . first == "start"
533
559
RubyLsp ::Rails ::Server . new ( capabilities : JSON . parse ( ARGV [ 1 ] , symbolize_names : true ) ) . start
534
560
end
Original file line number Diff line number Diff line change @@ -268,6 +268,38 @@ def print_it!
268
268
$> = original_stdout
269
269
end
270
270
271
+ test "forked processes are named based on caller" do
272
+ skip ( "Fork is not supported on Windows" ) if Gem . win_platform?
273
+
274
+ File . write ( "my_addon.rb" , <<~RUBY )
275
+ class MyServerAddon < RubyLsp::Rails::ServerAddon
276
+ def name
277
+ "MyAddon"
278
+ end
279
+
280
+ def execute(request, params)
281
+ pid = fork do
282
+ # We can't directly send a message in theses tests because we're using a StringIO as stdout instead of the
283
+ # actual pipe, which means that the child process doesn't have access to the same object
284
+ File.write("process_name.txt", $0)
285
+ end
286
+
287
+ Process.wait(pid)
288
+ send_message({ process_name: File.read("process_name.txt") })
289
+ File.delete("process_name.txt")
290
+ end
291
+ end
292
+ RUBY
293
+
294
+ addon_path = File . expand_path ( "my_addon.rb" )
295
+ @server . execute ( "server_addon/register" , server_addon_path : addon_path )
296
+ @server . execute ( "server_addon/delegate" , server_addon_name : "MyAddon" , request_name : "dsl" )
297
+
298
+ assert_equal ( response , { process_name : "ruby-lsp-rails: #{ addon_path } " } )
299
+ ensure
300
+ FileUtils . rm ( "my_addon.rb" )
301
+ end
302
+
271
303
private
272
304
273
305
def response
You can’t perform that action at this time.
0 commit comments