mirror of
https://gh-proxy.org/https://github.com/klinsmaya/CLIProxyAPI.git
synced 2026-11-08 01:16:47 +08:00
fix(management): reload plugins asynchronously after changes
This commit is contained in:
@@ -274,7 +274,7 @@ func (h *Handler) installPluginFromStore(c *gin.Context, goos, goarch string) {
|
||||
reloadCfg := h.cfg
|
||||
h.mu.Unlock()
|
||||
|
||||
h.reloadConfigAfterManagementSave(c.Request.Context(), reloadCfg)
|
||||
h.reloadConfigAfterManagementSaveAsync(c.Request.Context(), reloadCfg)
|
||||
log.WithFields(log.Fields{
|
||||
"plugin_id": result.ID,
|
||||
"source_id": source.ID,
|
||||
|
||||
@@ -511,12 +511,9 @@ func TestInstallPluginFromStoreOverwritesFilePreservesConfigAndReloads(t *testin
|
||||
"https://downloads.example/checksums.txt": []byte(hex.EncodeToString(checksum[:]) + " " + archiveName + "\n"),
|
||||
},
|
||||
}
|
||||
reloads := 0
|
||||
reloads := make(chan *config.Config, 1)
|
||||
h.SetConfigReloadHook(func(_ context.Context, cfg *config.Config) {
|
||||
reloads++
|
||||
if cfg != h.cfg {
|
||||
t.Fatalf("reload config = %p, want handler config %p", cfg, h.cfg)
|
||||
}
|
||||
reloads <- cfg
|
||||
})
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
@@ -529,8 +526,8 @@ func TestInstallPluginFromStoreOverwritesFilePreservesConfigAndReloads(t *testin
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d; body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
if reloads != 1 {
|
||||
t.Fatalf("reloads = %d, want 1", reloads)
|
||||
if cfg := waitForAsyncReload(t, reloads); cfg != h.cfg {
|
||||
t.Fatalf("reload config = %p, want handler config %p", cfg, h.cfg)
|
||||
}
|
||||
data, errRead := os.ReadFile(existingPath)
|
||||
if errRead != nil {
|
||||
|
||||
@@ -215,18 +215,27 @@ func (h *Handler) PatchPluginEnabled(c *gin.Context) {
|
||||
}
|
||||
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
ensurePluginConfigMap(h.cfg)
|
||||
item := h.cfg.Plugins.Configs[id]
|
||||
node := pluginConfigNode(item)
|
||||
setYAMLMappingValue(node, "enabled", boolYAMLNode(*body.Enabled))
|
||||
updated, errConfig := pluginInstanceConfigFromNode(node)
|
||||
if errConfig != nil {
|
||||
h.mu.Unlock()
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_config", "message": errConfig.Error()})
|
||||
return
|
||||
}
|
||||
h.cfg.Plugins.Configs[id] = updated
|
||||
h.persistLocked(c)
|
||||
if errSave := config.SaveConfigPreserveComments(h.configFilePath, h.cfg); errSave != nil {
|
||||
h.mu.Unlock()
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("failed to save config: %v", errSave)})
|
||||
return
|
||||
}
|
||||
reloadCfg := h.cfg
|
||||
h.mu.Unlock()
|
||||
|
||||
h.reloadConfigAfterManagementSaveAsync(c.Request.Context(), reloadCfg)
|
||||
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
||||
}
|
||||
|
||||
// PutPluginConfig replaces plugins.configs.<id> with the request object.
|
||||
|
||||
@@ -241,6 +241,10 @@ func TestPatchPluginEnabledUpdatesOnlyPluginConfig(t *testing.T) {
|
||||
},
|
||||
configFilePath: writeTestConfigFile(t),
|
||||
}
|
||||
reloads := make(chan *config.Config, 1)
|
||||
h.SetConfigReloadHook(func(_ context.Context, cfg *config.Config) {
|
||||
reloads <- cfg
|
||||
})
|
||||
|
||||
rec := httptest.NewRecorder()
|
||||
c, _ := gin.CreateTestContext(rec)
|
||||
@@ -253,6 +257,9 @@ func TestPatchPluginEnabledUpdatesOnlyPluginConfig(t *testing.T) {
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("status = %d, want %d; body=%s", rec.Code, http.StatusOK, rec.Body.String())
|
||||
}
|
||||
if cfg := waitForAsyncReload(t, reloads); cfg != h.cfg {
|
||||
t.Fatalf("reload config = %p, want handler config %p", cfg, h.cfg)
|
||||
}
|
||||
if h.cfg.Plugins.Enabled {
|
||||
t.Fatal("global Plugins.Enabled changed to true")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user