Skip to content

Commit 949233f

Browse files
thomhurstclaude
andcommitted
fix(logging): Address additional code review issues
Fix issues identified in second review: 1. AfterPipelineLogger: Use boolean flag for cache validity - Added _isCacheValid field instead of relying on StringBuilder.Length - Prevents unnecessary rebuilds when GetOutput() called multiple times - Clear StringBuilder on rebuild, set flag to true after build 2. ModuleLoggerProvider: Separate caching concerns - GetLogger(Type type) no longer modifies _moduleLogger cache - Removes lock from GetLogger(Type type) - doesn't need shared cache - Renamed MakeLogger to CreateLogger for clarity - Parameterless GetLogger() properly caches with lock protection - Avoids potential deadlock by not holding lock during DI resolution in GetLogger(Type type) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent 590443f commit 949233f

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed

src/ModularPipelines/Logging/AfterPipelineLogger.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ internal class AfterPipelineLogger : IAfterPipelineLogger
1313
private readonly StringBuilder _stringBuilder = new();
1414
private readonly List<string> _values = [];
1515
private readonly object _lock = new();
16+
private bool _isCacheValid;
1617

1718
public AfterPipelineLogger(ILogger<AfterPipelineLogger> logger)
1819
{
@@ -27,8 +28,7 @@ public void LogOnPipelineEnd(string value)
2728
lock (_lock)
2829
{
2930
_values.Add(value);
30-
// Clear cached output so GetOutput() rebuilds it with the new value
31-
_stringBuilder.Clear();
31+
_isCacheValid = false;
3232
}
3333
}
3434

@@ -39,17 +39,18 @@ public string GetOutput()
3939
{
4040
lock (_lock)
4141
{
42-
if (_stringBuilder.Length > 0)
42+
if (_isCacheValid)
4343
{
4444
return _stringBuilder.ToString();
4545
}
4646

47-
// Build once and cache
47+
_stringBuilder.Clear();
4848
foreach (var value in _values)
4949
{
5050
_stringBuilder.AppendLine(value);
5151
}
5252

53+
_isCacheValid = true;
5354
return _stringBuilder.ToString();
5455
}
5556
}

src/ModularPipelines/Logging/ModuleLoggerProvider.cs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ public ModuleLoggerProvider(
3232
_stackTraceDetector = stackTraceDetector;
3333
}
3434

35+
/// <summary>
36+
/// Gets a logger for a specific module type.
37+
/// Does not cache to _moduleLogger to avoid conflicts with parameterless GetLogger().
38+
/// </summary>
3539
public IModuleLogger GetLogger(Type type)
3640
{
37-
lock (_lock)
38-
{
39-
return MakeLogger(type);
40-
}
41+
var loggerType = typeof(ModuleLogger<>).MakeGenericType(type);
42+
43+
return _moduleLoggerContainer.GetLogger(loggerType)
44+
?? (IModuleLogger)_serviceProvider.GetRequiredService(loggerType);
4145
}
4246

4347
public IModuleLogger GetLogger()
@@ -59,7 +63,7 @@ public IModuleLogger GetLogger()
5963
var moduleType = ModuleLogger.CurrentModuleType.Value;
6064
if (moduleType != null)
6165
{
62-
return MakeLogger(moduleType);
66+
return _moduleLogger = CreateLogger(moduleType);
6367
}
6468

6569
// Fallback: use stack trace inspection (for edge cases where AsyncLocal context is lost)
@@ -70,7 +74,7 @@ public IModuleLogger GetLogger()
7074
throw new InvalidOperationException("Could not detect module type from call stack.");
7175
}
7276

73-
return MakeLogger(detectedType);
77+
return _moduleLogger = CreateLogger(detectedType);
7478
}
7579
}
7680

@@ -79,11 +83,11 @@ public void Dispose()
7983
_moduleLogger?.Dispose();
8084
}
8185

82-
private IModuleLogger MakeLogger(Type module)
86+
private IModuleLogger CreateLogger(Type module)
8387
{
8488
var loggerType = typeof(ModuleLogger<>).MakeGenericType(module);
8589

86-
return _moduleLogger ??= _moduleLoggerContainer.GetLogger(loggerType)
87-
?? (IModuleLogger) _serviceProvider.GetRequiredService(loggerType);
90+
return _moduleLoggerContainer.GetLogger(loggerType)
91+
?? (IModuleLogger)_serviceProvider.GetRequiredService(loggerType);
8892
}
8993
}

0 commit comments

Comments
 (0)