- execution event와 agent run 기록이 들어올 때마다 즉시 저장하지 않고 conversationPersistTimer로 220ms 단위 지연 저장하도록 변경함 - Cowork/Code 연속 이벤트 구간의 디스크 I/O를 줄여 체감 끊김과 잦은 저장 부하를 낮추는 방향으로 정리함 - 검증: dotnet build src/AxCopilot/AxCopilot.csproj -c Release -v minimal -p:OutputPath=bin\\verify\\ -p:IntermediateOutputPath=obj\\verify\\ 경고 0 / 오류 0
This commit is contained in:
@@ -85,6 +85,7 @@ public partial class ChatWindow : Window
|
||||
private readonly DispatcherTimer _inputUiRefreshTimer;
|
||||
private readonly DispatcherTimer _executionHistoryRenderTimer;
|
||||
private readonly DispatcherTimer _taskSummaryRefreshTimer;
|
||||
private readonly DispatcherTimer _conversationPersistTimer;
|
||||
private CancellationTokenSource? _gitStatusRefreshCts;
|
||||
private int _displayedLength; // 현재 화면에 표시된 글자 수
|
||||
private ResourceDictionary? _agentThemeDictionary;
|
||||
@@ -119,6 +120,7 @@ public partial class ChatWindow : Window
|
||||
private int _sessionPostCompactionPromptTokens;
|
||||
private int _sessionPostCompactionCompletionTokens;
|
||||
private bool _pendingExecutionHistoryAutoScroll;
|
||||
private readonly Dictionary<string, ChatConversation> _pendingConversationPersists = new(StringComparer.OrdinalIgnoreCase);
|
||||
private void ApplyQuickActionVisual(Button button, bool active, string activeBg, string activeFg)
|
||||
{
|
||||
if (button?.Content is not string text)
|
||||
@@ -251,6 +253,12 @@ public partial class ChatWindow : Window
|
||||
_taskSummaryRefreshTimer.Stop();
|
||||
UpdateTaskSummaryIndicators();
|
||||
};
|
||||
_conversationPersistTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(220) };
|
||||
_conversationPersistTimer.Tick += (_, _) =>
|
||||
{
|
||||
_conversationPersistTimer.Stop();
|
||||
FlushPendingConversationPersists();
|
||||
};
|
||||
|
||||
KeyDown += ChatWindow_KeyDown;
|
||||
UpdateConversationFailureFilterUi();
|
||||
@@ -8557,6 +8565,7 @@ public partial class ChatWindow : Window
|
||||
_executionHistoryRenderTimer.Stop();
|
||||
_pendingExecutionHistoryAutoScroll = false;
|
||||
_taskSummaryRefreshTimer.Stop();
|
||||
_conversationPersistTimer.Stop();
|
||||
HideStickyProgress();
|
||||
StopRainbowGlow();
|
||||
_activeStreamText = null;
|
||||
@@ -8626,6 +8635,30 @@ public partial class ChatWindow : Window
|
||||
_taskSummaryRefreshTimer.Start();
|
||||
}
|
||||
|
||||
private void ScheduleConversationPersist(ChatConversation? conversation)
|
||||
{
|
||||
if (conversation == null || string.IsNullOrWhiteSpace(conversation.Id))
|
||||
return;
|
||||
|
||||
_pendingConversationPersists[conversation.Id] = conversation;
|
||||
_conversationPersistTimer.Stop();
|
||||
_conversationPersistTimer.Start();
|
||||
}
|
||||
|
||||
private void FlushPendingConversationPersists()
|
||||
{
|
||||
if (_pendingConversationPersists.Count == 0)
|
||||
return;
|
||||
|
||||
foreach (var conversation in _pendingConversationPersists.Values.ToList())
|
||||
{
|
||||
try { _storage.Save(conversation); }
|
||||
catch (Exception ex) { Services.LogService.Debug($"대화 지연 저장 실패: {ex.Message}"); }
|
||||
}
|
||||
|
||||
_pendingConversationPersists.Clear();
|
||||
}
|
||||
|
||||
// ─── 코워크 에이전트 지원 ────────────────────────────────────────────
|
||||
|
||||
private string BuildCoworkSystemPrompt()
|
||||
@@ -9106,15 +9139,18 @@ public partial class ChatWindow : Window
|
||||
|
||||
var normalizedTarget = NormalizeTabName(targetTab);
|
||||
var normalizedActive = NormalizeTabName(_activeTab);
|
||||
ChatConversation updatedConversation;
|
||||
if (string.Equals(normalizedTarget, normalizedActive, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_currentConversation = session.AppendAgentRun(normalizedTarget, evt, status, summary, _storage);
|
||||
_currentConversation = updatedConversation = session.AppendAgentRun(normalizedTarget, evt, status, summary, null);
|
||||
ScheduleConversationPersist(updatedConversation);
|
||||
return;
|
||||
}
|
||||
|
||||
var activeSnapshot = _currentConversation;
|
||||
var previousSessionConversation = session.CurrentConversation;
|
||||
session.AppendAgentRun(normalizedTarget, evt, status, summary, _storage);
|
||||
updatedConversation = session.AppendAgentRun(normalizedTarget, evt, status, summary, null);
|
||||
ScheduleConversationPersist(updatedConversation);
|
||||
|
||||
if (activeSnapshot != null && string.Equals(NormalizeTabName(activeSnapshot.Tab), normalizedActive, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@@ -9156,15 +9192,18 @@ public partial class ChatWindow : Window
|
||||
|
||||
var normalizedTarget = NormalizeTabName(targetTab);
|
||||
var normalizedActive = NormalizeTabName(_activeTab);
|
||||
ChatConversation updatedConversation;
|
||||
if (string.Equals(normalizedTarget, normalizedActive, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_currentConversation = session.AppendExecutionEvent(normalizedTarget, evt, _storage);
|
||||
_currentConversation = updatedConversation = session.AppendExecutionEvent(normalizedTarget, evt, null);
|
||||
ScheduleConversationPersist(updatedConversation);
|
||||
return;
|
||||
}
|
||||
|
||||
var activeSnapshot = _currentConversation;
|
||||
var previousSessionConversation = session.CurrentConversation;
|
||||
session.AppendExecutionEvent(normalizedTarget, evt, _storage);
|
||||
updatedConversation = session.AppendExecutionEvent(normalizedTarget, evt, null);
|
||||
ScheduleConversationPersist(updatedConversation);
|
||||
|
||||
if (activeSnapshot != null && string.Equals(NormalizeTabName(activeSnapshot.Tab), normalizedActive, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user