public virtual void testEventSubprocess() { InvocationLogListener.reset(); // given a process instance runtimeService.startProcessInstanceByKey("testProcess"); // and two threads correlating in parallel ThreadControl thread1 = executeControllableCommand(new ControllableMessageCorrelationCommand("incoming", false)); thread1.reportInterrupts(); ThreadControl thread2 = executeControllableCommand(new ControllableMessageCorrelationCommand("incoming", false)); thread2.reportInterrupts(); // both threads open a transaction and wait before correlating the message thread1.waitForSync(); thread2.waitForSync(); // both threads correlate thread1.makeContinue(); thread2.makeContinue(); thread1.waitForSync(); thread2.waitForSync(); // the first thread ends its transaction thread1.waitUntilDone(); assertNull(thread1.Exception); // the second thread ends its transaction and fails with optimistic locking exception thread2.waitUntilDone(); assertTrue(thread2.Exception != null); assertTrue(thread2.Exception is OptimisticLockingException); }
public virtual void testConcurrentExclusiveCorrelation() { InvocationLogListener.reset(); // given a process instance runtimeService.startProcessInstanceByKey("testProcess"); // and two threads correlating in parallel ThreadControl thread1 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", true)); thread1.reportInterrupts(); ThreadControl thread2 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", true)); thread2.reportInterrupts(); // both threads open a transaction and wait before correlating the message thread1.waitForSync(); thread2.waitForSync(); // thread one correlates and acquires the exclusive lock thread1.makeContinue(); thread1.waitForSync(); // the service task was executed once assertEquals(1, InvocationLogListener.Invocations); // thread two attempts to acquire the exclusive lock but can't since thread 1 hasn't released it yet thread2.makeContinue(); Thread.Sleep(2000); // let the first thread ends its transaction thread1.makeContinue(); assertNull(thread1.Exception); // thread 2 can't continue because the event subscription it tried to lock was deleted thread2.waitForSync(); assertTrue(thread2.Exception != null); assertTrue(thread2.Exception is ProcessEngineException); assertTextPresent("does not have a subscription to a message event with name 'Message'", thread2.Exception.Message); // the first thread ended successfully without an exception thread1.join(); assertNull(thread1.Exception); // the follow-up task was reached Task afterMessageTask = taskService.createTaskQuery().singleResult(); assertEquals(afterMessageTask.TaskDefinitionKey, "afterMessageUserTask"); // the service task was not executed a second time assertEquals(1, InvocationLogListener.Invocations); }
public virtual void FAILING_testConcurrentMixedCorrelationCase2() { InvocationLogListener.reset(); // given a process instance runtimeService.startProcessInstanceByKey("testProcess"); // and two threads correlating in parallel (one exclusive, one non-exclusive) ThreadControl thread1 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", false)); thread1.reportInterrupts(); ThreadControl thread2 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", true)); thread2.reportInterrupts(); // both threads open a transaction and wait before correlating the message thread1.waitForSync(); thread2.waitForSync(); // thread one correlates and acquires no lock thread1.makeContinue(); thread1.waitForSync(); // thread two acquires a lock and succeeds because thread one hasn't acquired one thread2.makeContinue(); thread2.waitForSync(); // the service task was executed twice assertEquals(2, InvocationLogListener.Invocations); // thread one ends its transaction and blocks on flush when it attempts to delete the event subscription thread1.makeContinue(); Thread.Sleep(5000); assertNull(thread1.Exception); assertEquals(0, taskService.createTaskQuery().count()); // thread 2 flushes successfully and releases the lock thread2.waitUntilDone(); assertNull(thread2.Exception); Task afterMessageTask = taskService.createTaskQuery().singleResult(); assertNotNull(afterMessageTask); assertEquals(afterMessageTask.TaskDefinitionKey, "afterMessageUserTask"); // thread 1 flush fails with optimistic locking thread1.join(); assertTrue(thread1.Exception != null); assertTrue(thread1.Exception is OptimisticLockingException); }
//JAVA TO C# CONVERTER TODO TASK: Most Java annotations will not have direct .NET equivalent attributes: //ORIGINAL LINE: @Deployment public void testConcurrentEndExecutionListener() public virtual void testConcurrentEndExecutionListener() { InvocationLogListener.reset(); // given a process instance runtimeService.startProcessInstanceByKey("testProcess"); IList <Execution> tasks = runtimeService.createExecutionQuery().messageEventSubscriptionName("Message").list(); // two tasks waiting for the message assertEquals(2, tasks.Count); // start first thread and wait in the second execution end listener ThreadControl thread1 = executeControllableCommand(new ControllableMessageEventReceivedCommand(tasks[0].Id, "Message", true)); thread1.reportInterrupts(); thread1.waitForSync(); // the counting execution listener was executed on task 1 assertEquals(1, InvocationLogListener.Invocations); // start second thread and complete the task ThreadControl thread2 = executeControllableCommand(new ControllableMessageEventReceivedCommand(tasks[1].Id, "Message", false)); thread2.waitForSync(); thread2.waitUntilDone(); // the counting execution listener was executed on task 1 and 2 assertEquals(2, InvocationLogListener.Invocations); // continue with thread 1 thread1.makeContinueAndWaitForSync(); // the counting execution listener was not executed again assertEquals(2, InvocationLogListener.Invocations); // try to complete thread 1 thread1.waitUntilDone(); // thread 1 was rolled back with an optimistic locking exception Exception exception = thread1.Exception; assertNotNull(exception); assertTrue(exception is OptimisticLockingException); // the execution listener was not executed again assertEquals(2, InvocationLogListener.Invocations); }
public virtual void testConcurrentExclusiveCorrelationToDifferentExecutions() { InvocationLogListener.reset(); // given a process instance ProcessInstance instance1 = runtimeService.startProcessInstanceByKey("testProcess"); ProcessInstance instance2 = runtimeService.startProcessInstanceByKey("testProcess"); // and two threads correlating in parallel to each of the two instances ThreadControl thread1 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", instance1.Id, true)); thread1.reportInterrupts(); ThreadControl thread2 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", instance2.Id, true)); thread2.reportInterrupts(); // both threads open a transaction and wait before correlating the message thread1.waitForSync(); thread2.waitForSync(); // thread one correlates and acquires the exclusive lock on the event subscription of instance1 thread1.makeContinue(); thread1.waitForSync(); // the service task was executed once assertEquals(1, InvocationLogListener.Invocations); // thread two correlates and acquires the exclusive lock on the event subscription of instance2 // depending on the database and locking used, this may block thread2 thread2.makeContinue(); // thread 1 completes successfully thread1.waitUntilDone(); assertNull(thread1.Exception); // thread2 should be able to continue at least after thread1 has finished and released its lock thread2.waitForSync(); // the service task was executed the second time assertEquals(2, InvocationLogListener.Invocations); // thread 2 completes successfully thread2.waitUntilDone(); assertNull(thread2.Exception); // the follow-up task was reached in both instances assertEquals(2, taskService.createTaskQuery().taskDefinitionKey("afterMessageUserTask").count()); }
public virtual void FAILING_testConcurrentExclusiveCorrelationToDifferentExecutionsCase2() { InvocationLogListener.reset(); // given a process instance IProcessInstance instance1 = runtimeService.StartProcessInstanceByKey("testProcess"); IProcessInstance instance2 = runtimeService.StartProcessInstanceByKey("testProcess"); // and two threads correlating in parallel to each of the two instances ThreadControl thread1 = ExecuteControllableCommand(new ControllableMessageCorrelationCommand("Message", instance1.Id, true)); thread1.ReportInterrupts(); ThreadControl thread2 = ExecuteControllableCommand(new ControllableMessageCorrelationCommand("Message", instance2.Id, true)); thread2.ReportInterrupts(); // both threads open a transaction and wait before correlating the message thread1.WaitForSync(); thread2.WaitForSync(); // thread one correlates and acquires the exclusive lock on the event subscription of instance1 thread1.MakeContinue(); thread1.WaitForSync(); // the service task was executed once Assert.AreEqual(1, InvocationLogListener.Invocations); // thread two correlates and acquires the exclusive lock on the event subscription of instance2 thread2.MakeContinue(); // FIXME: this does not return on sql server due to locking thread2.WaitForSync(); // the service task was executed the second time Assert.AreEqual(2, InvocationLogListener.Invocations); // thread 2 completes successfully, even though it acquired its lock after thread 1 thread2.WaitUntilDone(); Assert.IsNull(thread2.Exception); // thread 1 completes successfully thread1.WaitUntilDone(); Assert.IsNull(thread1.Exception); // the follow-up task was reached in both instances Assert.AreEqual(2, taskService.CreateTaskQuery(c => c.TaskDefinitionKey == "afterMessageUserTask").Count()); }
public virtual void testConcurrentMixedCorrelation() { InvocationLogListener.reset(); // given a process instance runtimeService.startProcessInstanceByKey("testProcess"); // and two threads correlating in parallel (one exclusive, one non-exclusive) ThreadControl thread1 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", true)); thread1.reportInterrupts(); ThreadControl thread2 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", false)); thread2.reportInterrupts(); // both threads open a transaction and wait before correlating the message thread1.waitForSync(); thread2.waitForSync(); // thread one correlates and acquires the exclusive lock thread1.makeContinue(); thread1.waitForSync(); // thread two correlates since it does not need a pessimistic lock thread2.makeContinue(); thread2.waitForSync(); // the service task was executed twice assertEquals(2, InvocationLogListener.Invocations); // the first thread ends its transaction and releases the lock; the event subscription is now gone thread1.waitUntilDone(); assertNull(thread1.Exception); Task afterMessageTask = taskService.createTaskQuery().singleResult(); assertEquals(afterMessageTask.TaskDefinitionKey, "afterMessageUserTask"); // thread two attempts to end its transaction and fails with optimistic locking thread2.makeContinue(); thread2.waitForSync(); assertTrue(thread2.Exception != null); assertTrue(thread2.Exception is OptimisticLockingException); }
public virtual void testConcurrentCorrelationFailsWithOptimisticLockingException() { InvocationLogListener.reset(); // given a process instance runtimeService.startProcessInstanceByKey("testProcess"); // and two threads correlating in parallel ThreadControl thread1 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", false)); thread1.reportInterrupts(); ThreadControl thread2 = executeControllableCommand(new ControllableMessageCorrelationCommand("Message", false)); thread2.reportInterrupts(); // both threads open a transaction and wait before correlating the message thread1.waitForSync(); thread2.waitForSync(); // both threads correlate thread1.makeContinue(); thread2.makeContinue(); thread1.waitForSync(); thread2.waitForSync(); // the service task was executed twice assertEquals(2, InvocationLogListener.Invocations); // the first thread ends its transcation thread1.waitUntilDone(); assertNull(thread1.Exception); Task afterMessageTask = taskService.createTaskQuery().singleResult(); assertEquals(afterMessageTask.TaskDefinitionKey, "afterMessageUserTask"); // the second thread ends its transaction and fails with optimistic locking exception thread2.waitUntilDone(); assertTrue(thread2.Exception != null); assertTrue(thread2.Exception is OptimisticLockingException); }