2024-04-11 23:04:30 +02:00
|
|
|
// Copyright (C) NHR@FAU, University Erlangen-Nuremberg.
|
2022-07-29 06:29:21 +02:00
|
|
|
// All rights reserved.
|
|
|
|
// Use of this source code is governed by a MIT-style
|
|
|
|
// license that can be found in the LICENSE file.
|
2021-12-17 15:49:22 +01:00
|
|
|
package schema
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2023-04-21 12:59:27 +02:00
|
|
|
// BaseJob is the common part of the job metadata structs
|
|
|
|
//
|
|
|
|
// Common subset of Job and JobMeta. Use one of those, not this type directly.
|
2022-09-21 11:54:19 +02:00
|
|
|
|
2021-12-17 15:49:22 +01:00
|
|
|
type BaseJob struct {
|
2024-07-05 16:16:01 +02:00
|
|
|
Cluster string `json:"cluster" db:"cluster" example:"fritz"`
|
|
|
|
SubCluster string `json:"subCluster" db:"subcluster" example:"main"`
|
2024-11-21 15:02:30 +01:00
|
|
|
Partition string `json:"partition,omitempty" db:"cluster_partition" example:"main"`
|
2024-07-05 16:16:01 +02:00
|
|
|
Project string `json:"project" db:"project" example:"abcd200"`
|
2024-11-21 15:02:30 +01:00
|
|
|
User string `json:"user" db:"hpc_user" example:"abcd100h"`
|
2024-07-05 16:16:01 +02:00
|
|
|
State JobState `json:"jobState" db:"job_state" example:"completed" enums:"completed,failed,cancelled,stopped,timeout,out_of_memory"`
|
|
|
|
Tags []*Tag `json:"tags,omitempty"`
|
|
|
|
RawEnergyFootprint []byte `json:"-" db:"energy_footprint"`
|
|
|
|
RawFootprint []byte `json:"-" db:"footprint"`
|
|
|
|
RawMetaData []byte `json:"-" db:"meta_data"`
|
|
|
|
RawResources []byte `json:"-" db:"resources"`
|
|
|
|
Resources []*Resource `json:"resources"`
|
|
|
|
EnergyFootprint map[string]float64 `json:"energyFootprint"`
|
|
|
|
Footprint map[string]float64 `json:"footprint"`
|
|
|
|
MetaData map[string]string `json:"metaData"`
|
|
|
|
ConcurrentJobs JobLinkResultList `json:"concurrentJobs"`
|
2024-08-15 09:41:54 +02:00
|
|
|
Energy float64 `json:"energy" db:"energy"`
|
2024-07-05 16:16:01 +02:00
|
|
|
ArrayJobId int64 `json:"arrayJobId,omitempty" db:"array_job_id" example:"123000"`
|
|
|
|
Walltime int64 `json:"walltime,omitempty" db:"walltime" example:"86400" minimum:"1"`
|
|
|
|
JobID int64 `json:"jobId" db:"job_id" example:"123000"`
|
|
|
|
Duration int32 `json:"duration" db:"duration" example:"43200" minimum:"1"`
|
|
|
|
SMT int32 `json:"smt,omitempty" db:"smt" example:"4"`
|
|
|
|
MonitoringStatus int32 `json:"monitoringStatus,omitempty" db:"monitoring_status" example:"1" minimum:"0" maximum:"3"`
|
|
|
|
Exclusive int32 `json:"exclusive" db:"exclusive" example:"1" minimum:"0" maximum:"2"`
|
|
|
|
NumAcc int32 `json:"numAcc,omitempty" db:"num_acc" example:"2" minimum:"1"`
|
|
|
|
NumHWThreads int32 `json:"numHwthreads,omitempty" db:"num_hwthreads" example:"20" minimum:"1"`
|
|
|
|
NumNodes int32 `json:"numNodes" db:"num_nodes" example:"2" minimum:"1"`
|
2022-01-07 09:39:00 +01:00
|
|
|
}
|
2021-12-17 15:49:22 +01:00
|
|
|
|
2023-04-21 12:59:27 +02:00
|
|
|
// Job struct type
|
|
|
|
//
|
|
|
|
// This type is used as the GraphQL interface and using sqlx as a table row.
|
|
|
|
//
|
2022-09-21 11:54:19 +02:00
|
|
|
// Job model
|
|
|
|
// @Description Information of a HPC job.
|
2022-01-07 09:39:00 +01:00
|
|
|
type Job struct {
|
2024-06-28 16:48:10 +02:00
|
|
|
StartTime time.Time `json:"startTime"`
|
2022-01-07 09:39:00 +01:00
|
|
|
BaseJob
|
2024-06-28 16:48:10 +02:00
|
|
|
ID int64 `json:"id" db:"id"`
|
|
|
|
StartTimeUnix int64 `json:"-" db:"start_time" example:"1649723812"`
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
2023-04-21 12:59:27 +02:00
|
|
|
// JobMeta struct type
|
|
|
|
//
|
|
|
|
// When reading from the database or sending data via GraphQL, the start time
|
|
|
|
// can be in the much more convenient time.Time type. In the `meta.json`
|
|
|
|
// files, the start time is encoded as a unix epoch timestamp. This is why
|
|
|
|
// there is this struct, which contains all fields from the regular job
|
|
|
|
// struct, but "overwrites" the StartTime field with one of type int64. ID
|
|
|
|
// *int64 `json:"id,omitempty"` >> never used in the job-archive, only
|
|
|
|
// available via REST-API
|
|
|
|
//
|
2023-06-01 15:24:26 +02:00
|
|
|
|
2023-05-16 12:42:06 +02:00
|
|
|
type JobLink struct {
|
|
|
|
ID int64 `json:"id"`
|
|
|
|
JobID int64 `json:"jobId"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type JobLinkResultList struct {
|
|
|
|
Items []*JobLink `json:"items"`
|
|
|
|
Count int `json:"count"`
|
|
|
|
}
|
|
|
|
|
2022-09-21 11:54:19 +02:00
|
|
|
// JobMeta model
|
|
|
|
// @Description Meta data information of a HPC job.
|
2021-12-17 15:49:22 +01:00
|
|
|
type JobMeta struct {
|
2024-06-28 16:48:10 +02:00
|
|
|
ID *int64 `json:"id,omitempty"`
|
|
|
|
Statistics map[string]JobStatistics `json:"statistics"`
|
2021-12-17 15:49:22 +01:00
|
|
|
BaseJob
|
2024-06-28 16:48:10 +02:00
|
|
|
StartTime int64 `json:"startTime" db:"start_time" example:"1649723812" minimum:"1"`
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
2022-02-15 14:25:39 +01:00
|
|
|
const (
|
|
|
|
MonitoringStatusDisabled int32 = 0
|
|
|
|
MonitoringStatusRunningOrArchiving int32 = 1
|
|
|
|
MonitoringStatusArchivingFailed int32 = 2
|
|
|
|
MonitoringStatusArchivingSuccessful int32 = 3
|
|
|
|
)
|
|
|
|
|
2021-12-17 15:49:22 +01:00
|
|
|
var JobDefaults BaseJob = BaseJob{
|
|
|
|
Exclusive: 1,
|
2022-02-15 14:25:39 +01:00
|
|
|
MonitoringStatus: MonitoringStatusRunningOrArchiving,
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
2022-10-04 10:12:35 +02:00
|
|
|
type Unit struct {
|
2023-04-25 09:26:48 +02:00
|
|
|
Base string `json:"base"`
|
|
|
|
Prefix string `json:"prefix,omitempty"`
|
2022-10-04 10:12:35 +02:00
|
|
|
}
|
|
|
|
|
2022-09-21 11:54:19 +02:00
|
|
|
// JobStatistics model
|
|
|
|
// @Description Specification for job metric statistics.
|
2021-12-17 15:49:22 +01:00
|
|
|
type JobStatistics struct {
|
2023-06-14 14:33:36 +02:00
|
|
|
Unit Unit `json:"unit"`
|
2022-09-21 11:54:19 +02:00
|
|
|
Avg float64 `json:"avg" example:"2500" minimum:"0"` // Job metric average
|
|
|
|
Min float64 `json:"min" example:"2000" minimum:"0"` // Job metric minimum
|
|
|
|
Max float64 `json:"max" example:"3000" minimum:"0"` // Job metric maximum
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
2022-09-21 11:54:19 +02:00
|
|
|
// Tag model
|
|
|
|
// @Description Defines a tag using name and type.
|
2021-12-17 15:49:22 +01:00
|
|
|
type Tag struct {
|
2024-08-01 18:59:24 +02:00
|
|
|
Type string `json:"type" db:"tag_type" example:"Debug"`
|
|
|
|
Name string `json:"name" db:"tag_name" example:"Testjob"`
|
|
|
|
Scope string `json:"scope" db:"tag_scope" example:"global"`
|
|
|
|
ID int64 `json:"id" db:"id"`
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
2022-09-21 11:54:19 +02:00
|
|
|
// Resource model
|
|
|
|
// @Description A resource used by a job
|
2021-12-17 15:49:22 +01:00
|
|
|
type Resource struct {
|
2024-06-28 16:48:10 +02:00
|
|
|
Hostname string `json:"hostname"`
|
|
|
|
Configuration string `json:"configuration,omitempty"`
|
|
|
|
HWThreads []int `json:"hwthreads,omitempty"`
|
|
|
|
Accelerators []string `json:"accelerators,omitempty"`
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
type JobState string
|
|
|
|
|
|
|
|
const (
|
2022-02-17 08:56:37 +01:00
|
|
|
JobStateRunning JobState = "running"
|
|
|
|
JobStateCompleted JobState = "completed"
|
|
|
|
JobStateFailed JobState = "failed"
|
|
|
|
JobStateCancelled JobState = "cancelled"
|
|
|
|
JobStateStopped JobState = "stopped"
|
|
|
|
JobStateTimeout JobState = "timeout"
|
|
|
|
JobStatePreempted JobState = "preempted"
|
|
|
|
JobStateOutOfMemory JobState = "out_of_memory"
|
2021-12-17 15:49:22 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
func (e *JobState) UnmarshalGQL(v interface{}) error {
|
|
|
|
str, ok := v.(string)
|
|
|
|
if !ok {
|
2023-01-19 16:59:14 +01:00
|
|
|
return fmt.Errorf("SCHEMA/JOB > enums must be strings")
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
*e = JobState(str)
|
|
|
|
if !e.Valid() {
|
2023-01-19 16:59:14 +01:00
|
|
|
return errors.New("SCHEMA/JOB > invalid job state")
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e JobState) MarshalGQL(w io.Writer) {
|
|
|
|
fmt.Fprintf(w, "\"%s\"", e)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e JobState) Valid() bool {
|
|
|
|
return e == JobStateRunning ||
|
|
|
|
e == JobStateCompleted ||
|
|
|
|
e == JobStateFailed ||
|
2022-02-17 08:56:37 +01:00
|
|
|
e == JobStateCancelled ||
|
2021-12-17 15:49:22 +01:00
|
|
|
e == JobStateStopped ||
|
2022-02-17 09:22:43 +01:00
|
|
|
e == JobStateTimeout ||
|
|
|
|
e == JobStatePreempted ||
|
|
|
|
e == JobStateOutOfMemory
|
2021-12-17 15:49:22 +01:00
|
|
|
}
|