| // Licensed to the Apache Software Foundation (ASF) under one |
| // or more contributor license agreements. See the NOTICE file |
| // distributed with this work for additional information |
| // regarding copyright ownership. The ASF licenses this file |
| // to you 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.Collections.Generic; |
| using System.Diagnostics; |
| using System.Globalization; |
| using System.IO; |
| using System.Linq; |
| using System.Threading; |
| using Org.Apache.REEF.Common.Runtime.Evaluator; |
| using Org.Apache.REEF.Common.Runtime.Evaluator.Utils; |
| using Org.Apache.REEF.Driver.Bridge; |
| using Org.Apache.REEF.Tang.Annotations; |
| using Org.Apache.REEF.Tang.Formats; |
| using Org.Apache.REEF.Tang.Implementations.Tang; |
| using Org.Apache.REEF.Tang.Interface; |
| using Org.Apache.REEF.Utilities.Diagnostics; |
| using Org.Apache.REEF.Utilities.Logging; |
| using Org.Apache.REEF.Wake.Time; |
| using Org.Apache.REEF.Wake.Time.Parameters; |
| using Org.Apache.REEF.Wake.Time.Runtime; |
| using Org.Apache.REEF.Wake.Time.Runtime.Event; |
| |
| namespace Org.Apache.REEF.Evaluator |
| { |
| public sealed class Evaluator |
| { |
| private static Logger logger = Logger.GetLogger(typeof(Evaluator)); |
| private readonly RuntimeClock _clock; |
| private readonly EvaluatorExitLogger _evaluatorExitLogger; |
| |
| [Inject] |
| private Evaluator( |
| RuntimeClock clock, |
| CustomTraceListeners customTraceListeners, |
| CustomTraceLevel customTraceLevel, |
| EvaluatorExitLogger evaluatorExitLogger) |
| { |
| _evaluatorExitLogger = evaluatorExitLogger; |
| _clock = clock; |
| SetCustomTraceListeners(customTraceListeners, customTraceLevel); |
| } |
| |
| private void Run() |
| { |
| _clock.Run(); |
| _evaluatorExitLogger.LogExit(true); |
| } |
| |
| /// <summary> |
| /// The command line to run it is "evaluator.exe evaluator.config" |
| /// </summary> |
| /// <param name="args"></param> |
| public static void Main(string[] args) |
| { |
| DefaultUnhandledExceptionHandler.Register(); |
| |
| if (args.Count() != 1) |
| { |
| var e = new InvalidOperationException("Must supply only the evaluator.config file!"); |
| Utilities.Diagnostics.Exceptions.Throw(e, logger); |
| } |
| |
| if (IsDebuggingEnabled()) |
| { |
| AttachDebugger(); |
| } |
| |
| var fullEvaluatorConfiguration = ReadEvaluatorConfiguration(args[0]); |
| var injector = TangFactory.GetTang().NewInjector(fullEvaluatorConfiguration); |
| var serializer = injector.GetInstance<AvroConfigurationSerializer>(); |
| var rootEvaluatorConfiguration = |
| TangFactory.GetTang().NewConfigurationBuilder(serializer.FromString(injector.GetNamedInstance<EvaluatorConfiguration, string>())) |
| .BindSetEntry<RuntimeStartHandler, EvaluatorRuntime, IObserver<RuntimeStart>>() |
| .BindSetEntry<RuntimeStopHandler, EvaluatorRuntime, IObserver<RuntimeStop>>() |
| .Build(); |
| var evaluator = injector.ForkInjector(rootEvaluatorConfiguration).GetInstance<Evaluator>(); |
| |
| evaluator.Run(); |
| logger.Log(Level.Info, "Evaluator is returned from Run()"); |
| } |
| |
| /// <summary> |
| /// Determines whether debugging is enabled. |
| /// </summary> |
| /// <returns>true, if debugging is enabled</returns> |
| private static bool IsDebuggingEnabled() |
| { |
| var debugEnabledString = Environment.GetEnvironmentVariable("Org.Apache.REEF.EvaluatorDebug"); |
| return !string.IsNullOrWhiteSpace(debugEnabledString) && |
| debugEnabledString.Equals("enabled", StringComparison.OrdinalIgnoreCase); |
| } |
| |
| /// <summary> |
| /// Waits for the debugger to be attached. |
| /// </summary> |
| private static void AttachDebugger() |
| { |
| // Wait for the debugger |
| while (true) |
| { |
| if (Debugger.IsAttached) |
| { |
| break; |
| } |
| |
| logger.Log(Level.Info, "Evaluator in debug mode, waiting for debugger to be attached..."); |
| Thread.Sleep(2000); |
| } |
| } |
| |
| /// <summary> |
| /// Read evaluator configuration from evaluator.conf generated from Java |
| /// </summary> |
| /// <param name="evaluatorConfigFile"></param> |
| /// <returns></returns> |
| private static IConfiguration ReadEvaluatorConfiguration(string evaluatorConfigFile) |
| { |
| if (string.IsNullOrWhiteSpace(evaluatorConfigFile)) |
| { |
| Utilities.Diagnostics.Exceptions.Throw(new ArgumentNullException("configFile"), logger); |
| } |
| if (!File.Exists(evaluatorConfigFile)) |
| { |
| Utilities.Diagnostics.Exceptions.Throw(new FileNotFoundException("cannot find file " + evaluatorConfigFile), logger); |
| } |
| |
| AvroConfigurationSerializer serializer = new AvroConfigurationSerializer(); |
| var classHierarchy = TangFactory.GetTang() |
| .GetClassHierarchy(new string[] { typeof(ApplicationIdentifier).Assembly.GetName().Name }); |
| var evaluatorConfiguration = serializer.FromFile(evaluatorConfigFile, classHierarchy); |
| |
| logger.Log(Level.Info, |
| string.Format(CultureInfo.CurrentCulture, "Evaluator Configuration is deserialized from file {0}:", evaluatorConfigFile)); |
| |
| return evaluatorConfiguration; |
| } |
| |
| private static void SetCustomTraceListeners(CustomTraceListeners customTraceListener, CustomTraceLevel traceLevel) |
| { |
| ISet<TraceListener> customTraceListeners = customTraceListener.Listeners; |
| foreach (TraceListener listener in customTraceListeners) |
| { |
| Logger.AddTraceListener(listener); |
| } |
| logger = Logger.GetLogger(typeof(Evaluator)); |
| Logger.SetCustomLevel(traceLevel.TraceLevel); |
| } |
| } |
| } |