예제 #1
0
        public virtual void TestIdlingAfterConcurrentJobAddedNotification()
        {
            // start job acquisition - Waiting before acquiring jobs
            _jobExecutor.Start();
            _acquisitionThread.WaitForSync();

            // acquire jobs
            _acquisitionThread.MakeContinueAndWaitForSync();

            // issue a message added notification
            _engineRule.RuntimeService.StartProcessInstanceByKey("simpleAsyncProcess");

            // complete job acquisition - trigger re-configuration
            // => due to the hint, the job executor should not become idle
            _acquisitionThread.MakeContinueAndWaitForSync();
            AssertJobExecutorWaitEvent(0);

            // another cycle of job acquisition
            // => acquires and executes the new job
            // => acquisition does not become idle because enough jobs could be acquired
            TriggerReconfigurationAndNextCycle();
            AssertJobExecutorWaitEvent(0);

            CycleJobAcquisitionToMaxIdleTime();
        }
예제 #2
0
        public virtual void TestJobLockingFailure()
        {
            var numberOfInstances = 3;

            // when starting a number of process instances
            for (var i = 0; i < numberOfInstances; i++)
            {
                var id = EngineRule.RuntimeService.StartProcessInstanceByKey("simpleAsyncProcess").Id;
            }

            // when starting job execution, both acquisition threads Wait before acquiring something
            JobExecutor1.Start();
            AcquisitionThread1.WaitForSync();
            JobExecutor2.Start();
            AcquisitionThread2.WaitForSync();

            // when having both threads acquire jobs
            // then both Wait before committing the acquiring transaction (AcquireJobsCmd)
            AcquisitionThread1.MakeContinueAndWaitForSync();
            AcquisitionThread2.MakeContinueAndWaitForSync();

            // when continuing acquisition thread 1
            AcquisitionThread1.MakeContinueAndWaitForSync();

            // then it has not performed Waiting since it was able to acquire and execute all jobs
            Assert.AreEqual(0, EngineRule.ManagementService.CreateJobQuery(c => c.SuspensionState == SuspensionStateFields.Active.StateCode).Count());
            var jobExecutor1WaitEvents = ((RecordingAcquireJobsRunnable)JobExecutor1.AcquireJobsRunnable).WaitEvents;

            Assert.AreEqual(1, jobExecutor1WaitEvents.Count);
            Assert.AreEqual(0, jobExecutor1WaitEvents[0].TimeBetweenAcquisitions);

            // when continuing acquisition thread 2
            AcquisitionThread2.MakeContinueAndWaitForSync();

            // then its acquisition cycle fails with OLEs
            // but the acquisition thread immediately tries again
            var jobExecutor2WaitEvents = ((RecordingAcquireJobsRunnable)JobExecutor2.AcquireJobsRunnable).WaitEvents;

            Assert.AreEqual(1, jobExecutor2WaitEvents.Count);
            Assert.AreEqual(0, jobExecutor2WaitEvents[0].TimeBetweenAcquisitions);
        }
예제 #3
0
        public virtual void TestBackoffOnOptimisticLocking()
        {
            // when starting a number of process instances process instance
            for (var i = 0; i < 9; i++)
            {
                _engineRule.RuntimeService.StartProcessInstanceByKey("simpleAsyncProcess"); //.Id;
            }

            // ensure that both acquisition threads acquire the same jobs thereby provoking an optimistic locking exception
            JobAcquisitionTestHelper.SuspendInstances(_engineRule.ProcessEngine, 6);

            // when starting job execution, both acquisition threads Wait before acquiring something
            _jobExecutor1.Start();
            _acquisitionThread1.WaitForSync();
            _jobExecutor2.Start();
            _acquisitionThread2.WaitForSync();

            // when having both threads acquire jobs
            // then both Wait before committing the acquiring transaction (AcquireJobsCmd)
            _acquisitionThread1.MakeContinueAndWaitForSync();
            _acquisitionThread2.MakeContinueAndWaitForSync();

            // when continuing acquisition thread 1
            _acquisitionThread1.MakeContinueAndWaitForSync();

            // then it has not performed Waiting since it was able to acquire and execute all jobs
            var jobExecutor1WaitEvents = _jobExecutor1.AcquireJobsRunnable.WaitEvents;

            Assert.AreEqual(1, jobExecutor1WaitEvents.Count);
            Assert.AreEqual(0, jobExecutor1WaitEvents.ElementAt(0).TimeBetweenAcquisitions);

            // when continuing acquisition thread 2, acquisition fails with an OLE
            _acquisitionThread2.MakeContinueAndWaitForSync();

            // and has performed backoff
            var jobExecutor2WaitEvents = _jobExecutor2.AcquireJobsRunnable.WaitEvents;

            Assert.AreEqual(1, jobExecutor2WaitEvents.Count);
            var waitEvent = jobExecutor2WaitEvents.ElementAt(0);

            // we don't know the exact Wait time,
            // since there is random jitter applied
            JobAcquisitionTestHelper.AssertInBetween(BaseBackoffTime, BaseBackoffTime + BaseBackoffTime / 2, waitEvent.TimeBetweenAcquisitions);

            // when performing another cycle of acquisition
            JobAcquisitionTestHelper.ActivateInstances(_engineRule.ProcessEngine, 6);
            _acquisitionThread1.MakeContinueAndWaitForSync();
            _acquisitionThread2.MakeContinueAndWaitForSync();

            // and thread 1 again acquires all jobs successfully
            _acquisitionThread1.MakeContinueAndWaitForSync();

            // while thread 2 again fails with OLE
            _acquisitionThread2.MakeContinueAndWaitForSync();

            // then thread 1 has tried to acquired 3 jobs again
            var jobExecutor1AcquisitionEvents = _jobExecutor1.AcquireJobsRunnable.AcquisitionEvents;
            var secondAcquisitionAttempt      = jobExecutor1AcquisitionEvents.ElementAt(1);

            Assert.AreEqual(3, secondAcquisitionAttempt.NumJobsToAcquire);

            // and not Waited
            jobExecutor1WaitEvents = _jobExecutor1.AcquireJobsRunnable.WaitEvents;
            Assert.AreEqual(2, jobExecutor1WaitEvents.Count);
            Assert.AreEqual(0, jobExecutor1WaitEvents.ElementAt(1).TimeBetweenAcquisitions);

            // then thread 2 has tried to acquire 6 jobs this time
            var jobExecutor2AcquisitionEvents = _jobExecutor2.AcquireJobsRunnable.AcquisitionEvents;

            secondAcquisitionAttempt = jobExecutor2AcquisitionEvents.ElementAt(1);
            Assert.AreEqual(6, secondAcquisitionAttempt.NumJobsToAcquire);

            // and again increased its backoff
            jobExecutor2WaitEvents = _jobExecutor2.AcquireJobsRunnable.WaitEvents;
            Assert.AreEqual(2, jobExecutor2WaitEvents.Count);
            var  secondWaitEvent     = jobExecutor2WaitEvents.ElementAt(1);
            long expectedBackoffTime = BaseBackoffTime * BackoffFactor; // 1000 * 2^1

            JobAcquisitionTestHelper.AssertInBetween(expectedBackoffTime, expectedBackoffTime + expectedBackoffTime / 2, secondWaitEvent.TimeBetweenAcquisitions);
        }