mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2024-12-25 21:09:05 +01:00
new filterRanges query and Cluster.filterRanges field
This commit is contained in:
parent
5c0ada7ec9
commit
b6df8e88b9
@ -59,6 +59,10 @@ models:
|
|||||||
fields:
|
fields:
|
||||||
tags:
|
tags:
|
||||||
resolver: true
|
resolver: true
|
||||||
|
Cluster:
|
||||||
|
fields:
|
||||||
|
filterRanges:
|
||||||
|
resolver: true
|
||||||
JobTag:
|
JobTag:
|
||||||
model: "github.com/ClusterCockpit/cc-jobarchive/graph/model.JobTag"
|
model: "github.com/ClusterCockpit/cc-jobarchive/graph/model.JobTag"
|
||||||
Timestamp:
|
Timestamp:
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,14 +9,10 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AddJobInput struct {
|
type FilterRanges struct {
|
||||||
JobID string `json:"jobId"`
|
Duration *IntRangeOutput `json:"duration"`
|
||||||
UserID string `json:"userId"`
|
NumNodes *IntRangeOutput `json:"numNodes"`
|
||||||
ProjectID string `json:"projectId"`
|
StartTime *TimeRangeOutput `json:"startTime"`
|
||||||
ClusterID string `json:"clusterId"`
|
|
||||||
StartTime time.Time `json:"startTime"`
|
|
||||||
Duration int `json:"duration"`
|
|
||||||
NumNodes int `json:"numNodes"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type FloatRange struct {
|
type FloatRange struct {
|
||||||
@ -34,6 +30,11 @@ type IntRange struct {
|
|||||||
To int `json:"to"`
|
To int `json:"to"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IntRangeOutput struct {
|
||||||
|
From int `json:"from"`
|
||||||
|
To int `json:"to"`
|
||||||
|
}
|
||||||
|
|
||||||
type JobFilter struct {
|
type JobFilter struct {
|
||||||
Tags []string `json:"tags"`
|
Tags []string `json:"tags"`
|
||||||
JobID *StringInput `json:"jobId"`
|
JobID *StringInput `json:"jobId"`
|
||||||
@ -110,19 +111,6 @@ type PageRequest struct {
|
|||||||
Page *int `json:"page"`
|
Page *int `json:"page"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StartJobInput struct {
|
|
||||||
JobID string `json:"jobId"`
|
|
||||||
UserID string `json:"userId"`
|
|
||||||
ProjectID string `json:"projectId"`
|
|
||||||
ClusterID string `json:"clusterId"`
|
|
||||||
StartTime time.Time `json:"startTime"`
|
|
||||||
NumNodes int `json:"numNodes"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StopJobInput struct {
|
|
||||||
StopTime time.Time `json:"stopTime"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type StringInput struct {
|
type StringInput struct {
|
||||||
Eq *string `json:"eq"`
|
Eq *string `json:"eq"`
|
||||||
Contains *string `json:"contains"`
|
Contains *string `json:"contains"`
|
||||||
@ -135,6 +123,11 @@ type TimeRange struct {
|
|||||||
To time.Time `json:"to"`
|
To time.Time `json:"to"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TimeRangeOutput struct {
|
||||||
|
From time.Time `json:"from"`
|
||||||
|
To time.Time `json:"to"`
|
||||||
|
}
|
||||||
|
|
||||||
type JobMetricScope string
|
type JobMetricScope string
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -357,34 +357,9 @@ func (r *queryResolver) JobMetrics(
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) Tags(
|
func (r *queryResolver) Tags(
|
||||||
ctx context.Context, jobId *string) ([]*model.JobTag, error) {
|
ctx context.Context) ([]*model.JobTag, error) {
|
||||||
|
|
||||||
if jobId == nil {
|
rows, err := r.DB.Queryx("SELECT * FROM tag")
|
||||||
rows, err := r.DB.Queryx("SELECT * FROM tag")
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
tags := []*model.JobTag{}
|
|
||||||
for rows.Next() {
|
|
||||||
var tag model.JobTag
|
|
||||||
err = rows.StructScan(&tag)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
tags = append(tags, &tag)
|
|
||||||
}
|
|
||||||
return tags, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/* TODO: Use cluster id? */
|
|
||||||
query := `
|
|
||||||
SELECT tag.id, tag.tag_name, tag.tag_type FROM tag
|
|
||||||
JOIN jobtag ON tag.id = jobtag.tag_id
|
|
||||||
JOIN job ON job.id = jobtag.job_id
|
|
||||||
WHERE job.job_id = $1
|
|
||||||
`
|
|
||||||
rows, err := r.DB.Queryx(query, jobId)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -398,10 +373,42 @@ func (r *queryResolver) Tags(
|
|||||||
}
|
}
|
||||||
tags = append(tags, &tag)
|
tags = append(tags, &tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
return tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *queryResolver) FilterRanges(
|
||||||
|
ctx context.Context) (*model.FilterRanges, error) {
|
||||||
|
|
||||||
|
rows, err := r.DB.Query(`
|
||||||
|
SELECT MIN(duration), MAX(duration),
|
||||||
|
MIN(num_nodes), MAX(num_nodes),
|
||||||
|
MIN(start_time), MAX(start_time) FROM job
|
||||||
|
`)
|
||||||
|
defer rows.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !rows.Next() {
|
||||||
|
panic("expected exactly one row")
|
||||||
|
}
|
||||||
|
|
||||||
|
duration := &model.IntRangeOutput{};
|
||||||
|
numNodes := &model.IntRangeOutput{};
|
||||||
|
var startTimeMin, startTimeMax int64
|
||||||
|
|
||||||
|
err = rows.Scan(&duration.From, &duration.To,
|
||||||
|
&numNodes.From, &numNodes.To,
|
||||||
|
&startTimeMin, &startTimeMax)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime := &model.TimeRangeOutput {
|
||||||
|
time.Unix(startTimeMin, 0), time.Unix(startTimeMax, 0) }
|
||||||
|
return &model.FilterRanges{ duration, numNodes, startTime }, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *jobResolver) Tags(ctx context.Context, job *model.Job) ([]*model.JobTag, error) {
|
func (r *jobResolver) Tags(ctx context.Context, job *model.Job) ([]*model.JobTag, error) {
|
||||||
query := `
|
query := `
|
||||||
SELECT tag.id, tag.tag_name, tag.tag_type FROM tag
|
SELECT tag.id, tag.tag_name, tag.tag_type FROM tag
|
||||||
@ -426,8 +433,44 @@ func (r *jobResolver) Tags(ctx context.Context, job *model.Job) ([]*model.JobTag
|
|||||||
return tags, nil
|
return tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Resolver) Job() generated.JobResolver { return &jobResolver{r} }
|
func (r *clusterResolver) FilterRanges(
|
||||||
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
ctx context.Context, cluster *model.Cluster) (*model.FilterRanges, error) {
|
||||||
|
|
||||||
|
rows, err := r.DB.Query(`
|
||||||
|
SELECT MIN(duration), MAX(duration),
|
||||||
|
MIN(num_nodes), MAX(num_nodes),
|
||||||
|
MIN(start_time), MAX(start_time)
|
||||||
|
FROM job WHERE job.cluster_id = $1
|
||||||
|
`, cluster.ClusterID)
|
||||||
|
defer rows.Close()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !rows.Next() {
|
||||||
|
panic("expected exactly one row")
|
||||||
|
}
|
||||||
|
|
||||||
|
duration := &model.IntRangeOutput{};
|
||||||
|
numNodes := &model.IntRangeOutput{};
|
||||||
|
var startTimeMin, startTimeMax int64
|
||||||
|
|
||||||
|
err = rows.Scan(&duration.From, &duration.To,
|
||||||
|
&numNodes.From, &numNodes.To,
|
||||||
|
&startTimeMin, &startTimeMax)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
startTime := &model.TimeRangeOutput {
|
||||||
|
time.Unix(startTimeMin, 0), time.Unix(startTimeMax, 0) }
|
||||||
|
return &model.FilterRanges{ duration, numNodes, startTime }, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *Resolver) Job() generated.JobResolver { return &jobResolver{r} }
|
||||||
|
func (r *Resolver) Cluster() generated.ClusterResolver { return &clusterResolver{r} }
|
||||||
|
func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
||||||
|
|
||||||
type jobResolver struct{ *Resolver }
|
type jobResolver struct{ *Resolver }
|
||||||
|
type clusterResolver struct{ *Resolver }
|
||||||
type queryResolver struct{ *Resolver }
|
type queryResolver struct{ *Resolver }
|
||||||
|
@ -10,11 +10,11 @@ type Job {
|
|||||||
numNodes: Int!
|
numNodes: Int!
|
||||||
hasProfile: Boolean!
|
hasProfile: Boolean!
|
||||||
|
|
||||||
memUsed_max: Float
|
memUsedMax: Float
|
||||||
flopsAny_avg: Float
|
flopsAnyAvg: Float
|
||||||
memBw_avg: Float
|
memBwAvg: Float
|
||||||
netBw_avg: Float
|
netBwAvg: Float
|
||||||
fileBw_avg: Float
|
fileBwAvg: Float
|
||||||
|
|
||||||
tags: [JobTag!]
|
tags: [JobTag!]
|
||||||
}
|
}
|
||||||
@ -29,6 +29,7 @@ type Cluster {
|
|||||||
flopRateSimd: Int!
|
flopRateSimd: Int!
|
||||||
memoryBandwidth: Int!
|
memoryBandwidth: Int!
|
||||||
metricConfig: [MetricConfig!]!
|
metricConfig: [MetricConfig!]!
|
||||||
|
filterRanges: FilterRanges!
|
||||||
}
|
}
|
||||||
|
|
||||||
type MetricConfig {
|
type MetricConfig {
|
||||||
@ -80,8 +81,9 @@ type Query {
|
|||||||
jobsStatistics(filter: JobFilterList): JobsStatistics!
|
jobsStatistics(filter: JobFilterList): JobsStatistics!
|
||||||
jobMetrics(jobId: String!, clusterId: String, startTime: Time, metrics: [String]): [JobMetricWithName]!
|
jobMetrics(jobId: String!, clusterId: String, startTime: Time, metrics: [String]): [JobMetricWithName]!
|
||||||
|
|
||||||
# Return all known tags or, if jobId is specified, only tags from this job
|
tags: [JobTag!]!
|
||||||
tags(jobId: String): [JobTag!]!
|
|
||||||
|
filterRanges: FilterRanges!
|
||||||
}
|
}
|
||||||
|
|
||||||
input JobFilterList {
|
input JobFilterList {
|
||||||
@ -100,6 +102,22 @@ input JobFilter {
|
|||||||
hasProfile: Boolean
|
hasProfile: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type IntRangeOutput {
|
||||||
|
from: Int!
|
||||||
|
to: Int!
|
||||||
|
}
|
||||||
|
|
||||||
|
type TimeRangeOutput {
|
||||||
|
from: Time!
|
||||||
|
to: Time!
|
||||||
|
}
|
||||||
|
|
||||||
|
type FilterRanges {
|
||||||
|
duration: IntRangeOutput!
|
||||||
|
numNodes: IntRangeOutput!
|
||||||
|
startTime: TimeRangeOutput!
|
||||||
|
}
|
||||||
|
|
||||||
input OrderByInput {
|
input OrderByInput {
|
||||||
field: String!
|
field: String!
|
||||||
order: SortDirectionEnum = ASC
|
order: SortDirectionEnum = ASC
|
||||||
|
Loading…
Reference in New Issue
Block a user