godotenv icon indicating copy to clipboard operation
godotenv copied to clipboard

Ignore interrupts and wait for child process to exit

Open AdamSLevy opened this issue 5 years ago • 7 comments
trafficstars

Because signals were not handled, godotenv will sometimes exit before its child process, causing unexpected behavior in some apps. Instead ignore interrupts and just wait for the subprocess to exit.

fix #21

AdamSLevy avatar Sep 14 '20 20:09 AdamSLevy

I've been using Adam's patched version for a while now and it works great. Can we get this merged please @joho?

Thanks!

bhechinger avatar Apr 01 '21 13:04 bhechinger

@joho any chance to see this merged?

scalp42 avatar Aug 24 '22 18:08 scalp42

👍 It would be great to have this fix released!

Alternatively, I was looking at somewhat similar tools like aws-env and it uses syscall.Exec which replaces the process rather than spawning a child process, leaving nothing for godotenv to handle after being called if it helps.

evandam avatar Aug 24 '22 19:08 evandam

Hey @AdamSLevy I was wondering in the meantime would you be able to rebase your fork to be in sync with the latest release here?

I'd also love to switch to your version but not as familiar with how to install/build it - would you be able to share how we can get up and running?

Thanks in advance!

evandam avatar Aug 25 '22 21:08 evandam

I also have this annoying signal issue, would like to see this PR getting merged! Thanks!

c9s avatar Apr 07 '23 06:04 c9s

Looks like node's dotenv-cli has the same issue, Only ruby's dotenv is working fine, I will switch to the ruby version for now.

c9s avatar Apr 07 '23 06:04 c9s

Here is the simple test code, if you want to reproduce this:

package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	done := make(chan struct{})
	ctx, cancel := context.WithCancel(context.Background())

	go func() {
		ticker := time.NewTicker(time.Second)

		defer close(done)
		for {
			select {
			case <-ctx.Done():
				fmt.Println("ticker shutting down")
				for i := 0; i < 10; i++ {
					time.Sleep(1 * time.Second)
					fmt.Println(i)
				}
				fmt.Println("ticker shut down")
				return

			case t := <-ticker.C:
				fmt.Println(t)
			}
		}
	}()

	sig := make(chan os.Signal, 1)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
	fmt.Println("blocking, press ctrl+c to continue...")
	s := <-sig // Will block here until user hits ctrl+c
	fmt.Println("sig received", s)
	cancel()

	fmt.Println("waiting for done")
	<-done
	fmt.Println("done")
}

c9s avatar Apr 07 '23 06:04 c9s