Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Process.on_terminate proc cannot be executed? #14836

Closed
lost22git opened this issue Jul 26, 2024 · 9 comments
Closed

Process.on_terminate proc cannot be executed? #14836

lost22git opened this issue Jul 26, 2024 · 9 comments
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. status:duplicate topic:stdlib:concurrency

Comments

@lost22git
Copy link

lost22git commented Jul 26, 2024

❯ hostnamectl
Operating System: Debian GNU/Linux 12 (bookworm)
          Kernel: Linux 5.15.153.1-microsoft-standard-WSL2
    Architecture: x86-64

❯ crystal version
Crystal 1.12.1 [4cea10199] (2024-04-11)

LLVM: 15.0.7
Default target: x86_64-unknown-linux-gnu

When I press CTRL+C, the program will be blocked all the time, and the on_termiante proc will not be executed to print and exit the program.

I want to know under what circumstances will it be blocked?
Or how can I debug the program to find out what is causing it to get blocked?

Process.on_terminate do |reason|
  case reason
  when .interrupted?
    puts "Signal : interrupted"
  when .terminal_disconnected?
    puts "Signal : terminal disconnected"
  when .session_ended?
    puts "Signal : session ended"
  end
  Process.exit
end

Screenshot 2024-07-26 191613

@lost22git lost22git added the kind:bug A bug in the code. Does not apply to documentation, specs, etc. label Jul 26, 2024
@devnote-dev
Copy link
Contributor

With just the above code, the program will always exit with no output because there is no interrupt/terminate signal sent to the program, it terminates itself. The #on_terminate method and its underlying implementations also do not block, so I believe there is other code being executed in the program. Can you share more of the source?

@lost22git
Copy link
Author

lost22git commented Jul 26, 2024

because there is no interrupt/terminate signal sent to the program, it terminates itself.

why CTRL+C not sent interrupt/terminate signal sent to the program?

and same issue when kill <pid>

@lost22git
Copy link
Author

lost22git commented Jul 26, 2024

Can you share more of the source?

the mainly code is spawnning 16 fibers to consume downloading task from task queue and download something from remote server

@Blacksmoke16
Copy link
Member

In that case it's possible there is some fiber in a tight loop that is not blocking/yielding which is not allowing the main fiber to run/execute the #on_terminate handler. Crystal also doesn't have any form of preemption. Hard to say without seeing the code, but I'm pretty sure the problem is going to be in your code, rather than the stdlib/compiler.

@lost22git
Copy link
Author

lost22git commented Jul 26, 2024

Process.on_terminate do |reason|
  case reason
  when .interrupted?
    puts "Signal : interrupted"
  when .terminal_disconnected?
    puts "Signal : terminal disconnected"
  when .session_ended?
    puts "Signal : session ended"
  end

  puts "Hook exit"
  Process.exit
end

chan = Channel(Nil).new(16)
(1..16).each do
  spawn do
    begin
      loop { }
    ensure
      chan.send nil
      puts "Fiber exit"
    end
  end
end

(1..16).each do
  chan.receive
end

puts "Main exit"

Screenshot 2024-07-26 215952

Maybe running the signal listener on a separate thread (not sharing with worker fibers) can avoid this problem

My real program fibers is waiting network io, it should be yield automically, but same problem was occurred

@devnote-dev
Copy link
Contributor

chan.receive is blocking which will switch to the first available fiber, in this case it's one of the 16 spawned. All of those fibers will remain blocked because of loop { } which is the same as while true.

@Blacksmoke16
Copy link
Member

Blacksmoke16 commented Jul 26, 2024

Going to close this as a duplicate of #1454. Until that is resolved you'll need to ensure none of your fibers in user code will block forever/starve the main fiber.

@Blacksmoke16 Blacksmoke16 closed this as not planned Won't fix, can't repro, duplicate, stale Jul 26, 2024
@Blacksmoke16
Copy link
Member

Duplicate of #1454

@lost22git
Copy link
Author

Skill issue

Solution: I should use Go lang ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. status:duplicate topic:stdlib:concurrency
Projects
None yet
Development

No branches or pull requests

3 participants