Skip to content

Commit 3d52114

Browse files
committed
Fixing CompositeTraceWriter concurrency issue
1 parent c311a91 commit 3d52114

File tree

2 files changed

+33
-4
lines changed

2 files changed

+33
-4
lines changed

src/WebJobs.Script/Diagnostics/CompositeTraceWriter.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,29 @@
33

44
using System;
55
using System.Collections.Generic;
6+
using System.Collections.ObjectModel;
67
using System.Diagnostics;
8+
using System.Linq;
79
using Microsoft.Azure.WebJobs.Host;
810

911
namespace Microsoft.Azure.WebJobs.Script
1012
{
11-
// TODO: The core WebJobs SDK also defines a CompositeTraceWriter, but that is internal.
12-
// We should consider exposing the core SDK CompositeTraceWriter and adopting that instead.
13+
// This is a copy of the WebJobs SDK CompositeTraceWriter, but that is internal.
1314
public class CompositeTraceWriter : TraceWriter, IDisposable
1415
{
15-
private readonly IEnumerable<TraceWriter> _innerTraceWriters;
16+
private readonly ReadOnlyCollection<TraceWriter> _innerTraceWriters;
1617
private bool _disposed = false;
1718

1819
public CompositeTraceWriter(IEnumerable<TraceWriter> traceWriters, TraceLevel level = TraceLevel.Verbose)
1920
: base(level)
2021
{
21-
_innerTraceWriters = traceWriters ?? throw new ArgumentNullException("traceWriters");
22+
if (traceWriters == null)
23+
{
24+
throw new ArgumentNullException("traceWriters");
25+
}
26+
27+
// create a copy of the collection to ensure it isn't modified
28+
_innerTraceWriters = traceWriters.ToList().AsReadOnly();
2229
}
2330

2431
public override void Trace(TraceEvent traceEvent)

test/WebJobs.Script.Tests/Diagnostics/CompositeTraceWriterTests.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// Licensed under the MIT License. See License.txt in the project root for license information.
33

44
using System;
5+
using System.Collections.Generic;
56
using System.Diagnostics;
67
using System.Linq;
78
using Microsoft.Azure.WebJobs.Host;
@@ -58,6 +59,27 @@ public void Flush_FlushesInternalWriters()
5859
Assert.True(traceWriter.Flushed);
5960
}
6061

62+
[Fact]
63+
public void Constructor_CreatesCopyOfCollection()
64+
{
65+
var t1 = new TestTraceWriter(TraceLevel.Verbose);
66+
var t2 = new TestTraceWriter(TraceLevel.Verbose);
67+
List<TraceWriter> traceWriters = new List<TraceWriter> { t1, t2 };
68+
var traceWriter = new CompositeTraceWriter(traceWriters);
69+
70+
traceWriter.Info("Test");
71+
Assert.Equal(1, t1.GetTraces().Count);
72+
Assert.Equal(1, t2.GetTraces().Count);
73+
74+
var t3 = new TestTraceWriter(TraceLevel.Verbose);
75+
traceWriters.Add(t3);
76+
77+
traceWriter.Info("Test");
78+
Assert.Equal(2, t1.GetTraces().Count);
79+
Assert.Equal(2, t2.GetTraces().Count);
80+
Assert.Equal(0, t3.GetTraces().Count);
81+
}
82+
6183
[Fact]
6284
public void Dispose_Disposes_If_IDisposable()
6385
{

0 commit comments

Comments
 (0)