Ensure Story Intelligence queue supports known characters
This commit is contained in:
parent
01555136e7
commit
dbbc46f02b
@ -41,6 +41,9 @@ public interface IStoryIntelligenceResultRepository
|
|||||||
|
|
||||||
public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory connectionFactory) : IStoryIntelligenceResultRepository
|
public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory connectionFactory) : IStoryIntelligenceResultRepository
|
||||||
{
|
{
|
||||||
|
private static readonly SemaphoreSlim QueueSupportLock = new(1, 1);
|
||||||
|
private static bool queueSupportEnsured;
|
||||||
|
|
||||||
public async Task<int> SaveAsync(StoryIntelligenceRunSaveRequest request)
|
public async Task<int> SaveAsync(StoryIntelligenceRunSaveRequest request)
|
||||||
{
|
{
|
||||||
using var connection = connectionFactory.CreateConnection();
|
using var connection = connectionFactory.CreateConnection();
|
||||||
@ -160,6 +163,7 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
public async Task<int> QueueAdminTextAsync(StoryIntelligenceRunQueueRequest request)
|
public async Task<int> QueueAdminTextAsync(StoryIntelligenceRunQueueRequest request)
|
||||||
{
|
{
|
||||||
using var connection = connectionFactory.CreateConnection();
|
using var connection = connectionFactory.CreateConnection();
|
||||||
|
await EnsureKnownCharacterQueueSupportAsync(connection);
|
||||||
return await connection.QuerySingleAsync<int>(
|
return await connection.QuerySingleAsync<int>(
|
||||||
"dbo.StoryIntelligenceRun_QueueAdminText",
|
"dbo.StoryIntelligenceRun_QueueAdminText",
|
||||||
new
|
new
|
||||||
@ -185,6 +189,129 @@ public sealed class StoryIntelligenceResultRepository(ISqlConnectionFactory conn
|
|||||||
commandType: CommandType.StoredProcedure);
|
commandType: CommandType.StoredProcedure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static async Task EnsureKnownCharacterQueueSupportAsync(IDbConnection connection)
|
||||||
|
{
|
||||||
|
if (queueSupportEnsured)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await QueueSupportLock.WaitAsync();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (queueSupportEnsured)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await connection.ExecuteAsync(
|
||||||
|
"""
|
||||||
|
IF COL_LENGTH(N'dbo.StoryIntelligenceRuns', N'KnownCharactersJson') IS NULL
|
||||||
|
BEGIN
|
||||||
|
ALTER TABLE dbo.StoryIntelligenceRuns ADD KnownCharactersJson nvarchar(max) NULL;
|
||||||
|
END;
|
||||||
|
""");
|
||||||
|
|
||||||
|
await connection.ExecuteAsync(
|
||||||
|
"""
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.StoryIntelligenceRun_QueueAdminText
|
||||||
|
@UserID int,
|
||||||
|
@ProjectID int = NULL,
|
||||||
|
@BookID int = NULL,
|
||||||
|
@ChapterID int = NULL,
|
||||||
|
@ChapterNumber decimal(9, 2) = NULL,
|
||||||
|
@SourceType nvarchar(50),
|
||||||
|
@SourceLabel nvarchar(300),
|
||||||
|
@SourceText nvarchar(max),
|
||||||
|
@SourceFileName nvarchar(260) = NULL,
|
||||||
|
@SourceFileSizeBytes bigint = NULL,
|
||||||
|
@SourceWordCount int = NULL,
|
||||||
|
@SourceCharacterCount int = NULL,
|
||||||
|
@SourceParagraphCount int = NULL,
|
||||||
|
@SourceChapterCount int = NULL,
|
||||||
|
@Model nvarchar(100),
|
||||||
|
@PromptVersionsSummary nvarchar(500),
|
||||||
|
@KnownCharactersJson nvarchar(max) = NULL
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
|
||||||
|
INSERT dbo.StoryIntelligenceRuns
|
||||||
|
(
|
||||||
|
UserID, ProjectID, BookID, ChapterID, ChapterNumber, Status, SourceType, SourceLabel, SourceText,
|
||||||
|
SourceFileName, SourceFileSizeBytes, SourceWordCount, SourceCharacterCount, SourceParagraphCount,
|
||||||
|
SourceChapterCount, Model, PromptVersion, PromptVersionsSummary, KnownCharactersJson, StartedUtc,
|
||||||
|
CurrentStage, CurrentMessage, CompletedScenes, FailedScenes
|
||||||
|
)
|
||||||
|
VALUES
|
||||||
|
(
|
||||||
|
@UserID, @ProjectID, @BookID, @ChapterID, @ChapterNumber, N'Pending', @SourceType, @SourceLabel, @SourceText,
|
||||||
|
@SourceFileName, @SourceFileSizeBytes, @SourceWordCount, @SourceCharacterCount, @SourceParagraphCount,
|
||||||
|
@SourceChapterCount, @Model, @PromptVersionsSummary, @PromptVersionsSummary, @KnownCharactersJson,
|
||||||
|
SYSUTCDATETIME(), N'Pending', N'Queued for Story Intelligence processing.', 0, 0
|
||||||
|
);
|
||||||
|
|
||||||
|
SELECT CAST(SCOPE_IDENTITY() AS int) AS StoryIntelligenceRunID;
|
||||||
|
END;
|
||||||
|
""");
|
||||||
|
|
||||||
|
await connection.ExecuteAsync(
|
||||||
|
"""
|
||||||
|
CREATE OR ALTER PROCEDURE dbo.StoryIntelligenceRun_ClaimNextPending
|
||||||
|
AS
|
||||||
|
BEGIN
|
||||||
|
SET NOCOUNT ON;
|
||||||
|
SET XACT_ABORT ON;
|
||||||
|
|
||||||
|
DECLARE @StoryIntelligenceRunID int;
|
||||||
|
|
||||||
|
SELECT TOP (1) @StoryIntelligenceRunID = StoryIntelligenceRunID
|
||||||
|
FROM dbo.StoryIntelligenceRuns WITH (UPDLOCK, READPAST)
|
||||||
|
WHERE Status = N'Pending'
|
||||||
|
ORDER BY CreatedUtc;
|
||||||
|
|
||||||
|
IF @StoryIntelligenceRunID IS NULL
|
||||||
|
BEGIN
|
||||||
|
SELECT TOP (0)
|
||||||
|
StoryIntelligenceRunID, UserID, ProjectID, BookID, ChapterID, ChapterNumber, Status, SourceType, SourceLabel,
|
||||||
|
SourceText, SourceWordCount, SourceCharacterCount, SourceParagraphCount, SourceChapterCount, PromptVersion,
|
||||||
|
PromptVersionsSummary, KnownCharactersJson, Model, StartedUtc, CompletedUtc, FailureStage, TotalInputTokens,
|
||||||
|
TotalOutputTokens, TotalTokens, TotalDurationMs, EstimatedCostGBP, EstimatedCostUSD,
|
||||||
|
ErrorMessage, ErrorDetail, CurrentStage, CurrentMessage, TotalDetectedScenes,
|
||||||
|
CompletedScenes, FailedScenes, CancellationRequestedUtc, CancelledUtc, CreatedUtc, UpdatedUtc
|
||||||
|
FROM dbo.StoryIntelligenceRuns;
|
||||||
|
RETURN;
|
||||||
|
END;
|
||||||
|
|
||||||
|
UPDATE dbo.StoryIntelligenceRuns
|
||||||
|
SET Status = N'Running',
|
||||||
|
StartedUtc = SYSUTCDATETIME(),
|
||||||
|
CurrentStage = N'ChapterStructure',
|
||||||
|
CurrentMessage = N'Running Chapter Structure analysis.',
|
||||||
|
UpdatedUtc = SYSUTCDATETIME()
|
||||||
|
WHERE StoryIntelligenceRunID = @StoryIntelligenceRunID
|
||||||
|
AND Status = N'Pending';
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
StoryIntelligenceRunID, UserID, ProjectID, BookID, ChapterID, ChapterNumber, Status, SourceType, SourceLabel,
|
||||||
|
SourceText, SourceWordCount, SourceCharacterCount, SourceParagraphCount, SourceChapterCount, PromptVersion,
|
||||||
|
PromptVersionsSummary, KnownCharactersJson, Model, StartedUtc, CompletedUtc, FailureStage, TotalInputTokens,
|
||||||
|
TotalOutputTokens, TotalTokens, TotalDurationMs, EstimatedCostGBP, EstimatedCostUSD,
|
||||||
|
ErrorMessage, ErrorDetail, CurrentStage, CurrentMessage, TotalDetectedScenes,
|
||||||
|
CompletedScenes, FailedScenes, CancellationRequestedUtc, CancelledUtc, CreatedUtc, UpdatedUtc
|
||||||
|
FROM dbo.StoryIntelligenceRuns
|
||||||
|
WHERE StoryIntelligenceRunID = @StoryIntelligenceRunID;
|
||||||
|
END;
|
||||||
|
""");
|
||||||
|
|
||||||
|
queueSupportEnsured = true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
QueueSupportLock.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<StoryIntelligenceQueuedRun?> ClaimNextPendingAsync()
|
public async Task<StoryIntelligenceQueuedRun?> ClaimNextPendingAsync()
|
||||||
{
|
{
|
||||||
using var connection = connectionFactory.CreateConnection();
|
using var connection = connectionFactory.CreateConnection();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user