1212
1313namespace Xtensive . Orm . Reprocessing . Tests . ReprocessingContext
1414{
15- public class Context
15+ public class Context : IDisposable
1616 {
1717 private readonly Domain domain ;
18+
1819 public int Count ;
1920 private AutoResetEvent wait1 = new AutoResetEvent ( false ) ;
2021 private AutoResetEvent wait2 = new AutoResetEvent ( false ) ;
2122
22- public void Deadlock ( bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
23+ public bool Disposed { get ; private set ; }
24+
25+ /// <summary>
26+ /// Root runner.
27+ /// </summary>
28+ public void Run (
29+ IsolationLevel ? isolationLevel ,
30+ TransactionOpenMode ? transactionOpenMode ,
31+ Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
2332 {
24- TestContext . WriteLine ( "Context.DeadLock entered" ) ;
25- domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation ) . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) ) . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) ) . Execute (
33+ domain . Execute (
2634 session => {
35+ session . Remove ( session . Query . All < Foo > ( ) ) ;
36+ session . Remove ( session . Query . All < Bar > ( ) ) ;
37+ session . Remove ( session . Query . All < Bar2 > ( ) ) ;
38+ _ = new Bar ( session ) ;
39+ _ = new Foo ( session ) ;
40+ } ) ;
41+
42+ Parallel . Invoke (
43+ ( ) => action ( true , isolationLevel , transactionOpenMode ) ,
44+ ( ) => action ( false , isolationLevel , transactionOpenMode ) ) ;
45+ }
46+
47+ #region Actions
48+
49+ // The actions that can be passed to root runner method (Run)
50+ // Some might be wrapped by other actons,
51+ // others used only directrly from runner method
52+
53+ public void Deadlock ( bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
54+ {
55+ domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation )
56+ . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
57+ . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
58+ . Execute ( session => {
2759 _ = Interlocked . Increment ( ref Count ) ;
2860 _ = new Bar2 ( session , DateTime . Now , Guid . NewGuid ( ) ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
2961 if ( first ) {
3062 _ = session . Query . All < Foo > ( ) . Lock ( LockMode . Exclusive , LockBehavior . Wait ) . ToArray ( ) ;
3163 if ( wait1 != null ) {
3264 _ = wait1 . Set ( ) ;
3365 _ = wait2 . WaitOne ( ) ;
66+ wait1 . Dispose ( ) ;
3467 wait1 = null ;
3568 }
3669 _ = session . Query . All < Bar > ( ) . Lock ( LockMode . Exclusive , LockBehavior . Wait ) . ToArray ( ) ;
@@ -40,12 +73,12 @@ public void Deadlock(bool first, IsolationLevel? isolationLevel, TransactionOpen
4073 if ( wait2 != null ) {
4174 _ = wait2 . Set ( ) ;
4275 _ = wait1 . WaitOne ( ) ;
76+ wait2 . Dispose ( ) ;
4377 wait2 = null ;
4478 }
4579 _ = session . Query . All < Foo > ( ) . Lock ( LockMode . Exclusive , LockBehavior . Wait ) . ToArray ( ) ;
4680 }
4781 } ) ;
48- TestContext . WriteLine ( "Context.DeadLock left" ) ;
4982 }
5083
5184 public void External (
@@ -54,7 +87,6 @@ public void External(
5487 TransactionOpenMode ? transactionOpenMode ,
5588 Action < Session , bool , IsolationLevel ? , TransactionOpenMode ? > action )
5689 {
57- TestContext . WriteLine ( "Context.External entered" ) ;
5890 using ( var session = domain . OpenSession ( ) )
5991 using ( var tran = isolationLevel == null ? null : session . OpenTransaction ( ) ) {
6092 if ( tran != null ) {
@@ -76,7 +108,6 @@ public void External(
76108 tran . Complete ( ) ;
77109 }
78110 }
79- TestContext . WriteLine ( "Context.External left" ) ;
80111 }
81112
82113 public void Parent (
@@ -86,7 +117,6 @@ public void Parent(
86117 IExecuteActionStrategy strategy ,
87118 Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
88119 {
89- TestContext . WriteLine ( "Context.Parent1 entered" ) ;
90120 domain . WithStrategy ( strategy )
91121 . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
92122 . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
@@ -106,7 +136,6 @@ public void Parent(
106136 }
107137 action ( first , isolationLevel , transactionOpenMode ) ;
108138 } ) ;
109- TestContext . WriteLine ( "Context.Parent1 left" ) ;
110139 }
111140
112141 public void Parent (
@@ -117,7 +146,6 @@ public void Parent(
117146 IExecuteActionStrategy strategy ,
118147 Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
119148 {
120- TestContext . WriteLine ( "Context.Parent2 entered" ) ;
121149 domain . WithStrategy ( strategy )
122150 . WithSession ( session )
123151 . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
@@ -138,38 +166,15 @@ public void Parent(
138166 }
139167 action ( first , isolationLevel , transactionOpenMode ) ;
140168 } ) ;
141- TestContext . WriteLine ( "Context.Parent2 left" ) ;
142- }
143-
144- public void Run (
145- IsolationLevel ? isolationLevel ,
146- TransactionOpenMode ? transactionOpenMode ,
147- Action < bool , IsolationLevel ? , TransactionOpenMode ? > action )
148- {
149- TestContext . WriteLine ( "Context.Run entered" ) ;
150- domain . Execute (
151- session => {
152- session . Remove ( session . Query . All < Foo > ( ) ) ;
153- session . Remove ( session . Query . All < Bar > ( ) ) ;
154- session . Remove ( session . Query . All < Bar2 > ( ) ) ;
155- _ = new Bar ( session ) ;
156- _ = new Foo ( session ) ;
157- } ) ;
158- TestContext . WriteLine ( "Context.Run executed Domain.Execute" ) ;
159- TestContext . WriteLine ( "Context.Run Parallel.Invoke started" ) ;
160- Parallel . Invoke (
161- ( ) => action ( true , isolationLevel , transactionOpenMode ) ,
162- ( ) => action ( false , isolationLevel , transactionOpenMode ) ) ;
163- TestContext . WriteLine ( "Context.Run Parallel.Invoke ended" ) ;
164- TestContext . WriteLine ( "Context.Run left" ) ;
165169 }
166170
167171 public void UniqueConstraintViolation (
168172 bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
169173 {
170- TestContext . WriteLine ( "Context.UniqueConstraintViolation entered" ) ;
171- domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation ) . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) ) . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) ) . Execute (
172- session => {
174+ domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation )
175+ . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
176+ . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
177+ . Execute ( session => {
173178 _ = Interlocked . Increment ( ref Count ) ;
174179 session . EnsureTransactionIsStarted ( ) ;
175180 _ = new Bar2 ( session , DateTime . Now , Guid . NewGuid ( ) ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
@@ -179,27 +184,29 @@ public void UniqueConstraintViolation(
179184 if ( wait1 != null && wait2 != null ) {
180185 _ = wait1 . Set ( ) ;
181186 _ = wait2 . WaitOne ( ) ;
187+ wait1 . Dispose ( ) ;
182188 wait1 = null ;
183189 }
184190 }
185191 else if ( wait2 != null && wait2 != null ) {
186192 _ = wait2 . Set ( ) ;
187193 _ = wait1 . WaitOne ( ) ;
194+ wait2 . Dispose ( ) ;
188195 wait2 = null ;
189196 }
190197 _ = new Foo ( session ) { Name = name } ;
191198 }
192199 session . SaveChanges ( ) ;
193200 } ) ;
194- TestContext . WriteLine ( "Context.UniqueConstraintViolation left" ) ;
195201 }
196202
197203 public void UniqueConstraintViolationPrimaryKey (
198204 bool first , IsolationLevel ? isolationLevel , TransactionOpenMode ? transactionOpenMode )
199205 {
200- TestContext . WriteLine ( "Context.UniqueConstraintViolationPrimaryKey entered" ) ;
201- domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation ) . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) ) . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) ) . Execute (
202- session => {
206+ domain . WithStrategy ( ExecuteActionStrategy . HandleUniqueConstraintViolation )
207+ . WithIsolationLevel ( isolationLevel . GetValueOrDefault ( IsolationLevel . RepeatableRead ) )
208+ . WithTransactionOpenMode ( transactionOpenMode . GetValueOrDefault ( TransactionOpenMode . New ) )
209+ . Execute ( session => {
203210 _ = Interlocked . Increment ( ref Count ) ;
204211 session . EnsureTransactionIsStarted ( ) ;
205212 _ = new Bar2 ( session , DateTime . Now , Guid . NewGuid ( ) ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
@@ -211,25 +218,36 @@ public void UniqueConstraintViolationPrimaryKey(
211218 if ( w1 != null && w2 != null ) {
212219 _ = w1 . Set ( ) ;
213220 _ = w2 . WaitOne ( ) ;
221+ wait1 . Dispose ( ) ;
214222 wait1 = null ;
215223 }
216224 }
217225 else if ( w1 != null && w2 != null ) {
218226 _ = w2 . Set ( ) ;
219227 _ = w1 . WaitOne ( ) ;
228+ wait2 . Dispose ( ) ;
220229 wait2 = null ;
221230 }
222231 _ = new Foo ( session , id ) { Name = Guid . NewGuid ( ) . ToString ( ) } ;
223232 }
224233 session . SaveChanges ( ) ;
225234 } ) ;
226- TestContext . WriteLine ( "Context.UniqueConstraintViolationPrimaryKey left" ) ;
227235 }
236+ #endregion
228237
229238 public Context ( Domain domain )
230239 {
231240 this . domain = domain ;
232241 }
242+
243+ public void Dispose ( )
244+ {
245+ if ( Disposed )
246+ return ;
247+ Disposed = true ;
248+ wait1 ? . Dispose ( ) ;
249+ wait2 ? . Dispose ( ) ;
250+ }
233251 }
234252}
235253
0 commit comments