Skip to content

Commit a82c02f

Browse files
authored
fix: fix plugin upgrade use context (#639)
1 parent fcc3467 commit a82c02f

File tree

5 files changed

+98
-4
lines changed

5 files changed

+98
-4
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,9 @@ PLUGIN_STDIO_MAX_BUFFER_SIZE=5242880
203203
PLUGIN_RUNTIME_BUFFER_SIZE=1024
204204
PLUGIN_RUNTIME_MAX_BUFFER_SIZE=5242880
205205

206+
# plugin install/upgrade timeout in minutes
207+
PLUGIN_INSTALL_TIMEOUT=15
208+
206209
# dify backwards invocation write timeout in milliseconds
207210
DIFY_BACKWARDS_INVOCATION_WRITE_TIMEOUT=5000
208211
# dify backwards invocation read timeout in milliseconds

internal/server/controllers/plugins.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,6 @@ func UpgradePlugin(app *app.Config) gin.HandlerFunc {
112112
}
113113

114114
c.JSON(http.StatusOK, service.UpgradePlugin(
115-
c.Request.Context(),
116115
app,
117116
request.TenantID,
118117
request.Source,

internal/service/install_plugin.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ func InstallMultiplePluginsToTenant(
118118
for _, job := range jobs {
119119
jobCopy := job
120120
// create a detached context for async task to avoid http request cancellation
121-
taskCtx, taskCancel := context.WithTimeout(context.Background(), 15*time.Minute)
121+
taskCtx, taskCancel := context.WithTimeout(context.Background(), time.Duration(config.PluginInstallTimeout)*time.Minute)
122122
// start a new goroutine to install the plugin
123123
routine.Submit(routinepkg.Labels{
124124
routinepkg.RoutineLabelKeyModule: "service",
@@ -197,7 +197,6 @@ func ReinstallPluginFromIdentifier(
197197
* Upgrade a plugin between 2 identifiers
198198
*/
199199
func UpgradePlugin(
200-
ctx context.Context,
201200
config *app.Config,
202201
tenantId string,
203202
source string,
@@ -299,8 +298,10 @@ func UpgradePlugin(
299298
routinepkg.RoutineLabelKeyModule: "service",
300299
routinepkg.RoutineLabelKeyMethod: "UpgradePlugin",
301300
}, func() {
301+
taskCtx, taskCancel := context.WithTimeout(context.Background(), time.Duration(config.PluginInstallTimeout)*time.Minute)
302+
defer taskCancel()
302303
tasks.ProcessUpgradeJob(
303-
ctx,
304+
taskCtx,
304305
manager,
305306
tenants,
306307
runtimeType,
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package service
2+
3+
import (
4+
"encoding/json"
5+
"testing"
6+
7+
"github.com/langgenius/dify-plugin-daemon/internal/types/app"
8+
"github.com/langgenius/dify-plugin-daemon/pkg/entities/plugin_entities"
9+
)
10+
11+
func TestUpgradePlugin(t *testing.T) {
12+
originalIdentifier, err := plugin_entities.NewPluginUniqueIdentifier("author/test-plugin:1.0.0@abcdef1234567890abcdef1234567890ab")
13+
if err != nil {
14+
t.Fatalf("failed to create original plugin unique identifier: %v", err)
15+
}
16+
17+
newIdentifier, err := plugin_entities.NewPluginUniqueIdentifier("author/test-plugin:2.0.0@1234567890abcdef1234567890abcdef12")
18+
if err != nil {
19+
t.Fatalf("failed to create new plugin unique identifier: %v", err)
20+
}
21+
22+
config := &app.Config{
23+
PluginInstallTimeout: 15,
24+
}
25+
26+
tests := []struct {
27+
name string
28+
tenantId string
29+
source string
30+
meta map[string]any
31+
originalPluginUniqueIdentifier plugin_entities.PluginUniqueIdentifier
32+
newPluginUniqueIdentifier plugin_entities.PluginUniqueIdentifier
33+
wantSuccess bool
34+
wantAllInstalled bool
35+
wantTaskIDEmpty bool
36+
}{
37+
{
38+
name: "same plugin identifiers",
39+
tenantId: "tenant-123",
40+
source: "test",
41+
meta: map[string]any{},
42+
originalPluginUniqueIdentifier: originalIdentifier,
43+
newPluginUniqueIdentifier: originalIdentifier,
44+
wantSuccess: false,
45+
},
46+
{
47+
name: "different plugin identifiers",
48+
tenantId: "tenant-123",
49+
source: "test",
50+
meta: map[string]any{},
51+
originalPluginUniqueIdentifier: originalIdentifier,
52+
newPluginUniqueIdentifier: newIdentifier,
53+
wantSuccess: false,
54+
},
55+
}
56+
57+
for _, tt := range tests {
58+
t.Run(tt.name, func(t *testing.T) {
59+
response := UpgradePlugin(
60+
config,
61+
tt.tenantId,
62+
tt.source,
63+
tt.meta,
64+
tt.originalPluginUniqueIdentifier,
65+
tt.newPluginUniqueIdentifier,
66+
)
67+
68+
isSuccess := response.Code == 0
69+
if isSuccess != tt.wantSuccess {
70+
t.Errorf("UpgradePlugin() success = %v, want %v", isSuccess, tt.wantSuccess)
71+
}
72+
73+
if isSuccess {
74+
var result InstallPluginResponse
75+
dataBytes, err := json.Marshal(response.Data)
76+
if err == nil {
77+
_ = json.Unmarshal(dataBytes, &result)
78+
if tt.wantAllInstalled && !result.AllInstalled {
79+
t.Errorf("UpgradePlugin() AllInstalled = %v, want %v", result.AllInstalled, tt.wantAllInstalled)
80+
}
81+
if tt.wantTaskIDEmpty && result.TaskID != "" {
82+
t.Errorf("UpgradePlugin() TaskID = %v, want empty", result.TaskID)
83+
}
84+
}
85+
}
86+
})
87+
}
88+
}

internal/types/app/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ type Config struct {
105105
// request timeout
106106
PluginMaxExecutionTimeout int `envconfig:"PLUGIN_MAX_EXECUTION_TIMEOUT" validate:"required"`
107107

108+
// plugin install timeout in minutes
109+
PluginInstallTimeout int `envconfig:"PLUGIN_INSTALL_TIMEOUT" default:"15"`
110+
108111
// local launching max concurrent
109112
PluginLocalLaunchingConcurrent int `envconfig:"PLUGIN_LOCAL_LAUNCHING_CONCURRENT" validate:"required"`
110113

0 commit comments

Comments
 (0)