Skip to content

Commit 9f69e95

Browse files
authored
refactor(bootstrap): move booting logic to bootstrap package (#57)
* refactor(bootstrap): move booting logic to bootstrap package * fix: add register hook
1 parent 9bb8e98 commit 9f69e95

File tree

1 file changed

+24
-203
lines changed

1 file changed

+24
-203
lines changed

openlist-lib/openlistlib/server.go

Lines changed: 24 additions & 203 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,13 @@
11
package openlistlib
22

33
import (
4-
"context"
54
"errors"
6-
"fmt"
7-
"net"
8-
"net/http"
9-
"os"
10-
"strconv"
115
"time"
126

13-
"github.com/OpenListTeam/OpenList/v4/openlistlib/internal"
14-
"github.com/OpenListTeam/OpenList/v4/cmd"
15-
"github.com/OpenListTeam/OpenList/v4/cmd/flags"
167
"github.com/OpenListTeam/OpenList/v4/internal/bootstrap"
17-
"github.com/OpenListTeam/OpenList/v4/internal/conf"
188
"github.com/OpenListTeam/OpenList/v4/internal/db"
9+
"github.com/OpenListTeam/OpenList/v4/openlistlib/internal"
1910
"github.com/OpenListTeam/OpenList/v4/pkg/utils"
20-
"github.com/OpenListTeam/OpenList/v4/server"
21-
"github.com/OpenListTeam/sftpd-openlist"
22-
ftpserver "github.com/fclairamb/ftpserverlib"
23-
"github.com/gin-gonic/gin"
2411
log "github.com/sirupsen/logrus"
2512
)
2613

@@ -34,12 +21,22 @@ type Event interface {
3421
OnProcessExit(code int)
3522
}
3623

37-
var event Event
24+
var startFailedHookUuid = ""
25+
var shutdownHookUuid = ""
3826
var logFormatter *internal.MyFormatter
3927

40-
func Init(e Event, cb LogCallback) error {
41-
event = e
42-
cmd.Init()
28+
func Init(event Event, cb LogCallback) error {
29+
if startFailedHookUuid != "" {
30+
bootstrap.RemoveEndpointStartFailedHook(startFailedHookUuid)
31+
startFailedHookUuid = ""
32+
}
33+
if shutdownHookUuid != "" {
34+
bootstrap.RemoveEndpointShutdownHook(shutdownHookUuid)
35+
shutdownHookUuid = ""
36+
}
37+
bootstrap.Init()
38+
startFailedHookUuid = bootstrap.RegisterEndpointStartFailedHook(event.OnStartError)
39+
shutdownHookUuid = bootstrap.RegisterEndpointShutdownHook(event.OnShutdown)
4340
logFormatter = &internal.MyFormatter{
4441
OnLog: func(entry *log.Entry) {
4542
cb.OnLog(int16(entry.Level), entry.Time.UnixMilli(), entry.Message)
@@ -54,206 +51,30 @@ func Init(e Event, cb LogCallback) error {
5451
return nil
5552
}
5653

57-
var httpSrv, httpsSrv, unixSrv *http.Server
58-
59-
func listenAndServe(t string, srv *http.Server) {
60-
err := srv.ListenAndServe()
61-
if err != nil && err != http.ErrServerClosed {
62-
event.OnStartError(t, err.Error())
63-
} else {
64-
event.OnShutdown(t)
65-
}
66-
}
67-
6854
func IsRunning(t string) bool {
69-
switch t {
70-
case "http":
71-
return httpSrv != nil
72-
case "https":
73-
return httpsSrv != nil
74-
case "unix":
75-
return unixSrv != nil
76-
}
77-
78-
return httpSrv != nil && httpsSrv != nil && unixSrv != nil
55+
return bootstrap.IsRunning(t)
7956
}
8057

8158
// Start starts the server
8259
func Start() {
83-
if conf.Conf.DelayedStart != 0 {
84-
utils.Log.Infof("delayed start for %d seconds", conf.Conf.DelayedStart)
85-
time.Sleep(time.Duration(conf.Conf.DelayedStart) * time.Second)
86-
}
87-
bootstrap.InitOfflineDownloadTools()
88-
bootstrap.LoadStorages()
89-
bootstrap.InitTaskManager()
90-
if !flags.Debug && !flags.Dev {
91-
gin.SetMode(gin.ReleaseMode)
92-
}
93-
r := gin.New()
94-
r.Use(gin.LoggerWithWriter(log.StandardLogger().Out), gin.RecoveryWithWriter(log.StandardLogger().Out))
95-
server.Init(r)
96-
97-
if conf.Conf.Scheme.HttpPort != -1 {
98-
httpBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpPort)
99-
utils.Log.Infof("start HTTP server @ %s", httpBase)
100-
httpSrv = &http.Server{Addr: httpBase, Handler: r}
101-
go func() {
102-
listenAndServe("http", httpSrv)
103-
httpSrv = nil
104-
}()
105-
}
106-
if conf.Conf.Scheme.HttpsPort != -1 {
107-
httpsBase := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.Scheme.HttpsPort)
108-
utils.Log.Infof("start HTTPS server @ %s", httpsBase)
109-
httpsSrv = &http.Server{Addr: httpsBase, Handler: r}
110-
go func() {
111-
listenAndServe("https", httpsSrv)
112-
httpsSrv = nil
113-
}()
114-
}
115-
if conf.Conf.Scheme.UnixFile != "" {
116-
utils.Log.Infof("start unix server @ %s", conf.Conf.Scheme.UnixFile)
117-
unixSrv = &http.Server{Handler: r}
118-
go func() {
119-
listener, err := net.Listen("unix", conf.Conf.Scheme.UnixFile)
120-
if err != nil {
121-
//utils.Log.Fatalf("failed to listenAndServe unix: %+v", err)
122-
event.OnStartError("unix", err.Error())
123-
} else {
124-
// set socket file permission
125-
mode, err := strconv.ParseUint(conf.Conf.Scheme.UnixFilePerm, 8, 32)
126-
if err != nil {
127-
utils.Log.Errorf("failed to parse socket file permission: %+v", err)
128-
} else {
129-
err = os.Chmod(conf.Conf.Scheme.UnixFile, os.FileMode(mode))
130-
if err != nil {
131-
utils.Log.Errorf("failed to chmod socket file: %+v", err)
132-
}
133-
}
134-
err = unixSrv.Serve(listener)
135-
if err != nil && err != http.ErrServerClosed {
136-
event.OnStartError("unix", err.Error())
137-
}
138-
}
139-
140-
unixSrv = nil
141-
}()
142-
}
143-
if conf.Conf.S3.Port != -1 && conf.Conf.S3.Enable {
144-
s3r := gin.New()
145-
s3r.Use(gin.LoggerWithWriter(log.StandardLogger().Out), gin.RecoveryWithWriter(log.StandardLogger().Out))
146-
server.InitS3(s3r)
147-
s3Base := fmt.Sprintf("%s:%d", conf.Conf.Scheme.Address, conf.Conf.S3.Port)
148-
fmt.Printf("start S3 server @ %s\n", s3Base)
149-
utils.Log.Infof("start S3 server @ %s", s3Base)
150-
go func() {
151-
var err error
152-
if conf.Conf.S3.SSL {
153-
httpsSrv = &http.Server{Addr: s3Base, Handler: s3r}
154-
err = httpsSrv.ListenAndServeTLS(conf.Conf.Scheme.CertFile, conf.Conf.Scheme.KeyFile)
155-
}
156-
if !conf.Conf.S3.SSL {
157-
httpSrv = &http.Server{Addr: s3Base, Handler: s3r}
158-
err = httpSrv.ListenAndServe()
159-
}
160-
if err != nil && !errors.Is(err, http.ErrServerClosed) {
161-
utils.Log.Fatalf("failed to start s3 server: %s", err.Error())
162-
}
163-
}()
164-
}
165-
var ftpDriver *server.FtpMainDriver
166-
var ftpServer *ftpserver.FtpServer
167-
if conf.Conf.FTP.Listen != "" && conf.Conf.FTP.Enable {
168-
var err error
169-
ftpDriver, err = server.NewMainDriver()
170-
if err != nil {
171-
utils.Log.Fatalf("failed to start ftp driver: %s", err.Error())
172-
} else {
173-
fmt.Printf("start ftp server on %s\n", conf.Conf.FTP.Listen)
174-
utils.Log.Infof("start ftp server on %s", conf.Conf.FTP.Listen)
175-
go func() {
176-
ftpServer = ftpserver.NewFtpServer(ftpDriver)
177-
err = ftpServer.ListenAndServe()
178-
if err != nil {
179-
utils.Log.Fatalf("problem ftp server listening: %s", err.Error())
180-
}
181-
}()
182-
}
183-
}
184-
var sftpDriver *server.SftpDriver
185-
var sftpServer *sftpd.SftpServer
186-
if conf.Conf.SFTP.Listen != "" && conf.Conf.SFTP.Enable {
187-
var err error
188-
sftpDriver, err = server.NewSftpDriver()
189-
if err != nil {
190-
utils.Log.Fatalf("failed to start sftp driver: %s", err.Error())
191-
} else {
192-
fmt.Printf("start sftp server on %s", conf.Conf.SFTP.Listen)
193-
utils.Log.Infof("start sftp server on %s", conf.Conf.SFTP.Listen)
194-
go func() {
195-
sftpServer = sftpd.NewSftpServer(sftpDriver)
196-
err = sftpServer.RunServer()
197-
if err != nil {
198-
utils.Log.Fatalf("problem sftp server listening: %s", err.Error())
199-
}
200-
}()
201-
}
202-
}
203-
}
204-
205-
func shutdown(srv *http.Server, timeout time.Duration) error {
206-
if srv == nil {
207-
return nil
208-
}
209-
210-
ctx, cancel := context.WithTimeout(context.Background(), timeout)
211-
defer cancel()
212-
213-
err := srv.Shutdown(ctx)
214-
215-
return err
60+
bootstrap.Start()
21661
}
21762

21863
// Shutdown timeout 毫秒
21964
func Shutdown(timeout int64) (err error) {
22065
timeoutDuration := time.Duration(timeout) * time.Millisecond
221-
utils.Log.Println("Shutdown server...")
222-
if conf.Conf.Scheme.HttpPort != -1 {
223-
err := shutdown(httpSrv, timeoutDuration)
224-
if err != nil {
225-
return err
226-
}
227-
httpSrv = nil
228-
utils.Log.Println("Server HTTP Shutdown")
229-
}
230-
if conf.Conf.Scheme.HttpsPort != -1 {
231-
err := shutdown(httpsSrv, timeoutDuration)
232-
if err != nil {
233-
return err
234-
}
235-
httpsSrv = nil
236-
utils.Log.Println("Server HTTPS Shutdown")
237-
}
238-
if conf.Conf.Scheme.UnixFile != "" {
239-
err := shutdown(unixSrv, timeoutDuration)
240-
if err != nil {
241-
return err
242-
}
243-
unixSrv = nil
244-
utils.Log.Println("Server UNIX Shutdown")
245-
}
66+
bootstrap.Shutdown(timeoutDuration)
24667

24768
// Force database sync before shutdown
24869
ForceDBSync()
249-
//cmd.Release()
70+
//bootstrap.Release()
25071
return nil
25172
}
25273

25374
// ForceDBSync forces SQLite WAL checkpoint to sync data to main database file
25475
func ForceDBSync() error {
25576
log.Info("Forcing database sync (WAL checkpoint)...")
256-
77+
25778
// Get the database instance and execute WAL checkpoint
25879
gormDB := db.GetDb()
25980
if gormDB != nil {
@@ -262,24 +83,24 @@ func ForceDBSync() error {
26283
log.Errorf("Failed to get database connection: %v", err)
26384
return err
26485
}
265-
86+
26687
// Execute WAL checkpoint with TRUNCATE mode to force sync and remove WAL files
26788
_, err = sqlDB.Exec("PRAGMA wal_checkpoint(TRUNCATE)")
26889
if err != nil {
26990
log.Errorf("Failed to execute WAL checkpoint: %v", err)
27091
return err
27192
}
272-
93+
27394
// Also execute synchronous commit to ensure data is written to disk
27495
_, err = sqlDB.Exec("PRAGMA synchronous=FULL")
27596
if err != nil {
27697
log.Warnf("Failed to set synchronous mode: %v", err)
27798
}
278-
99+
279100
log.Info("Database sync completed successfully")
280101
} else {
281102
log.Warn("Database instance is nil, skipping sync")
282103
}
283-
104+
284105
return nil
285106
}

0 commit comments

Comments
 (0)