@@ -48,6 +48,7 @@ defmodule ElixirLS.Debugger.Server do
48
48
}
49
49
} ,
50
50
requests: % { } ,
51
+ requests_seqs_by_pid: % { } ,
51
52
progresses: MapSet . new ( ) ,
52
53
next_id: 1 ,
53
54
output: Output ,
@@ -314,40 +315,61 @@ defmodule ElixirLS.Debugger.Server do
314
315
_from ,
315
316
state = % __MODULE__ { }
316
317
) do
317
- if MapSet . member? ( state . progresses , packet [ "seq" ] ) do
318
- Output . send_event ( "progressEnd" , % {
319
- "progressId" => packet [ "seq" ]
320
- } )
321
- end
318
+ seq = packet [ "seq" ]
319
+ { request , updated_requests } = Map . pop ( state . requests , seq )
322
320
323
- case result do
324
- { :error , e = % ServerError { } } ->
325
- Output . send_error_response (
326
- packet ,
327
- e . message ,
328
- e . format ,
329
- e . variables ,
330
- e . send_telemetry ,
331
- e . show_user
332
- )
321
+ { updated_requests_seqs_by_pid , updated_progresses } =
322
+ if request do
323
+ { pid , ref , _packet } = request
333
324
334
- { :ok , response_body } ->
335
- elapsed = System . monotonic_time ( :millisecond ) - start_time
336
- Output . send_response ( packet , response_body )
325
+ # we are not interested in :DOWN message anymore
326
+ Process . demonitor ( ref , [ :flush ] )
337
327
338
- Output . telemetry (
339
- "dap_request" ,
340
- % { "elixir_ls.dap_command" => String . replace ( command , "/" , "_" ) } ,
341
- % {
342
- "elixir_ls.dap_request_time" => elapsed
343
- }
344
- )
345
- end
328
+ updated_progresses =
329
+ if MapSet . member? ( state . progresses , seq ) do
330
+ Output . send_event ( "progressEnd" , % {
331
+ "progressId" => seq
332
+ } )
333
+
334
+ MapSet . delete ( state . progresses , seq )
335
+ else
336
+ state . progresses
337
+ end
338
+
339
+ case result do
340
+ { :error , e = % ServerError { } } ->
341
+ Output . send_error_response (
342
+ packet ,
343
+ e . message ,
344
+ e . format ,
345
+ e . variables ,
346
+ e . send_telemetry ,
347
+ e . show_user
348
+ )
349
+
350
+ { :ok , response_body } ->
351
+ elapsed = System . monotonic_time ( :millisecond ) - start_time
352
+ Output . send_response ( packet , response_body )
353
+
354
+ Output . telemetry (
355
+ "dap_request" ,
356
+ % { "elixir_ls.dap_command" => String . replace ( command , "/" , "_" ) } ,
357
+ % {
358
+ "elixir_ls.dap_request_time" => elapsed
359
+ }
360
+ )
361
+ end
362
+
363
+ { Map . delete ( state . requests_seqs_by_pid , pid ) , updated_progresses }
364
+ else
365
+ { state . requests_seqs_by_pid , state . progresses }
366
+ end
346
367
347
368
state = % {
348
369
state
349
- | requests: Map . delete ( state . requests , packet [ "seq" ] ) ,
350
- progresses: MapSet . delete ( state . progresses , packet [ "seq" ] )
370
+ | requests: updated_requests ,
371
+ requests_seqs_by_pid: updated_requests_seqs_by_pid ,
372
+ progresses: updated_progresses
351
373
}
352
374
353
375
{ :reply , :ok , state }
@@ -421,8 +443,13 @@ defmodule ElixirLS.Debugger.Server do
421
443
state
422
444
423
445
{ :async , fun , state } ->
424
- { pid , _ref } = handle_request_async ( packet , start_time , fun )
425
- % { state | requests: Map . put ( state . requests , seq , { pid , packet } ) }
446
+ { pid , ref } = handle_request_async ( packet , start_time , fun )
447
+
448
+ % {
449
+ state
450
+ | requests: Map . put ( state . requests , seq , { pid , ref , packet } ) ,
451
+ requests_seqs_by_pid: Map . put ( state . requests_seqs_by_pid , pid , seq )
452
+ }
426
453
end
427
454
428
455
{ :noreply , state }
@@ -525,38 +552,45 @@ defmodule ElixirLS.Debugger.Server do
525
552
526
553
# if the exited process was a request handler respond with error
527
554
# and optionally end progress
528
- request =
529
- state . requests
530
- |> Enum . find ( fn { _request_id , { request_pid , _packet } } -> request_pid == pid end )
555
+ { seq , updated_requests_seqs_by_pid } = Map . pop ( state . requests_seqs_by_pid , pid )
531
556
532
- state =
533
- case request do
534
- { request_id , { _pid , packet } } ->
535
- Output . send_error_response (
536
- packet ,
537
- "internalServerError" ,
538
- "Request handler exited with reason #{ Exception . format_exit ( reason ) } " ,
539
- % { } ,
540
- true ,
541
- false
542
- )
557
+ { updated_requests , updated_progresses } =
558
+ if seq do
559
+ { { _pid , _ref , packet } , updated_requests } = Map . pop! ( state . requests , seq )
560
+
561
+ Output . send_error_response (
562
+ packet ,
563
+ "internalServerError" ,
564
+ "Request handler exited with reason #{ Exception . format_exit ( reason ) } " ,
565
+ % { } ,
566
+ true ,
567
+ false
568
+ )
543
569
544
- if MapSet . member? ( state . progresses , request_id ) do
570
+ # no MapSet.pop...
571
+ updated_progresses =
572
+ if MapSet . member? ( state . progresses , seq ) do
545
573
Output . send_event ( "progressEnd" , % {
546
- "progressId" => request_id
574
+ "progressId" => seq
547
575
} )
548
- end
549
576
550
- % {
551
- state
552
- | requests: Map . delete ( state . requests , request_id ) ,
553
- progresses: MapSet . delete ( state . progresses , request_id )
554
- }
577
+ MapSet . delete ( state . progresses , seq )
578
+ else
579
+ state . progresses
580
+ end
555
581
556
- nil ->
557
- state
582
+ { updated_requests , updated_progresses }
583
+ else
584
+ { state . requests , state . progresses }
558
585
end
559
586
587
+ state = % {
588
+ state
589
+ | requests: updated_requests ,
590
+ requests_seqs_by_pid: updated_requests_seqs_by_pid ,
591
+ progresses: updated_progresses
592
+ }
593
+
560
594
{ :noreply , state }
561
595
end
562
596
@@ -627,34 +661,45 @@ defmodule ElixirLS.Debugger.Server do
627
661
# in or case progressId is requestId so choose first not null
628
662
request_or_progress_id = args [ "requestId" ] || args [ "progressId" ]
629
663
630
- state =
631
- case requests do
632
- % { ^ request_or_progress_id => { pid , packet } } ->
633
- Process . exit ( pid , :cancelled )
634
- Output . send_error_response ( packet , "cancelled" , "cancelled" , % { } , false , false )
664
+ { request , updated_requests } = Map . pop ( requests , request_or_progress_id )
665
+
666
+ { updated_requests_seqs_by_pid , updated_progresses } =
667
+ if request do
668
+ { pid , ref , packet } = request
669
+ # flush as we are not interested in :DOWN message anymore
670
+ Process . demonitor ( ref , [ :flush ] )
671
+ Process . exit ( pid , :cancelled )
672
+ Output . send_error_response ( packet , "cancelled" , "cancelled" , % { } , false , false )
635
673
636
- # send progressEnd if cancelling a progress
674
+ # send progressEnd if cancelling a progress
675
+ updated_progresses =
637
676
if MapSet . member? ( state . progresses , request_or_progress_id ) do
638
677
Output . send_event ( "progressEnd" , % {
639
678
"progressId" => request_or_progress_id
640
679
} )
680
+
681
+ MapSet . delete ( state . progresses , request_or_progress_id )
682
+ else
683
+ state . progresses
641
684
end
642
685
643
- % {
644
- state
645
- | requests: Map . delete ( requests , request_or_progress_id ) ,
646
- progresses: MapSet . delete ( state . progresses , request_or_progress_id )
686
+ { Map . delete ( state . requests_seqs_by_pid , pid ) , updated_progresses }
687
+ else
688
+ raise ServerError ,
689
+ message: "invalidRequest" ,
690
+ format: "Request or progress {reguestOrProgressId} cannot be cancelled" ,
691
+ variables: % {
692
+ "reguestOrProgressId" => inspect ( request_or_progress_id )
647
693
}
648
-
649
- _ ->
650
- raise ServerError ,
651
- message: "invalidRequest" ,
652
- format: "Request or progress {reguestOrProgressId} cannot be cancelled" ,
653
- variables: % {
654
- "reguestOrProgressId" => inspect ( request_or_progress_id )
655
- }
656
694
end
657
695
696
+ state = % {
697
+ state
698
+ | requests: updated_requests ,
699
+ requests_seqs_by_pid: updated_requests_seqs_by_pid ,
700
+ progresses: updated_progresses
701
+ }
702
+
658
703
{ % { } , state }
659
704
end
660
705
0 commit comments