public void JobExecutorShell_Will_Execute_Jobs()
        {
            var queueName = QueueNameHelper.CreateQueueName();
            var container = new SimpleInjector.Container();

            container.Register <IContainerFactory, TestSimpleInjectorContainerFactory>();
            container.Register <ISqlDbJobQueueTableConfiguration, SqlDbJobQueueDefaultTableConfiguration>();
            container.Register <IJobAdderQueueTableResolver, DefaultJobAdderQueueTableResolver>();
            container.Register <SQLiteJobQueueDataConnectionFactory>(() => new SQLiteJobQueueDataConnectionFactory(UnitTestTableHelper.connString));
            container.Register <IJobQueueManager, SQLiteJobQueueManager>();
            container.Register <IJobQueueAdder, SQLiteJobQueueAdder>();
            container.Register <IJobTypeResolver, NullOnMissingTypeJobTypeResolver>();
            container.Register <IJobExecutor, DefaultJobExecutor>();
            container.Register <JobQueueLayerActor>();
            container.Register <JobWorkerActor>();
            container.Register <JobQueueCoordinator>();
            var jobStore = (IJobQueueAdder)container.GetInstance(typeof(IJobQueueAdder));
            var executor = new DependencyInjectedJobExecutorShell(
                (system) => new SimpleInjectorDependencyResolver(container, system),
                null);

            container.Verify();

            /*var executor = new HardInjectedJobExecutorShell(() => new JobQueueLayerActor(jobStore),
            *   () => new JobWorkerActor(new DefaultJobExecutor(new DefaultContainerFactory())), null);*/
            executor.StartJobQueue(queueName, 5, 1, 1);
            jobStore.AddJob((DIShellMockJob m) => m.DoThing(nameof(JobExecutorShell_Will_Execute_Jobs), 1), null, null, queueName);
            SpinWait.SpinUntil(() => false, TimeSpan.FromSeconds(8));
            Xunit.Assert.True(DIShellMockJob.MyCounter.ContainsKey(nameof(JobExecutorShell_Will_Execute_Jobs)));
        }
        public void JobCoordinator_Will_Fire_OnJobQueueSaturation()
        {
            var queueName = QueueNameHelper.CreateQueueName();
            //TODO: Make this less like an integration test; there's no reason we couldn't mock this out with just testprobe.
            var workerCount     = 1;
            var jobAdder        = AkkaExecutionTest.GetJobQueueAdder;
            var executor        = new DefaultJobExecutor(new DefaultContainerFactory());
            var probe           = CreateTestProbe("queue");
            var queueLayerProps = Props.Create(() => new JobQueueLayerActor(AkkaExecutionTest.GetJobQueueManager));
            var workerProps     = Props.Create(() => new JobWorkerActor(executor)).WithRouter(new RoundRobinPool(workerCount));
            var coordinator     = Sys.ActorOf(Props.Create(() => new CountingOnJobQueueSaturatedCoordinator()));

            jobAdder.AddJob((DelayJob j) => j.DoDelay("qs-1"), queueName: queueName);
            jobAdder.AddJob((DelayJob j) => j.DoDelay("qs-2"), queueName: queueName);
            jobAdder.AddJob((DelayJob j) => j.DoDelay("qs-3"), queueName: queueName);
            coordinator.Tell(new SetJobQueueConfiguration(workerProps, queueLayerProps, queueName, 1, 1, 1));
            coordinator.Tell(new JobSweep());
            coordinator.Tell(new JobSweep());
            coordinator.Tell(new JobSweep());
            SpinWait.SpinUntil(() => false, TimeSpan.FromSeconds(2));
            Xunit.Assert.Equal(2, CountingOnJobQueueSaturatedCoordinator.pulseCount[queueName]);
            Xunit.Assert.True(DelayJob.MsgCounter.ContainsKey("qs-1"));
            Xunit.Assert.True(DelayJob.MsgCounter.ContainsKey("qs-2"));
            Xunit.Assert.False(DelayJob.MsgCounter.ContainsKey("qs-3"));
        }
        public void JobShell_Can_Start()
        {
            var queueName = QueueNameHelper.CreateQueueName();
            var jobStore  = new InMemoryTestStore();
            var executor  = new HardInjectedJobExecutorShell <JobQueueLayerActor, JobWorkerActor, JobQueueCoordinator>(() => new JobQueueLayerActor(jobStore),
                                                                                                                       () => new JobWorkerActor(new MockJobSuccessExecutor()),
                                                                                                                       () => new JobQueueCoordinator(), null);

            executor.StartJobQueue(queueName, 5, 1);
        }
        public void JobExecutorShell_Will_Execute_Jobs()
        {
            var queueName = QueueNameHelper.CreateQueueName();
            var jobStore  = new InMemoryTestStore();
            var executor  = new HardInjectedJobExecutorShell <JobQueueLayerActor, JobWorkerActor, JobQueueCoordinator>(() => new JobQueueLayerActor(jobStore),
                                                                                                                       () => new JobWorkerActor(new DefaultJobExecutor(new DefaultContainerFactory())),
                                                                                                                       () => new JobQueueCoordinator(), null);

            executor.StartJobQueue(queueName, 5, 1, 1);
            jobStore.AddJob((ShellMockJob m) => m.DoThing(0), null, null, queueName);
            SpinWait.SpinUntil(() => false, TimeSpan.FromSeconds(8));
            Xunit.Assert.Equal(1, ShellMockJob.MyCounter);
        }
        public void JobCoordinator_Can_Shutdown()
        {
            var queueName       = QueueNameHelper.CreateQueueName();
            var workerCount     = 5;
            var jobStore        = AkkaExecutionTest.GetJobQueueManager;
            var executor        = new MockJobSuccessExecutor();
            var queueLayerProps = Props.Create(() => new JobQueueLayerActor(jobStore));
            var workerProps     = Props.Create(() => new JobWorkerActor(executor)).WithRouter(new RoundRobinPool(workerCount));
            var coordinator     = Sys.ActorOf(Props.Create(() => new JobQueueCoordinator()));
            var set             = coordinator.Ask(new SetJobQueueConfiguration(workerProps, queueLayerProps, queueName, 1, 1, 1)).Result;

            coordinator.Tell(new ShutDownQueues());
            ExpectMsgFrom <QueueShutDown>(coordinator);
        }
        public void JobCoordinator_Will_Send_Job_To_Queue()
        {
            var queueName       = QueueNameHelper.CreateQueueName();
            var workerCount     = 5;
            var executor        = new MockJobSuccessExecutor();
            var probe           = CreateTestProbe("queue");
            var queueLayerProps = Props.Create(() => new QueueLayerMock(probe, "Success"));
            var workerProbe     = CreateTestProbe("worker");
            var workerProps     = Props.Create(() => new MockJobWorker(workerProbe)).WithRouter(new RoundRobinPool(workerCount));
            var coordinator     = Sys.ActorOf(Props.Create(() => new JobQueueCoordinator()));

            coordinator.Tell(new SetJobQueueConfiguration(workerProps, queueLayerProps, queueName, 1, 0, 5));
            coordinator.Tell(new JobSweep());
            workerProbe.ExpectMsg <ExecuteJobRequest>(TimeSpan.FromSeconds(5));
        }
        public void JobCoordinator_Will_Sweep_When_Asked()
        {
            var queueName   = QueueNameHelper.CreateQueueName();
            var workerCount = 5;

            var executor        = new MockJobSuccessExecutor();
            var probe           = CreateTestProbe("queue");
            var queueLayerProps = Props.Create(() => new QueueLayerMock(probe, JobStates.New));
            var workerProps     = Props.Create(() => new JobWorkerActor(executor)).WithRouter(new RoundRobinPool(workerCount));
            var coordinator     = Sys.ActorOf(Props.Create(() => new JobQueueCoordinator()));

            coordinator.Tell(new SetJobQueueConfiguration(workerProps, queueLayerProps, queueName, 1, 1, 1));
            coordinator.Tell(new JobSweep());
            probe.ExpectMsg <GetJobs>();
        }
        public void JobExecutorShell_Will_Shutdown()
        {
            var queueName = QueueNameHelper.CreateQueueName();
            //Warning: this test is a bit racy, due to the nature of JobExecutor and the scheduler.
            //Lowering the timeouts may cause false failures on the test, as the timer may fire before the shutdown is even called.
            var jobStore = new InMemoryTestStore();
            var executor = new HardInjectedJobExecutorShell <JobQueueLayerActor, JobWorkerActor, JobQueueCoordinator>(() => new JobQueueLayerActor(jobStore),
                                                                                                                      () => new JobWorkerActor(new DefaultJobExecutor(new DefaultContainerFactory())),
                                                                                                                      () => new JobQueueCoordinator(), null);

            jobStore.AddJob((ShellShutdownMockJob1 m) => m.DoThing(0), null, null, queueName);
            executor.StartJobQueue(queueName, 5, 5, 5);
            executor.ShutDownQueue(queueName);
            SpinWait.SpinUntil(() => false, TimeSpan.FromSeconds(5));
            Xunit.Assert.True(ShellShutdownMockJob1.MyCounter.ContainsKey(0) == false);
        }
        public void JobShell_Can_Start()
        {
            var queueName = QueueNameHelper.CreateQueueName();
            var container = new SimpleInjector.Container();

            container.Register <IContainerFactory, TestSimpleInjectorContainerFactory>();
            container.Register <ISqlDbJobQueueTableConfiguration, SqlDbJobQueueDefaultTableConfiguration>();
            container.Register <IJobAdderQueueTableResolver, DefaultJobAdderQueueTableResolver>();
            container.Register <SQLiteJobQueueDataConnectionFactory>(() => new SQLiteJobQueueDataConnectionFactory(UnitTestTableHelper.connString));
            container.Register <IJobQueueManager, SQLiteJobQueueManager>();
            container.Register <IJobQueueAdder, SQLiteJobQueueAdder>();
            container.Register <IJobExecutor, MockJobSuccessExecutor>();
            container.Register <JobQueueLayerActor>();
            container.Register <JobWorkerActor>();
            //container.Verify();
            // HardInjectedJobExecutorShell(() => new JobQueueLayerActor(jobStore),
            //() => new JobWorkerActor(new MockJobSuccessExecutor()), null);
            var executor = new DependencyInjectedJobExecutorShell(
                (system) => new SimpleInjectorDependencyResolver(container, system),
                null);

            executor.StartJobQueue(queueName, 5, 1);
        }