mirror of
https://github.com/langgenius/dify-plugin-daemon.git
synced 2026-07-22 01:35:24 -04:00
ca3d00229e
* use slog instead of log package and format to new log schema * update the environment name to LOG_OUTPUT_FORMAT * add the env to .env.example * fix log reference error * change the order of milldlewares * delete unused code * fix the concurrently session potential race condition * fix the log format in tests * update the duplicate code * refactor: convert log functions to slog structured format - Change log.Error/Info/Warn/Debug/Panic to accept msg + key-value pairs - Remove printf-style formatting from log functions - Update log calls in internal/cluster, internal/db, internal/core/session_manager - Remove unused 'initialized' variable from log package - Remaining files will be updated in follow-up commits 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: update all log call sites to use slog structured format Convert all log.Error, log.Info, log.Warn, log.Debug, and log.Panic calls from printf-style formatting to slog key-value pairs. Before: log.Error("failed to do something: %s", err.Error()) After: log.Error("failed to do something", "error", err) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: update cmd/ log calls to use slog structured format 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: implement GnetLogger for structured logging in gnet * refactor: remove deprecated log visibility functions and related calls * feat: enhance session management with trace and identity context propagation * feat: implement serverless transaction handler and writer for plugin runtime * refactor: rename context field to traceCtx in RealBackwardsInvocation --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: Yeuoly <admin@srmxy.cn>
183 lines
5.7 KiB
Go
183 lines
5.7 KiB
Go
package tasks
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/langgenius/dify-plugin-daemon/internal/core/plugin_manager"
|
|
"github.com/langgenius/dify-plugin-daemon/internal/types/models"
|
|
"github.com/langgenius/dify-plugin-daemon/internal/types/models/curd"
|
|
"github.com/langgenius/dify-plugin-daemon/pkg/entities/installation_entities"
|
|
"github.com/langgenius/dify-plugin-daemon/pkg/entities/plugin_entities"
|
|
"github.com/langgenius/dify-plugin-daemon/pkg/utils/log"
|
|
)
|
|
|
|
type PluginInstallJob struct {
|
|
Identifier plugin_entities.PluginUniqueIdentifier
|
|
Declaration *plugin_entities.PluginDeclaration
|
|
Meta map[string]any
|
|
NeedsRuntimeInstall bool
|
|
}
|
|
|
|
type PluginUpgradeJob struct {
|
|
NewIdentifier plugin_entities.PluginUniqueIdentifier
|
|
NewDeclaration *plugin_entities.PluginDeclaration
|
|
OriginalIdentifier plugin_entities.PluginUniqueIdentifier
|
|
OriginalDeclaration *plugin_entities.PluginDeclaration
|
|
Meta map[string]any
|
|
}
|
|
|
|
func ProcessInstallJob(
|
|
ctx context.Context,
|
|
manager *plugin_manager.PluginManager,
|
|
tenants []string,
|
|
runtimeType plugin_entities.PluginRuntimeType,
|
|
source string,
|
|
taskIDs []string,
|
|
job PluginInstallJob,
|
|
) {
|
|
startTasks(taskIDs)
|
|
defer endTasks(taskIDs)
|
|
|
|
// if the plugin does not need runtime install, just save the installation to the database
|
|
if !job.NeedsRuntimeInstall {
|
|
if err := SaveInstallationForTenantsToDB(tenants, job, runtimeType, source); err != nil {
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusFailed, err.Error())
|
|
return
|
|
}
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusSuccess, "installed")
|
|
return
|
|
}
|
|
|
|
// set status to running
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusRunning, "starting")
|
|
|
|
// start installation process
|
|
installationStream, err := manager.Install(ctx, job.Identifier)
|
|
if err != nil {
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusFailed, fmt.Sprintf("failed to start installation: %v", err))
|
|
return
|
|
}
|
|
|
|
// wait for the job to be done
|
|
err = installationStream.Process(func(resp installation_entities.PluginInstallResponse) {
|
|
switch resp.Event {
|
|
case installation_entities.PluginInstallEventInfo:
|
|
SetTaskMessageForOnePlugin(taskIDs, job.Identifier, resp.Data)
|
|
case installation_entities.PluginInstallEventError:
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusFailed, resp.Data)
|
|
case installation_entities.PluginInstallEventDone:
|
|
if err := SaveInstallationForTenantsToDB(tenants, job, runtimeType, source); err != nil {
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusFailed, err.Error())
|
|
return
|
|
}
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusSuccess, "installed")
|
|
// delete the task in 60 seconds
|
|
time.AfterFunc(time.Second*60, func() {
|
|
for _, taskID := range taskIDs {
|
|
if err := DeleteTask(taskID); err != nil {
|
|
log.Error("failed to delete task", "task_id", taskID, "error", err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
})
|
|
if err != nil {
|
|
SetTaskStatusForOnePlugin(taskIDs, job.Identifier, models.InstallTaskStatusFailed, err.Error())
|
|
}
|
|
}
|
|
|
|
func ProcessUpgradeJob(
|
|
ctx context.Context,
|
|
manager *plugin_manager.PluginManager,
|
|
tenants []string,
|
|
runtimeType plugin_entities.PluginRuntimeType,
|
|
source string,
|
|
taskIDs []string,
|
|
job PluginUpgradeJob,
|
|
) {
|
|
startTasks(taskIDs)
|
|
defer endTasks(taskIDs)
|
|
|
|
// set status to running
|
|
SetTaskStatusForOnePlugin(taskIDs, job.NewIdentifier, models.InstallTaskStatusRunning, "starting")
|
|
|
|
// start installation process
|
|
installationStream, err := manager.Install(ctx, job.NewIdentifier)
|
|
if err != nil {
|
|
SetTaskStatusForOnePlugin(taskIDs, job.NewIdentifier, models.InstallTaskStatusFailed, fmt.Sprintf("failed to start installation: %v", err))
|
|
return
|
|
}
|
|
|
|
err = installationStream.Process(func(resp installation_entities.PluginInstallResponse) {
|
|
switch resp.Event {
|
|
case installation_entities.PluginInstallEventInfo:
|
|
SetTaskMessageForOnePlugin(taskIDs, job.NewIdentifier, resp.Data)
|
|
case installation_entities.PluginInstallEventError:
|
|
SetTaskStatusForOnePlugin(taskIDs, job.NewIdentifier, models.InstallTaskStatusFailed, resp.Data)
|
|
case installation_entities.PluginInstallEventDone:
|
|
for _, tenantID := range tenants {
|
|
response, err := curd.UpgradePlugin(
|
|
tenantID,
|
|
job.OriginalIdentifier,
|
|
job.NewIdentifier,
|
|
job.OriginalDeclaration,
|
|
job.NewDeclaration,
|
|
runtimeType,
|
|
source,
|
|
job.Meta,
|
|
)
|
|
if err != nil {
|
|
SetTaskStatusForOnePlugin(taskIDs, job.NewIdentifier, models.InstallTaskStatusFailed, err.Error())
|
|
return
|
|
}
|
|
|
|
if err := RemovePluginIfNeeded(manager, job.OriginalIdentifier, response); err != nil {
|
|
log.Error("failed to remove uninstalled plugin", "error", err)
|
|
}
|
|
}
|
|
|
|
SetTaskStatusForOnePlugin(taskIDs, job.NewIdentifier, models.InstallTaskStatusSuccess, "upgraded")
|
|
}
|
|
})
|
|
if err != nil {
|
|
SetTaskStatusForOnePlugin(taskIDs, job.NewIdentifier, models.InstallTaskStatusFailed, err.Error())
|
|
}
|
|
|
|
}
|
|
|
|
func SaveInstallationForTenantsToDB(
|
|
tenants []string,
|
|
job PluginInstallJob,
|
|
runtimeType plugin_entities.PluginRuntimeType,
|
|
source string,
|
|
) error {
|
|
for _, tenantID := range tenants {
|
|
if err := SaveInstallationForTenantToDB(tenantID, job, runtimeType, source); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func SaveInstallationForTenantToDB(
|
|
tenantID string,
|
|
job PluginInstallJob,
|
|
runtimeType plugin_entities.PluginRuntimeType,
|
|
source string,
|
|
) error {
|
|
_, _, err := curd.InstallPlugin(
|
|
tenantID,
|
|
job.Identifier,
|
|
runtimeType,
|
|
job.Declaration,
|
|
source,
|
|
job.Meta,
|
|
)
|
|
if err != nil && err != curd.ErrPluginAlreadyInstalled {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|