fix(并发控制): 修复apps数据保存时的并发安全问题

将saveApps函数的锁管理移到调用方,确保在文件保存操作期间保持锁
在uploadApp和deleteApp中调整锁的释放时机,防止数据竞争
This commit is contained in:
2026-01-07 14:03:45 +08:00
parent 48caa4168c
commit b733f81ed8

View File

@@ -70,11 +70,8 @@ func loadApps() {
}
}
// 保存apps数据
// 保存apps数据(调用者需要持有锁)
func saveApps() error {
appsMutex.Lock()
defer appsMutex.Unlock()
file, err := os.Create(jsonFile)
if err != nil {
return fmt.Errorf("failed to create apps.json: %w", err)
@@ -129,7 +126,7 @@ func main() {
{
api.GET("/apps", getApps)
api.POST("/apps", uploadApp)
api.DELETE("/apps/:id", deleteApp) // 添加删除应用的API端点
api.DELETE("/apps/:id", deleteApp) // 添加删除应用的API端点
api.GET("/apps/:id", downloadApp)
api.GET("/apps/:id/", downloadApp) // 处理以/结尾的URL
api.GET("/docs", getDocs) // 新增获取文档的API端点
@@ -223,13 +220,13 @@ func uploadApp(c *gin.Context) {
appsMutex.Lock()
apps = append(apps, newApp)
appsMutex.Unlock()
// 保存到文件
if err := saveApps(); err != nil {
appsMutex.Unlock()
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": "保存数据失败: " + err.Error()})
return
}
appsMutex.Unlock()
c.JSON(http.StatusOK, gin.H{"success": true})
}
@@ -308,13 +305,13 @@ func deleteApp(c *gin.Context) {
// 从apps切片中删除该应用
appsMutex.Lock()
apps = append(apps[:targetIndex], apps[targetIndex+1:]...)
appsMutex.Unlock()
// 保存到文件
if err := saveApps(); err != nil {
appsMutex.Unlock()
c.JSON(http.StatusInternalServerError, gin.H{"success": false, "message": "保存数据失败: " + err.Error()})
return
}
appsMutex.Unlock()
c.JSON(http.StatusOK, gin.H{"success": true, "message": "删除成功"})
}