Files
UnrealEngineUWP/Engine/Source/Programs/Horde/HordeServer/Models/Telemetry.cs
Ben Marsh 5abbc95b6e Add missing copyright notices.
[CL 16160939 by Ben Marsh in ue5-main branch]
2021-04-29 15:35:57 -04:00

214 lines
5.5 KiB
C#

// Copyright Epic Games, Inc. All Rights Reserved.
using HordeServer.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PoolId = HordeServer.Utilities.StringId<HordeServer.Models.IPool>;
using StreamId = HordeServer.Utilities.StringId<HordeServer.Models.IStream>;
namespace HordeServer.Models
{
/// <summary>
/// Information about the utilization of a pool
/// </summary>
public interface IUtilizationTelemetry
{
/// <summary>
/// Start time for the bucket
/// </summary>
public DateTime StartTime { get; }
/// <summary>
/// Finish time for this bucket
/// </summary>
public DateTime FinishTime { get; }
/// <summary>
/// Number of agents in total
/// </summary>
public int NumAgents { get; }
/// <summary>
/// Breakdown of utilization by pool
/// </summary>
public IReadOnlyList<IPoolUtilizationTelemetry> Pools { get; }
/// <summary>
/// Total time spent running administrative tasks (conform, etc...)
/// </summary>
public double AdminTime { get; }
}
/// <summary>
/// Concrete implementation of <see cref="IUtilizationTelemetry"/>
/// </summary>
public sealed class NewUtilizationTelemetry : IUtilizationTelemetry
{
/// <inheritdoc/>
public DateTime StartTime { get; set; }
/// <inheritdoc/>
public DateTime FinishTime { get; set; }
/// <inheritdoc/>
public int NumAgents { get; set; }
/// <inheritdoc/>
List<NewPoolUtilizationTelemetry> Pools { get; set; } = new List<NewPoolUtilizationTelemetry>();
IReadOnlyList<IPoolUtilizationTelemetry> IUtilizationTelemetry.Pools => Pools;
Dictionary<PoolId, NewPoolUtilizationTelemetry> PoolsLookup { get; set; } = new Dictionary<PoolId, NewPoolUtilizationTelemetry>();
/// <inheritdoc/>
public double AdminTime { get; set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="StartTime"></param>
/// <param name="FinishTime"></param>
public NewUtilizationTelemetry(DateTime StartTime, DateTime FinishTime)
{
this.StartTime = StartTime;
this.FinishTime = FinishTime;
}
/// <summary>
/// Adds a new pool
/// </summary>
/// <param name="PoolId">The pool id</param>
/// <returns>Telemetry for the given pool</returns>
public NewPoolUtilizationTelemetry FindOrAddPool(PoolId PoolId)
{
NewPoolUtilizationTelemetry? Pool;
if (!PoolsLookup.TryGetValue(PoolId, out Pool))
{
Pool = new NewPoolUtilizationTelemetry(PoolId);
Pools.Add(Pool);
PoolsLookup.Add(PoolId, Pool);
}
return Pool;
}
}
/// <summary>
/// Information about the utilization of a pool
/// </summary>
public interface IPoolUtilizationTelemetry
{
/// <summary>
/// Pool containing the work to execute
/// </summary>
public PoolId PoolId { get; }
/// <summary>
/// Number of agents in this pool
/// </summary>
public int NumAgents { get; }
/// <summary>
/// The stream executing work. If this is null, the time accounts for the machine executing work in another pool.
/// </summary>
public IReadOnlyList<IStreamUtilizationTelemetry> Streams { get; }
/// <summary>
/// Admount of time spent running
/// </summary>
public double AdminTime { get; }
/// <summary>
/// Amount of time spent by agents in this pool servicing other pools
/// </summary>
public double OtherTime { get; }
}
/// <summary>
/// Concrete implementation of <see cref="IPoolUtilizationTelemetry"/>
/// </summary>
public sealed class NewPoolUtilizationTelemetry : IPoolUtilizationTelemetry
{
/// <inheritdoc/>
public PoolId PoolId { get; set; }
/// <inheritdoc/>
public int NumAgents { get; set; }
/// <inheritdoc/>
List<NewPoolUtilizationTelemetryStream> Streams { get; set; } = new List<NewPoolUtilizationTelemetryStream>();
IReadOnlyList<IStreamUtilizationTelemetry> IPoolUtilizationTelemetry.Streams => Streams;
Dictionary<StreamId, NewPoolUtilizationTelemetryStream> StreamLookup { get; set; } = new Dictionary<StreamId, NewPoolUtilizationTelemetryStream>();
/// <inheritdoc/>
public double AdminTime { get; set; }
/// <inheritdoc/>
public double OtherTime { get; set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="PoolId"></param>
public NewPoolUtilizationTelemetry(PoolId PoolId)
{
this.PoolId = PoolId;
}
/// <summary>
/// Adds a stream to the object
/// </summary>
/// <param name="StreamId"></param>
public NewPoolUtilizationTelemetryStream FindOrAddStream(StreamId StreamId)
{
NewPoolUtilizationTelemetryStream? Stream;
if (!StreamLookup.TryGetValue(StreamId, out Stream))
{
Stream = new NewPoolUtilizationTelemetryStream(StreamId);
Streams.Add(Stream);
StreamLookup.Add(StreamId, Stream);
}
return Stream;
}
}
/// <summary>
/// Utilization of a pool for a particular stream
/// </summary>
public interface IStreamUtilizationTelemetry
{
/// <summary>
/// The stream id
/// </summary>
public StreamId StreamId { get; }
/// <summary>
/// Number of machine hours spent executing work for this stream
/// </summary>
public double Time { get; }
}
/// <summary>
/// Concrete implementation of <see cref="IStreamUtilizationTelemetry"/>
/// </summary>
public sealed class NewPoolUtilizationTelemetryStream : IStreamUtilizationTelemetry
{
/// <inheritdoc/>
public StreamId StreamId { get; set; }
/// <inheritdoc/>
public double Time { get; set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="StreamId"></param>
public NewPoolUtilizationTelemetryStream(StreamId StreamId)
{
this.StreamId = StreamId;
}
}
}