github.com/zntrio/harp/v2@v2.0.9/pkg/sdk/platform/reloader/reloader_other.go (about) 1 // Licensed to Elasticsearch B.V. under one or more contributor 2 // license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright 4 // ownership. Elasticsearch B.V. licenses this file to you under 5 // the Apache License, Version 2.0 (the "License"); you may 6 // not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 //go:build !windows 19 // +build !windows 20 21 package reloader 22 23 import ( 24 "context" 25 "os" 26 "os/signal" 27 "syscall" 28 29 "github.com/cloudflare/tableflip" 30 "github.com/oklog/run" 31 32 "github.com/zntrio/harp/v2/pkg/sdk/log" 33 ) 34 35 // TableflipReloader deleagtes socket reloading to tableflip library which his 36 // not windows compatible. 37 type TableflipReloader struct { 38 *tableflip.Upgrader 39 } 40 41 // Create a descriptor reload based on tableflip. 42 func Create(ctx context.Context) Reloader { 43 upg, _ := tableflip.New(tableflip.Options{}) 44 45 // Do an upgrade on SIGHUP 46 go func() { 47 ch := make(chan os.Signal, 1) 48 signal.Notify(ch, syscall.SIGHUP) 49 for range ch { 50 log.For(ctx).Warn("Graceful reloading socket descriptor") 51 _ = upg.Upgrade() 52 } 53 }() 54 55 return &TableflipReloader{upg} 56 } 57 58 // SetupGracefulRestart arms the graceful restart handler. 59 func (t *TableflipReloader) SetupGracefulRestart(ctx context.Context, group run.Group) { 60 ctx, cancel := context.WithCancel(ctx) 61 62 // Register an actor, i.e. an execute and interrupt func, that 63 // terminates when graceful restart is initiated and the child process 64 // signals to be ready, or the parent context is canceled. 65 group.Add(func() error { 66 // Tell the parent we are ready 67 err := t.Ready() 68 if err != nil { 69 return err 70 } 71 72 select { 73 case <-t.Exit(): // Wait for child to be ready (or application shutdown) 74 return nil 75 76 case <-ctx.Done(): 77 return ctx.Err() 78 } 79 }, func(error) { 80 cancel() 81 t.Stop() 82 }) 83 }