A privacy-first, self-hosted, fully open source personal knowledge management software, written in typescript and golang. (PERSONAL FORK)
at lambda-fork/main 141 lines 3.4 kB view raw
1// SiYuan - Refactor your thinking 2// Copyright (c) 2020-present, b3log.org 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU Affero General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU Affero General Public License for more details. 13// 14// You should have received a copy of the GNU Affero General Public License 15// along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17package model 18 19import ( 20 "os" 21 "os/signal" 22 "strconv" 23 "strings" 24 "syscall" 25 "time" 26 27 goPS "github.com/mitchellh/go-ps" 28 "github.com/siyuan-note/logging" 29 "github.com/siyuan-note/siyuan/kernel/util" 30) 31 32func HandleSignal() { 33 c := make(chan os.Signal) 34 signal.Notify(c, syscall.SIGINT, syscall.SIGQUIT, syscall.SIGTERM) 35 s := <-c 36 logging.LogInfof("received os signal [%s], exit kernel process now", s) 37 Close(false, true, 1) 38} 39 40var ( 41 firstRunHookDesktopUIProcJob = true 42) 43 44func HookDesktopUIProcJob() { 45 if util.ContainerStd != util.Container || "dev" == util.Mode { 46 return 47 } 48 49 if firstRunHookDesktopUIProcJob { 50 // 等待启动结束再监控 51 time.Sleep(30 * time.Second) 52 firstRunHookDesktopUIProcJob = false 53 return 54 } 55 56 if 0 < util.CountSessions() { 57 // 如果存在活动的会话则说明 UI 进程还在运行 58 return 59 } 60 61 uiProcCount := getAttachedUIProcCount() 62 if 0 < uiProcCount { 63 return 64 } 65 66 logging.LogWarnf("no active UI proc, continue to check from attached ui processes after 15s") 67 time.Sleep(15 * time.Second) 68 uiProcCount = getAttachedUIProcCount() 69 if 0 < uiProcCount { 70 return 71 } 72 logging.LogWarnf("no active UI proc, continue to check from all processes after 15s") 73 time.Sleep(15 * time.Second) 74 uiProcCount = getUIProcCount() 75 if 0 < uiProcCount { 76 logging.LogInfof("active UI proc count [%d]", uiProcCount) 77 return 78 } 79 80 logging.LogWarnf("confirmed no active UI proc, exit kernel process now") 81 Close(false, true, 1) 82} 83 84var uiProcNames = []string{"siyuan", "electron"} 85 86// getAttachedUIProcCount 获取已经附加的 UI 进程数。 87func getAttachedUIProcCount() (ret int) { 88 util.UIProcessIDs.Range(func(uiProcIDArg, _ interface{}) bool { 89 uiProcID, err := strconv.Atoi(uiProcIDArg.(string)) 90 if err != nil { 91 logging.LogErrorf("invalid UI proc ID [%s]: %s", uiProcIDArg, err) 92 return true 93 } 94 95 proc, err := goPS.FindProcess(uiProcID) 96 if err != nil { 97 logging.LogErrorf("find UI proc [%d] failed: %s", uiProcID, err) 98 return true 99 } 100 101 if nil == proc { 102 return true 103 } 104 105 procName := strings.ToLower(proc.Executable()) 106 uiProcOk := false 107 for _, name := range uiProcNames { 108 if uiProcOk = strings.Contains(procName, name); uiProcOk { 109 break 110 } 111 } 112 if uiProcOk { 113 ret++ 114 } 115 return true 116 }) 117 return 118} 119 120// getUIProcCount 获取 UI 进程数。 121func getUIProcCount() (ret int) { 122 pid := os.Getpid() 123 procs, _ := goPS.Processes() 124 for _, proc := range procs { 125 if proc.Pid() == pid { 126 continue 127 } 128 129 procName := strings.ToLower(proc.Executable()) 130 uiProcOk := false 131 for _, name := range uiProcNames { 132 if uiProcOk = strings.Contains(procName, name); uiProcOk { 133 break 134 } 135 } 136 if uiProcOk { 137 ret++ 138 } 139 } 140 return 141}