# How to implement resonable process timeout

**URL:** <https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207>\
**Category:** Help & Support\
**Created:** [December 6, 2023, 4:19pm UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207 "2023-12-06T16:19:02Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cry4me](https://avatars.discourse-cdn.com/v4/letter/c/d6d6ee/32.png) [@cry4me](https://forum.crystal-lang.org/u/cry4me)\
**Post date:** [December 6, 2023, 4:19pm UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207/1 "2023-12-06T16:19:02Z")

</div>

```auto
def do_work
  process = Process.new ("D:/tool.bat", ["-version"])

  p process.pid 

  process.wait 
end

spawn do
  loop do 
    do_work
  end
end

spawn do
  loop do 
    do_work
  end
end

sleep

```

I want to use the process class to run an external tool. What would be a reasonable solution to implement a timeout which terminates the process after the specified time ?

---

<div class="post-metadata">

**Author:** ![naqvis](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/naqvis/32/906_2.png) [@naqvis](https://forum.crystal-lang.org/u/naqvis)\
**Post date:** [December 6, 2023, 6:08pm UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207/2 "2023-12-06T18:08:20Z")

</div>

Use channel and `select` with timeout. Something like

```auto
def do_work
 channel = Channel(Process::Status).new(capacity: 1)
 process = nil
 spawn do
   process = Process.new ("D:/tool.bat", ["-version"])
   status = process.wait
   channel.send(status) unless channel.closed?
 end 

 select
 when status = channel.receive
    # process terminates before timeout
    # .....
 when timeout(MY_TIMEOUT) # MY_TIMEOUT is your own custom timeout value you want to wait
   # this will be reached when `timeout` is met and process still running
   channel.close
   process.try &.terminate rescue nil
   # process.terminate may raise, so better to catch and handle. above example just ignoring the exception
 end
end   

```

HIH

---

<div class="post-metadata">

**Author:** ![cry4me](https://avatars.discourse-cdn.com/v4/letter/c/d6d6ee/32.png) [@cry4me](https://forum.crystal-lang.org/u/cry4me)\
**Post date:** [December 7, 2023, 9:06am UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207/4 "2023-12-07T09:06:57Z")

</div>

The proposed solution works. However on windows I get periodically a block of warnings:

GC Warning: Finalization cycle involving 0000019E29E6E360  
GC Warning: Finalization cycle involving 0000019E29E67300  
GC Warning: Finalization cycle involving 0000019E29E4A300  
GC Warning: Finalization cycle involving 0000019E29E4A660  
GC Warning: Finalization cycle involving 0000019E29E4A780  
GC Warning: Finalization cycle involving 0000019E29E4AAE0  
GC Warning: Finalization cycle involving 0000019E29E4AE40  
GC Warning: Finalization cycle involving 0000019E29E4AF00

The task manager also shows an increase of the process memory consumption

This does not happen on linux !

---

<div class="post-metadata">

**Author:** ![cry4me](https://avatars.discourse-cdn.com/v4/letter/c/d6d6ee/32.png) [@cry4me](https://forum.crystal-lang.org/u/cry4me)\
**Post date:** [December 7, 2023, 10:48am UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207/5 "2023-12-07T10:48:26Z")

</div>

Is this related to [Memory Leak on Windows?](https://forum.crystal-lang.org/t/memory-leak-on-windows/6197) ?

---

<div class="post-metadata">

**Author:** ![naqvis](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/naqvis/32/906_2.png) [@naqvis](https://forum.crystal-lang.org/u/naqvis)\
**Post date:** [December 7, 2023, 12:15pm UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207/6 "2023-12-07T12:15:52Z")

</div>

Windows support is still in **preview** and it might be related to that. For status of windows port refer to the [issue-5430](https://github.com/crystal-lang/crystal/issues/5430)

---

<div class="post-metadata">

**Author:** ![cry4me](https://avatars.discourse-cdn.com/v4/letter/c/d6d6ee/32.png) [@cry4me](https://forum.crystal-lang.org/u/cry4me)\
**Post date:** [December 7, 2023, 1:04pm UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207/7 "2023-12-07T13:04:23Z")

</div>

While digging in the crystal sources I found in ‘spec/std/thread\_spec.cr’ a hint:

```auto
  it "returns current thread object" do
    current = nil
    thread = Thread.new { current = Thread.current }
    thread.join
    current.should be(thread)
    current.should_not be(Thread.current)
  ensure
    # avoids a "GC Warning: Finalization cycle" caused by *current*
    # referencing the thread itself, preventing the finalizer to run:
    current = nil
  end

```

The warnings vanish when I set the `process = nil` as the last statement in the do\_work method !

---

<div class="post-metadata">

**Author:** ![cry4me](https://avatars.discourse-cdn.com/v4/letter/c/d6d6ee/32.png) [@cry4me](https://forum.crystal-lang.org/u/cry4me)\
**Post date:** [December 9, 2023, 12:10pm UTC](https://forum.crystal-lang.org/t/how-to-implement-resonable-process-timeout/6207/8 "2023-12-09T12:10:41Z")

</div>

Can somebody explain me why in this case the finalizer is NOT called, thus preventing the GC warning.
