Skip to content

Commit dbf2386

Browse files
Make BlockingCell.GetValue use exceptions, support TimeSpans
1 parent f569efa commit dbf2386

File tree

2 files changed

+78
-48
lines changed

2 files changed

+78
-48
lines changed

projects/client/RabbitMQ.Client/src/util/BlockingCell.cs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -108,40 +108,56 @@ public static int validatedTimeout(int timeout)
108108
/// If a value is present in the cell at the time the call is
109109
/// made, the call will return immediately. Otherwise, the
110110
/// calling thread blocks until either a value appears, or
111-
/// millisecondsTimeout milliseconds have elapsed.
111+
/// operation times out.
112112
///</para>
113113
///<para>
114-
/// Returns true in the case that the value was available
115-
/// before the timeout, in which case the out parameter
116-
/// "result" is set to the value itself.
114+
/// If no value was available before the timeout, an exception
115+
/// is thrown.
117116
///</para>
117+
///</remarks>
118+
public object GetValue(TimeSpan timeout)
119+
{
120+
lock (_lock)
121+
{
122+
if (!m_valueSet)
123+
{
124+
Monitor.Wait(_lock, timeout);
125+
if (!m_valueSet)
126+
{
127+
throw new TimeoutException();
128+
}
129+
}
130+
return m_value;
131+
}
132+
}
133+
134+
///<summary>Retrieve the cell's value, waiting for the given
135+
///timeout if no value is immediately available.</summary>
136+
///<remarks>
118137
///<para>
119-
/// If no value was available before the timeout, returns
120-
/// false, and sets "result" to null.
138+
/// If a value is present in the cell at the time the call is
139+
/// made, the call will return immediately. Otherwise, the
140+
/// calling thread blocks until either a value appears, or
141+
/// operation times out.
121142
///</para>
122143
///<para>
123-
/// A timeout of -1 (i.e. System.Threading.Timeout.Infinite)
124-
/// will be interpreted as a command to wait for an
125-
/// indefinitely long period of time for the cell's value to
126-
/// become available. See the MSDN documentation for
127-
/// System.Threading.Monitor.Wait(object,int).
144+
/// If no value was available before the timeout, an exception
145+
/// is thrown.
128146
///</para>
129147
///</remarks>
130-
public bool GetValue(int millisecondsTimeout, out object result)
148+
public object GetValue(int timeout)
131149
{
132150
lock (_lock)
133151
{
134152
if (!m_valueSet)
135153
{
136-
Monitor.Wait(_lock, validatedTimeout(millisecondsTimeout));
154+
Monitor.Wait(_lock, validatedTimeout(timeout));
137155
if (!m_valueSet)
138156
{
139-
result = null;
140-
return false;
157+
throw new TimeoutException();
141158
}
142159
}
143-
result = m_value;
144-
return true;
160+
return m_value;
145161
}
146162
}
147163
}

projects/client/Unit/src/unit/TestBlockingCell.cs

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
using NUnit.Framework;
4242

4343
using System;
44-
using System.IO;
45-
using System.Collections;
4644
using System.Threading;
4745

4846
using RabbitMQ.Util;
@@ -94,85 +92,101 @@ public void TestSetBeforeGet()
9492
}
9593

9694
[Test]
97-
public void TestTimeoutShort()
95+
public void TestGetValueWhichDoesNotTimeOut()
9896
{
9997
BlockingCell k = new BlockingCell();
10098
k.Value = 123;
10199

102100
ResetTimer();
103-
object v;
104-
bool r = k.GetValue(TimingInterval, out v);
101+
var v = k.GetValue(TimingInterval);
105102
Assert.Greater(SafetyMargin, ElapsedMs());
106-
Assert.IsTrue(r);
107103
Assert.AreEqual(123, v);
108104
}
109105

110106
[Test]
111-
public void TestTimeoutLong()
107+
public void TestGetValueWhichDoesTimeOut()
112108
{
113109
BlockingCell k = new BlockingCell();
110+
ResetTimer();
111+
Assert.Throws<TimeoutException>(() => k.GetValue(TimingInterval));
112+
}
113+
114+
[Test]
115+
public void TestGetValueWhichDoesTimeOutWithTimeSpan()
116+
{
117+
BlockingCell k = new BlockingCell();
118+
ResetTimer();
119+
Assert.Throws<TimeoutException>(() => k.GetValue(TimeSpan.FromMilliseconds(TimingInterval)));
120+
}
121+
122+
[Test]
123+
public void TestGetValueWithTimeoutInfinite()
124+
{
125+
BlockingCell k = new BlockingCell();
126+
SetAfter(TimingInterval, k, 123);
127+
128+
ResetTimer();
129+
var v = k.GetValue(Timeout.Infinite);
130+
Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
131+
Assert.AreEqual(123, v);
132+
}
133+
134+
[Test]
135+
public void TestBackgroundUpdateSucceeds()
136+
{
137+
BlockingCell k = new BlockingCell();
138+
SetAfter(TimingInterval, k, 123);
114139

115140
ResetTimer();
116-
object v;
117-
bool r = k.GetValue(TimingInterval, out v);
141+
var v = k.GetValue(TimingInterval * 2);
118142
Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
119-
Assert.IsTrue(!r);
120-
Assert.AreEqual(null, v);
143+
Assert.AreEqual(123, v);
121144
}
122145

123146
[Test]
124-
public void TestTimeoutNegative()
147+
public void TestBackgroundUpdateSucceedsWithTimeSpan()
125148
{
126149
BlockingCell k = new BlockingCell();
150+
SetAfter(TimingInterval, k, 123);
127151

128152
ResetTimer();
129-
object v;
130-
bool r = k.GetValue(-10000, out v);
131-
Assert.Greater(SafetyMargin, ElapsedMs());
132-
Assert.IsTrue(!r);
133-
Assert.AreEqual(null, v);
153+
var v = k.GetValue(TimeSpan.FromMilliseconds(TimingInterval * 2));
154+
Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
155+
Assert.AreEqual(123, v);
134156
}
135157

136158
[Test]
137-
public void TestTimeoutInfinite()
159+
public void TestBackgroundUpdateSucceedsWithInfiniteTimeout()
138160
{
139161
BlockingCell k = new BlockingCell();
140162
SetAfter(TimingInterval, k, 123);
141163

142164
ResetTimer();
143-
object v;
144-
bool r = k.GetValue(Timeout.Infinite, out v);
165+
var v = k.GetValue(Timeout.Infinite);
145166
Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
146-
Assert.IsTrue(r);
147167
Assert.AreEqual(123, v);
148168
}
149169

150170
[Test]
151-
public void TestBgShort()
171+
public void TestBackgroundUpdateSucceedsWithInfiniteTimeoutTimeSpan()
152172
{
153173
BlockingCell k = new BlockingCell();
154174
SetAfter(TimingInterval, k, 123);
155175

156176
ResetTimer();
157-
object v;
158-
bool r = k.GetValue(TimingInterval * 2, out v);
177+
var v = k.GetValue(Timeout.InfiniteTimeSpan);
159178
Assert.Less(TimingInterval - SafetyMargin, ElapsedMs());
160-
Assert.IsTrue(r);
161179
Assert.AreEqual(123, v);
162180
}
163181

164182
[Test]
165-
public void TestBgLong()
183+
public void TestBackgroundUpdateFails()
166184
{
167185
BlockingCell k = new BlockingCell();
168186
SetAfter(TimingInterval * 2, k, 123);
169187

170188
ResetTimer();
171-
object v;
172-
bool r = k.GetValue(TimingInterval, out v);
173-
Assert.Greater(TimingInterval + SafetyMargin, ElapsedMs());
174-
Assert.IsTrue(!r);
175-
Assert.AreEqual(null, v);
189+
Assert.Throws<TimeoutException>(() => k.GetValue(TimingInterval));
176190
}
177191
}
178192
}

0 commit comments

Comments
 (0)