wait with timeout + correct error processing
This commit is contained in:
parent
5b52490495
commit
2c6429065b
@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path"
|
||||||
|
"time"
|
||||||
|
|
||||||
kittenipc "efprojects.com/kitten-ipc"
|
kittenipc "efprojects.com/kitten-ipc"
|
||||||
)
|
)
|
||||||
@ -59,9 +60,9 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
log.Printf("remote call result = %v", res)
|
log.Printf("remote call result from ts = %v", res)
|
||||||
|
|
||||||
if err := ipc.Wait(); err != nil {
|
if err := ipc.Wait(1 * time.Second); err != nil {
|
||||||
log.Panic(err)
|
log.Panic(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,7 +20,7 @@ async function main() {
|
|||||||
|
|
||||||
await ipc.start();
|
await ipc.start();
|
||||||
|
|
||||||
console.log(`remote call result = ${await remoteApi.Div(10, 2)}`);
|
console.log(`remote call result from go = ${await remoteApi.Div(10, 2)}`);
|
||||||
|
|
||||||
await ipc.wait();
|
await ipc.wait();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -350,22 +350,27 @@ func (p *ParentIPC) Stop() error {
|
|||||||
}
|
}
|
||||||
p.stopRequested.Store(true)
|
p.stopRequested.Store(true)
|
||||||
if err := p.cmd.Process.Signal(syscall.SIGINT); err != nil {
|
if err := p.cmd.Process.Signal(syscall.SIGINT); err != nil {
|
||||||
return fmt.Errorf("send SIGTERM: %w", err)
|
return fmt.Errorf("send SIGINT: %w", err)
|
||||||
}
|
}
|
||||||
return p.Wait()
|
return p.Wait()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ParentIPC) Wait() error {
|
func (p *ParentIPC) Wait(timeout ...time.Duration) (retErr error) {
|
||||||
waitErrCh := make(chan error, 1)
|
waitErrCh := make(chan error, 1)
|
||||||
|
|
||||||
|
const defaultTimeout = time.Duration(1<<63 - 1) // max duration in go
|
||||||
|
_timeout := variadicToOption(timeout).OrElse(defaultTimeout)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
waitErrCh <- p.cmd.Wait()
|
waitErrCh <- p.cmd.Wait()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var retErr error
|
loop:
|
||||||
|
for {
|
||||||
select {
|
select {
|
||||||
case err := <-p.errCh:
|
case err := <-p.errCh:
|
||||||
retErr = fmt.Errorf("ipc internal error: %w", err)
|
retErr = mergeErr(retErr, fmt.Errorf("ipc internal error: %w", err))
|
||||||
|
break loop
|
||||||
case err := <-waitErrCh:
|
case err := <-waitErrCh:
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var exitErr *exec.ExitError
|
var exitErr *exec.ExitError
|
||||||
@ -373,11 +378,18 @@ func (p *ParentIPC) Wait() error {
|
|||||||
if !exitErr.Success() {
|
if !exitErr.Success() {
|
||||||
ws, ok := exitErr.Sys().(syscall.WaitStatus)
|
ws, ok := exitErr.Sys().(syscall.WaitStatus)
|
||||||
if !(ok && ws.Signaled() && ws.Signal() == syscall.SIGINT && p.stopRequested.Load()) {
|
if !(ok && ws.Signaled() && ws.Signal() == syscall.SIGINT && p.stopRequested.Load()) {
|
||||||
retErr = fmt.Errorf("cmd wait: %w", err)
|
retErr = mergeErr(retErr, fmt.Errorf("cmd wait: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
retErr = fmt.Errorf("cmd wait: %w", err)
|
retErr = mergeErr(retErr, fmt.Errorf("cmd wait: %w", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break loop
|
||||||
|
case <-time.After(_timeout):
|
||||||
|
p.stopRequested.Store(true)
|
||||||
|
if err := p.cmd.Process.Signal(syscall.SIGINT); err != nil {
|
||||||
|
retErr = mergeErr(retErr, fmt.Errorf("send SIGINT: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -450,3 +462,13 @@ func mapTypeNames(types []any) map[string]any {
|
|||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func variadicToOption[T any](variadic []T) mo.Option[T] {
|
||||||
|
if len(variadic) >= 2 {
|
||||||
|
panic("variadic param count must be 0 or 1")
|
||||||
|
}
|
||||||
|
if len(variadic) == 0 {
|
||||||
|
return mo.None[T]()
|
||||||
|
}
|
||||||
|
return mo.Some(variadic[0])
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user