Free cookie consent management tool by TermsFeed Policy Generator

Ignore:
Timestamp:
06/17/19 10:40:41 (5 years ago)
Author:
dpiringe
Message:

#2924:

  • some changes in CLIApplication.cs to reduce unnecessary allocation of string objects
  • renamed AppTest to ConsoleOptimizer and fixed race condition
  • replaced enum RunnerJob with class RunnerMessage for more control of saved data
  • changed usage of BinaryFormatter with HEAL.Attic, following types are now Storable:
    • ConsoleOptimizer
    • InspectApplication
    • ApplicationBase
    • ApplicationRunner
    • AssemblyInfo
    • Runner
    • UniPath
    • RunnerMessage
  • switched QuietMode from ApplicationRunner to IRunner
  • DockerRunnerHost can now automatically build docker images for linux and windows containers (also identifies which container type is active) -> removes the condition to have the image preinstalled
    • to achieve this, there are two new folders DockerLinuxBuild and DockerWindowsBuild included in build output, which include Dockerfiles to build images for linux and windows container
  • added NuGet package System.CodeDom to project HeuristicLab.Scripting-3.3
  • added method Send(RunnerMessage) to IRunnerHost and transferred methods Pause and Resume to IRunner
  • added internal reference of RunnerHost in Runner
  • added abstract method SendMessage(RunnerMessage) in RunnerHost which gets called from method Send(RunnerMessage)
  • because of a Google.Protobuf "bug", RunnerMessages cannot get serialized/deserialized directly on stream -> workaround with a byte array, which gets written and read
    • additionally, the length of the array gets sent first (length as integer -> 4 bytes)
    • static method in RunnerMessage to read a message from a stream
    • the method SendMessage(RunnerMessage) in RunnerHost implements this functionality
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2924_DotNetCoreMigration/HeuristicLab.PluginInfrastructure/3.3/Isolation/RunnerHost.cs

    r16993 r17013  
    44using System.Threading;
    55using System.Threading.Tasks;
     6using HEAL.Attic;
    67
    78namespace HeuristicLab.PluginInfrastructure {
     
    1415    Starting,
    1516    Running,
    16     Paused,
    17     Stopping,
    1817    Stopped
    1918  }
     
    2726    #region Vars
    2827    protected Process process;
     28    private ProtoBufSerializer serializer = new ProtoBufSerializer();
    2929    #endregion
    3030
    3131    #region Properties
     32    /// <summary>
     33    /// Set this to true, if console output should be disabled.
     34    /// </summary>
     35    public bool QuietMode { get; set; }
     36
     37
    3238    /// <summary>
    3339    /// The programm, which should be used. For example 'docker'.
     
    4147    protected string Password { get; private set; }
    4248    protected string Domain { get; private set; }
     49    protected IRunner Runner { get; set; }
    4350
    44     /// <summary>
    45     /// The runner state.
    46     /// </summary>
    4751    public RunnerState State { get; protected set; } = RunnerState.Created;
    4852    #endregion
    4953
    5054    #region Constructors
     55
    5156    protected RunnerHost(string program, string startArgument, string userName, string password, string domain) {
    5257      Program = program;
     
    6368        throw new InvalidOperationException("Runner must be in state 'Created'.");
    6469      State = RunnerState.Starting;
     70      Runner = runner;
    6571      process = new Process {
    6672        StartInfo = new ProcessStartInfo {
     
    7278          RedirectStandardError = true,
    7379          CreateNoWindow = false,
    74           UserName = string.IsNullOrEmpty(UserName) ? null : UserName,
     80          UserName = string.IsNullOrEmpty(UserName) ? null : UserName, // TODO: accounts testen: https://docs.microsoft.com/en-us/windows/security/identity-protection/access-control/local-accounts#sec-localsystem
    7581          PasswordInClearText = string.IsNullOrEmpty(Password) ? null : Password,
    7682          Domain = string.IsNullOrEmpty(Domain) ? null : Domain,
     
    8086      };
    8187      process.Start();
     88
    8289      // registers a task for cancellation, prevents the use of polling (while-loop)
    8390      var task = RegisterCancellation(token.HasValue ? token.Value : CancellationToken.None);
    8491
    85       // write config to standardinput, runner listens on this and deserializes the config
    86       Runner.Serialize(runner, process.StandardInput.BaseStream);
     92      // set runnerhost in runner
     93      Runner r = Runner as Runner;
     94      if (r != null) r.Host = this;
    8795
    8896      process.BeginOutputReadLine();
    8997      process.BeginErrorReadLine();
    9098
    91       if (!runner.QuietMode) {
     99      if (!QuietMode) {
    92100        process.OutputDataReceived += (s, e) => Console.WriteLine(e.Data);
    93101        process.ErrorDataReceived += (s, e) => Console.WriteLine(e.Data);
    94102      }
     103
     104      // write config to standardinput, runner listens on this and deserializes the config
     105      SendMessage(new TransportRunnerMessage(Runner));
     106
    95107      State = RunnerState.Running;
    96108      if (await task) State = RunnerState.Cancelled;
    97109      else State = RunnerState.Stopped;
    98 
    99110    }
    100111
    101     /// <summary>
    102     /// Pauses the runners. The childprocess gets notified with the help of the standard input and a serialized RunnerJob.
    103     /// To pause the runner, the state must be "Running".
    104     /// </summary>
    105     public void Pause() {
     112
     113    public void Send(RunnerMessage runnerMessage) {
    106114      if (State != RunnerState.Running) throw new InvalidOperationException("Runner must be in state 'Running'!");
    107       Runner.Pause(process.StandardInput.BaseStream);
    108       State = RunnerState.Paused;
     115      SendMessage(runnerMessage);
    109116    }
    110117
    111     /// <summary>
    112     /// Resumes a paused runner. The childprocess gets notified with the help of the standard input and a serialized RunnerJob.
    113     /// To resume the runner, the state must be "Paused".
    114     /// </summary>
    115     public void Resume() {
    116       if (State != RunnerState.Paused) throw new InvalidOperationException("Runner must be in state 'Paused'!");
    117       Runner.Resume(process.StandardInput.BaseStream);
    118       State = RunnerState.Running;
     118    // because we need to transfer the runner with a TransportRunnerMessage in the starting state and the
     119    // original send method should not be available until running state
     120    protected virtual void SendMessage(RunnerMessage runnerMessage) {
     121      runnerMessage.SendTime = DateTime.Now;
     122      byte[] bytes = serializer.Serialize(runnerMessage);
     123      byte[] size = BitConverter.GetBytes(bytes.Length);
     124      process.StandardInput.BaseStream.Write(size, 0, size.Length);
     125      process.StandardInput.BaseStream.Flush();
     126      process.StandardInput.BaseStream.Write(bytes, 0, bytes.Length);
     127      process.StandardInput.BaseStream.Flush();
    119128    }
    120129
     
    125134    /// When the child process gets finished without requested cancellation, the linked token gets cancelled and a result set.
    126135    /// </summary>
    127     private Task<bool> RegisterCancellation(CancellationToken token) {
     136    protected Task<bool> RegisterCancellation(CancellationToken token) {
    128137      if (process != null && State == RunnerState.Starting) {
    129138        var cts = CancellationTokenSource.CreateLinkedTokenSource(token);
     
    133142        cts.Token.Register(() => {
    134143          if (!process.HasExited) {
    135             Runner.Cancel(process.StandardInput.BaseStream);
     144            Runner.Cancel();
    136145            process.WaitForExit();
    137146          }
Note: See TracChangeset for help on using the changeset viewer.