diff --git a/kernel/model/conf.go b/kernel/model/conf.go index e489ca151..b94bfa986 100644 --- a/kernel/model/conf.go +++ b/kernel/model/conf.go @@ -18,6 +18,7 @@ package model import ( "bytes" + "fmt" "os" "path/filepath" "runtime" @@ -396,6 +397,7 @@ func Close(force bool, execInstallPkg int) (exitCode int) { Conf.Close() sql.CloseDatabase() clearWorkspaceTemp() + clearPortJSON() go func() { time.Sleep(500 * time.Millisecond) @@ -607,6 +609,34 @@ func GetMaskedConf() (ret *AppConf, err error) { return } +func clearPortJSON() { + pid := fmt.Sprintf("%d", os.Getpid()) + portJSON := filepath.Join(util.HomeDir, ".config", "siyuan", "port.json") + pidPorts := map[string]string{} + var data []byte + var err error + + if gulu.File.IsExist(portJSON) { + data, err = os.ReadFile(portJSON) + if nil != err { + logging.LogWarnf("read port.json failed: %s", err) + } else { + if err = gulu.JSON.UnmarshalJSON(data, &pidPorts); nil != err { + logging.LogWarnf("unmarshal port.json failed: %s", err) + } + } + } + + delete(pidPorts, pid) + if data, err = gulu.JSON.MarshalIndentJSON(pidPorts, "", " "); nil != err { + logging.LogWarnf("marshal port.json failed: %s", err) + } else { + if err = os.WriteFile(portJSON, data, 0644); nil != err { + logging.LogWarnf("write port.json failed: %s", err) + } + } +} + func clearWorkspaceTemp() { os.RemoveAll(filepath.Join(util.TempDir, "bazaar")) os.RemoveAll(filepath.Join(util.TempDir, "export")) diff --git a/kernel/model/index.go b/kernel/model/index.go index 0087a6f88..6d52e5c9d 100644 --- a/kernel/model/index.go +++ b/kernel/model/index.go @@ -191,72 +191,6 @@ func IndexRefs() { util.SetBootDetails("Resolving refs...") util.PushEndlessProgress(Conf.Language(54)) - context := map[string]interface{}{eventbus.CtxPushMsg: eventbus.CtxPushMsgToStatusBarAndProgress} - // 解析并更新引用块 - util.SetBootDetails("Resolving ref block content...") - refUnresolvedBlocks := sql.GetRefUnresolvedBlocks() // TODO: v2.2.0 以后移除 - if 0 < len(refUnresolvedBlocks) { - dynamicRefTreeIDs := hashset.New() - bootProgressPart := 10.0 / float64(len(refUnresolvedBlocks)) - anchors := map[string]string{} - var refBlockIDs []string - for i, refBlock := range refUnresolvedBlocks { - util.IncBootProgress(bootProgressPart, "Resolving ref block content "+util.ShortPathForBootingDisplay(refBlock.ID)) - tx, err := sql.BeginTx() - if nil != err { - return - } - blockContent := sql.ResolveRefContent(refBlock, &anchors) - refBlock.Content = blockContent - refBlockIDs = append(refBlockIDs, refBlock.ID) - dynamicRefTreeIDs.Add(refBlock.RootID) - sql.CommitTx(tx) - if 1 < i && 0 == i%64 { - util.PushEndlessProgress(fmt.Sprintf(Conf.Language(53), i, len(refUnresolvedBlocks)-i)) - } - } - - // 将需要更新动态引用文本内容的块先删除,后面会重新插入,这样比直接 update 快很多 - util.SetBootDetails("Deleting unresolved block content...") - tx, err := sql.BeginTx() - if nil != err { - return - } - sql.DeleteBlockByIDs(tx, refBlockIDs) - sql.CommitTx(tx) - - bootProgressPart = 10.0 / float64(len(refUnresolvedBlocks)) - for i, refBlock := range refUnresolvedBlocks { - util.IncBootProgress(bootProgressPart, "Updating block content "+util.ShortPathForBootingDisplay(refBlock.ID)) - tx, err = sql.BeginTx() - if nil != err { - return - } - sql.InsertBlock(tx, refBlock, context) - sql.CommitTx(tx) - if 1 < i && 0 == i%64 { - util.PushEndlessProgress(fmt.Sprintf(Conf.Language(53), i, len(refUnresolvedBlocks)-i)) - } - } - - if 0 < dynamicRefTreeIDs.Size() { - // 块引锚文本静态化 - for _, dynamicRefTreeIDVal := range dynamicRefTreeIDs.Values() { - dynamicRefTreeID := dynamicRefTreeIDVal.(string) - util.IncBootProgress(bootProgressPart, "Persisting block ref text "+util.ShortPathForBootingDisplay(dynamicRefTreeID)) - tree, err := loadTreeByBlockID(dynamicRefTreeID) - if nil != err { - logging.LogErrorf("tree [%s] dynamic ref text to static failed: %s", dynamicRefTreeID, err) - continue - } - - if err := filesys.WriteTree(tree); nil == err { - //logging.LogInfof("persisted tree [%s] dynamic ref text", tree.Box+tree.Path) - } - } - } - } - // 引用入库 util.SetBootDetails("Indexing refs...") refBlocks := sql.GetRefExistedBlocks() diff --git a/kernel/server/serve.go b/kernel/server/serve.go index 21e67b291..cee2aee03 100644 --- a/kernel/server/serve.go +++ b/kernel/server/serve.go @@ -17,6 +17,8 @@ package server import ( + "fmt" + "net" "net/http" "net/http/pprof" "os" @@ -70,20 +72,70 @@ func Serve(fastMode bool) { serveTemplates(ginServer) api.ServeAPI(ginServer) - var addr string + var host string if model.Conf.System.NetworkServe || util.ContainerDocker == util.Container { - addr = "0.0.0.0:" + util.ServerPort + host = "0.0.0.0" } else { - addr = "127.0.0.1:" + util.ServerPort + host = "127.0.0.1" } - logging.LogInfof("kernel is booting [%s]", "http://"+addr) - util.HttpServing = true - if err := ginServer.Run(addr); nil != err { + + ln, err := net.Listen("tcp", ":"+util.ServerPort) + if nil != err { if !fastMode { logging.LogErrorf("boot kernel failed: %s", err) os.Exit(util.ExitCodeUnavailablePort) } } + + _, port, err := net.SplitHostPort(ln.Addr().String()) + if nil != err { + if !fastMode { + logging.LogErrorf("boot kernel failed: %s", err) + os.Exit(util.ExitCodeUnavailablePort) + } + } + + pid := fmt.Sprintf("%d", os.Getpid()) + if !fastMode { + rewritePortJSON(pid, port) + } + + logging.LogInfof("kernel [pid=%s] is booting [%s]", pid, "http://"+host+":"+port) + util.HttpServing = true + + if err = http.Serve(ln, ginServer); nil != err { + if !fastMode { + logging.LogErrorf("boot kernel failed: %s", err) + os.Exit(util.ExitCodeUnavailablePort) + } + } +} + +func rewritePortJSON(pid, port string) { + portJSON := filepath.Join(util.HomeDir, ".config", "siyuan", "port.json") + pidPorts := map[string]string{} + var data []byte + var err error + + if gulu.File.IsExist(portJSON) { + data, err = os.ReadFile(portJSON) + if nil != err { + logging.LogWarnf("read port.json failed: %s", err) + } else { + if err = gulu.JSON.UnmarshalJSON(data, &pidPorts); nil != err { + logging.LogWarnf("unmarshal port.json failed: %s", err) + } + } + } + + pidPorts[pid] = port + if data, err = gulu.JSON.MarshalIndentJSON(pidPorts, "", " "); nil != err { + logging.LogWarnf("marshal port.json failed: %s", err) + } else { + if err = os.WriteFile(portJSON, data, 0644); nil != err { + logging.LogWarnf("write port.json failed: %s", err) + } + } } func serveExport(ginServer *gin.Engine) { diff --git a/kernel/sql/block_query.go b/kernel/sql/block_query.go index 4b694137f..a98b23794 100644 --- a/kernel/sql/block_query.go +++ b/kernel/sql/block_query.go @@ -550,22 +550,6 @@ func GetAllChildBlocks(rootID, condition string) (ret []*Block) { return } -func GetRefUnresolvedBlocks() (ret []*Block) { - stmt := "SELECT * FROM blocks WHERE content LIKE ?" - rows, err := query(stmt, "%ref resolve failed%") - if nil != err { - logging.LogErrorf("sql query [%s] failed: %s", stmt, err) - return - } - defer rows.Close() - for rows.Next() { - if block := scanBlockRows(rows); nil != block { - ret = append(ret, block) - } - } - return -} - func GetRefExistedBlocks() (ret []*Block) { stmt := "SELECT * FROM blocks WHERE markdown LIKE ? OR markdown LIKE ?" rows, err := query(stmt, "%((20%", "%<<20%") diff --git a/kernel/util/working.go b/kernel/util/working.go index 515cdc389..72dd02561 100644 --- a/kernel/util/working.go +++ b/kernel/util/working.go @@ -110,8 +110,6 @@ func Boot() { bootBanner := figure.NewColorFigure("SiYuan", "isometric3", "green", true) logging.LogInfof("\n" + bootBanner.String()) logBootInfo() - - go cleanOld() } func setBootDetails(details string) { @@ -322,17 +320,6 @@ func initPathDir() { } } -// TODO: v2.2.0 移除 -func cleanOld() { - dirs, _ := os.ReadDir(WorkingDir) - for _, dir := range dirs { - if strings.HasSuffix(dir.Name(), ".old") { - old := filepath.Join(WorkingDir, dir.Name()) - os.RemoveAll(old) - } - } -} - func checkPort() { portOpened := isPortOpen(ServerPort) if !portOpened {