chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
|
||||
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using QuantConnect.Configuration;
|
||||
using QuantConnect.Lean.Engine;
|
||||
using QuantConnect.Logging;
|
||||
using QuantConnect.Packets;
|
||||
using QuantConnect.Python;
|
||||
using QuantConnect.Util;
|
||||
|
||||
namespace QuantConnect.Lean.Launcher
|
||||
{
|
||||
public class Program
|
||||
{
|
||||
private const string _collapseMessage = "Unhandled exception breaking past controls and causing collapse of algorithm node. This is likely a memory leak of an external dependency or the underlying OS terminating the LEAN engine.";
|
||||
private static LeanEngineSystemHandlers leanEngineSystemHandlers;
|
||||
private static LeanEngineAlgorithmHandlers leanEngineAlgorithmHandlers;
|
||||
private static AlgorithmNodePacket job;
|
||||
private static AlgorithmManager algorithmManager;
|
||||
|
||||
static Program()
|
||||
{
|
||||
AppDomain.CurrentDomain.AssemblyLoad += (sender, e) =>
|
||||
{
|
||||
if (e.LoadedAssembly.FullName.ToLowerInvariant().Contains("python"))
|
||||
{
|
||||
Log.Trace($"Python for .NET Assembly: {e.LoadedAssembly.GetName()}");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
if (OS.IsWindows)
|
||||
{
|
||||
Console.OutputEncoding = System.Text.Encoding.UTF8;
|
||||
}
|
||||
|
||||
// expect first argument to be config file name
|
||||
if (args.Length > 0)
|
||||
{
|
||||
Config.MergeCommandLineArgumentsWithConfiguration(LeanArgumentParser.ParseArguments(args));
|
||||
}
|
||||
|
||||
//Name thread for the profiler:
|
||||
Thread.CurrentThread.Name = "Algorithm Analysis Thread";
|
||||
|
||||
Initializer.Start();
|
||||
leanEngineSystemHandlers = Initializer.GetSystemHandlers();
|
||||
|
||||
//-> Pull job from QuantConnect job queue, or, pull local build:
|
||||
job = leanEngineSystemHandlers.JobQueue.NextJob(out var assemblyPath);
|
||||
|
||||
leanEngineAlgorithmHandlers = Initializer.GetAlgorithmHandlers();
|
||||
|
||||
if (job == null)
|
||||
{
|
||||
const string jobNullMessage = "Engine.Main(): Sorry we could not process this algorithm request.";
|
||||
Log.Error(jobNullMessage);
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
// Activate our PythonVirtualEnvironment
|
||||
PythonInitializer.ActivatePythonVirtualEnvironment(job.PythonVirtualEnvironment);
|
||||
|
||||
// if the job version doesn't match this instance version then we can't process it
|
||||
// we also don't want to reprocess redelivered jobs
|
||||
if (job.Redelivered)
|
||||
{
|
||||
Log.Error("Engine.Run(): Job Version: " + job.Version + " Deployed Version: " + Globals.Version + " Redelivered: " + job.Redelivered);
|
||||
//Tiny chance there was an uncontrolled collapse of a server, resulting in an old user task circulating.
|
||||
//In this event kill the old algorithm and leave a message so the user can later review.
|
||||
leanEngineSystemHandlers.Api.SetAlgorithmStatus(job.AlgorithmId, AlgorithmStatus.RuntimeError, _collapseMessage);
|
||||
leanEngineSystemHandlers.Notify.SetAuthentication(job);
|
||||
leanEngineSystemHandlers.Notify.Send(new RuntimeErrorPacket(job.UserId, job.AlgorithmId, _collapseMessage));
|
||||
leanEngineSystemHandlers.JobQueue.AcknowledgeJob(job);
|
||||
Exit(1);
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// Set our exit handler for the algorithm
|
||||
Console.CancelKeyPress += new ConsoleCancelEventHandler(ExitKeyPress);
|
||||
|
||||
// Create the algorithm manager and start our engine
|
||||
algorithmManager = new AlgorithmManager(Globals.LiveMode, job);
|
||||
|
||||
leanEngineSystemHandlers.LeanManager.Initialize(leanEngineSystemHandlers, leanEngineAlgorithmHandlers, job, algorithmManager);
|
||||
|
||||
OS.Initialize();
|
||||
|
||||
var engine = new Engine.Engine(leanEngineSystemHandlers, leanEngineAlgorithmHandlers, Globals.LiveMode);
|
||||
engine.Run(job, algorithmManager, assemblyPath, WorkerThread.Instance);
|
||||
}
|
||||
finally
|
||||
{
|
||||
var algorithmStatus = algorithmManager?.State ?? AlgorithmStatus.DeployError;
|
||||
|
||||
Exit(algorithmStatus != AlgorithmStatus.Completed ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ExitKeyPress(object sender, ConsoleCancelEventArgs args)
|
||||
{
|
||||
// Allow our process to resume after this event
|
||||
args.Cancel = true;
|
||||
|
||||
// Stop the algorithm
|
||||
algorithmManager.SetStatus(AlgorithmStatus.Stopped);
|
||||
Log.Trace("Program.ExitKeyPress(): Lean instance has been cancelled, shutting down safely now");
|
||||
}
|
||||
|
||||
public static void Exit(int exitCode)
|
||||
{
|
||||
// The job can be null if the algorithm file was not found
|
||||
if (job != null)
|
||||
{
|
||||
//Delete the message from the job queue:
|
||||
leanEngineSystemHandlers.JobQueue.AcknowledgeJob(job);
|
||||
Log.Trace("Engine.Main(): Packet removed from queue: " + job.AlgorithmId);
|
||||
}
|
||||
|
||||
// clean up resources
|
||||
leanEngineSystemHandlers.DisposeSafely();
|
||||
leanEngineAlgorithmHandlers.DisposeSafely();
|
||||
OS.Dispose();
|
||||
try
|
||||
{
|
||||
var isolator = new Isolator();
|
||||
isolator.ExecuteWithTimeLimit(TimeSpan.FromSeconds(10), PythonInitializer.Shutdown, -1);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.Error(ex, $"Failed to shutdown python");
|
||||
}
|
||||
|
||||
Log.Trace("Program.Main(): Exiting Lean...");
|
||||
Log.LogHandler.DisposeSafely();
|
||||
Environment.Exit(exitCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user