mirror of
				https://gitcode.com/gitea/gitea.git
				synced 2025-10-26 05:04:27 +08:00 
			
		
		
		
	 e3c3b33ea7
			
		
	
	e3c3b33ea7
	
	
	
		
			
			* Change graceful to use a singleton obtained through GetManager instead of a global. * Graceful: Make TestPullRequests shutdownable * Graceful: Make the cron tasks graceful * Graceful: AddTestPullRequest run in graceful ctx * Graceful: SyncMirrors shutdown * Graceful: SetDefaultContext for Xorm to be HammerContext * Avoid starting graceful for migrate commands and checkout * Graceful: DeliverHooks now can be shutdown * Fix multiple syncing errors in modules/sync/UniqueQueue & Make UniqueQueue closable * Begin the process of making the repo indexer shutdown gracefully
		
			
				
	
	
		
			87 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			87 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // +build !windows
 | |
| 
 | |
| // Copyright 2019 The Gitea Authors. All rights reserved.
 | |
| // Use of this source code is governed by a MIT-style
 | |
| // license that can be found in the LICENSE file.
 | |
| // This code is heavily inspired by the archived gofacebook/gracenet/net.go handler
 | |
| 
 | |
| package graceful
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"net"
 | |
| 	"os"
 | |
| 	"os/exec"
 | |
| 	"strings"
 | |
| 	"sync"
 | |
| 	"syscall"
 | |
| )
 | |
| 
 | |
| var killParent sync.Once
 | |
| 
 | |
| // KillParent sends the kill signal to the parent process if we are a child
 | |
| func KillParent() {
 | |
| 	killParent.Do(func() {
 | |
| 		if GetManager().IsChild() {
 | |
| 			ppid := syscall.Getppid()
 | |
| 			if ppid > 1 {
 | |
| 				_ = syscall.Kill(ppid, syscall.SIGTERM)
 | |
| 			}
 | |
| 		}
 | |
| 	})
 | |
| }
 | |
| 
 | |
| // RestartProcess starts a new process passing it the active listeners. It
 | |
| // doesn't fork, but starts a new process using the same environment and
 | |
| // arguments as when it was originally started. This allows for a newly
 | |
| // deployed binary to be started. It returns the pid of the newly started
 | |
| // process when successful.
 | |
| func RestartProcess() (int, error) {
 | |
| 	listeners := getActiveListeners()
 | |
| 
 | |
| 	// Extract the fds from the listeners.
 | |
| 	files := make([]*os.File, len(listeners))
 | |
| 	for i, l := range listeners {
 | |
| 		var err error
 | |
| 		// Now, all our listeners actually have File() functions so instead of
 | |
| 		// individually casting we just use a hacky interface
 | |
| 		files[i], err = l.(filer).File()
 | |
| 		if err != nil {
 | |
| 			return 0, err
 | |
| 		}
 | |
| 
 | |
| 		if unixListener, ok := l.(*net.UnixListener); ok {
 | |
| 			unixListener.SetUnlinkOnClose(false)
 | |
| 		}
 | |
| 		// Remember to close these at the end.
 | |
| 		defer files[i].Close()
 | |
| 	}
 | |
| 
 | |
| 	// Use the original binary location. This works with symlinks such that if
 | |
| 	// the file it points to has been changed we will use the updated symlink.
 | |
| 	argv0, err := exec.LookPath(os.Args[0])
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 
 | |
| 	// Pass on the environment and replace the old count key with the new one.
 | |
| 	var env []string
 | |
| 	for _, v := range os.Environ() {
 | |
| 		if !strings.HasPrefix(v, listenFDs+"=") {
 | |
| 			env = append(env, v)
 | |
| 		}
 | |
| 	}
 | |
| 	env = append(env, fmt.Sprintf("%s=%d", listenFDs, len(listeners)))
 | |
| 
 | |
| 	allFiles := append([]*os.File{os.Stdin, os.Stdout, os.Stderr}, files...)
 | |
| 	process, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{
 | |
| 		Dir:   originalWD,
 | |
| 		Env:   env,
 | |
| 		Files: allFiles,
 | |
| 	})
 | |
| 	if err != nil {
 | |
| 		return 0, err
 | |
| 	}
 | |
| 	return process.Pid, nil
 | |
| }
 |