/// <summary> /// Process object that represents running runner script.</summary> public ProActiveRuntimeExecutor(CommonStartInfo commonStartInfo, int rank) { this.commonStartInfo = commonStartInfo; this.rank = rank; if (this.rank == 0) { // Init the next usable ProActive Port specified by the configuration nextUsableProActivePort = commonStartInfo.configuration.config.portRange.first; } // Init the current and increment the next usable port this.currentProActivePort = nextUsableProActivePort++; this.LOGGER = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType + "" + rank); // The logger needs to be customized programmatically to log stout/stderr into a separate file this.processLogger = LogManager.GetLogger("Executor" + rank + "ProcessLogger"); Logger customLogger = this.processLogger.Logger as log4net.Repository.Hierarchy.Logger; if (customLogger != null) { customLogger.Additivity = false; customLogger.AddAppender(createRollingFileAppender(rank) /*, commonStartInfo.logsDirectory */); } // The restart timer is only created it will not start until Timer.Change() method is called this.restartTimer = new Timer(new TimerCallback(internalRestart), null, System.Threading.Timeout.Infinite, System.Threading.Timeout.Infinite); this.restartBarrierDateTime = DateTime.MaxValue; this.callersState = new Dictionary <ApplicationType, Int32>(); this.rootProcess = null; // Create a new job object for limits this.jobObject = new JobObject(Constants.JOB_OBJECT_NAME + rank); this.jobObject.Events.OnNewProcess += new jobEventHandler <NewProcessEventArgs>(Events_OnNewProcess); // If memory management is enabled ushort memoryLimit = commonStartInfo.configuration.config.memoryLimit; if (memoryLimit != 0) { // Add user defined memory limitations this.jobObject.Limits.JobMemoryLimit = new IntPtr(memoryLimit * 1024 * 1024); LOGGER.Info("A memory limitation of " + memoryLimit + " Mbytes is set for the ProActive Runtime process (and its children)"); // Add event handler to keep track of job events this.jobObject.Events.OnJobMemoryLimit += new jobEventHandler <JobMemoryLimitEventArgs>(Events_OnJobMemoryLimit); } // Apply priority this.jobObject.Limits.PriorityClass = commonStartInfo.configuration.config.processPriority; // Children process will not be able to escape from job this.jobObject.Limits.CanChildProcessBreakAway = false; // Create new instance of the cpu limiter this.cpuLimiter = new CPULimiter(); }
// The constructor should be called only during starting the service public ExecutorsManager(AgentType configuration) { // The configuration specifies the number of executors int nbProcesses = configuration.config.nbRuntimes == 0 ? 1 : configuration.config.nbRuntimes; LOGGER.Info("Creating " + nbProcesses + " executors"); // Get the runtime common start info shared between all executors CommonStartInfo commonStartInfo = new CommonStartInfo(configuration); // Create as many executors with a unique rank as specified in the configuration this.proActiveRuntimeExecutors = new List <ProActiveRuntimeExecutor>(nbProcesses); for (int rank = 0; rank < nbProcesses; rank++) { ProActiveRuntimeExecutor executor = new ProActiveRuntimeExecutor(commonStartInfo, rank); this.proActiveRuntimeExecutors.Add(executor); } // Create the start/stop timers for scheduled events this.startTimers = new List <Timer>(); this.stopTimers = new List <Timer>(); // If always available simply invoke start method with the stop time at max value if (configuration.isAlwaysAvailable()) { LOGGER.Info("Using always available planning"); this.mySendStartAction(new StartActionInfo( commonStartInfo.enabledConnection, DateTime.MaxValue, commonStartInfo.configuration.config.processPriority, commonStartInfo.configuration.config.maxCpuUsage, commonStartInfo.configuration.config.nbWorkers)); } else { // Fix the current time (usefull when there is a lot of events) DateTime currentFixedTime = DateTime.Now; int currentDayOfWeek = (int)currentFixedTime.DayOfWeek; foreach (CalendarEventType cEvent in configuration.events) { // for each calendar event we calculate remaining time to start and stop service // and according to that register timers // we provide the day of the week to present start time // the algorithm to count next start is as follows: // 1. how many days are to start action // 2. we add this amount to the current date // 3. we create time event that will be the exact start time (taking year, month and // day from the current date and other fields from configuration // 4. we keep duration of task // 5. we count due time for beginning and stopping the task // 6. if time is negative, we move it into next week (to avoid waiting for past events) int eventDayOfWeek = (int)cEvent.start.day; int daysAhead = dayDifference(currentDayOfWeek, eventDayOfWeek); DateTime startTime = currentFixedTime.AddDays(daysAhead); // Absolute start time DateTime absoluteStartTime = new DateTime(startTime.Year, startTime.Month, startTime.Day, cEvent.start.hour, cEvent.start.minute, cEvent.start.second); // Delay to wait until start TimeSpan delayUntilStart = absoluteStartTime - currentFixedTime; // Get the time span duration TimeSpan duration = new TimeSpan(cEvent.duration.days, cEvent.duration.hours, cEvent.duration.minutes, cEvent.duration.seconds); // Delay to wait until stop TimeSpan delayUntilStop = delayUntilStart.Add(duration); // Absolute stop time DateTime absoluteStopTime = absoluteStartTime.Add(duration); // Check if we need to start immidiately bool startNow = (delayUntilStart <TimeSpan.Zero && delayUntilStop> TimeSpan.Zero); if (delayUntilStart < TimeSpan.Zero) { delayUntilStart = delayUntilStart.Add(WEEK_DELAY); } if (delayUntilStop < TimeSpan.Zero) { delayUntilStop = delayUntilStop.Add(WEEK_DELAY); } StartActionInfo startInfo = new StartActionInfo( commonStartInfo.enabledConnection, absoluteStopTime, cEvent.config.processPriority, cEvent.config.maxCpuUsage, cEvent.config.nbWorkers); LOGGER.Info("Loading weekly event [" + absoluteStartTime.DayOfWeek + ":" + absoluteStartTime.ToString(Constants.DATE_FORMAT) + "] -> [" + absoluteStopTime.DayOfWeek + ":" + absoluteStopTime.ToString(Constants.DATE_FORMAT) + "]"); // After dueStart milliseconds this timer will invoke only once per week the callback Timer startT = new Timer(new TimerCallback(mySendStartAction), startInfo, delayUntilStart, WEEK_DELAY); this.startTimers.Add(startT); // After dueStop milliseconds this timer will invoke only once per week the callback Timer stopT = new Timer(new TimerCallback(mySendStopAction), null, delayUntilStop, WEEK_DELAY); this.stopTimers.Add(stopT); if (startNow) { this.mySendStartAction(startInfo); } } } }