Пример #1
0
        public void Should_not_call_processor_when_queue_is_empty()
        {
            var worker = new TestProcessor();
            var target = new WorkerThread<int>("test", TimeSpan.FromMilliseconds(10), worker.Process);

            worker.Go.WaitOne(TimeSpan.FromSeconds(1)).Should().Be.False();
        }
Пример #2
0
 public void Test()
 {
     var th = new WorkerThread();
     //
     #if false
     {
         var a = th.StartNew(Worker0);
         while (!a.Wait(0)) {
             Thread.Sleep(1);
         }
         Assert.AreEqual(1, Worker0Count);
     }
     {
         var a = th.StartNew(Worker1, 0);
         while (!a.Wait(0)) {
             Thread.Sleep(1);
         }
         Assert.AreEqual(1, Worker1Count);
     }
     #endif
     {
         var a = th.StartNew(Worker2);
         while (!a.Wait(0)) {
             Thread.Sleep(1);
         }
         Assert.AreEqual(1, Worker2Count);
     }
     {
         var a = th.StartNew(Worker3, 0);
         while (!a.Wait(0)) {
             Thread.Sleep(1);
         }
         Assert.AreEqual(1, Worker3Count);
     }
 }
        public SynchronizationContextMock()
        {
            CallQueued = new Semaphore(0, Int32.MaxValue);
            m_WorkItemQueue = new Queue<WorkItem>();

            m_WorkerThread = new WorkerThread("SynchronizationContextMockThread", this);
        }
        public void DoWorkShouldNotCallWorkItemDequeueWhenWorkerThreadManagerShouldExitWorkerThreadReturnsTrue()
        {
            WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); 
            
            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            IWorkItemQueue workItemQueue = Substitute.For<IWorkItemQueue>();
            WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false);
            workerThreadManager.WorkerThreadExiting += (sender, args) =>
                {
                    if (args.WorkerThreadExitReason == WorkerThreadExitReason.MaximumThreadCountExceeded)
                    {
                        manualResetEvent.Set();
                    }
                };
            workerThreadManager.ShouldExitWorkerThread(workerThread, false).ReturnsForAnyArgs(true);
            workerThread.Start();

            manualResetEvent.WaitOne(500);

            workerThread.Stop();

            Wait.While(() => workerThread.Thread.IsAlive, 300);

            Assert.AreEqual(false, workerThread.Thread.IsAlive);

            workItemQueue.DidNotReceive().Dequeue();
        }
Пример #5
0
 public CustomThreadPool(int NumberOfThreads)
 {
     WorkerThreads = new WorkerThread[NumberOfThreads];
     for (int n = 0; n < NumberOfThreads; n++)
     {
         WorkerThreads[n] = new WorkerThread();
     }
 }
        /// <summary>
        /// İşçi Thread havuzu yeni bir işçi Thread'i başlatıyor olay argümanları sınıfı inşacı metodu.
        /// </summary>
        /// <param name="currentNumberOfWorkerThreads">Mevcut işçi thread sayısı.</param>
        /// <param name="workerThread">İşçi Thread.</param>
        public WorkerThreadPoolStartingNewWorkerThreadEventArgs(int currentNumberOfWorkerThreads, WorkerThread workerThread)
        {
            if (workerThread == null)
            {
                throw new ArgumentNullException("workerThread");
            }

            m_CurrentNumberOfWorkerThreads = currentNumberOfWorkerThreads;
            m_WorkerThread = workerThread;
        }
Пример #7
0
 /// <summary>
 /// Constructs a new scheduler
 /// </summary>
 /// <param name="connection">The database connection</param>
 /// <param name="worker">The worker thread</param>
 /// <param name="datalock">The database lock object</param>
 public Scheduler(WorkerThread<Server.Runner.IRunnerData> worker)
 {
     m_thread = new Thread(new ThreadStart(Runner));
     m_worker = worker;
     m_worker.CompletedWork += OnCompleted;
     m_schedule = new ISchedule[0];
     m_terminate = false;
     m_event = new AutoResetEvent(false);
     m_updateTasks = new Dictionary<Server.Runner.IRunnerData, Tuple<ISchedule, DateTime, DateTime>>();
     m_thread.IsBackground = true;
     m_thread.Name = "TaskScheduler";
     m_thread.Start();
 }
Пример #8
0
        public void Should_be_able_to_dispose_failing_worker()
        {
            var worker = new TestProcessor();
            var target = new WorkerThread<int>("test", TimeSpan.FromDays(1), worker.Process);

            target.Enqueue(1);

            target.Dispose();

            worker.Logs.Should().Have.SameSequenceAs(new[] {
                "1"
            });
        }
        public ThreadPoolSynchronizer(uint poolSize,string poolName)
        {
            if(poolSize == 0)
             {
            throw new InvalidOperationException("Pool size cannot be zero");
             }
             CallQueued = new Semaphore(0,Int32.MaxValue);
             m_WorkItemQueue = new Queue<WorkItem>();

             m_WorkerThreads = new WorkerThread[poolSize];
             for(int index = 0;index<poolSize;index++)
             {
            m_WorkerThreads[index] = new WorkerThread(poolName + " " + (index+1),this);
             }
        }
Пример #10
0
        public void Should_dequeue_all_when_disposing()
        {
            var worker = new TestProcessor();
            var target = new WorkerThread<int>("test", TimeSpan.FromDays(1), worker.Process);

            target.Enqueue(1);
            target.Enqueue(2);
            target.Enqueue(3);

            target.Dispose();

            worker.Logs.Should().Have.SameSequenceAs(new[] {
                "1, 2, 3"
            });
        }
Пример #11
0
    /// <summary>
    /// Add a new callback function to the worker thread.
    /// </summary>
    public static void Add(CallbackFunction fn, object param)
    {
        if (mInstance == null)
        {
            GameObject go = new GameObject("_WorkerThread");
            DontDestroyOnLoad(go);
            mInstance = go.AddComponent<WorkerThread>();
            mInstance.mThread = new Thread(mInstance.ThreadFunction);
            mInstance.mThread.Start();
        }

        Entry ent = new Entry();
        ent.fnct = fn;
        ent.param = param;
        lock (mInstance) mInstance.mActive.Add(ent);
    }
 /// <summary>
 /// Blocks until all the ReceivingThreads are started.
 /// </summary>
 public override void Start()
 {
     Logger.Info("Starting service '" + ServiceName + "'.");
     Logger.Info("Configuration: " + this.PrettyFormat());
     for (int i = 0; i < NumberOfWorkingThreads; i++)
     {
         WorkerThread t = new WorkerThread("Receiving thread " + i.ToString("00"), ReceiveOneMessageFromTransport);
         t.Stopped += (x, e) =>
         {
             if (e.Error != null)
             {
                 WorkerThread worker = (WorkerThread)x;
                 Logger.Error(worker.Id + " threw an exception", e.Error);
             }
         };
         ReceivingThreads.Add(t);
         t.Start();
     }
 }
Пример #13
0
        public CoreDriver(UIWindow uiWindow, Configuration config)
        {
            IsDisposed = false;

            try
            {
                _config = config;

                _inputAggregator = new InputAggregator();
                _buttonStates = SnesJoypadButtons.None;

                _workerThread = new WorkerThread();

                _workerThread.DoWork(() =>
                {
                    _uiWindow = uiWindow;

                    _snes = new Snes();
                    _snes.VideoUpdated += Snes_VideoUpdated;
                    _snes.AudioUpdated += Snes_AudioUpdated;
                    _snes.SetControllerPortDevice(1, SnesDevice.Joypad);

                    _inputAggregator.InputReceived += InputAggregator_InputReceived;

                    _isAudioSynced = true;
                    _isVideoSynced = false;

                    _isRunning = false;

                    _stopwatch = new Stopwatch();
                    _stopwatch.Start();
                    _frameCount = 0;
                });
                _workerThread.WaitFor();
            }
            catch
            {
                Dispose();
                throw;
            }
        }
        public void StartShouldStartThread()
        {
            WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create(); 

            IWorkItemQueue workItemQueue = Substitute.For<IWorkItemQueue>();
            workItemQueue.Dequeue().Returns((IWorkItem)null);

            WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false);
            workerThreadManager.ShouldExitWorkerThread(workerThread, false).Returns(false);            
            workerThread.Start();

            Wait.While(() => !workerThread.Thread.IsAlive, 300);

            Assert.AreEqual(true, workerThread.Thread.IsAlive);

            workerThread.Stop();

            Wait.While(() => workerThread.Thread.IsAlive, 300);

            Assert.AreEqual(false, workerThread.Thread.IsAlive);
        }
Пример #15
0
        public void Should_dequeue_in_batch()
        {
            var worker = new TestProcessor();
            var target = new WorkerThread<int>("test", TimeSpan.FromSeconds(.75), worker.Process);

            target.Enqueue(1);
            target.Enqueue(2);
            target.Enqueue(3);

            worker.Go.WaitOne();

            target.Enqueue(4);
            target.Enqueue(5);
            target.Enqueue(6);

            worker.Go.WaitOne();

            worker.Logs.Should().Have.SameSequenceAs(new[] {
                "1, 2, 3",
                "4, 5, 6"
            });
        }
Пример #16
0
 internal void RequestWorker()
 {
     Interlocked.Increment(ref _numRequestedWorkers);
     WorkerThread.MaybeAddWorkingWorker();
     GateThread.EnsureRunning();
 }
        public void CreateTypeBuilderIsThreadSafe()
        {
            const int WORKERS = 20;

            WorkerThread[] workers = new WorkerThread[WORKERS];
            for(int i=0;i<WORKERS;i++)
            {
                workers[i] = new WorkerThread(new WaitCallback(CallCreateTypeBuilder),  i);
                workers[i].Start();
            }

            for(int i=0;i<WORKERS;i++)
            {
                workers[i].Join();
                Assert.AreEqual(null, workers[i].Exception);
            }
        }
Пример #18
0
 public override void DoWork(WorkerThread workerThread)
 {
 }
Пример #19
0
    public static async Task RunBot()
    {
        try
        {
            newBot = new TelegramBot(botToken);
            //    botDetail = (User)await newBot.MakeRequestAsync(new GetMe());
            var botDetail = await newBot.MakeRequestAsync(new GetMe());

            Console.WriteLine("UserName Is {0}", botDetail.Username);

            Session = new Hashtable();



            long offset = 0;

            while (true)
            {
                try
                {
                    Update[] updates = await newBot.MakeRequestAsync(new GetUpdates()
                    {
                        Offset = offset
                    });

                    if (updates.Length == 0)
                    {
                        continue;
                    }
                    Console.WriteLine("");
                    if ((updates[0].Message != null))
                    {
                        Console.WriteLine(updates[0].Message.Chat.Id.ToString() + "-" + updates[0].Message.Text + " in Main Loop");
                    }
                    else
                    {
                        Console.WriteLine(updates[0].UpdateId);
                    }

                    foreach (var update in updates)
                    {
                        //  Console.ReadLine();
                        WorkerThread worker = new WorkerThread(update);

                        if ((update.Message != null))
                        {
                            Console.WriteLine(update.Message.Chat.Id.ToString() + "-" + update.Message.Text + " Worker Thread Created");
                        }
                        else
                        {
                            Console.WriteLine(update.UpdateId);
                        }

                        Thread t = new Thread(new ThreadStart(worker.ThreadProc));

                        if ((update.Message != null))
                        {
                            Console.WriteLine(update.Message.Chat.Id.ToString() + "-" + update.Message.Text + "  Thread Created");
                        }
                        else
                        {
                            Console.WriteLine(update.UpdateId);
                        }

                        t.Start();
                        offset = update.UpdateId + 1;
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(" Exception:" + ex.Message);
                }
            }
        }
        catch (Exception e)
        { Console.WriteLine(" Exception:" + e.Message); }
    }
Пример #20
0
 public async Task TestWorkerThread()
 {
     await WorkerThread.RunWorkerThread();
 }
Пример #21
0
        execute(ThreadPoolWorkItem workItem)
        {
            _m.Lock();
            try
            {
                Debug.Assert(!_destroyed);
                if(_workItems.Count == 0)
                {
                    _m.Notify();
                }
                _workItems.Enqueue(workItem);

                //
                // If this is a dynamic thread pool which can still grow and if all threads are
                // currently busy dispatching or about to dispatch, we spawn a new thread to 
                // execute this new work item right away.
                //
                if(_threads.Count < _sizeMax && 
                   (_inUse + _workItems.Count) > _threads.Count &&
                   !_destroyed)
                {
                    if(_instance.traceLevels().threadPool >= 1)
                    {
                        string s = "growing " + _prefix + ": Size = " + (_threads.Count + 1);
                        _instance.initializationData().logger.trace(_instance.traceLevels().threadPoolCat, s);
                    }
                    
                    try
                    {
                        WorkerThread t = new WorkerThread(this, _threadPrefix + "-" + _threadIndex++);
                        if(_hasPriority)
                        {
                            t.start(_priority);
                        }
                        else
                        {
                            t.start(ThreadPriority.Normal);
                        }
                        _threads.Add(t);
                    }
                    catch(System.Exception ex)
                    {
                        string s = "cannot create thread for `" + _prefix + "':\n" + ex;
                        _instance.initializationData().logger.error(s);
                    }
                }
            }
            finally
            {
                _m.Unlock();
            }
        }
Пример #22
0
        /// <summary>
        /// Creates the worker threads.
        /// </summary>
        /// <param name="threadCount">The thread count.</param>
        /// <returns></returns>
        protected internal virtual IList CreateWorkerThreads(int threadCount)
        {
            workers = new ArrayList();
            for (int i = 1; i <= threadCount; ++i)
            {
                WorkerThread wt = new WorkerThread(
                    this,
                    string.Format(CultureInfo.InvariantCulture, "{0}-{1}", ThreadNamePrefix, i),
                    ThreadPriority,
                    MakeThreadsDaemons);

                workers.Add(wt);
            }

            return workers;
        }
Пример #23
0
 /// <summary>
 /// Starts the worker thread once the window is loaded.
 /// </summary>
 /// <param name="sender">Window.</param>
 /// <param name="e">Event arguments.</param>
 private void StartWorkerThread(object sender, RoutedEventArgs e)
 {
     workerThread              = new WorkerThread(ref cameras);
     workerThread.ResultReady += ResultReady;
 }
            private static void GateThreadStart()
            {
                bool disableStarvationDetection =
                    AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.DisableStarvationDetection", false);
                bool debuggerBreakOnWorkStarvation =
                    AppContextConfigHelper.GetBooleanConfig("System.Threading.ThreadPool.DebugBreakOnWorkerStarvation", false);

                // The first reading is over a time range other than what we are focusing on, so we do not use the read other
                // than to send it to any runtime-specific implementation that may also use the CPU utilization.
                CpuUtilizationReader cpuUtilizationReader = default;

                _ = cpuUtilizationReader.CurrentUtilization;

                PortableThreadPool threadPoolInstance = ThreadPoolInstance;
                LowLevelLock       hillClimbingThreadAdjustmentLock = threadPoolInstance._hillClimbingThreadAdjustmentLock;

                while (true)
                {
                    s_runGateThreadEvent.WaitOne();

                    bool needGateThreadForRuntime;
                    do
                    {
                        Thread.Sleep(GateThreadDelayMs);

                        if (ThreadPool.EnableWorkerTracking && PortableThreadPoolEventSource.Log.IsEnabled())
                        {
                            PortableThreadPoolEventSource.Log.ThreadPoolWorkingThreadCount(
                                (uint)threadPoolInstance.GetAndResetHighWatermarkCountOfThreadsProcessingUserCallbacks());
                        }

                        int cpuUtilization = cpuUtilizationReader.CurrentUtilization;
                        threadPoolInstance._cpuUtilization = cpuUtilization;

                        needGateThreadForRuntime = ThreadPool.PerformRuntimeSpecificGateActivities(cpuUtilization);

                        if (!disableStarvationDetection &&
                            threadPoolInstance._separated.numRequestedWorkers > 0 &&
                            SufficientDelaySinceLastDequeue(threadPoolInstance))
                        {
                            try
                            {
                                hillClimbingThreadAdjustmentLock.Acquire();
                                ThreadCounts counts = threadPoolInstance._separated.counts.VolatileRead();

                                // Don't add a thread if we're at max or if we are already in the process of adding threads.
                                // This logic is slightly different from the native implementation in CoreCLR because there are
                                // no retired threads. In the native implementation, when hill climbing reduces the thread count
                                // goal, threads that are stopped from processing work are switched to "retired" state, and they
                                // don't count towards the equivalent existing thread count. In this implementation, the
                                // existing thread count includes any worker thread that has not yet exited, including those
                                // stopped from working by hill climbing, so here the number of threads processing work, instead
                                // of the number of existing threads, is compared with the goal. There may be alternative
                                // solutions, for now this is only to maintain consistency in behavior.
                                while (
                                    counts.NumExistingThreads < threadPoolInstance._maxThreads &&
                                    counts.NumProcessingWork >= counts.NumThreadsGoal)
                                {
                                    if (debuggerBreakOnWorkStarvation)
                                    {
                                        Debugger.Break();
                                    }

                                    ThreadCounts newCounts         = counts;
                                    short        newNumThreadsGoal = (short)(counts.NumProcessingWork + 1);
                                    newCounts.NumThreadsGoal = newNumThreadsGoal;

                                    ThreadCounts oldCounts = threadPoolInstance._separated.counts.InterlockedCompareExchange(newCounts, counts);
                                    if (oldCounts == counts)
                                    {
                                        HillClimbing.ThreadPoolHillClimber.ForceChange(newNumThreadsGoal, HillClimbing.StateOrTransition.Starvation);
                                        WorkerThread.MaybeAddWorkingWorker(threadPoolInstance);
                                        break;
                                    }

                                    counts = oldCounts;
                                }
                            }
                            finally
                            {
                                hillClimbingThreadAdjustmentLock.Release();
                            }
                        }
                    } while (
                        needGateThreadForRuntime ||
                        threadPoolInstance._separated.numRequestedWorkers > 0 ||
                        Interlocked.Decrement(ref threadPoolInstance._separated.gateThreadRunningState) > GetRunningStateForNumRuns(0));
                }
            }
 /// <summary>
 /// Initializes the configuration window.
 /// </summary>
 /// <param name="workerThread">Used worker thread.</param>
 public void InitConfiguration(ref WorkerThread workerThread)
 {
     manager           = new ConfigurationManager(ref workerThread, instructionsText, instructionsBox, audioInputDeviceVolume, positions, saveButton);
     this.workerThread = workerThread;
     UpdateStartButton();
 }
Пример #26
0
 public static void StopWatchingLogFile()
 {
     WorkerThread.Abort();
     Trace.WriteLine("stop watch");
 }
Пример #27
0
 public static void StartWatchingLogFile()
 {
     WorkerThread.Start();
     Trace.WriteLine("starting watching");
 }
Пример #28
0
        //
        // This method must only be called if ShouldAdjustMaxWorkersActive has returned true, *and*
        // _hillClimbingThreadAdjustmentLock is held.
        //
        private void AdjustMaxWorkersActive()
        {
            LowLevelLock threadAdjustmentLock = _threadAdjustmentLock;

            if (!threadAdjustmentLock.TryAcquire())
            {
                // The lock is held by someone else, they will take care of this for us
                return;
            }

            bool addWorker = false;

            try
            {
                // Repeated checks from ShouldAdjustMaxWorkersActive() inside the lock
                ThreadCounts counts = _separated.counts;
                if (counts.NumProcessingWork > counts.NumThreadsGoal ||
                    _pendingBlockingAdjustment != PendingBlockingAdjustment.None)
                {
                    return;
                }

                long   endTime        = Stopwatch.GetTimestamp();
                double elapsedSeconds = Stopwatch.GetElapsedTime(_currentSampleStartTime, endTime).TotalSeconds;

                if (elapsedSeconds * 1000 >= _threadAdjustmentIntervalMs / 2)
                {
                    int currentTicks        = Environment.TickCount;
                    int totalNumCompletions = (int)_completionCounter.Count;
                    int numCompletions      = totalNumCompletions - _separated.priorCompletionCount;

                    short oldNumThreadsGoal = counts.NumThreadsGoal;
                    int   newNumThreadsGoal;
                    (newNumThreadsGoal, _threadAdjustmentIntervalMs) =
                        HillClimbing.ThreadPoolHillClimber.Update(oldNumThreadsGoal, elapsedSeconds, numCompletions);
                    if (oldNumThreadsGoal != (short)newNumThreadsGoal)
                    {
                        _separated.counts.InterlockedSetNumThreadsGoal((short)newNumThreadsGoal);

                        //
                        // If we're increasing the goal, inject a thread.  If that thread finds work, it will inject
                        // another thread, etc., until nobody finds work or we reach the new goal.
                        //
                        // If we're reducing the goal, whichever threads notice this first will sleep and timeout themselves.
                        //
                        if (newNumThreadsGoal > oldNumThreadsGoal)
                        {
                            addWorker = true;
                        }
                    }

                    _separated.priorCompletionCount          = totalNumCompletions;
                    _separated.nextCompletedWorkRequestsTime = currentTicks + _threadAdjustmentIntervalMs;
                    Volatile.Write(ref _separated.priorCompletedWorkRequestsTime, currentTicks);
                    _currentSampleStartTime = endTime;
                }
            }
            finally
            {
                threadAdjustmentLock.Release();
            }

            if (addWorker)
            {
                WorkerThread.MaybeAddWorkingWorker(this);
            }
        }
Пример #29
0
        public bool SetMinThreads(int workerThreads, int ioCompletionThreads)
        {
            if (workerThreads < 0 || ioCompletionThreads < 0)
            {
                return(false);
            }

            bool addWorker      = false;
            bool wakeGateThread = false;

            _threadAdjustmentLock.Acquire();
            try
            {
                if (workerThreads > _maxThreads)
                {
                    return(false);
                }

                if (ThreadPool.UsePortableThreadPoolForIO
                        ? ioCompletionThreads > _legacy_maxIOCompletionThreads
                        : !ThreadPool.CanSetMinIOCompletionThreads(ioCompletionThreads))
                {
                    return(false);
                }

                if (HasForcedMinThreads && workerThreads != ForcedMinWorkerThreads)
                {
                    return(false);
                }

                if (ThreadPool.UsePortableThreadPoolForIO)
                {
                    _legacy_minIOCompletionThreads = (short)Math.Max(1, ioCompletionThreads);
                }
                else
                {
                    ThreadPool.SetMinIOCompletionThreads(ioCompletionThreads);
                }

                short newMinThreads = (short)Math.Max(1, workerThreads);
                if (newMinThreads == _minThreads)
                {
                    return(true);
                }

                _minThreads = newMinThreads;
                if (_numBlockedThreads > 0)
                {
                    // Blocking adjustment will adjust the goal according to its heuristics
                    if (_pendingBlockingAdjustment != PendingBlockingAdjustment.Immediately)
                    {
                        _pendingBlockingAdjustment = PendingBlockingAdjustment.Immediately;
                        wakeGateThread             = true;
                    }
                }
                else if (_separated.counts.NumThreadsGoal < newMinThreads)
                {
                    _separated.counts.InterlockedSetNumThreadsGoal(newMinThreads);
                    if (_separated.numRequestedWorkers > 0)
                    {
                        addWorker = true;
                    }
                }
            }
            finally
            {
                _threadAdjustmentLock.Release();
            }

            if (addWorker)
            {
                WorkerThread.MaybeAddWorkingWorker(this);
            }
            else if (wakeGateThread)
            {
                GateThread.Wake(this);
            }
            return(true);
        }
Пример #30
0
        /// <summary>
        /// Creates a new loader with the specified configuration
        /// </summary>
        /// <param name="debugging">True if we are debugging</param>
        /// <param name="language">Which language are we trying to load</param>
        /// <param name="loaderTimeLimit">
        /// Used to limit how long it takes to create a new instance
        /// </param>
        /// <param name="multipleTypeNameResolverFunction">
        /// Used to resolve multiple type names found in assembly to a single type name, if null, defaults to names => names.SingleOrDefault()
        ///
        /// When we search an assembly for derived types of IAlgorithm, sometimes the assembly will contain multiple matching types. This is the case
        /// for the QuantConnect.Algorithm assembly in this solution.  In order to pick the correct type, consumers must specify how to pick the type,
        /// that's what this function does, it picks the correct type from the list of types found within the assembly.
        /// </param>
        /// <param name="workerThread">The worker thread instance the loader should use</param>
        public Loader(bool debugging, Language language, TimeSpan loaderTimeLimit, Func <List <string>, string> multipleTypeNameResolverFunction, WorkerThread workerThread = null)
        {
            _debugging    = debugging;
            _language     = language;
            _workerThread = workerThread;
            if (multipleTypeNameResolverFunction == null)
            {
                throw new ArgumentNullException("multipleTypeNameResolverFunction");
            }

            _loaderTimeLimit = loaderTimeLimit;
            _multipleTypeNameResolverFunction = multipleTypeNameResolverFunction;
        }
Пример #31
0
        /// <summary>
        /// Run the given <see cref="IThreadRunnable" /> object in the next available
        /// <see cref="Thread" />. If while waiting the thread pool is asked to
        /// shut down, the Runnable is executed immediately within a new additional
        /// thread.
        /// </summary>
        /// <param name="runnable">The <see cref="IThreadRunnable" /> to be added.</param>
        public virtual bool RunInThread(IThreadRunnable runnable)
        {
            if (runnable == null)
            {
                return false;
            }

            lock (nextRunnableLock)
            {
                handoffPending = true;

                // Wait until a worker thread is available
                while ((availWorkers.Count < 1) && !isShutdown)
                {
                    try
                    {
                        Monitor.Wait(nextRunnableLock, 500);
                    }
                    catch (ThreadInterruptedException)
                    {
                    }
                }

                if (!isShutdown)
                {
                    WorkerThread wt = (WorkerThread)availWorkers[0];
                    availWorkers.RemoveAt(0);
                    busyWorkers.Add(wt);
                    wt.Run(runnable);
                }
                else
                {
                    // If the thread pool is going down, execute the Runnable
                    // within a new additional worker thread (no thread from the pool).
                    WorkerThread wt =
                        new WorkerThread(this, "WorkerThread-LastJob", prio, MakeThreadsDaemons, runnable);
                    busyWorkers.Add(wt);
                    workers.Add(wt);
                    wt.Start();
                }
                Monitor.PulseAll(nextRunnableLock);
                handoffPending = false;
            }

            return true;
        }
 public ConfigurationStepSpeaker(ConfigurationManager manager, ref WorkerThread workerThread)
 {
     this.manager      = manager;
     this.workerThread = workerThread;
 }
Пример #33
0
			public Task SetUp (TestSuite suite)
			{
				worker = new WorkerThread ();
				return Task.FromResult<object> (null);
			}
        public void ConstructorShouldNotStartThread()
        {
            WorkerThread workerThread = new WorkerThread(Substitute.For <IWorkerThreadManager>(), Substitute.For <IWorkItemQueue>(), "Test", false);

            Assert.AreEqual(false, workerThread.Thread.IsAlive);
        }
Пример #35
0
        /// <summary>
        /// Execute a code block with a maximum limit on time and memory.
        /// </summary>
        /// <param name="timeSpan">Timeout in timespan</param>
        /// <param name="withinCustomLimits">Function used to determine if the codeBlock is within custom limits, such as with algorithm manager
        /// timing individual time loops, return a non-null and non-empty string with a message indicating the error/reason for stoppage</param>
        /// <param name="codeBlock">Action codeblock to execute</param>
        /// <param name="memoryCap">Maximum memory allocation, default 1024Mb</param>
        /// <param name="sleepIntervalMillis">Sleep interval between each check in ms</param>
        /// <param name="workerThread">The worker thread instance that will execute the provided action, if null
        /// will use a <see cref="Task"/></param>
        /// <returns>True if algorithm exited successfully, false if cancelled because it exceeded limits.</returns>
        public bool ExecuteWithTimeLimit(TimeSpan timeSpan, Func <IsolatorLimitResult> withinCustomLimits, Action codeBlock, long memoryCap = 1024, int sleepIntervalMillis = 1000, WorkerThread workerThread = null)
        {
            workerThread?.Add(codeBlock);

            var task = workerThread == null
                       //Launch task
                ? Task.Factory.StartNew(codeBlock, CancellationTokenSource.Token)
                       // wrapper task so we can reuse MonitorTask
                : Task.Factory.StartNew(() => workerThread.FinishedWorkItem.WaitOne(), CancellationTokenSource.Token);

            try
            {
                return(MonitorTask(task, timeSpan, withinCustomLimits, memoryCap, sleepIntervalMillis));
            }
            catch (Exception)
            {
                if (!task.IsCompleted)
                {
                    // lets free the wrapper task even if the worker thread didn't finish
                    workerThread?.FinishedWorkItem.Set();
                }
                throw;
            }
        }
        public void ConstructorShouldSetIsBackgroundPropertyOfThread([Values(true, false)] bool isBackground)
        {
            WorkerThread workerThread = new WorkerThread(Substitute.For <IWorkerThreadManager>(), Substitute.For <IWorkItemQueue>(), "Test", isBackground);

            Assert.AreEqual(isBackground, workerThread.Thread.IsBackground);
        }
Пример #37
0
 /// <summary>
 /// Adds a thread to the manager.
 /// </summary>
 /// <param name="initialization">A function to run to perform any initialization on the new thread.</param>
 /// <param name="initializationInformation">Data to give the ParameterizedThreadStart for initialization.</param>
 public void AddThread(Action<object> initialization, object initializationInformation)
 {
     lock (workers)
     {
         var worker = new WorkerThread(workers.Count, this, initialization, initializationInformation);
         workers.Add(worker);
         RemakeLoopSections();
     }
 }
        public void DoWorkShouldCallWorkerThreadExceptionEventWhenExceptionOccursOutsideOfWorkItemDoWorkMethod()
        {
            WorkerThreadManagerStub workerThreadManager = WorkerThreadManagerStub.Create();

            ManualResetEvent manualResetEvent = new ManualResetEvent(false);
            IWorkItemQueue   workItemQueue    = Substitute.For <IWorkItemQueue>();
            IWorkItem        workItem         = Substitute.For <IWorkItem>();

            workItemQueue.Dequeue().Returns(workItem);

            Exception    invalidCastException             = new InvalidCastException();
            Exception    otherThreadsException            = null;
            bool         workerThreadExitingEventIsCalled = false;
            WorkerThread workerThread = new WorkerThread(workerThreadManager, workItemQueue, "Test", false);

            workerThreadManager.WorkerThreadStarted += (sender, args) =>
            {
                throw invalidCastException;
            };
            workerThreadManager.WorkerThreadException += (sender, args) =>
            {
                try
                {
                    Assert.AreEqual(invalidCastException, args.Exception);
                }
                catch (Exception ex)
                {
                    otherThreadsException = ex;
                }
            };
            workerThreadManager.WorkerThreadExiting += (sender, args) =>
            {
                workerThreadExitingEventIsCalled = true;

                try
                {
                    Assert.AreEqual(WorkerThreadExitReason.ExceptionOccurred, args.WorkerThreadExitReason);
                }
                catch (Exception ex)
                {
                    otherThreadsException = ex;
                }

                manualResetEvent.Set();
            };
            workerThread.Start();

            Wait.While(() => !workerThread.Thread.IsAlive, 300);

            manualResetEvent.WaitOne(500);
            workerThread.Stop();

            Wait.While(() => workerThread.Thread.IsAlive, 300);

            Assert.AreEqual(false, workerThread.Thread.IsAlive);

            Assert.AreEqual(true, workerThreadExitingEventIsCalled);

            if (otherThreadsException != null)
            {
                throw otherThreadsException;
            }
        }
Пример #39
0
        /// <summary>
        /// Creates the worker threads.
        /// </summary>
        /// <param name="threadCount">The thread count.</param>
        /// <returns></returns>
        protected virtual IList<WorkerThread> CreateWorkerThreads(int threadCount)
        {
            workers = new List<WorkerThread>();
            for (int i = 1; i <= threadCount; ++i)
            {
                string threadPrefix = ThreadNamePrefix;
                if (threadPrefix == null)
                {
                    threadPrefix = schedulerInstanceName + "_Worker";
                }

                var workerThread = new WorkerThread(
                    this,
                    string.Format(CultureInfo.InvariantCulture, "{0}-{1}", threadPrefix, i),
                    ThreadPriority,
                    MakeThreadsDaemons);

                workers.Add(workerThread);
            }

            return workers;
        }
Пример #40
0
        /// <summary>
        /// Runs a single backtest/live job from the job queue
        /// </summary>
        /// <param name="job">The algorithm job to be processed</param>
        /// <param name="manager"></param>
        /// <param name="assemblyPath">The path to the algorithm's assembly</param>
        public void Run(AlgorithmNodePacket job, AlgorithmManager manager, string assemblyPath)
        {
            var marketHoursDatabaseTask = Task.Run(() => StaticInitializations());

            var algorithm        = default(IAlgorithm);
            var algorithmManager = manager;

            try
            {
                //Reset thread holders.
                var          initializeComplete = false;
                Thread       threadResults      = null;
                Thread       threadRealTime     = null;
                Thread       threadAlphas       = null;
                WorkerThread workerThread       = null;

                //-> Initialize messaging system
                _systemHandlers.Notify.SetAuthentication(job);

                //-> Set the result handler type for this algorithm job, and launch the associated result thread.
                _algorithmHandlers.Results.Initialize(job, _systemHandlers.Notify, _systemHandlers.Api, _algorithmHandlers.Setup, _algorithmHandlers.Transactions);

                threadResults = new Thread(_algorithmHandlers.Results.Run, 0)
                {
                    IsBackground = true, Name = "Result Thread"
                };
                threadResults.Start();

                IBrokerage  brokerage    = null;
                DataManager dataManager  = null;
                var         synchronizer = _liveMode ? new LiveSynchronizer() : new Synchronizer();
                try
                {
                    // we get the mhdb before creating the algorithm instance,
                    // since the algorithm constructor will use it
                    var marketHoursDatabase = marketHoursDatabaseTask.Result;

                    // start worker thread
                    workerThread = new WorkerThread();
                    _algorithmHandlers.Setup.WorkerThread = workerThread;

                    // Save algorithm to cache, load algorithm instance:
                    algorithm = _algorithmHandlers.Setup.CreateAlgorithmInstance(job, assemblyPath);

                    // Set algorithm in ILeanManager
                    _systemHandlers.LeanManager.SetAlgorithm(algorithm);

                    // initialize the alphas handler with the algorithm instance
                    _algorithmHandlers.Alphas.Initialize(job, algorithm, _systemHandlers.Notify, _systemHandlers.Api);

                    // Initialize the brokerage
                    IBrokerageFactory factory;
                    brokerage = _algorithmHandlers.Setup.CreateBrokerage(job, algorithm, out factory);

                    var symbolPropertiesDatabase = SymbolPropertiesDatabase.FromDataFolder();

                    var securityService = new SecurityService(algorithm.Portfolio.CashBook,
                                                              marketHoursDatabase,
                                                              symbolPropertiesDatabase,
                                                              (ISecurityInitializerProvider)algorithm);

                    algorithm.Securities.SetSecurityService(securityService);

                    dataManager = new DataManager(_algorithmHandlers.DataFeed,
                                                  new UniverseSelection(
                                                      algorithm,
                                                      securityService),
                                                  algorithm,
                                                  algorithm.TimeKeeper,
                                                  marketHoursDatabase,
                                                  _liveMode);

                    _algorithmHandlers.Results.SetDataManager(dataManager);
                    algorithm.SubscriptionManager.SetDataManager(dataManager);

                    synchronizer.Initialize(algorithm, dataManager);

                    // Initialize the data feed before we initialize so he can intercept added securities/universes via events
                    _algorithmHandlers.DataFeed.Initialize(
                        algorithm,
                        job,
                        _algorithmHandlers.Results,
                        _algorithmHandlers.MapFileProvider,
                        _algorithmHandlers.FactorFileProvider,
                        _algorithmHandlers.DataProvider,
                        dataManager,
                        (IDataFeedTimeProvider)synchronizer);

                    // set the order processor on the transaction manager (needs to be done before initializing BrokerageHistoryProvider)
                    algorithm.Transactions.SetOrderProcessor(_algorithmHandlers.Transactions);
                    algorithm.SetOrderEventProvider(_algorithmHandlers.Transactions);

                    // set the history provider before setting up the algorithm
                    var historyProvider = GetHistoryProvider(job.HistoryProvider);
                    if (historyProvider is BrokerageHistoryProvider)
                    {
                        (historyProvider as BrokerageHistoryProvider).SetBrokerage(brokerage);
                    }

                    var historyDataCacheProvider = new ZipDataCacheProvider(_algorithmHandlers.DataProvider, isDataEphemeral: _liveMode);
                    historyProvider.Initialize(
                        new HistoryProviderInitializeParameters(
                            job,
                            _systemHandlers.Api,
                            _algorithmHandlers.DataProvider,
                            historyDataCacheProvider,
                            _algorithmHandlers.MapFileProvider,
                            _algorithmHandlers.FactorFileProvider,
                            progress =>
                    {
                        // send progress updates to the result handler only during initialization
                        if (!algorithm.GetLocked() || algorithm.IsWarmingUp)
                        {
                            _algorithmHandlers.Results.SendStatusUpdate(AlgorithmStatus.History,
                                                                        string.Format("Processing history {0}%...", progress));
                        }
                    }
                            )
                        );

                    historyProvider.InvalidConfigurationDetected += (sender, args) => { _algorithmHandlers.Results.ErrorMessage(args.Message); };
                    historyProvider.NumericalPrecisionLimited    += (sender, args) => { _algorithmHandlers.Results.DebugMessage(args.Message); };
                    historyProvider.DownloadFailed      += (sender, args) => { _algorithmHandlers.Results.ErrorMessage(args.Message, args.StackTrace); };
                    historyProvider.ReaderErrorDetected += (sender, args) => { _algorithmHandlers.Results.RuntimeError(args.Message, args.StackTrace); };

                    algorithm.HistoryProvider = historyProvider;

                    // initialize the default brokerage message handler
                    algorithm.BrokerageMessageHandler = factory.CreateBrokerageMessageHandler(algorithm, job, _systemHandlers.Api);

                    //Initialize the internal state of algorithm and job: executes the algorithm.Initialize() method.
                    initializeComplete = _algorithmHandlers.Setup.Setup(new SetupHandlerParameters(dataManager.UniverseSelection, algorithm, brokerage, job, _algorithmHandlers.Results, _algorithmHandlers.Transactions, _algorithmHandlers.RealTime));

                    // set this again now that we've actually added securities
                    _algorithmHandlers.Results.SetAlgorithm(algorithm);

                    // alpha handler needs start/end dates to determine sample step sizes
                    _algorithmHandlers.Alphas.OnAfterAlgorithmInitialized(algorithm);

                    //If there are any reasons it failed, pass these back to the IDE.
                    if (!initializeComplete || algorithm.ErrorMessages.Count > 0 || _algorithmHandlers.Setup.Errors.Count > 0)
                    {
                        initializeComplete = false;
                        //Get all the error messages: internal in algorithm and external in setup handler.
                        var errorMessage = String.Join(",", algorithm.ErrorMessages);
                        errorMessage += String.Join(",", _algorithmHandlers.Setup.Errors.Select(e =>
                        {
                            var message = e.Message;
                            if (e.InnerException != null)
                            {
                                var err  = _exceptionInterpreter.Value.Interpret(e.InnerException, _exceptionInterpreter.Value);
                                message += _exceptionInterpreter.Value.GetExceptionMessageHeader(err);
                            }
                            return(message);
                        }));
                        Log.Error("Engine.Run(): " + errorMessage);
                        _algorithmHandlers.Results.RuntimeError(errorMessage);
                        _systemHandlers.Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, errorMessage);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);
                    var runtimeMessage = "Algorithm.Initialize() Error: " + err.Message + " Stack Trace: " + err;
                    _algorithmHandlers.Results.RuntimeError(runtimeMessage, err.ToString());
                    _systemHandlers.Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, runtimeMessage);
                }


                // log the job endpoints
                Log.Trace("JOB HANDLERS: ");
                Log.Trace("         DataFeed:     " + _algorithmHandlers.DataFeed.GetType().FullName);
                Log.Trace("         Setup:        " + _algorithmHandlers.Setup.GetType().FullName);
                Log.Trace("         RealTime:     " + _algorithmHandlers.RealTime.GetType().FullName);
                Log.Trace("         Results:      " + _algorithmHandlers.Results.GetType().FullName);
                Log.Trace("         Transactions: " + _algorithmHandlers.Transactions.GetType().FullName);
                Log.Trace("         Alpha:        " + _algorithmHandlers.Alphas.GetType().FullName);
                if (algorithm?.HistoryProvider != null)
                {
                    Log.Trace("         History Provider:     " + algorithm.HistoryProvider.GetType().FullName);
                }
                if (job is LiveNodePacket)
                {
                    Log.Trace("         Brokerage:      " + brokerage?.GetType().FullName);
                }

                //-> Using the job + initialization: load the designated handlers:
                if (initializeComplete)
                {
                    // notify the LEAN manager that the algorithm is initialized and starting
                    _systemHandlers.LeanManager.OnAlgorithmStart();

                    //-> Reset the backtest stopwatch; we're now running the algorithm.
                    var startTime = DateTime.Now;

                    //Set algorithm as locked; set it to live mode if we're trading live, and set it to locked for no further updates.
                    algorithm.SetAlgorithmId(job.AlgorithmId);
                    algorithm.SetLocked();

                    //Load the associated handlers for transaction and realtime events:
                    _algorithmHandlers.Transactions.Initialize(algorithm, brokerage, _algorithmHandlers.Results);
                    _algorithmHandlers.RealTime.Setup(algorithm, job, _algorithmHandlers.Results, _systemHandlers.Api);

                    // wire up the brokerage message handler
                    brokerage.Message += (sender, message) =>
                    {
                        algorithm.BrokerageMessageHandler.Handle(message);

                        // fire brokerage message events
                        algorithm.OnBrokerageMessage(message);
                        switch (message.Type)
                        {
                        case BrokerageMessageType.Disconnect:
                            algorithm.OnBrokerageDisconnect();
                            break;

                        case BrokerageMessageType.Reconnect:
                            algorithm.OnBrokerageReconnect();
                            break;
                        }
                    };

                    //Send status to user the algorithm is now executing.
                    _algorithmHandlers.Results.SendStatusUpdate(AlgorithmStatus.Running);

                    //Launch the data, transaction and realtime handlers into dedicated threads
                    threadRealTime = new Thread(_algorithmHandlers.RealTime.Run)
                    {
                        IsBackground = true, Name = "RealTime Thread"
                    };
                    threadAlphas = new Thread(() => _algorithmHandlers.Alphas.Run())
                    {
                        IsBackground = true, Name = "Alpha Thread"
                    };

                    //Launch the data feed, result sending, and transaction models/handlers in separate threads.
                    threadRealTime.Start(); // RealTime scan time for time based events:
                    threadAlphas.Start();   // Alpha thread for processing algorithm alpha insights

                    // Result manager scanning message queue: (started earlier)
                    _algorithmHandlers.Results.DebugMessage(string.Format("Launching analysis for {0} with LEAN Engine v{1}", job.AlgorithmId, Globals.Version));

                    try
                    {
                        //Create a new engine isolator class
                        var isolator = new Isolator();

                        // Execute the Algorithm Code:
                        var complete = isolator.ExecuteWithTimeLimit(_algorithmHandlers.Setup.MaximumRuntime, algorithmManager.TimeLoopWithinLimits, () =>
                        {
                            try
                            {
                                //Run Algorithm Job:
                                // -> Using this Data Feed,
                                // -> Send Orders to this TransactionHandler,
                                // -> Send Results to ResultHandler.
                                algorithmManager.Run(job, algorithm, synchronizer, _algorithmHandlers.Transactions, _algorithmHandlers.Results, _algorithmHandlers.RealTime, _systemHandlers.LeanManager, _algorithmHandlers.Alphas, isolator.CancellationToken);
                            }
                            catch (Exception err)
                            {
                                //Debugging at this level is difficult, stack trace needed.
                                Log.Error(err);
                                algorithm.RunTimeError = err;
                                algorithmManager.SetStatus(AlgorithmStatus.RuntimeError);
                                return;
                            }

                            Log.Trace("Engine.Run(): Exiting Algorithm Manager");
                        }, job.Controls.RamAllocation, workerThread: workerThread);

                        if (!complete)
                        {
                            Log.Error("Engine.Main(): Failed to complete in time: " + _algorithmHandlers.Setup.MaximumRuntime.ToString("F"));
                            throw new Exception("Failed to complete algorithm within " + _algorithmHandlers.Setup.MaximumRuntime.ToString("F")
                                                + " seconds. Please make it run faster.");
                        }

                        // Algorithm runtime error:
                        if (algorithm.RunTimeError != null)
                        {
                            HandleAlgorithmError(job, algorithm.RunTimeError);
                        }
                    }
                    catch (Exception err)
                    {
                        //Error running the user algorithm: purge datafeed, send error messages, set algorithm status to failed.
                        HandleAlgorithmError(job, err);
                    }

                    // notify the LEAN manager that the algorithm has finished
                    _systemHandlers.LeanManager.OnAlgorithmEnd();

                    try
                    {
                        var trades            = algorithm.TradeBuilder.ClosedTrades;
                        var charts            = new Dictionary <string, Chart>(_algorithmHandlers.Results.Charts);
                        var orders            = new Dictionary <int, Order>(_algorithmHandlers.Transactions.Orders);
                        var holdings          = new Dictionary <string, Holding>();
                        var banner            = new Dictionary <string, string>();
                        var statisticsResults = new StatisticsResults();

                        var csvTransactionsFileName = Config.Get("transaction-log");
                        if (!string.IsNullOrEmpty(csvTransactionsFileName))
                        {
                            SaveListOfTrades(_algorithmHandlers.Transactions, csvTransactionsFileName);
                        }

                        try
                        {
                            //Generates error when things don't exist (no charting logged, runtime errors in main algo execution)
                            const string strategyEquityKey   = "Strategy Equity";
                            const string equityKey           = "Equity";
                            const string dailyPerformanceKey = "Daily Performance";
                            const string benchmarkKey        = "Benchmark";

                            // make sure we've taken samples for these series before just blindly requesting them
                            if (charts.ContainsKey(strategyEquityKey) &&
                                charts[strategyEquityKey].Series.ContainsKey(equityKey) &&
                                charts[strategyEquityKey].Series.ContainsKey(dailyPerformanceKey) &&
                                charts.ContainsKey(benchmarkKey) &&
                                charts[benchmarkKey].Series.ContainsKey(benchmarkKey)
                                )
                            {
                                var equity            = charts[strategyEquityKey].Series[equityKey].Values;
                                var performance       = charts[strategyEquityKey].Series[dailyPerformanceKey].Values;
                                var profitLoss        = new SortedDictionary <DateTime, decimal>(algorithm.Transactions.TransactionRecord);
                                var totalTransactions = algorithm.Transactions.GetOrders(x => x.Status.IsFill()).Count();
                                var benchmark         = charts[benchmarkKey].Series[benchmarkKey].Values;

                                statisticsResults = StatisticsBuilder.Generate(trades, profitLoss, equity, performance, benchmark,
                                                                               _algorithmHandlers.Setup.StartingPortfolioValue, algorithm.Portfolio.TotalFees, totalTransactions);

                                //Some users have $0 in their brokerage account / starting cash of $0. Prevent divide by zero errors
                                var netReturn = _algorithmHandlers.Setup.StartingPortfolioValue > 0 ?
                                                (algorithm.Portfolio.TotalPortfolioValue - _algorithmHandlers.Setup.StartingPortfolioValue) / _algorithmHandlers.Setup.StartingPortfolioValue
                                                : 0;

                                //Add other fixed parameters.
                                banner.Add("Unrealized", "$" + algorithm.Portfolio.TotalUnrealizedProfit.ToString("N2"));
                                banner.Add("Fees", "-$" + algorithm.Portfolio.TotalFees.ToString("N2"));
                                banner.Add("Net Profit", "$" + algorithm.Portfolio.TotalProfit.ToString("N2"));
                                banner.Add("Return", netReturn.ToString("P"));
                                banner.Add("Equity", "$" + algorithm.Portfolio.TotalPortfolioValue.ToString("N2"));
                            }
                        }
                        catch (Exception err)
                        {
                            Log.Error(err, "Error generating statistics packet");
                        }

                        //Diagnostics Completed, Send Result Packet:
                        var totalSeconds = (DateTime.Now - startTime).TotalSeconds;
                        var dataPoints   = algorithmManager.DataPoints + algorithm.HistoryProvider.DataPointCount;

                        if (!_liveMode)
                        {
                            var kps = dataPoints / (double)1000 / totalSeconds;
                            _algorithmHandlers.Results.DebugMessage($"Algorithm Id:({job.AlgorithmId}) completed in {totalSeconds:F2} seconds at {kps:F0}k data points per second. Processing total of {dataPoints:N0} data points.");
                        }

                        _algorithmHandlers.Results.SendFinalResult(job, orders, algorithm.Transactions.TransactionRecord, holdings, algorithm.Portfolio.CashBook, statisticsResults, banner);
                    }
                    catch (Exception err)
                    {
                        Log.Error(err, "Error sending analysis results");
                    }

                    //Before we return, send terminate commands to close up the threads
                    _algorithmHandlers.Transactions.Exit();
                    _algorithmHandlers.DataFeed.Exit();
                    _algorithmHandlers.RealTime.Exit();
                    _algorithmHandlers.Alphas.Exit();
                    dataManager?.RemoveAllSubscriptions();
                    workerThread?.Dispose();
                }

                //Close result handler:
                _algorithmHandlers.Results.Exit();

                //Wait for the threads to complete:
                var millisecondInterval  = 10;
                var millisecondTotalWait = 0;
                while ((_algorithmHandlers.Results.IsActive ||
                        (_algorithmHandlers.Transactions != null && _algorithmHandlers.Transactions.IsActive) ||
                        (_algorithmHandlers.DataFeed != null && _algorithmHandlers.DataFeed.IsActive) ||
                        (_algorithmHandlers.RealTime != null && _algorithmHandlers.RealTime.IsActive) ||
                        (_algorithmHandlers.Alphas != null && _algorithmHandlers.Alphas.IsActive)) &&
                       millisecondTotalWait < 30 * 1000)
                {
                    Thread.Sleep(millisecondInterval);
                    if (millisecondTotalWait % (millisecondInterval * 10) == 0)
                    {
                        Log.Trace("Waiting for threads to exit...");
                    }
                    millisecondTotalWait += millisecondInterval;
                }

                //Terminate threads still in active state.
                if (threadResults != null && threadResults.IsAlive)
                {
                    threadResults.Abort();
                }
                if (threadAlphas != null && threadAlphas.IsAlive)
                {
                    threadAlphas.Abort();
                }

                if (brokerage != null)
                {
                    Log.Trace("Engine.Run(): Disconnecting from brokerage...");
                    brokerage.Disconnect();
                    brokerage.Dispose();
                }
                if (_algorithmHandlers.Setup != null)
                {
                    Log.Trace("Engine.Run(): Disposing of setup handler...");
                    _algorithmHandlers.Setup.Dispose();
                }
                Log.Trace("Engine.Main(): Analysis Completed and Results Posted.");
            }
            catch (Exception err)
            {
                Log.Error(err, "Error running algorithm");
            }
            finally
            {
                //No matter what for live mode; make sure we've set algorithm status in the API for "not running" conditions:
                if (_liveMode && algorithmManager.State != AlgorithmStatus.Running && algorithmManager.State != AlgorithmStatus.RuntimeError)
                {
                    _systemHandlers.Api.SetAlgorithmStatus(job.AlgorithmId, algorithmManager.State);
                }

                _algorithmHandlers.Results.Exit();
                _algorithmHandlers.DataFeed.Exit();
                _algorithmHandlers.Transactions.Exit();
                _algorithmHandlers.RealTime.Exit();
            }
        }
Пример #41
0
 /// <summary>
 ///
 /// </summary>
 public override void Start()
 {
     WorkerThread.Start();
     Paused = false;
 }
Пример #42
0
        public ThreadPool(Instance instance, string prefix, int timeout)
        {
            Ice.Properties properties = instance.initializationData().properties;

            _instance = instance;
            _dispatcher = instance.initializationData().dispatcher;
            _destroyed = false;
            _prefix = prefix;
            _threadIndex = 0;
            _inUse = 0;
            _serialize = properties.getPropertyAsInt(_prefix + ".Serialize") > 0;
            _serverIdleTime = timeout;

            string programName = properties.getProperty("Ice.ProgramName");
            if(programName.Length > 0)
            {
                _threadPrefix = programName + "-" + _prefix;
            }
            else
            {
                _threadPrefix = _prefix;
            }

            //
            // We use just one thread as the default. This is the fastest
            // possible setting, still allows one level of nesting, and
            // doesn't require to make the servants thread safe.
            //
            int size = properties.getPropertyAsIntWithDefault(_prefix + ".Size", 1);
            if(size < 1)
            {
                string s = _prefix + ".Size < 1; Size adjusted to 1";
                _instance.initializationData().logger.warning(s);
                size = 1;
            }

            int sizeMax = properties.getPropertyAsIntWithDefault(_prefix + ".SizeMax", size);
            if(sizeMax < size)
            {
                string s = _prefix + ".SizeMax < " + _prefix + ".Size; SizeMax adjusted to Size (" + size + ")";
                _instance.initializationData().logger.warning(s);
                sizeMax = size;
            }

            int sizeWarn = properties.getPropertyAsInt(_prefix + ".SizeWarn");
            if(sizeWarn != 0 && sizeWarn < size)
            {
                string s = _prefix + ".SizeWarn < " + _prefix + ".Size; adjusted SizeWarn to Size (" + size + ")";
                _instance.initializationData().logger.warning(s);
                sizeWarn = size;
            }
            else if(sizeWarn > sizeMax)
            {
                string s = _prefix + ".SizeWarn > " + _prefix + ".SizeMax; adjusted SizeWarn to SizeMax ("
                    + sizeMax + ")";
                _instance.initializationData().logger.warning(s);
                sizeWarn = sizeMax;
            }

            int threadIdleTime = properties.getPropertyAsIntWithDefault(_prefix + ".ThreadIdleTime", 60);
            if(threadIdleTime < 0)
            {
                string s = _prefix + ".ThreadIdleTime < 0; ThreadIdleTime adjusted to 0";
                _instance.initializationData().logger.warning(s);
                threadIdleTime = 0;
            }

            _size = size;
            _sizeMax = sizeMax;
            _sizeWarn = sizeWarn;
            _threadIdleTime = threadIdleTime;

            int stackSize = properties.getPropertyAsInt(_prefix + ".StackSize");
            if(stackSize < 0)
            {
                string s = _prefix + ".StackSize < 0; Size adjusted to OS default";
                _instance.initializationData().logger.warning(s);
                stackSize = 0;
            }
            _stackSize = stackSize;
            _hasPriority = properties.getProperty(_prefix + ".ThreadPriority").Length > 0;
            _priority = IceInternal.Util.stringToThreadPriority(properties.getProperty(_prefix + ".ThreadPriority"));
            if(!_hasPriority)
            {
                _hasPriority = properties.getProperty("Ice.ThreadPriority").Length > 0;
                _priority = IceInternal.Util.stringToThreadPriority(properties.getProperty("Ice.ThreadPriority"));
            }

            if(_instance.traceLevels().threadPool >= 1)
            {
                string s = "creating " + _prefix + ": Size = " + _size + ", SizeMax = " + _sizeMax + ", SizeWarn = " +
                           _sizeWarn;
                _instance.initializationData().logger.trace(_instance.traceLevels().threadPoolCat, s);
            }

            _workItems = new Queue<ThreadPoolWorkItem>();

            try
            {
                _threads = new List<WorkerThread>();
                for(int i = 0; i < _size; ++i)
                {
                    WorkerThread thread = new WorkerThread(this, _threadPrefix + "-" + _threadIndex++);
                    if(_hasPriority)
                    {
                        thread.start(_priority);
                    }
                    else
                    {
                        thread.start(ThreadPriority.Normal);
                    }
                    _threads.Add(thread);
                }
            }
            catch(System.Exception ex)
            {
                string s = "cannot create thread for `" + _prefix + "':\n" + ex;
                _instance.initializationData().logger.error(s);

                destroy();
                joinWithAllThreads();
                throw;
            }
        }
Пример #43
0
        /// <summary>
        /// Runs a single backtest/live job from the job queue
        /// </summary>
        /// <param name="job">The algorithm job to be processed</param>
        /// <param name="manager">The algorithm manager instance</param>
        /// <param name="assemblyPath">The path to the algorithm's assembly</param>
        /// <param name="workerThread">The worker thread instance</param>
        public void Run(AlgorithmNodePacket job, AlgorithmManager manager, string assemblyPath, WorkerThread workerThread)
        {
            var marketHoursDatabaseTask = Task.Run(() => StaticInitializations());

            var algorithm        = default(IAlgorithm);
            var algorithmManager = manager;

            try
            {
                TextSubscriptionDataSourceReader.SetCacheSize((int)(job.RamAllocation * 0.4));

                //Reset thread holders.
                var initializeComplete = false;

                //-> Initialize messaging system
                SystemHandlers.Notify.SetAuthentication(job);

                //-> Set the result handler type for this algorithm job, and launch the associated result thread.
                AlgorithmHandlers.Results.Initialize(job, SystemHandlers.Notify, SystemHandlers.Api, AlgorithmHandlers.Transactions);

                IBrokerage         brokerage   = null;
                DataManager        dataManager = null;
                IDataCacheProvider historyDataCacheProvider = null;
                var synchronizer = _liveMode ? new LiveSynchronizer() : new Synchronizer();
                try
                {
                    // we get the mhdb before creating the algorithm instance,
                    // since the algorithm constructor will use it
                    var marketHoursDatabase = marketHoursDatabaseTask.Result;

                    AlgorithmHandlers.Setup.WorkerThread = workerThread;

                    // Save algorithm to cache, load algorithm instance:
                    algorithm = AlgorithmHandlers.Setup.CreateAlgorithmInstance(job, assemblyPath);

                    // Set algorithm in ILeanManager
                    SystemHandlers.LeanManager.SetAlgorithm(algorithm);

                    // initialize the alphas handler with the algorithm instance
                    AlgorithmHandlers.Alphas.Initialize(job, algorithm, SystemHandlers.Notify, SystemHandlers.Api, AlgorithmHandlers.Transactions);

                    // initialize the object store
                    AlgorithmHandlers.ObjectStore.Initialize(algorithm.Name, job.UserId, job.ProjectId, job.UserToken, job.Controls);

                    // initialize the data permission manager
                    AlgorithmHandlers.DataPermissionsManager.Initialize(job);

                    // notify the user of any errors w/ object store persistence
                    AlgorithmHandlers.ObjectStore.ErrorRaised += (sender, args) => algorithm.Debug($"ObjectStore Persistence Error: {args.Error.Message}");


                    // Initialize the brokerage
                    IBrokerageFactory factory;
                    brokerage = AlgorithmHandlers.Setup.CreateBrokerage(job, algorithm, out factory);

                    // forward brokerage message events to the result handler
                    brokerage.Message += (_, e) => AlgorithmHandlers.Results.BrokerageMessage(e);

                    var symbolPropertiesDatabase       = SymbolPropertiesDatabase.FromDataFolder();
                    var mapFilePrimaryExchangeProvider = new MapFilePrimaryExchangeProvider(AlgorithmHandlers.MapFileProvider);
                    var registeredTypesProvider        = new RegisteredSecurityDataTypesProvider();
                    var securityService = new SecurityService(algorithm.Portfolio.CashBook,
                                                              marketHoursDatabase,
                                                              symbolPropertiesDatabase,
                                                              algorithm,
                                                              registeredTypesProvider,
                                                              new SecurityCacheProvider(algorithm.Portfolio),
                                                              mapFilePrimaryExchangeProvider);

                    algorithm.Securities.SetSecurityService(securityService);

                    dataManager = new DataManager(AlgorithmHandlers.DataFeed,
                                                  new UniverseSelection(
                                                      algorithm,
                                                      securityService,
                                                      AlgorithmHandlers.DataPermissionsManager,
                                                      AlgorithmHandlers.DataProvider),
                                                  algorithm,
                                                  algorithm.TimeKeeper,
                                                  marketHoursDatabase,
                                                  _liveMode,
                                                  registeredTypesProvider,
                                                  AlgorithmHandlers.DataPermissionsManager);

                    algorithm.SubscriptionManager.SetDataManager(dataManager);

                    synchronizer.Initialize(algorithm, dataManager);

                    // Initialize the data feed before we initialize so he can intercept added securities/universes via events
                    AlgorithmHandlers.DataFeed.Initialize(
                        algorithm,
                        job,
                        AlgorithmHandlers.Results,
                        AlgorithmHandlers.MapFileProvider,
                        AlgorithmHandlers.FactorFileProvider,
                        AlgorithmHandlers.DataProvider,
                        dataManager,
                        (IDataFeedTimeProvider)synchronizer,
                        AlgorithmHandlers.DataPermissionsManager.DataChannelProvider);

                    // set the order processor on the transaction manager (needs to be done before initializing BrokerageHistoryProvider)
                    algorithm.Transactions.SetOrderProcessor(AlgorithmHandlers.Transactions);

                    // set the history provider before setting up the algorithm
                    var historyProvider = GetHistoryProvider();
                    historyProvider.SetBrokerage(brokerage);
                    historyDataCacheProvider = new ZipDataCacheProvider(AlgorithmHandlers.DataProvider, isDataEphemeral: _liveMode);
                    historyProvider.Initialize(
                        new HistoryProviderInitializeParameters(
                            job,
                            SystemHandlers.Api,
                            AlgorithmHandlers.DataProvider,
                            historyDataCacheProvider,
                            AlgorithmHandlers.MapFileProvider,
                            AlgorithmHandlers.FactorFileProvider,
                            progress =>
                    {
                        // send progress updates to the result handler only during initialization
                        if (!algorithm.GetLocked() || algorithm.IsWarmingUp)
                        {
                            AlgorithmHandlers.Results.SendStatusUpdate(AlgorithmStatus.History,
                                                                       Invariant($"Processing history {progress}%..."));
                        }
                    },
                            // disable parallel history requests for live trading
                            parallelHistoryRequestsEnabled: !_liveMode,
                            dataPermissionManager: AlgorithmHandlers.DataPermissionsManager
                            )
                        );

                    historyProvider.InvalidConfigurationDetected += (sender, args) => { AlgorithmHandlers.Results.ErrorMessage(args.Message); };
                    historyProvider.DownloadFailed      += (sender, args) => { AlgorithmHandlers.Results.ErrorMessage(args.Message, args.StackTrace); };
                    historyProvider.ReaderErrorDetected += (sender, args) => { AlgorithmHandlers.Results.RuntimeError(args.Message, args.StackTrace); };

                    algorithm.HistoryProvider = historyProvider;

                    // initialize the default brokerage message handler
                    algorithm.BrokerageMessageHandler = factory.CreateBrokerageMessageHandler(algorithm, job, SystemHandlers.Api);

                    //Initialize the internal state of algorithm and job: executes the algorithm.Initialize() method.
                    initializeComplete = AlgorithmHandlers.Setup.Setup(new SetupHandlerParameters(dataManager.UniverseSelection, algorithm, brokerage, job, AlgorithmHandlers.Results,
                                                                                                  AlgorithmHandlers.Transactions, AlgorithmHandlers.RealTime, AlgorithmHandlers.ObjectStore, AlgorithmHandlers.DataProvider));

                    // set this again now that we've actually added securities
                    AlgorithmHandlers.Results.SetAlgorithm(algorithm, AlgorithmHandlers.Setup.StartingPortfolioValue);

                    // alpha handler needs start/end dates to determine sample step sizes
                    AlgorithmHandlers.Alphas.OnAfterAlgorithmInitialized(algorithm);

                    //If there are any reasons it failed, pass these back to the IDE.
                    if (!initializeComplete || algorithm.ErrorMessages.Count > 0 || AlgorithmHandlers.Setup.Errors.Count > 0)
                    {
                        initializeComplete = false;
                        //Get all the error messages: internal in algorithm and external in setup handler.
                        var errorMessage = string.Join(",", algorithm.ErrorMessages);
                        errorMessage += string.Join(",", AlgorithmHandlers.Setup.Errors.Select(e =>
                        {
                            var message = e.Message;
                            if (e.InnerException != null)
                            {
                                var interpreter = StackExceptionInterpreter.Instance.Value;
                                var err         = interpreter.Interpret(e.InnerException);
                                message        += interpreter.GetExceptionMessageHeader(err);
                            }
                            return(message);
                        }));
                        Log.Error("Engine.Run(): " + errorMessage);
                        AlgorithmHandlers.Results.RuntimeError(errorMessage);
                        SystemHandlers.Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, errorMessage);
                    }
                }
                catch (Exception err)
                {
                    Log.Error(err);

                    // for python we don't add the ugly pythonNet stack trace
                    var stackTrace = job.Language == Language.Python ? err.Message : err.ToString();

                    var runtimeMessage = "Algorithm.Initialize() Error: " + err.Message + " Stack Trace: " + stackTrace;
                    AlgorithmHandlers.Results.RuntimeError(runtimeMessage, stackTrace);
                    SystemHandlers.Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, runtimeMessage);
                }


                // log the job endpoints
                Log.Trace("JOB HANDLERS: ");
                Log.Trace("         DataFeed:     " + AlgorithmHandlers.DataFeed.GetType().FullName);
                Log.Trace("         Setup:        " + AlgorithmHandlers.Setup.GetType().FullName);
                Log.Trace("         RealTime:     " + AlgorithmHandlers.RealTime.GetType().FullName);
                Log.Trace("         Results:      " + AlgorithmHandlers.Results.GetType().FullName);
                Log.Trace("         Transactions: " + AlgorithmHandlers.Transactions.GetType().FullName);
                Log.Trace("         Alpha:        " + AlgorithmHandlers.Alphas.GetType().FullName);
                Log.Trace("         ObjectStore:  " + AlgorithmHandlers.ObjectStore.GetType().FullName);
                if (algorithm?.HistoryProvider != null)
                {
                    Log.Trace("         History Provider:     " + algorithm.HistoryProvider.GetType().FullName);
                }
                if (job is LiveNodePacket)
                {
                    Log.Trace("         Brokerage:      " + brokerage?.GetType().FullName);
                }

                //-> Using the job + initialization: load the designated handlers:
                if (initializeComplete)
                {
                    // notify the LEAN manager that the algorithm is initialized and starting
                    SystemHandlers.LeanManager.OnAlgorithmStart();

                    //-> Reset the backtest stopwatch; we're now running the algorithm.
                    var startTime = DateTime.UtcNow;

                    //Set algorithm as locked; set it to live mode if we're trading live, and set it to locked for no further updates.
                    algorithm.SetAlgorithmId(job.AlgorithmId);
                    algorithm.SetLocked();

                    //Load the associated handlers for transaction and realtime events:
                    AlgorithmHandlers.Transactions.Initialize(algorithm, brokerage, AlgorithmHandlers.Results);
                    AlgorithmHandlers.RealTime.Setup(algorithm, job, AlgorithmHandlers.Results, SystemHandlers.Api, algorithmManager.TimeLimit);

                    // wire up the brokerage message handler
                    brokerage.Message += (sender, message) =>
                    {
                        algorithm.BrokerageMessageHandler.Handle(message);

                        // fire brokerage message events
                        algorithm.OnBrokerageMessage(message);
                        switch (message.Type)
                        {
                        case BrokerageMessageType.Disconnect:
                            algorithm.OnBrokerageDisconnect();
                            break;

                        case BrokerageMessageType.Reconnect:
                            algorithm.OnBrokerageReconnect();
                            break;
                        }
                    };

                    //Send status to user the algorithm is now executing.
                    AlgorithmHandlers.Results.SendStatusUpdate(AlgorithmStatus.Running);

                    // Result manager scanning message queue: (started earlier)
                    AlgorithmHandlers.Results.DebugMessage(
                        $"Launching analysis for {job.AlgorithmId} with LEAN Engine v{Globals.Version}");

                    try
                    {
                        //Create a new engine isolator class
                        var isolator = new Isolator();

                        // Execute the Algorithm Code:
                        var complete = isolator.ExecuteWithTimeLimit(AlgorithmHandlers.Setup.MaximumRuntime, algorithmManager.TimeLimit.IsWithinLimit, () =>
                        {
                            try
                            {
                                //Run Algorithm Job:
                                // -> Using this Data Feed,
                                // -> Send Orders to this TransactionHandler,
                                // -> Send Results to ResultHandler.
                                algorithmManager.Run(job, algorithm, synchronizer, AlgorithmHandlers.Transactions, AlgorithmHandlers.Results, AlgorithmHandlers.RealTime, SystemHandlers.LeanManager, AlgorithmHandlers.Alphas, isolator.CancellationToken);
                            }
                            catch (Exception err)
                            {
                                algorithm.SetRuntimeError(err, "AlgorithmManager.Run");
                                return;
                            }

                            Log.Trace("Engine.Run(): Exiting Algorithm Manager");
                        }, job.Controls.RamAllocation, workerThread: workerThread);

                        if (!complete)
                        {
                            Log.Error("Engine.Main(): Failed to complete in time: " + AlgorithmHandlers.Setup.MaximumRuntime.ToStringInvariant("F"));
                            throw new Exception("Failed to complete algorithm within " + AlgorithmHandlers.Setup.MaximumRuntime.ToStringInvariant("F")
                                                + " seconds. Please make it run faster.");
                        }
                    }
                    catch (Exception err)
                    {
                        //Error running the user algorithm: purge datafeed, send error messages, set algorithm status to failed.
                        algorithm.SetRuntimeError(err, "Engine Isolator");
                    }

                    // Algorithm runtime error:
                    if (algorithm.RunTimeError != null)
                    {
                        HandleAlgorithmError(job, algorithm.RunTimeError);
                    }

                    // notify the LEAN manager that the algorithm has finished
                    SystemHandlers.LeanManager.OnAlgorithmEnd();

                    try
                    {
                        var csvTransactionsFileName = Config.Get("transaction-log");
                        if (!string.IsNullOrEmpty(csvTransactionsFileName))
                        {
                            SaveListOfTrades(AlgorithmHandlers.Transactions, csvTransactionsFileName);
                        }

                        if (!_liveMode)
                        {
                            //Diagnostics Completed, Send Result Packet:
                            var totalSeconds = (DateTime.UtcNow - startTime).TotalSeconds;
                            var dataPoints   = algorithmManager.DataPoints + algorithm.HistoryProvider.DataPointCount;
                            var kps          = dataPoints / (double)1000 / totalSeconds;
                            AlgorithmHandlers.Results.DebugMessage($"Algorithm Id:({job.AlgorithmId}) completed in {totalSeconds:F2} seconds at {kps:F0}k data points per second. Processing total of {dataPoints:N0} data points.");
                        }
                    }
                    catch (Exception err)
                    {
                        Log.Error(err, "Error sending analysis results");
                    }

                    //Before we return, send terminate commands to close up the threads
                    AlgorithmHandlers.Transactions.Exit();
                    AlgorithmHandlers.RealTime.Exit();
                    dataManager?.RemoveAllSubscriptions();
                    workerThread?.Dispose();
                }

                synchronizer.DisposeSafely();
                // Close data feed, alphas. Could be running even if algorithm initialization failed
                AlgorithmHandlers.DataFeed.Exit();
                AlgorithmHandlers.Alphas.Exit();

                //Close result handler:
                AlgorithmHandlers.Results.Exit();

                //Wait for the threads to complete:
                var millisecondInterval  = 10;
                var millisecondTotalWait = 0;
                while ((AlgorithmHandlers.Results.IsActive ||
                        (AlgorithmHandlers.Transactions != null && AlgorithmHandlers.Transactions.IsActive) ||
                        (AlgorithmHandlers.DataFeed != null && AlgorithmHandlers.DataFeed.IsActive) ||
                        (AlgorithmHandlers.RealTime != null && AlgorithmHandlers.RealTime.IsActive) ||
                        (AlgorithmHandlers.Alphas != null && AlgorithmHandlers.Alphas.IsActive)) &&
                       millisecondTotalWait < 30 * 1000)
                {
                    Thread.Sleep(millisecondInterval);
                    if (millisecondTotalWait % (millisecondInterval * 10) == 0)
                    {
                        Log.Trace("Waiting for threads to exit...");
                    }
                    millisecondTotalWait += millisecondInterval;
                }

                if (brokerage != null)
                {
                    Log.Trace("Engine.Run(): Disconnecting from brokerage...");
                    brokerage.Disconnect();
                    brokerage.Dispose();
                }
                if (AlgorithmHandlers.Setup != null)
                {
                    Log.Trace("Engine.Run(): Disposing of setup handler...");
                    AlgorithmHandlers.Setup.Dispose();
                }

                historyDataCacheProvider.DisposeSafely();
                Log.Trace("Engine.Main(): Analysis Completed and Results Posted.");
            }
            catch (Exception err)
            {
                Log.Error(err, "Error running algorithm");
            }
            finally
            {
                //No matter what for live mode; make sure we've set algorithm status in the API for "not running" conditions:
                if (_liveMode && algorithmManager.State != AlgorithmStatus.Running && algorithmManager.State != AlgorithmStatus.RuntimeError)
                {
                    SystemHandlers.Api.SetAlgorithmStatus(job.AlgorithmId, algorithmManager.State);
                }

                AlgorithmHandlers.Results.Exit();
                AlgorithmHandlers.DataFeed.Exit();
                AlgorithmHandlers.Transactions.Exit();
                AlgorithmHandlers.RealTime.Exit();
            }
        }
Пример #44
0
        private void run(WorkerThread thread)
        {
            ThreadPoolWorkItem workItem = null;
            while(true)
            {
                lock(this)
                {
                    if(workItem != null)
                    {
                        Debug.Assert(_inUse > 0);
                        --_inUse;
                        if(_workItems.Count == 0)
                        {
                            thread.setState(Ice.Instrumentation.ThreadState.ThreadStateIdle);
                        }
                    }

                    workItem = null;

                    while(_workItems.Count == 0)
                    {
                        if(_destroyed)
                        {
                            return;
                        }

                        if(_threadIdleTime > 0)
                        {
                            if(!System.Threading.Monitor.Wait(this, _threadIdleTime * 1000) && _workItems.Count == 0) // If timeout
                            {
                                if(_destroyed)
                                {
                                    return;
                                }
                                else if(_serverIdleTime == 0 || _threads.Count > 1)
                                {
                                    //
                                    // If not the last thread or if server idle time isn't configured,
                                    // we can exit. Unlike C++/Java, there's no need to have a thread
                                    // always spawned in the thread pool because all the IO is done
                                    // by the .NET thread pool threads. Instead, we'll just spawn a
                                    // new thread when needed (i.e.: when a new work item is queued).
                                    //
                                    if(_instance.traceLevels().threadPool >= 1)
                                    {
                                        string s = "shrinking " + _prefix + ": Size=" + (_threads.Count - 1);
                                        _instance.initializationData().logger.trace(
                                            _instance.traceLevels().threadPoolCat, s);
                                    }

                                    _threads.Remove(thread);
                                    _instance.asyncIOThread().queue(() =>
                                        {
                                            thread.join();
                                        });
                                    return;
                                }
                                else
                                {
                                    Debug.Assert(_serverIdleTime > 0 && _inUse == 0 && _threads.Count == 1);
                                    if(!System.Threading.Monitor.Wait(this, _serverIdleTime * 1000)  &&
                                       _workItems.Count == 0)
                                    {
                                        if(!_destroyed)
                                        {
                                            _workItems.Enqueue(() =>
                                               {
                                                   try
                                                   {
                                                       _instance.objectAdapterFactory().shutdown();
                                                   }
                                                   catch(Ice.CommunicatorDestroyedException)
                                                   {
                                                   }
                                               });
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            System.Threading.Monitor.Wait(this);
                        }
                    }

                    Debug.Assert(_workItems.Count > 0);
                    workItem = _workItems.Dequeue();

                    Debug.Assert(_inUse >= 0);
                    ++_inUse;

                    thread.setState(Ice.Instrumentation.ThreadState.ThreadStateInUseForUser);

                    if(_sizeMax > 1 && _inUse == _sizeWarn)
                    {
                        string s = "thread pool `" + _prefix + "' is running low on threads\n"
                            + "Size=" + _size + ", " + "SizeMax=" + _sizeMax + ", " + "SizeWarn=" + _sizeWarn;
                        _instance.initializationData().logger.warning(s);
                    }
                }

                try
                {
                    workItem();
                }
                catch(System.Exception ex)
                {
                    string s = "exception in `" + _prefix + "' while calling on work item:\n" + ex + '\n';
                    _instance.initializationData().logger.error(s);
                }
            }
        }
Пример #45
0
 internal void CreateWorkThread()
 {
     fWorkerThread = new WorkerThread(true);
 }
Пример #46
0
        void MonitoredSystem_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (!DataModel.Instance.IsPowerwall)
            {
                StackTrace stackTrace = new StackTrace();
                if (!stackTrace.ToString().Contains("DataModel"))
                {
                    DateTime updateTime = DateTime.Now;

                    switch (e.PropertyName)
                    {
                    case "State":
                        this.LastUpdate = updateTime;
                        WorkerThread workerThreadState = ThreadManager.CreateWorkerThread("BackSync_MonitoredSystem.State", () =>
                        {
                            List <Tuple <string, DateTime> > paramList = new List <Tuple <string, DateTime> >();
                            paramList.Add(new Tuple <string, DateTime>(this.MAC, updateTime));

                            bool result;
                            if (this.State == MappingState.Maintenance)
                            {
                                result = DataModel.Instance.SyncBackMonitoredSystemMaintenanceActivated(paramList);
                            }
                            else
                            {
                                result = DataModel.Instance.SyncBackMonitoredSystemMaintenanceDeactivated(paramList);
                            }
                        }, false);
                        break;

                    case "ResetDate":
                        this.LastUpdate = updateTime;
                        WorkerThread workerThreadResetDate = ThreadManager.CreateWorkerThread("BackSync_MonitoredSystem.ResetDate", () =>
                        {
                            List <Tuple <string, DateTime> > paramList = new List <Tuple <string, DateTime> >();
                            paramList.Add(new Tuple <string, DateTime>(this.MAC, updateTime));

                            bool result = DataModel.Instance.SyncBackMonitoredSystemResetDateUpdated(paramList);
                        }, false);
                        break;

                    case "OuID":
                        this.LastUpdate = updateTime;
                        WorkerThread workerThreadOuID = ThreadManager.CreateWorkerThread("BackSync_MonitoredSystem.OuID", () =>
                        {
                            List <Tuple <string, int, DateTime> > paramList = new List <Tuple <string, int, DateTime> >();
                            paramList.Add(new Tuple <string, int, DateTime>(this.MAC, this.OuID, updateTime));

                            bool result = DataModel.Instance.SyncBackMonitoredSystemMoved(paramList);
                        }, false);
                        break;

                    case "LastUpdate":
                        /* Do nothing */
                        break;

                    case "Name":
                        this.LastUpdate = updateTime;

                        Console.WriteLine(">>> NAME CHANGED");

                        WorkerThread workerThreadName = ThreadManager.CreateWorkerThread("BackSync_MonitoredSystem.Name", () =>
                        {
                            List <Tuple <string, string, DateTime> > paramList = new List <Tuple <string, string, DateTime> >();
                            paramList.Add(new Tuple <string, string, DateTime>(this.MAC, this.Name, updateTime));

                            bool result = DataModel.Instance.SyncBackMonitoredSystemName(paramList);
                        }, false);
                        break;

                    default:
                        break;
                    }
                }
                stackTrace = null;
            }
        }
Пример #47
0
        private WorkerThread AddWorkerThread()
        {
            lock (workerThreads)
            {
                var result = new WorkerThread(Process);
                workerThreads.Add(result);
                result.Stopped += delegate(object sender, EventArgs e)
                {
                    var wt = sender as WorkerThread;
                    lock (workerThreads)
                        workerThreads.Remove(wt);
                };

                return result;
            }
        }
Пример #48
0
        /// <summary>
        /// Initialize the debugger
        /// </summary>
        /// <param name="algorithmNodePacket">The algorithm node packet</param>
        /// <param name="workerThread">The worker thread instance to use</param>
        public static bool InitializeDebugging(AlgorithmNodePacket algorithmNodePacket, WorkerThread workerThread)
        {
            var isolator = new Isolator();

            return(isolator.ExecuteWithTimeLimit(TimeSpan.FromMinutes(5),
                                                 () => DebuggerHelper.Initialize(algorithmNodePacket.Language),
                                                 algorithmNodePacket.RamAllocation,
                                                 sleepIntervalMillis: 100,
                                                 workerThread: workerThread));
        }
Пример #49
0
 protected void MakeAvailable(WorkerThread wt)
 {
     lock (nextRunnableLock)
     {
         if (!isShutdown)
         {
             availWorkers.Add(wt);
         }
         busyWorkers.Remove(wt);
         Monitor.PulseAll(nextRunnableLock);
     }
 }
Пример #50
0
        public ThreadPool(Instance instance, string prefix, int timeout)
        {
            Ice.Properties properties = instance.initializationData().properties;

            _instance       = instance;
            _dispatcher     = instance.initializationData().dispatcher;
            _destroyed      = false;
            _prefix         = prefix;
            _threadIndex    = 0;
            _inUse          = 0;
            _serialize      = properties.getPropertyAsInt(_prefix + ".Serialize") > 0;
            _serverIdleTime = timeout;

            string programName = properties.getProperty("Ice.ProgramName");

            if (programName.Length > 0)
            {
                _threadPrefix = programName + "-" + _prefix;
            }
            else
            {
                _threadPrefix = _prefix;
            }

            //
            // We use just one thread as the default. This is the fastest
            // possible setting, still allows one level of nesting, and
            // doesn't require to make the servants thread safe.
            //
            int size = properties.getPropertyAsIntWithDefault(_prefix + ".Size", 1);

            if (size < 1)
            {
                string s = _prefix + ".Size < 1; Size adjusted to 1";
                _instance.initializationData().logger.warning(s);
                size = 1;
            }

            int sizeMax = properties.getPropertyAsIntWithDefault(_prefix + ".SizeMax", size);

            if (sizeMax < size)
            {
                string s = _prefix + ".SizeMax < " + _prefix + ".Size; SizeMax adjusted to Size (" + size + ")";
                _instance.initializationData().logger.warning(s);
                sizeMax = size;
            }

            int sizeWarn = properties.getPropertyAsInt(_prefix + ".SizeWarn");

            if (sizeWarn != 0 && sizeWarn < size)
            {
                string s = _prefix + ".SizeWarn < " + _prefix + ".Size; adjusted SizeWarn to Size (" + size + ")";
                _instance.initializationData().logger.warning(s);
                sizeWarn = size;
            }
            else if (sizeWarn > sizeMax)
            {
                string s = _prefix + ".SizeWarn > " + _prefix + ".SizeMax; adjusted SizeWarn to SizeMax ("
                           + sizeMax + ")";
                _instance.initializationData().logger.warning(s);
                sizeWarn = sizeMax;
            }

            int threadIdleTime = properties.getPropertyAsIntWithDefault(_prefix + ".ThreadIdleTime", 60);

            if (threadIdleTime < 0)
            {
                string s = _prefix + ".ThreadIdleTime < 0; ThreadIdleTime adjusted to 0";
                _instance.initializationData().logger.warning(s);
                threadIdleTime = 0;
            }

            _size           = size;
            _sizeMax        = sizeMax;
            _sizeWarn       = sizeWarn;
            _threadIdleTime = threadIdleTime;

            int stackSize = properties.getPropertyAsInt(_prefix + ".StackSize");

            if (stackSize < 0)
            {
                string s = _prefix + ".StackSize < 0; Size adjusted to OS default";
                _instance.initializationData().logger.warning(s);
                stackSize = 0;
            }
            _stackSize = stackSize;

            _priority = properties.getProperty(_prefix + ".ThreadPriority").Length > 0 ?
                        Util.stringToThreadPriority(properties.getProperty(_prefix + ".ThreadPriority")) :
                        Util.stringToThreadPriority(properties.getProperty("Ice.ThreadPriority"));

            if (_instance.traceLevels().threadPool >= 1)
            {
                string s = "creating " + _prefix + ": Size = " + _size + ", SizeMax = " + _sizeMax + ", SizeWarn = " +
                           _sizeWarn;
                _instance.initializationData().logger.trace(_instance.traceLevels().threadPoolCat, s);
            }

            _workItems = new Queue <ThreadPoolWorkItem>();

            try
            {
                _threads = new List <WorkerThread>();
                for (int i = 0; i < _size; ++i)
                {
                    WorkerThread thread = new WorkerThread(this, _threadPrefix + "-" + _threadIndex++);
                    thread.start(_priority);
                    _threads.Add(thread);
                }
            }
            catch (System.Exception ex)
            {
                string s = "cannot create thread for `" + _prefix + "':\n" + ex;
                _instance.initializationData().logger.error(s);

                destroy();
                joinWithAllThreads();
                throw;
            }
        }
Пример #51
0
 protected virtual void ClearFromBusyWorkersList(WorkerThread wt) 
 {
     lock(nextRunnableLock) 
     {
         busyWorkers.Remove(wt);
         Monitor.PulseAll(nextRunnableLock);
     }
 }
Пример #52
0
        private void run(WorkerThread thread)
        {
            ThreadPoolWorkItem workItem = null;

            while (true)
            {
                lock (this)
                {
                    if (workItem != null)
                    {
                        Debug.Assert(_inUse > 0);
                        --_inUse;
                        if (_workItems.Count == 0)
                        {
                            thread.setState(Ice.Instrumentation.ThreadState.ThreadStateIdle);
                        }
                    }

                    workItem = null;

                    while (_workItems.Count == 0)
                    {
                        if (_destroyed)
                        {
                            return;
                        }

                        if (_threadIdleTime > 0)
                        {
                            if (!Monitor.Wait(this, _threadIdleTime * 1000) && _workItems.Count == 0) // If timeout
                            {
                                if (_destroyed)
                                {
                                    return;
                                }
                                else if (_serverIdleTime == 0 || _threads.Count > 1)
                                {
                                    //
                                    // If not the last thread or if server idle time isn't configured,
                                    // we can exit. Unlike C++/Java, there's no need to have a thread
                                    // always spawned in the thread pool because all the IO is done
                                    // by the .NET thread pool threads. Instead, we'll just spawn a
                                    // new thread when needed (i.e.: when a new work item is queued).
                                    //
                                    if (_instance.traceLevels().threadPool >= 1)
                                    {
                                        string s = "shrinking " + _prefix + ": Size=" + (_threads.Count - 1);
                                        _instance.initializationData().logger.trace(
                                            _instance.traceLevels().threadPoolCat, s);
                                    }

                                    _threads.Remove(thread);
                                    _instance.asyncIOThread().queue(() =>
                                    {
                                        thread.join();
                                    });
                                    return;
                                }
                                else
                                {
                                    Debug.Assert(_serverIdleTime > 0 && _inUse == 0 && _threads.Count == 1);
                                    if (!Monitor.Wait(this, _serverIdleTime * 1000) &&
                                        _workItems.Count == 0)
                                    {
                                        if (!_destroyed)
                                        {
                                            _workItems.Enqueue(() =>
                                            {
                                                try
                                                {
                                                    _instance.objectAdapterFactory().shutdown();
                                                }
                                                catch (Ice.CommunicatorDestroyedException)
                                                {
                                                }
                                            });
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            Monitor.Wait(this);
                        }
                    }

                    Debug.Assert(_workItems.Count > 0);
                    workItem = _workItems.Dequeue();

                    Debug.Assert(_inUse >= 0);
                    ++_inUse;

                    thread.setState(Ice.Instrumentation.ThreadState.ThreadStateInUseForUser);

                    if (_sizeMax > 1 && _inUse == _sizeWarn)
                    {
                        string s = "thread pool `" + _prefix + "' is running low on threads\n"
                                   + "Size=" + _size + ", " + "SizeMax=" + _sizeMax + ", " + "SizeWarn=" + _sizeWarn;
                        _instance.initializationData().logger.warning(s);
                    }
                }

                try
                {
                    workItem();
                }
                catch (System.Exception ex)
                {
                    string s = "exception in `" + _prefix + "' while calling on work item:\n" + ex + '\n';
                    _instance.initializationData().logger.error(s);
                }
            }
        }
Пример #53
0
			public Task TearDown (TestSuite suite)
			{
				worker.Stop ();
				worker = null;
				return Task.FromResult<object> (null);
			}
Пример #54
0
        public FrmMain()
        {
            InitializeComponent();

            worker = new WorkerThread(Done);
        }
Пример #55
0
        /// <summary>
        /// Terminate any worker threads in this thread group.
        /// Jobs currently in progress will complete.
        /// </summary>
        public virtual void Shutdown(bool waitForJobsToComplete)
        {
            // Give waiting (wait(1000)) worker threads a chance to shut down.
            // Active worker threads will shut down after finishing their
            // current job.
            lock (nextRunnableLock)
            {
                isShutdown = true;

                if (workers == null) // case where the pool wasn't even initialize()ed
                {
                    return;
                }

                // signal each worker thread to shut down
                for (int i = 0; i < workers.Count; i++)
                {
                    if (workers[i] != null)
                    {
                        workers[i].Shutdown();
                    }
                }
                Monitor.PulseAll(nextRunnableLock);


                if (waitForJobsToComplete)
                {
                    // wait for hand-off in runInThread to complete...
                    while (handoffPending)
                    {
                        try
                        {
                            Monitor.Wait(nextRunnableLock, 100);
                        }
                        catch (ThreadInterruptedException)
                        {
                        }
                    }

                    // Wait until all worker threads are shut down
                    while (busyWorkers.Count > 0)
                    {
                        LinkedListNode <WorkerThread> wt = busyWorkers.First;
                        try
                        {
                            // note: with waiting infinite time the
                            // application may appear to 'hang'.
                            Monitor.Wait(nextRunnableLock, 2000);
                        }
                        catch (ThreadInterruptedException)
                        {
                        }
                    }

                    while (workers.Count > 0)
                    {
                        int          index = workers.Count - 1;
                        WorkerThread wt    = workers[index];
                        try
                        {
                            wt.Join();
                            workers.RemoveAt(index);
                        }
                        catch (ThreadStateException)
                        {
                        }
                    }
                }
            }
        }
Пример #56
0
 /// <summary>
 /// Execute a code block with a maximum limit on time and memory.
 /// </summary>
 /// <param name="timeSpan">Timeout in timespan</param>
 /// <param name="codeBlock">Action codeblock to execute</param>
 /// <param name="memoryCap">Maximum memory allocation, default 1024Mb</param>
 /// <param name="sleepIntervalMillis">Sleep interval between each check in ms</param>
 /// <param name="workerThread">The worker thread instance that will execute the provided action, if null
 /// will use a <see cref="Task"/></param>
 /// <returns>True if algorithm exited successfully, false if cancelled because it exceeded limits.</returns>
 public bool ExecuteWithTimeLimit(TimeSpan timeSpan, Action codeBlock, long memoryCap, int sleepIntervalMillis = 1000, WorkerThread workerThread = null)
 {
     return(ExecuteWithTimeLimit(timeSpan, null, codeBlock, memoryCap, sleepIntervalMillis, workerThread));
 }
Пример #57
0
        public void dispatch(System.Action call, Ice.Connection con)
        {
            lock(this)
            {
                if(_destroyed)
                {
                    throw new Ice.CommunicatorDestroyedException();
                }

                _workItems.Enqueue(() =>
                    {
                        dispatchFromThisThread(call, con);
                    });
                System.Threading.Monitor.Pulse(this);

                //
                // If this is a dynamic thread pool which can still grow and if all threads are
                // currently busy dispatching or about to dispatch, we spawn a new thread to
                // execute this new work item right away.
                //
                if(_threads.Count < _sizeMax &&
                   (_inUse + _workItems.Count) > _threads.Count &&
                   !_destroyed)
                {
                    if(_instance.traceLevels().threadPool >= 1)
                    {
                        string s = "growing " + _prefix + ": Size = " + (_threads.Count + 1);
                        _instance.initializationData().logger.trace(_instance.traceLevels().threadPoolCat, s);
                    }

                    try
                    {
                        WorkerThread t = new WorkerThread(this, _threadPrefix + "-" + _threadIndex++);
                        if(_hasPriority)
                        {
                            t.start(_priority);
                        }
                        else
                        {
                            t.start(ThreadPriority.Normal);
                        }
                        _threads.Add(t);
                    }
                    catch(System.Exception ex)
                    {
                        string s = "cannot create thread for `" + _prefix + "':\n" + ex;
                        _instance.initializationData().logger.error(s);
                    }
                }
            }
        }
Пример #58
0
 public void SetUp()
 {
     _workerThread = new TestWorkerThread();
 }
Пример #59
0
 _workingThread = new Thread(new ThreadStart(WorkerThread));
Пример #60
0
        /// <summary>
        /// Terminate any worker threads in this thread group.
        /// Jobs currently in progress will complete.
        /// </summary>
        public virtual void Shutdown(bool waitForJobsToComplete)
        {
            // Give waiting (wait(1000)) worker threads a chance to shut down.
            // Active worker threads will shut down after finishing their
            // current job.
            lock (nextRunnableLock)
            {
                log.Debug("Shutting down threadpool...");

                isShutdown = true;

                if (workers == null) // case where the pool wasn't even initialize()ed
                {
                    return;
                }

                // signal each worker thread to shut down
                foreach (WorkerThread thread in workers)
                {
                    if (thread != null)
                    {
                        thread.Shutdown();
                    }
                }
                Monitor.PulseAll(nextRunnableLock);


                if (waitForJobsToComplete)
                {
                    // wait for hand-off in runInThread to complete...
                    while (handoffPending)
                    {
                        try
                        {
                            Monitor.Wait(nextRunnableLock, 100);
                        }
                        catch (ThreadInterruptedException)
                        {
                        }
                    }

                    // Wait until all worker threads are shut down
                    while (busyWorkers.Count > 0)
                    {
                        LinkedListNode <WorkerThread> wt = busyWorkers.First;
                        try
                        {
                            log.DebugFormat(CultureInfo.InvariantCulture, "Waiting for thread {0} to shut down", wt.Value.Name);

                            // note: with waiting infinite time the
                            // application may appear to 'hang'.
                            Monitor.Wait(nextRunnableLock, 2000);
                        }
                        catch (ThreadInterruptedException)
                        {
                        }
                    }

                    while (workers.Count > 0)
                    {
                        int          index = workers.Count - 1;
                        WorkerThread wt    = workers[index];
                        try
                        {
                            wt.Join();
                            workers.RemoveAt(index);
                        }
                        catch (ThreadStateException)
                        {
                        }
                    }

                    log.Debug("No executing jobs remaining, all threads stopped.");
                }

                log.Debug("Shutdown of threadpool complete.");
            }
        }