alco / alco/porcelain

Investigate ways to terminate external processes cleanly (with and without goon)

未关闭
#13 17 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
bug
主要语言
Elixir
星标
958
派生
45
PR 合并指标
30 天内没有已合并 PR

描述

The current behaviour of stopping a process is not satisfactory no matter how you slice it.
## Without goon

Below, we have an error in the stream name which happens in the spawned process that controls the Erlang port.

``` iex
iex(1)> p = Porcelain.spawn_shell "ping google.com", out: IO.stream(:stdout, :line)
%Porcelain.Process{err: nil,
out: %IO.Stream{device: :stdout, line_or_bytes: :line, raw: false},
pid: #PID<0.74.0>}
iex(2)>
=ERROR REPORT==== 20-Jan-2015::00:14:52 ===
Error in process <0.78.0> with exit value: {badarg,[{io,put_chars,[stdout,unicode,<<112 bytes>>],[]},{'Elixir.Enum','-reduce/3-fun-0-',3,[{file,"lib/enum.ex"},{line,1266}]},{'Elixir.Stream',do_unfold,4,[{file,"lib/stream.ex"},{line,1126}]},{'Elixir.Enum',reduce,3,[{file,"lib/enum.ex"},{line,1265}]},{...

iex(3)> Porcelain.Process.alive? p
true
iex(4)> Porcelain.Process.stop p

# the shell just hangs
# the external process 'ping' remain alive even after terminating the VM
```

An example of successfully stopping a port:

```
iex(1)> p = Porcelain.spawn_shell "ping google.com", out: IO.binstream(:stdio, :line)
%Porcelain.Process{err: nil,
out: %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true},
pid: #PID<0.73.0>}
PING google.com (173.194.113.193): 56 data bytes
64 bytes from 173.194.113.193: icmp_seq=0 ttl=57 time=11.042 ms
...
iex(2)> Porcelain.Process.stop p
true
```

We don't get any more input, but `ping` keeps running in the background.
## With goon

```
iex(1)> p = Porcelain.spawn_shell "ping google.com", out: IO.binstream(:stdio, :line)
%Porcelain.Process{err: nil,
out: %IO.Stream{device: :standard_io, line_or_bytes: :line, raw: true},
pid: #PID<0.74.0>}
PING google.com (173.194.113.194): 56 data bytes
64 bytes from 173.194.113.194: icmp_seq=0 ttl=57 time=8.044 ms
...
iex(2)> Porcelain.Process.stop p
true
iex(3)> panic: write /dev/stdout: broken pipe

goroutine 3 [running]:
runtime.panic(0xa4ba0, 0x2102a5420)
/usr/local/Cellar/go/1.2.2/libexec/src/pkg/runtime/panic.c:266 +0xb6
log.(*Logger).Panicf(0x2102a6190, 0xde260, 0x3, 0x221040fe30, 0x1, ...)
/usr/local/Cellar/go/1.2.2/libexec/src/pkg/log/log.go:200 +0xbd
main.fatal_if(0xc2840, 0x2102bf7e0)
/Users/alco/extra/goworkspace/src/goon/util.go:38 +0x17e
main.outLoop(0x257338, 0x2102860e8, 0x256fe8, 0x210286008, 0x0, ...)
/Users/alco/extra/goworkspace/src/goon/io.go:151 +0x44a
created by main.wrapStdout
/Users/alco/extra/goworkspace/src/goon/io.go:34 +0x16a

goroutine 1 [chan receive]:
main.proto_2_0(0x7fff5fbf0100, 0xe3fc0, 0x3, 0xde7a0, 0x1, ...)
/Users/alco/extra/goworkspace/src/goon/proto_2_0.go:58 +0x3a3
main.main()
/Users/alco/extra/goworkspace/src/goon/main.go:51 +0x3b6
```

`ping` terminates, but `goon` panics.

贡献指南

这个仓库没有索引到贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。