fix:超算概览任务接口调整

Former-commit-id: de7a69443a0b12cf9a6b152064b0b228a4597b0d
This commit is contained in:
zhouqunjie 2023-05-17 20:43:21 +08:00
parent 90099d1dbb
commit 10ed9b35e9
4 changed files with 82 additions and 351 deletions

View File

@ -9,171 +9,39 @@ info(
) )
type Job { type Job {
SlurmVersion string `json:"slurmVersion"` SlurmVersion string `json:"slurmVersion"`
Account string `json:"account"` name string `json:"name"`
AllocNode string `json:"allocNode"` JobStartTime string `json:"JobStartTime"`
AllocSid uint32 `json:"allocSid"` JobRunTime string `json:"JobRunTime"`
ArrayJobId uint32 `json:"arrayJobId"` StateofJob string `json:"StateofJob"`
ArrayTaskId uint32 `json:"arrayTaskId"`
AssocId uint32 `json:"assocId"`
BatchFlag uint32 `json:"batchFlag"`
BatchHost string `json:"batchHost"`
BatchScript string `json:"batchScript"`
Command string `json:"command"`
Comment string `json:"comment"`
Contiguous uint32 `json:"contiguous"`
CpusPerTask uint32 `json:"cpusPerTask"`
Dependency string `json:"dependency"`
DerivedEc uint32 `json:"derivedEc"`
EligibleTime int64 `json:"eligibleTime"`
EndTime int64 `json:"endTime"`
ExcNodes string `json:"excNodes"` //NodeUsed in ac
ExcNodeInx int32 `json:"excNodeInx"`
ExitCode uint32 `json:"exitCode"`
Features string `json:"features"`
Gres string `json:"gres"`
GroupId uint32 `json:"groupId"`
JobId uint32 `json:"jobId"` //JobId in ac
JobState uint32 `json:"jobState"` //JobStatus in ac
Licenses string `json:"licenses"`
MaxCpus uint32 `json:"maxCpus"`
MaxNodes uint32 `json:"maxNodes"`
BoardsPerNode uint32 `json:"boardsPerNode"`
SocketsPerBoard uint32 `json:"socketsPerBoard"`
SocketsPerNode uint32 `json:"socketsPerNode"`
CoresPerSocket uint32 `json:"coresPerSocket"`
ThreadsPerCore uint32 `json:"threadsPerCore"`
Name string `json:"name"` //JobName in ac
Network string `json:"network"`
Nodes string `json:"nodes"`
Nice uint32 `json:"nice"`
NodeInx int32 `json:"nodeInx"`
NtasksPerCore uint32 `json:"ntasksPerCore"`
NtasksPerNode uint32 `json:"ntasksPerNode"`
NtasksPerSocket uint32 `json:"ntasksPerSocket"`
NtasksPerBoard uint32 `json:"ntasksPerBoard"`
NumNodes uint32 `json:"numNodes"`
NumCpus uint32 `json:"numCpus"` //ProcNumUsed in ac
Partition string `json:"partition"` //Queue in ac
PnMinMemory uint32 `json:"pnMinMemory"`
PnMinCpus uint32 `json:"pnMinCpus"`
PnMinTmpDisk uint32 `json:"pnMinTmpDisk"`
PreSusTime int64 `json:"preSusTime"`
Priority uint32 `json:"priority"`
Profile uint32 `json:"profile"`
Qos string `json:"qos"`
ReqNodes string `json:"reqNodes"`
ReqNodeInx int32 `json:"reqNodeInx"`
ReqSwitch uint32 `json:"reqSwitch"`
Requeue uint32 `json:"requeue"`
ResizeTime int64 `json:"resizeTime"`
RestartCnt uint32 `json:"restartCnt"`
ResvName string `json:"resvName"`
Shared uint32 `json:"shared"`
ShowFlags uint32 `json:"showFlags"`
StartTime int64 `json:"startTime"` //JobStartTime in ac
StateDesc string `json:"stateDesc"`
StateReason uint32 `json:"stateReason"`
SubmitTime int64 `json:"submitTime"`
SuspendTime int64 `json:"suspendTime"`
TimeLimit uint32 `json:"timeLimit"`
TimeMin uint32 `json:"timeMin"`
UserId uint32 `json:"userId"` //User in ac
PreemptTime int64 `json:"preemptTime"`
Wait4Switch uint32 `json:"wait4Switch"`
Wckey string `json:"wckey"`
WorkDir string `json:"workDir"` //WorkDir in ac
/****ac****/
JobRunTime string `json:"jobRunTime"`
JobmanagerId string `json:"jobmanagerId"`
JobmanagerName string `json:"jobmanagerName"`
JobmanagerType string `json:"jobmanagerType"`
ErrorPath string `json:"errorPath"`
OutputPath string `json:"outputPath"`
Reason string `json:"reason"`
AppType string `json:"appType"`
/****ac****/
} }
type ( type (
listJobReq { listJobReq {
} }
listJobResp { listJobResp {
Code int32 `json:"code"` Code int32 `json:"code"`
Msg string `json:"msg"` Msg string `json:"msg"`
RecordCount int32 `json:"recordCount"` RecordCount int32 `json:"recordCount"`
Jobs []Job `json:"jobs"` Jobs []Job `json:"jobInfos"`
} }
) )
type HistoryJob { type HistoryJob {
SlurmVersion string `json:"slurmVersion"` SlurmVersion string `json:"slurmVersion"`
AllocCPU uint32 `json:"allocCPU"` name string `json:"name"`
AllocNodes uint32 `json:"allocNodes"` //Nodect 分配的节点数 in ac JobStartTime string `json:"JobStartTime"`
Account string `json:"account"` JobRunTime string `json:"JobRunTime"`
AssocId uint32 `json:"assocId"` StateofJob string `json:"StateofJob"`
BlockId string `json:"blockId"`
Cluster string `json:"cluster"`
DerivedEc uint32 `json:"derivedEc"`
DerivedEs string `json:"derivedEs"`
Elapsed uint32 `json:"elapsed"`
Eligible int64 `json:"eligible"`
End int64 `json:"end"` //JobEndTime 作业结束时间 in ac
ExitCode uint32 `json:"exitCode"` //JobExitStatus 作业退出码 in ac
Gid uint32 `json:"gid"`
JobId uint32 `json:"jobId"` //JobId in ac
JobName string `json:"jobName"` //JobName in ac
Lft uint32 `json:"lft"`
Partition string `json:"partition"` //Queue 队列名 in ac
Nodes string `json:"nodes"` //JobExecHost 作业执行节点 in ac
Priority uint32 `json:"priority"`
Qosid uint32 `json:"qosid"`
ReqCpus uint32 `json:"reqCpus"`
ReqMem uint32 `json:"reqMem"`
Requid uint32 `json:"requid"`
Resvid uint32 `json:"resvid"`
ShowFull uint32 `json:"showFull"`
Start int64 `json:"start"` //JobStartTime 作业启动时间 in ac
State uint32 `json:"state"` //JobState 作业状态 in ac
Submit int64 `json:"submit"`
Suspended uint32 `json:"suspended"`
SysCpuSec uint32 `json:"sysCpuSec"`
SysCpuUsec uint32 `json:"sysCpuUsec"`
Timelimit uint32 `json:"timelimit"`
TotCpuSec uint32 `json:"totCpuSec"`
TotCpuUsec uint32 `json:"totCpuUsec"`
TrackSteps uint32 `json:"trackSteps"`
Uid uint32 `json:"uid"`
User string `json:"user"` //UserName 用户名 in ac
UserCpuSec uint32 `json:"userCpuSec"`
UserCpuUsec uint32 `json:"userCpuUsec"`
Wckey string `json:"wckey"`
Wckeyid uint32 `json:"wckeyid"`
WorkDir string `json:"workDir"` //Workdir 工作空间 in ac
/****************parmas from ac********************/
AcctTime string `json:"acctTime"` // 记账时间
AppType string `json:"appType"` // 作业应用类型
JobQueueTime string `json:"jobQueueTime"` //作业入队列时间
JobWalltimeUsed string `json:"jobWalltimeUsed"` //作业实际使用的Walltime,单位为秒
JobManagerId int `json:"jobmanagerId"` //区域id
/****************parmas from ac********************/
} }
type ( type (
listHistoryJobReq { listHistoryJobReq {
SlurmVersion string `json:"slurmVersion,optional"`
StartTime string `json:"startTime,optional"`
EndTime string `json:"endTime,optional"`
TimeType string `json:"timeType,optional"`
Start int32 `json:"start,optional"`
Limit int32 `json:"limit,optional"`
IsQueryByQueueTime int32 `json:"isQueryByQueueTime,optional"`
} }
listHistoryJobResp { listHistoryJobResp {
Code int32 `json:"code"` Code int32 `json:"code"`
Msg string `json:"msg"` Msg string `json:"msg"`
RecordCount int32 `json:"recordCount"` RecordCount int32 `json:"recordCount"`
HistoryJobs []HistoryJob `json:"historyJobs"` HistoryJobs []HistoryJob `json:"jobInfoDbs"`
} }
) )

View File

@ -1,15 +1,11 @@
package hpc package hpc
import ( import (
"PCM/adaptor/PCM-HPC/PCM-AC/rpc/hpcAC"
"PCM/adaptor/PCM-HPC/PCM-TH/rpc/hpcTH"
"PCM/common/tool"
"context"
"github.com/jinzhu/copier"
"time"
"PCM/adaptor/PCM-CORE/api/internal/svc" "PCM/adaptor/PCM-CORE/api/internal/svc"
"PCM/adaptor/PCM-CORE/api/internal/types" "PCM/adaptor/PCM-CORE/api/internal/types"
"PCM/common/enum"
"context"
"strings"
"github.com/zeromicro/go-zero/core/logx" "github.com/zeromicro/go-zero/core/logx"
) )
@ -31,41 +27,34 @@ func NewListHistoryJobLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Li
func (l *ListHistoryJobLogic) ListHistoryJob(req *types.ListHistoryJobReq) (resp *types.ListHistoryJobResp, err error) { func (l *ListHistoryJobLogic) ListHistoryJob(req *types.ListHistoryJobReq) (resp *types.ListHistoryJobResp, err error) {
resp = &types.ListHistoryJobResp{} resp = &types.ListHistoryJobResp{}
acReq := &hpcAC.ListHistoryJobReq{}
if req.SlurmVersion == "ac" { var tasks []types.HistoryJob
acReq.StartTime = req.StartTime // 查询任务数据
acReq.EndTime = req.EndTime
acReq.TimeType = req.TimeType tx := l.svcCtx.DbEngin.Raw("SELECT h.service_name as SlurmVersion,h.name,h.start_time as JobStartTime,h.running_time as JobRunTime,t.status as StateofJob from hpc h join task t on t.id = h.task_id and t.status = 'Completed'").Scan(&tasks)
acReq.Start = req.Start if tx.Error != nil {
acReq.Limit = req.Limit logx.Error(err)
acReq.IsQueryByQueueTime = string(req.IsQueryByQueueTime) return nil, tx.Error
} else {
acReq.StartTime = "2022-12-01 00:00:00"
acReq.EndTime = time.Now().Format("2006-01-02 15:04:05")
acReq.TimeType = "CUSTOM"
acReq.Start = 0
acReq.Limit = 25
acReq.IsQueryByQueueTime = string(0)
} }
for _, task := range tasks {
// 承接方转义
if task.SlurmVersion != "" {
var names []string
servicesName := strings.Split(task.SlurmVersion, ",")
for _, name := range servicesName {
names = append(names, enum.Partner(name).String())
}
task.SlurmVersion = strings.Join(names, ",")
}
resp.HistoryJobs = append(resp.HistoryJobs, types.HistoryJob{
SlurmVersion: task.SlurmVersion,
Name: task.Name,
JobStartTime: task.JobStartTime,
JobRunTime: task.JobRunTime,
StateofJob: task.StateofJob,
})
listHistoryJobRespAC, err := l.svcCtx.ACRpc.ListHistoryJob(l.ctx, acReq)
thReq := &hpcTH.ListHistoryJobReq{}
err = copier.CopyWithOption(thReq, req, copier.Option{Converters: tool.Converters})
listHistoryJobRespTianhe, err := l.svcCtx.THRpc.ListHistoryJob(l.ctx, thReq)
for i := 0; i < len(listHistoryJobRespAC.Data.List); i++ {
historyJobAC := types.HistoryJob{SlurmVersion: "ac"}
copier.CopyWithOption(&historyJobAC, &listHistoryJobRespAC.Data.List[i], copier.Option{Converters: tool.Converters})
resp.HistoryJobs = append(resp.HistoryJobs, historyJobAC)
} }
for i := 0; i < len(listHistoryJobRespTianhe.HistoryJobs); i++ {
historyJobTianhe := types.HistoryJob{SlurmVersion: "th"}
copier.CopyWithOption(&historyJobTianhe, &listHistoryJobRespTianhe.HistoryJobs[i], copier.Option{Converters: tool.Converters})
resp.HistoryJobs = append(resp.HistoryJobs, historyJobTianhe)
}
resp.Code = 200 resp.Code = 200
resp.Msg = "success" resp.Msg = "success"
resp.RecordCount = int32(len(resp.HistoryJobs)) resp.RecordCount = int32(len(resp.HistoryJobs))

View File

@ -1,11 +1,9 @@
package hpc package hpc
import ( import (
"PCM/adaptor/PCM-HPC/PCM-AC/rpc/hpcAC" "PCM/common/enum"
"PCM/adaptor/PCM-HPC/PCM-TH/rpc/hpcTH"
"PCM/common/tool"
"context" "context"
"github.com/jinzhu/copier" "strings"
"PCM/adaptor/PCM-CORE/api/internal/svc" "PCM/adaptor/PCM-CORE/api/internal/svc"
"PCM/adaptor/PCM-CORE/api/internal/types" "PCM/adaptor/PCM-CORE/api/internal/types"
@ -31,30 +29,33 @@ func (l *ListJobLogic) ListJob(req *types.ListJobReq) (resp *types.ListJobResp,
resp = &types.ListJobResp{} resp = &types.ListJobResp{}
acReq := &hpcAC.ListJobReq{} var tasks []types.Job
err = copier.CopyWithOption(acReq, req, copier.Option{Converters: tool.Converters}) // 查询任务数据
listJobRespAC, err := l.svcCtx.ACRpc.ListJob(l.ctx, acReq)
if listJobRespAC != nil {
for i := 0; i < len(listJobRespAC.Jobs); i++ {
jobAC := types.Job{SlurmVersion: "ac"}
copier.CopyWithOption(&jobAC, &listJobRespAC.Jobs[i], copier.Option{Converters: tool.Converters})
resp.Jobs = append(resp.Jobs, jobAC)
}
}
if l.svcCtx.THRpc != nil { tx := l.svcCtx.DbEngin.Raw("SELECT h.service_name as SlurmVersion,h.name,h.start_time as JobStartTime,h.running_time as JobRunTime,t.status as StateofJob from hpc h join task t on t.id = h.task_id and t.status != 'Completed'").Scan(&tasks)
tianheReq := &hpcTH.ListJobReq{} if tx.Error != nil {
err = copier.CopyWithOption(tianheReq, req, copier.Option{Converters: tool.Converters}) logx.Error(err)
listJobRespTH, _ := l.svcCtx.THRpc.ListJob(l.ctx, tianheReq) return nil, tx.Error
if listJobRespTH != nil { }
for i := 0; i < len(listJobRespTH.Jobs); i++ { for _, task := range tasks {
jobTH := types.Job{SlurmVersion: "th"} // 承接方转义
copier.CopyWithOption(&jobTH, &listJobRespTH.Jobs[i], copier.Option{Converters: tool.Converters}) if task.SlurmVersion != "" {
resp.Jobs = append(resp.Jobs, jobTH) var names []string
servicesName := strings.Split(task.SlurmVersion, ",")
for _, name := range servicesName {
names = append(names, enum.Partner(name).String())
} }
task.SlurmVersion = strings.Join(names, ",")
} }
} resp.Jobs = append(resp.Jobs, types.Job{
SlurmVersion: task.SlurmVersion,
Name: task.Name,
JobStartTime: task.JobStartTime,
JobRunTime: task.JobRunTime,
StateofJob: task.StateofJob,
})
}
resp.Code = 200 resp.Code = 200
resp.Msg = "success" resp.Msg = "success"
resp.RecordCount = int32(len(resp.Jobs)) resp.RecordCount = int32(len(resp.Jobs))

View File

@ -279,88 +279,11 @@ type DomainResource struct {
} }
type Job struct { type Job struct {
SlurmVersion string `json:"slurmVersion"` SlurmVersion string `json:"slurmVersion"`
Account string `json:"account"` Name string `json:"name"`
AllocNode string `json:"allocNode"` JobStartTime string `json:"JobStartTime"`
AllocSid uint32 `json:"allocSid"` JobRunTime string `json:"JobRunTime"`
ArrayJobId uint32 `json:"arrayJobId"` StateofJob string `json:"StateofJob"`
ArrayTaskId uint32 `json:"arrayTaskId"`
AssocId uint32 `json:"assocId"`
BatchFlag uint32 `json:"batchFlag"`
BatchHost string `json:"batchHost"`
BatchScript string `json:"batchScript"`
Command string `json:"command"`
Comment string `json:"comment"`
Contiguous uint32 `json:"contiguous"`
CpusPerTask uint32 `json:"cpusPerTask"`
Dependency string `json:"dependency"`
DerivedEc uint32 `json:"derivedEc"`
EligibleTime int64 `json:"eligibleTime"`
EndTime int64 `json:"endTime"`
ExcNodes string `json:"excNodes"` //NodeUsed in ac
ExcNodeInx int32 `json:"excNodeInx"`
ExitCode uint32 `json:"exitCode"`
Features string `json:"features"`
Gres string `json:"gres"`
GroupId uint32 `json:"groupId"`
JobId uint32 `json:"jobId"` //JobId in ac
JobState uint32 `json:"jobState"` //JobStatus in ac
Licenses string `json:"licenses"`
MaxCpus uint32 `json:"maxCpus"`
MaxNodes uint32 `json:"maxNodes"`
BoardsPerNode uint32 `json:"boardsPerNode"`
SocketsPerBoard uint32 `json:"socketsPerBoard"`
SocketsPerNode uint32 `json:"socketsPerNode"`
CoresPerSocket uint32 `json:"coresPerSocket"`
ThreadsPerCore uint32 `json:"threadsPerCore"`
Name string `json:"name"` //JobName in ac
Network string `json:"network"`
Nodes string `json:"nodes"`
Nice uint32 `json:"nice"`
NodeInx int32 `json:"nodeInx"`
NtasksPerCore uint32 `json:"ntasksPerCore"`
NtasksPerNode uint32 `json:"ntasksPerNode"`
NtasksPerSocket uint32 `json:"ntasksPerSocket"`
NtasksPerBoard uint32 `json:"ntasksPerBoard"`
NumNodes uint32 `json:"numNodes"`
NumCpus uint32 `json:"numCpus"` //ProcNumUsed in ac
Partition string `json:"partition"` //Queue in ac
PnMinMemory uint32 `json:"pnMinMemory"`
PnMinCpus uint32 `json:"pnMinCpus"`
PnMinTmpDisk uint32 `json:"pnMinTmpDisk"`
PreSusTime int64 `json:"preSusTime"`
Priority uint32 `json:"priority"`
Profile uint32 `json:"profile"`
Qos string `json:"qos"`
ReqNodes string `json:"reqNodes"`
ReqNodeInx int32 `json:"reqNodeInx"`
ReqSwitch uint32 `json:"reqSwitch"`
Requeue uint32 `json:"requeue"`
ResizeTime int64 `json:"resizeTime"`
RestartCnt uint32 `json:"restartCnt"`
ResvName string `json:"resvName"`
Shared uint32 `json:"shared"`
ShowFlags uint32 `json:"showFlags"`
StartTime int64 `json:"startTime"` //JobStartTime in ac
StateDesc string `json:"stateDesc"`
StateReason uint32 `json:"stateReason"`
SubmitTime int64 `json:"submitTime"`
SuspendTime int64 `json:"suspendTime"`
TimeLimit uint32 `json:"timeLimit"`
TimeMin uint32 `json:"timeMin"`
UserId uint32 `json:"userId"` //User in ac
PreemptTime int64 `json:"preemptTime"`
Wait4Switch uint32 `json:"wait4Switch"`
Wckey string `json:"wckey"`
WorkDir string `json:"workDir"` //WorkDir in ac
JobRunTime string `json:"jobRunTime"`
JobmanagerId string `json:"jobmanagerId"`
JobmanagerName string `json:"jobmanagerName"`
JobmanagerType string `json:"jobmanagerType"`
ErrorPath string `json:"errorPath"`
OutputPath string `json:"outputPath"`
Reason string `json:"reason"`
AppType string `json:"appType"`
} }
type ListJobReq struct { type ListJobReq struct {
@ -370,75 +293,25 @@ type ListJobResp struct {
Code int32 `json:"code"` Code int32 `json:"code"`
Msg string `json:"msg"` Msg string `json:"msg"`
RecordCount int32 `json:"recordCount"` RecordCount int32 `json:"recordCount"`
Jobs []Job `json:"jobs"` Jobs []Job `json:"jobInfos"`
} }
type HistoryJob struct { type HistoryJob struct {
SlurmVersion string `json:"slurmVersion"` SlurmVersion string `json:"slurmVersion"`
AllocCPU uint32 `json:"allocCPU"` Name string `json:"name"`
AllocNodes uint32 `json:"allocNodes"` //Nodect 分配的节点数 in ac JobStartTime string `json:"JobStartTime"`
Account string `json:"account"` JobRunTime string `json:"JobRunTime"`
AssocId uint32 `json:"assocId"` StateofJob string `json:"StateofJob"`
BlockId string `json:"blockId"`
Cluster string `json:"cluster"`
DerivedEc uint32 `json:"derivedEc"`
DerivedEs string `json:"derivedEs"`
Elapsed uint32 `json:"elapsed"`
Eligible int64 `json:"eligible"`
End int64 `json:"end"` //JobEndTime 作业结束时间 in ac
ExitCode uint32 `json:"exitCode"` //JobExitStatus 作业退出码 in ac
Gid uint32 `json:"gid"`
JobId uint32 `json:"jobId"` //JobId in ac
JobName string `json:"jobName"` //JobName in ac
Lft uint32 `json:"lft"`
Partition string `json:"partition"` //Queue 队列名 in ac
Nodes string `json:"nodes"` //JobExecHost 作业执行节点 in ac
Priority uint32 `json:"priority"`
Qosid uint32 `json:"qosid"`
ReqCpus uint32 `json:"reqCpus"`
ReqMem uint32 `json:"reqMem"`
Requid uint32 `json:"requid"`
Resvid uint32 `json:"resvid"`
ShowFull uint32 `json:"showFull"`
Start int64 `json:"start"` //JobStartTime 作业启动时间 in ac
State uint32 `json:"state"` //JobState 作业状态 in ac
Submit int64 `json:"submit"`
Suspended uint32 `json:"suspended"`
SysCpuSec uint32 `json:"sysCpuSec"`
SysCpuUsec uint32 `json:"sysCpuUsec"`
Timelimit uint32 `json:"timelimit"`
TotCpuSec uint32 `json:"totCpuSec"`
TotCpuUsec uint32 `json:"totCpuUsec"`
TrackSteps uint32 `json:"trackSteps"`
Uid uint32 `json:"uid"`
User string `json:"user"` //UserName 用户名 in ac
UserCpuSec uint32 `json:"userCpuSec"`
UserCpuUsec uint32 `json:"userCpuUsec"`
Wckey string `json:"wckey"`
Wckeyid uint32 `json:"wckeyid"`
WorkDir string `json:"workDir"` //Workdir 工作空间 in ac
AcctTime string `json:"acctTime"` // 记账时间
AppType string `json:"appType"` // 作业应用类型
JobQueueTime string `json:"jobQueueTime"` //作业入队列时间
JobWalltimeUsed string `json:"jobWalltimeUsed"` //作业实际使用的Walltime,单位为秒
JobManagerId int `json:"jobmanagerId"` //区域id
} }
type ListHistoryJobReq struct { type ListHistoryJobReq struct {
SlurmVersion string `json:"slurmVersion,optional"`
StartTime string `json:"startTime,optional"`
EndTime string `json:"endTime,optional"`
TimeType string `json:"timeType,optional"`
Start int32 `json:"start,optional"`
Limit int32 `json:"limit,optional"`
IsQueryByQueueTime int32 `json:"isQueryByQueueTime,optional"`
} }
type ListHistoryJobResp struct { type ListHistoryJobResp struct {
Code int32 `json:"code"` Code int32 `json:"code"`
Msg string `json:"msg"` Msg string `json:"msg"`
RecordCount int32 `json:"recordCount"` RecordCount int32 `json:"recordCount"`
HistoryJobs []HistoryJob `json:"historyJobs"` HistoryJobs []HistoryJob `json:"jobInfoDbs"`
} }
type DataSets struct { type DataSets struct {