4 Commits

Author SHA1 Message Date
bfca8c6f4a Fix util_test.go 2025-01-30 19:59:25 -05:00
641624ef3b examples/broken: Demonstrate new fix working 2025-01-30 19:58:11 -05:00
bae737e6b8 Environment exits if shutdown takes too long 2025-01-30 19:57:40 -05:00
0077a5d115 examples/http: Fix logging 2025-01-30 19:39:37 -05:00
4 changed files with 47 additions and 7 deletions

27
examples/broken/main.go Normal file
View File

@@ -0,0 +1,27 @@
// Example broken demonstrates how the environment will forcibly kill the
// program if an actor cannot shut down.
package main
import "os"
import "log"
import "context"
import "git.tebibyte.media/sashakoshka/camfish"
func main() {
camfish.Run("broken",
"Example broken demonstrates how the environment will " +
"forcibly kill the program if an actor cannot shut down",
new(broken))
}
// broken is an incorrectly implemented actor that cannot shut down.
type broken struct { }
var _ camfish.Runnable = new(broken)
func (this *broken) Type() string { return "broken" }
func (this *broken) Run(ctx context.Context) error {
log.Println("(i) [broken] wait for approximately 8 minutes")
log.Printf("(i) [broken] if impatient, run: kill -9 %d", os.Getpid())
<- (chan struct { })(nil)
return ctx.Err() // unreachable, of course
}

View File

@@ -42,7 +42,7 @@ func (this *httpServer) Init(ctx context.Context) error {
}
func (this *httpServer) Run() error {
log.Printf("[http] listening on %s", this.server.Addr)
log.Printf("(i) [http-server] listening on %s", this.server.Addr)
err := this.server.ListenAndServe()
if errors.Is(err, http.ErrServerClosed) { return nil }
return err

View File

@@ -255,6 +255,19 @@ func (this *environment) phase70_5Trimming() bool {
}
func (this *environment) phase80Shutdown() bool {
ctx, done := context.WithTimeout(
context.Background(),
defaul(this.timing.shutdownTimeout.Load(), defaultShutdownTimeout))
defer done()
go func() {
<- ctx.Done()
if errors.Is(context.Cause(ctx), context.DeadlineExceeded) {
log.Println("XXX (80) shutdown timeout expired, performing emergency halt")
log.Printf("====== [%s] END =======", this.name)
os.Exit(1)
}
}()
cause := context.Cause(this.ctx)
if cause != nil {
log.Println("XXX (80) shutting down because:", cause)

View File

@@ -17,17 +17,17 @@ func TestDefaul(test *testing.T) {
}
func TestPanicWrap(test *testing.T) {
err := panicWrap(func (ctx context.Context) error {
err := panicWrap(func () error {
return errors.New("test case 0")
})
test.Log(err)
if err.Error() != "test case 0" { test.Fatal("not equal") }
err = panicWrap(func (ctx context.Context) error {
err = panicWrap(func () error {
panic(errors.New("test case 1"))
})
test.Log(err)
if err.Error() != "test case 1" { test.Fatal("not equal") }
err = panicWrap( func (ctx context.Context) error {
err = panicWrap( func () error {
return nil
})
test.Log(err)
@@ -35,17 +35,17 @@ func TestPanicWrap(test *testing.T) {
}
func TestPanicWrapCtx(test *testing.T) {
err := panicWrap(context.Background(), func (ctx context.Context) error {
err := panicWrapCtx(context.Background(), func (ctx context.Context) error {
return errors.New("test case 0")
})
test.Log(err)
if err.Error() != "test case 0" { test.Fatal("not equal") }
err = panicWrap(context.Background(), func (ctx context.Context) error {
err = panicWrapCtx(context.Background(), func (ctx context.Context) error {
panic(errors.New("test case 1"))
})
test.Log(err)
if err.Error() != "test case 1" { test.Fatal("not equal") }
err = panicWrap(context.Background(), func (ctx context.Context) error {
err = panicWrapCtx(context.Background(), func (ctx context.Context) error {
return nil
})
test.Log(err)