namespace SQLInsight.Core.Data; /// /// Sessions that were blocked, and the sessions blocking them, at the moment of collection. /// public sealed record BlockingSnapshot { public required DateTimeOffset CapturedAt { get; init; } public required IReadOnlyList Sessions { get; init; } /// Sessions that block others without being blocked themselves. public IEnumerable HeadBlockers { get { var blocked = Sessions.Where(s => s.BlockingSessionId is > 0).Select(s => s.SessionId).ToHashSet(); var blockers = Sessions.Where(s => s.BlockingSessionId is > 0).Select(s => s.BlockingSessionId!.Value).ToHashSet(); return Sessions.Where(s => blockers.Contains(s.SessionId) && !blocked.Contains(s.SessionId)); } } public IEnumerable BlockedBy(int sessionId) => Sessions.Where(s => s.BlockingSessionId == sessionId); } public sealed record SessionInfo { public required int SessionId { get; init; } /// The session this one is waiting on, or . public int? BlockingSessionId { get; init; } /// running, runnable, suspended, sleeping … public string? Status { get; init; } public string? WaitType { get; init; } public long? WaitTimeMs { get; init; } public string? WaitResource { get; init; } public string? DatabaseName { get; init; } public string? LoginName { get; init; } public string? HostName { get; init; } public string? ProgramName { get; init; } public int OpenTransactionCount { get; init; } /// The current or last statement, truncated. Never includes parameter values. public string? SqlText { get; init; } public DateTime? LastRequestEndTime { get; init; } }