mirror of
https://github.com/openimsdk/open-im-server.git
synced 2026-04-28 14:29:19 +08:00
fix: refactoring code of graceful exits (#1885)
* fix: plant a layer * fix: print chanal * fix: print sigs * fix: print the sigs * fix: reconstruct exit gracefully * fix: fix the timeout * fix: fix the netDone * fix: fix the process exit * fix: refactor the elegant startup code * fix: fix the Signal.Notify * fix: fix the code * fix: remove not used header import. * Update init.go * fix: fix the InitConfig error * fix: fix branch name * fix: fix the signal value * fix: replace the signal with SIGTERM * fix: fix the script * fix: fix the unsolve error * fix: return the SIGTERM received,shutting down * fix: fix the tranfer exit error * fix: fix the error * fix: replace the SIGnal * fix: del the error return in tranfer * fix: fix SIGTERM error * fix: del the unreachalbe code * fix: fix the make stop print error --------- Co-authored-by: OpenIM-Gordon <46924906+FGadvancer@users.noreply.github.com> Co-authored-by: Xinwei Xiong (cubxxw) <3293172751nss@gmail.com>
This commit is contained in:
@@ -15,8 +15,11 @@
|
||||
package startrpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
util "github.com/openimsdk/open-im-server/v3/pkg/util/genutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -26,14 +29,10 @@ import (
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/OpenIMSDK/tools/errs"
|
||||
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/config"
|
||||
"github.com/openimsdk/open-im-server/v3/pkg/common/prommetrics"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
|
||||
grpcprometheus "github.com/grpc-ecosystem/go-grpc-prometheus"
|
||||
"google.golang.org/grpc"
|
||||
@@ -56,12 +55,13 @@ func Start(
|
||||
) error {
|
||||
fmt.Printf("start %s server, port: %d, prometheusPort: %d, OpenIM version: %s\n",
|
||||
rpcRegisterName, rpcPort, prometheusPort, config.Version)
|
||||
rpcTcpAddr := net.JoinHostPort(network.GetListenIP(config.Config.Rpc.ListenIP), strconv.Itoa(rpcPort))
|
||||
listener, err := net.Listen(
|
||||
"tcp",
|
||||
net.JoinHostPort(network.GetListenIP(config.Config.Rpc.ListenIP), strconv.Itoa(rpcPort)),
|
||||
rpcTcpAddr,
|
||||
)
|
||||
if err != nil {
|
||||
return errs.Wrap(err, network.GetListenIP(config.Config.Rpc.ListenIP), strconv.Itoa(rpcPort))
|
||||
return errs.Wrap(err, "rpc start err", rpcTcpAddr)
|
||||
}
|
||||
|
||||
defer listener.Close()
|
||||
@@ -108,46 +108,64 @@ func Start(
|
||||
return errs.Wrap(err)
|
||||
}
|
||||
|
||||
var wg errgroup.Group
|
||||
|
||||
wg.Go(func() error {
|
||||
var (
|
||||
netDone = make(chan struct{}, 2)
|
||||
netErr error
|
||||
httpServer *http.Server
|
||||
)
|
||||
go func() {
|
||||
if config.Config.Prometheus.Enable && prometheusPort != 0 {
|
||||
metric.InitializeMetrics(srv)
|
||||
// Create a HTTP server for prometheus.
|
||||
httpServer := &http.Server{Handler: promhttp.HandlerFor(reg, promhttp.HandlerOpts{}), Addr: fmt.Sprintf("0.0.0.0:%d", prometheusPort)}
|
||||
if err := httpServer.ListenAndServe(); err != nil {
|
||||
fmt.Fprintf(os.Stderr, "\n\nexit -1: \n%+v PrometheusPort: %d \n\n", err, prometheusPort)
|
||||
os.Exit(-1)
|
||||
httpServer = &http.Server{Handler: promhttp.HandlerFor(reg, promhttp.HandlerOpts{}), Addr: fmt.Sprintf("0.0.0.0:%d", prometheusPort)}
|
||||
if err := httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
netErr = errs.Wrap(err, "prometheus start err", httpServer.Addr)
|
||||
netDone <- struct{}{}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
wg.Go(func() error {
|
||||
return errs.Wrap(srv.Serve(listener))
|
||||
})
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
|
||||
<-sigs
|
||||
|
||||
var (
|
||||
done = make(chan struct{}, 1)
|
||||
gerr error
|
||||
)
|
||||
|
||||
go func() {
|
||||
once.Do(srv.GracefulStop)
|
||||
gerr = wg.Wait()
|
||||
close(done)
|
||||
}()
|
||||
|
||||
go func() {
|
||||
err := srv.Serve(listener)
|
||||
if err != nil {
|
||||
netErr = errs.Wrap(err, "rpc start err: ", rpcTcpAddr)
|
||||
netDone <- struct{}{}
|
||||
}
|
||||
}()
|
||||
|
||||
sigs := make(chan os.Signal, 1)
|
||||
signal.Notify(sigs, syscall.SIGTERM)
|
||||
select {
|
||||
case <-done:
|
||||
return gerr
|
||||
|
||||
case <-time.After(15 * time.Second):
|
||||
return errs.Wrap(errors.New("timeout exit"))
|
||||
case <-sigs:
|
||||
util.SIGUSR1Exit()
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
if err := gracefulStopWithCtx(ctx, srv.GracefulStop); err != nil {
|
||||
return err
|
||||
}
|
||||
ctx, cancel = context.WithTimeout(context.Background(), 15*time.Second)
|
||||
defer cancel()
|
||||
err := httpServer.Shutdown(ctx)
|
||||
if err != nil {
|
||||
return errs.Wrap(err, "shutdown err")
|
||||
}
|
||||
return errors.New("SIGTERM EXIT")
|
||||
case <-netDone:
|
||||
close(netDone)
|
||||
return netErr
|
||||
}
|
||||
}
|
||||
|
||||
func gracefulStopWithCtx(ctx context.Context, f func()) error {
|
||||
done := make(chan struct{}, 1)
|
||||
go func() {
|
||||
f()
|
||||
close(done)
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return errs.Wrap(errors.New("timeout, ctx graceful stop"))
|
||||
case <-done:
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user