135 lines
4.0 KiB
Go
135 lines
4.0 KiB
Go
package state
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"gitlink.org.cn/cloudream/common/pkgs/future"
|
||
"gitlink.org.cn/cloudream/common/pkgs/logger"
|
||
schsdk "gitlink.org.cn/cloudream/common/sdks/scheduler"
|
||
cdssdk "gitlink.org.cn/cloudream/common/sdks/storage"
|
||
schglb "gitlink.org.cn/cloudream/scheduler/common/globals"
|
||
jobmod "gitlink.org.cn/cloudream/scheduler/common/models/job"
|
||
exectsk "gitlink.org.cn/cloudream/scheduler/common/pkgs/mq/executor/task"
|
||
"gitlink.org.cn/cloudream/scheduler/manager/internal/jobmgr"
|
||
"gitlink.org.cn/cloudream/scheduler/manager/internal/jobmgr/event"
|
||
"gitlink.org.cn/cloudream/scheduler/manager/internal/jobmgr/job"
|
||
)
|
||
|
||
type MultiInstanceUpdate struct {
|
||
originalJob jobmod.JobDump
|
||
}
|
||
|
||
func NewMultiInstanceUpdate(originalJob jobmod.JobDump) *MultiInstanceUpdate {
|
||
return &MultiInstanceUpdate{
|
||
originalJob: originalJob,
|
||
}
|
||
}
|
||
|
||
func (s *MultiInstanceUpdate) Run(rtx jobmgr.JobStateRunContext, job *jobmgr.Job) {
|
||
s.do(rtx, job)
|
||
}
|
||
|
||
func (s *MultiInstanceUpdate) do(rtx jobmgr.JobStateRunContext, jo *jobmgr.Job) error {
|
||
updateJob := jo.Body.(*job.UpdateMultiInstanceJob)
|
||
|
||
ctx, cancel := context.WithCancel(context.Background())
|
||
defer cancel()
|
||
|
||
// 监听取消事件
|
||
go func() {
|
||
event.WaitType[*event.Cancel](ctx, rtx.EventSet)
|
||
cancel()
|
||
}()
|
||
|
||
var pkgID cdssdk.PackageID
|
||
// 等待回源任务完成
|
||
if rt, ok := updateJob.Info.Files.Code.(*schsdk.DataReturnJobFileInfo); ok {
|
||
evt, ok := event.WaitTypeAnd[*event.JobCompleted](ctx, rtx.EventSet, func(val *event.JobCompleted) bool {
|
||
return val.Job.GetInfo().GetLocalJobID() == rt.DataReturnLocalJobID
|
||
})
|
||
if !ok {
|
||
return jobmgr.ErrJobCancelled
|
||
}
|
||
if evt.Err != nil {
|
||
return fmt.Errorf("depended job %s was failed", evt.Job.JobID)
|
||
}
|
||
rtJob, ok := evt.Job.Body.(*job.DataReturnJob)
|
||
if !ok {
|
||
return fmt.Errorf("job %s is not a DataReturn job(which is %T)", evt.Job.JobID, evt.Job)
|
||
}
|
||
pkgID = rtJob.DataReturnPackageID
|
||
}
|
||
|
||
// 获取包对象列表
|
||
stgCli, err := schglb.CloudreamStoragePool.Acquire()
|
||
if err != nil {
|
||
return fmt.Errorf("new cloudream storage client: %w", err)
|
||
}
|
||
defer schglb.CloudreamStoragePool.Release(stgCli)
|
||
// TODO UserID
|
||
pkgObjs, err := stgCli.Object().GetPackageObjects(cdssdk.ObjectGetPackageObjects{UserID: 1, PackageID: pkgID})
|
||
if err != nil {
|
||
return fmt.Errorf("getting package objects: %w", err)
|
||
}
|
||
|
||
// 获取原始任务信息
|
||
originalMultiInstanceJobBody := s.originalJob.Body.(*jobmod.MultiInstanceJobDump)
|
||
originalPackageID := originalMultiInstanceJobBody.Files.Code.PackageID
|
||
var objArr []cdssdk.MovingObject
|
||
for _, obj := range pkgObjs.Objects {
|
||
objArr = append(objArr, cdssdk.MovingObject{
|
||
ObjectID: obj.ObjectID,
|
||
PackageID: originalPackageID,
|
||
Path: obj.Path,
|
||
})
|
||
}
|
||
// TODO UserID
|
||
objMoveParam := cdssdk.ObjectMove{
|
||
UserID: 1,
|
||
Movings: objArr,
|
||
}
|
||
|
||
ccInfo, err := rtx.Mgr.DB.ComputingCenter().GetByID(rtx.Mgr.DB.SQLCtx(), originalMultiInstanceJobBody.TargetCCID)
|
||
if err != nil {
|
||
return fmt.Errorf("getting computing center info: %w", err)
|
||
}
|
||
|
||
// 将增量包合并到原有包中
|
||
taskStatus, err := rtx.Mgr.ExecMgr.StartTask(exectsk.NewStorageMoveObject(objMoveParam), ccInfo)
|
||
if err != nil {
|
||
return fmt.Errorf("moving package: %w", err)
|
||
}
|
||
|
||
statusFut := taskStatus.Receive()
|
||
status := <-statusFut.Chan()
|
||
moveStatus := status.Value.Status.(*exectsk.StorageMoveObjectStatus)
|
||
if moveStatus.Error != "" {
|
||
return fmt.Errorf("moving package: %s", moveStatus.Error)
|
||
}
|
||
|
||
// 发送事件,更新各个instance
|
||
updateInfo := event.InstanceUpdateInfo{
|
||
Info: updateJob.Info,
|
||
}
|
||
fut := future.NewSetValue[event.OperateInstanceResult]()
|
||
rtx.Mgr.PostEvent(s.originalJob.JobID, event.NewInstanceOperate(&updateInfo, fut))
|
||
|
||
result, err := fut.Wait(context.TODO())
|
||
|
||
if err != nil {
|
||
return err
|
||
}
|
||
println(result.JobID)
|
||
|
||
if result.Err != nil {
|
||
return fmt.Errorf("update instance failed: %s", result.OperateResult)
|
||
}
|
||
|
||
logger.Info("update instance success!")
|
||
return nil
|
||
}
|
||
|
||
func (s *MultiInstanceUpdate) Dump(ctx jobmgr.JobStateRunContext, job *jobmgr.Job) jobmod.JobStateDump {
|
||
return &jobmod.MultiInstanceUpdateDump{}
|
||
}
|