Skip to content

Commit 5c955a3

Browse files
authored
Update go server (#13589)
### What problem does this PR solve? 1. Add more CLI command 2. Add some license hooks ### Type of change - [x] New Feature (non-breaking change which adds functionality) - [x] Refactoring Signed-off-by: Jin Hai <haijin.chn@gmail.com>
1 parent ef94a9c commit 5c955a3

File tree

13 files changed

+201
-48
lines changed

13 files changed

+201
-48
lines changed

admin/client/parser.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@
9595
| list_server_configs
9696
| show_fingerprint
9797
| set_license
98+
| set_license_config
9899
| show_license
99100
| check_license
100101
| benchmark
@@ -185,6 +186,7 @@
185186
FINGERPRINT: "FINGERPRINT"i
186187
LICENSE: "LICENSE"i
187188
CHECK: "CHECK"i
189+
CONFIG: "CONFIG"i
188190
189191
login_user: LOGIN USER quoted_string ";"
190192
list_services: LIST SERVICES ";"
@@ -232,6 +234,7 @@
232234
233235
show_fingerprint: SHOW FINGERPRINT ";"
234236
set_license: SET LICENSE quoted_string ";"
237+
set_license_config: SET LICENSE CONFIG NUMBER NUMBER ";"
235238
show_license: SHOW LICENSE ";"
236239
check_license: CHECK LICENSE ";"
237240
@@ -496,6 +499,11 @@ def set_license(self, items):
496499
license = items[2].children[0].strip("'\"")
497500
return {"type": "set_license", "license": license}
498501

502+
def set_license_config(self, items):
503+
value1: int = int(items[3])
504+
value2: int = int(items[4])
505+
return {"type": "set_license_config", "value1": value1, "value2": value2}
506+
499507
def show_license(self, items):
500508
return {"type": "show_license"}
501509

admin/client/ragflow_client.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,18 @@ def set_license(self, command):
604604
else:
605605
print(f"Fail to set license, code: {res_json['code']}, message: {res_json['message']}")
606606

607+
def set_license_config(self, command):
608+
if self.server_type != "admin":
609+
print("This command is only allowed in ADMIN mode")
610+
value1 = command["value1"]
611+
value2 = command["value2"]
612+
response = self.http_client.request("POST", "/admin/license/config", json_body={"value1": value1, "value2": value2}, use_api_base=True, auth_kind="admin")
613+
res_json = response.json()
614+
if response.status_code == 200:
615+
print("Set license successfully")
616+
else:
617+
print(f"Fail to set license, code: {res_json['code']}, message: {res_json['message']}")
618+
607619
def show_license(self, command):
608620
if self.server_type != "admin":
609621
print("This command is only allowed in ADMIN mode")
@@ -1560,6 +1572,8 @@ def run_command(client: RAGFlowClient, command_dict: dict):
15601572
client.show_fingerprint(command_dict)
15611573
case "set_license":
15621574
client.set_license(command_dict)
1575+
case "set_license_config":
1576+
client.set_license_config(command_dict)
15631577
case "show_license":
15641578
client.show_license(command_dict)
15651579
case "check_license":

cmd/admin_server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func main() {
5353
flag.Parse()
5454

5555
// Initialize logger
56-
if err := logger.Init("debug"); err != nil {
56+
if err := logger.Init("info"); err != nil {
5757
panic("failed to initialize logger: " + err.Error())
5858
}
5959

cmd/server_main.go

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -242,12 +242,11 @@ func startServer(config *server.Config) {
242242
} else {
243243
// Start heartbeat reporter with 30 seconds interval
244244
heartbeatReporter := utility.NewScheduledTask("Heartbeat reporter", 3*time.Second, func() {
245-
var message string
246-
if err, message = heartbeatService.SendHeartbeat(); err == nil {
245+
if err = heartbeatService.SendHeartbeat(); err == nil {
247246
local.SetAdminStatus(0, "")
248247
} else {
249-
local.SetAdminStatus(1, message)
250-
logger.Warn("Failed to send heartbeat", zap.Error(err))
248+
local.SetAdminStatus(1, err.Error())
249+
logger.Warn(fmt.Sprintf(err.Error()))
251250
}
252251
})
253252
heartbeatReporter.Start()

internal/admin/handler.go

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,20 @@ func errorResponse(c *gin.Context, message string, code int) {
8888
})
8989
}
9090

91+
func responseWithCode(c *gin.Context, message string, httpCode int, errorCode common.ErrorCode) {
92+
if message == "" {
93+
c.JSON(httpCode, ErrorResponse{
94+
Code: int(errorCode),
95+
Message: errorCode.Message(),
96+
})
97+
} else {
98+
c.JSON(httpCode, ErrorResponse{
99+
Code: int(errorCode),
100+
Message: message,
101+
})
102+
}
103+
}
104+
91105
// Health health check
92106
func (h *Handler) Health(c *gin.Context) {
93107
c.JSON(200, gin.H{"status": "ok"})
@@ -909,6 +923,19 @@ func (h *Handler) SetLicense(c *gin.Context) {
909923
return
910924
}
911925

926+
type SetLicenseConfigHTTPRequest struct {
927+
TimeRecordSaveInterval int64 `json:"value1" binding:"required"`
928+
TimeRecordTaskDuration int64 `json:"value2" binding:"required"`
929+
}
930+
931+
func (h *Handler) UpdateLicenseConfig(c *gin.Context) {
932+
c.JSON(http.StatusNotImplemented, gin.H{
933+
"code": common.CodeServerError,
934+
"message": "method not implemented",
935+
})
936+
return
937+
}
938+
912939
// ShowLicense to get system license
913940
func (h *Handler) ShowLicense(c *gin.Context) {
914941
c.JSON(http.StatusNotImplemented, gin.H{
@@ -1092,10 +1119,11 @@ func (h *Handler) Reports(c *gin.Context) {
10921119
}
10931120

10941121
// Handle the heartbeat
1095-
if err := h.service.HandleHeartbeat(&req); err != nil {
1096-
errorResponse(c, "Failed to process heartbeat: "+err.Error(), 500)
1122+
errCode, message := h.service.HandleHeartbeat(&req)
1123+
if errCode != common.CodeLicenseValid {
1124+
responseWithCode(c, message, 500, errCode)
10971125
return
10981126
}
10991127

1100-
successNoData(c, "Heartbeat received successfully")
1128+
responseWithCode(c, message, int(http.StatusOK), errCode)
11011129
}

internal/admin/router.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ func (r *Router) Setup(engine *gin.Engine) {
116116
protected.GET("/fingerprint", r.handler.GetFingerprint)
117117
// License
118118
protected.POST("/license", r.handler.SetLicense)
119+
protected.POST("/license/config", r.handler.UpdateLicenseConfig)
119120
protected.GET("/license", r.handler.ShowLicense)
120121
}
121122
}

internal/admin/service.go

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ var (
4848
type Service struct {
4949
userDAO *dao.UserDAO
5050
licenseDAO *dao.LicenseDAO
51+
timeRecordDAO *dao.TimeRecordDAO
5152
systemSettingsDAO *dao.SystemSettingsDAO
5253
}
5354

@@ -56,6 +57,7 @@ func NewService() *Service {
5657
return &Service{
5758
userDAO: dao.NewUserDAO(),
5859
licenseDAO: dao.NewLicenseDAO(),
60+
timeRecordDAO: dao.NewTimeRecordDAO(),
5961
systemSettingsDAO: dao.NewSystemSettingsDAO(),
6062
}
6163
}
@@ -1105,19 +1107,23 @@ func (s *Service) TestSandboxConnection(providerType string, config map[string]i
11051107
}, nil
11061108
}
11071109

1110+
var heartBeatCount int64 = 0
1111+
11081112
// HandleHeartbeat handle heartbeat
1109-
func (s *Service) HandleHeartbeat(msg *common.BaseMessage) error {
1113+
func (s *Service) HandleHeartbeat(message *common.BaseMessage) (common.ErrorCode, string) {
1114+
heartBeatCount++
1115+
11101116
status := &common.BaseMessage{
1111-
ServerName: msg.ServerName,
1112-
ServerType: msg.ServerType,
1113-
Host: msg.Host,
1114-
Port: msg.Port,
1115-
Version: msg.Version,
1116-
Timestamp: msg.Timestamp,
1117-
Ext: msg.Ext,
1118-
}
1119-
GlobalServerStatusStore.UpdateStatus(msg.ServerName, status)
1120-
return nil
1117+
ServerName: message.ServerName,
1118+
ServerType: message.ServerType,
1119+
Host: message.Host,
1120+
Port: message.Port,
1121+
Version: message.Version,
1122+
Timestamp: message.Timestamp,
1123+
Ext: message.Ext,
1124+
}
1125+
GlobalServerStatusStore.UpdateStatus(message.ServerName, status)
1126+
return common.CodeLicenseValid, ""
11211127
}
11221128

11231129
// InitDefaultAdmin initialize default admin user

internal/common/error_code.go

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,64 @@ package common
1919
type ErrorCode int
2020

2121
const (
22-
CodeSuccess ErrorCode = 0
23-
CodeNotEffective ErrorCode = 10
24-
CodeExceptionError ErrorCode = 100
25-
CodeArgumentError ErrorCode = 101
26-
CodeDataError ErrorCode = 102
27-
CodeOperatingError ErrorCode = 103
28-
CodeTimeoutError ErrorCode = 104
29-
CodeConnectionError ErrorCode = 105
30-
CodeRunning ErrorCode = 106
31-
CodeResourceExhausted ErrorCode = 107
32-
CodePermissionError ErrorCode = 108
33-
CodeAuthenticationError ErrorCode = 109
34-
CodeBadRequest ErrorCode = 400
35-
CodeUnauthorized ErrorCode = 401
36-
CodeForbidden ErrorCode = 403
37-
CodeNotFound ErrorCode = 404
38-
CodeConflict ErrorCode = 409
39-
CodeServerError ErrorCode = 500
22+
CodeSuccess ErrorCode = 0
23+
CodeNotEffective ErrorCode = 10
24+
CodeExceptionError ErrorCode = 100
25+
CodeArgumentError ErrorCode = 101
26+
CodeDataError ErrorCode = 102
27+
CodeOperatingError ErrorCode = 103
28+
CodeTimeoutError ErrorCode = 104
29+
CodeConnectionError ErrorCode = 105
30+
CodeRunning ErrorCode = 106
31+
CodeResourceExhausted ErrorCode = 107
32+
CodePermissionError ErrorCode = 108
33+
CodeAuthenticationError ErrorCode = 109
34+
CodeLicenseValid ErrorCode = 320
35+
CodeLicenseInactiveError ErrorCode = 321
36+
CodeLicenseExpiredError ErrorCode = 322
37+
CodeLicenseDigestError ErrorCode = 323
38+
CodeLicenseTimeRollback ErrorCode = 324
39+
CodeLicenseNotFound ErrorCode = 325
40+
CodeLicenseUnexpectedError ErrorCode = 326
41+
CodeBadRequest ErrorCode = 400
42+
CodeUnauthorized ErrorCode = 401
43+
CodeForbidden ErrorCode = 403
44+
CodeNotFound ErrorCode = 404
45+
CodeConflict ErrorCode = 409
46+
CodeServerError ErrorCode = 500
4047
)
48+
49+
var errorMessages = map[ErrorCode]string{
50+
CodeSuccess: "Success",
51+
CodeNotEffective: "Not effective",
52+
CodeExceptionError: "System exception",
53+
CodeArgumentError: "Invalid argument",
54+
CodeDataError: "Data error",
55+
CodeOperatingError: "Operation error",
56+
CodeTimeoutError: "Timeout",
57+
CodeConnectionError: "Connection error",
58+
CodeRunning: "System running",
59+
CodeResourceExhausted: "Resource exhausted",
60+
CodePermissionError: "Permission denied",
61+
CodeAuthenticationError: "Authentication failed",
62+
CodeLicenseValid: "License valid",
63+
CodeLicenseInactiveError: "License inactive",
64+
CodeLicenseExpiredError: "License expired",
65+
CodeLicenseDigestError: "License digest error",
66+
CodeLicenseTimeRollback: "License time rollback detected",
67+
CodeLicenseNotFound: "License not found",
68+
CodeLicenseUnexpectedError: "Unexpected license error",
69+
CodeBadRequest: "Bad request",
70+
CodeUnauthorized: "Unauthorized",
71+
CodeForbidden: "Forbidden",
72+
CodeNotFound: "Resource not found",
73+
CodeConflict: "Resource conflict",
74+
CodeServerError: "Internal server error",
75+
}
76+
77+
func (e ErrorCode) Message() string {
78+
if msg, ok := errorMessages[e]; ok {
79+
return msg
80+
}
81+
return "Unknown error"
82+
}

internal/dao/database.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ func InitDB() error {
9090
NowFunc: func() time.Time {
9191
return time.Now().Local()
9292
},
93+
TranslateError: true,
9394
})
9495
if err != nil {
9596
return fmt.Errorf("failed to connect database: %w", err)

internal/dao/time_record.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,40 @@ func (dao *TimeRecordDAO) GetByID(id int64) (*model.TimeRecord, error) {
6464
}
6565
return &record, nil
6666
}
67+
68+
// GetAll retrieves all records
69+
func (dao *TimeRecordDAO) GetAll() ([]*model.TimeRecord, error) {
70+
var records []*model.TimeRecord
71+
err := DB.Find(&records).Error
72+
return records, err
73+
}
74+
75+
// KeepLatest keeps the latest N records and deletes older ones
76+
func (dao *TimeRecordDAO) KeepLatest(count int64) error {
77+
// Step 1: Get the maximum ID
78+
var maxID int64
79+
if err := DB.Model(&model.TimeRecord{}).Select("COALESCE(MAX(id), 0)").Scan(&maxID).Error; err != nil {
80+
return err
81+
}
82+
83+
// If no records or count is 0, nothing to delete
84+
if maxID == 0 || count <= 0 {
85+
return nil
86+
}
87+
88+
// Step 2: Calculate the threshold ID
89+
thresholdID := maxID - count
90+
91+
// If threshold is less than 0, keep all records
92+
if thresholdID <= 0 {
93+
return nil
94+
}
95+
96+
// Step 3: Delete records with ID <= threshold
97+
return DB.Where("id <= ?", thresholdID).Delete(&model.TimeRecord{}).Error
98+
}
99+
100+
// DeleteAll deletes all records
101+
func (dao *TimeRecordDAO) DeleteAll() error {
102+
return DB.Where("1=1").Delete(&model.TimeRecord{}).Error
103+
}

0 commit comments

Comments
 (0)