public ActivationFilterResponse FilterActivation(Stream jobXml, int schedulerPass, int jobIndex, bool backfill, int resourceCount)
        {
            LogEventMsg("FilterActivation");

            ActivationFilterResponse retVal = ActivationFilterResponse.StartJob;

            _filterActivationCalls++;

            return(retVal);
        }
Esempio n. 2
0
        /// <summary>
        /// Analyse the Job and if all the required licenses are available start the job.
        /// If there are not enough total licenses to satisfy the request, fail the job.
        /// If there are not enough licenses currently available, request the scheduler keep
        /// the allocated resources so that when the licenses become available the job can
        /// be scheduled.
        /// </summary>
        /// <param name="job"></param>
        /// <param name="schedulerPass"></param>
        /// <param name="jobIndex"></param>
        /// <param name="backfill"></param>
        /// <param name="resourceCount"></param>
        /// <returns></returns>
        public ActivationFilterResponse FilterActivation(
            Stream jobXml,
            int schedulerPass,
            int jobIndex,
            bool backfill,
            int resourceCount)
        {
            ActivationFilterResponse returnDecision = ActivationFilterResponse.StartJob;

            _schedulerPass = schedulerPass;
            _jobIndex      = jobIndex;
            _backfill      = backfill;
            _resourceCount = resourceCount;

            if ((schedulerPass == 1) &&
                (jobIndex == 1))
            {
                // Scheduler restarted. Ensure we never use stale data from FlexLM server by clearing cache
                Cache.Clear();
            }

            ParseJobXml(jobXml);

            // If this job does not parse correctly or has no license requests, tell the Scheduler
            // to proceed and schedule the job as normal.
            if (_requestedFeatures.Count <= 0)
            {
                return(ActivationFilterResponse.StartJob);
            }

            // If the job is flagged as backfill then there is a possibility that allowing it to
            // run might block a higher priority job from running due to the use of shared licenses.
            if (backfill)
            {
                // Some users may wish to disable this feature so that licenses are utilized as much as
                // possible.

                // Let another job take the backfill slot if there is one.
                return(ActivationFilterResponse.DoNotRunKeepResourcesAllowOtherJobsToSchedule);
            }

            // Find out what licenses are available
            Cache.Load(schedulerPass, jobIndex);

            if (Cache.licenseInfo.PollServerFailed)
            {
                // FlexLM server is down. Hold the job and let other non-licensed Jobs
                // to be scheduled. Administrator can release the held jobs when the issue
                // is resolved using job modify /holduntil or just wait for the HoldUntil
                // time to elapse.
                return(ActivationFilterResponse.HoldJobReleaseResourcesAllowOtherJobsToSchedule);
            }

            // Iterate through the requesting features and determine whether
            // there are enough license tokens.
            IDictionaryEnumerator iterator = _requestedFeatures.GetEnumerator();

            // Run lmutils lmstat to verify the available license tokens.
            while (iterator.MoveNext())
            {
                string featureName     = iterator.Key as string;
                int    numberRequested = (int)iterator.Value;
                if (Cache.licenseInfo.LicenseDirectory.ContainsKey(featureName))
                {
                    int total = Cache.licenseInfo.LicenseDirectory[featureName].Total;
                    int inUse = Cache.licenseInfo.LicenseDirectory[featureName].InUse;

                    if (numberRequested > total)
                    {
                        if (_growing)
                        {
                            // Ignore additional resources
                            returnDecision = ActivationFilterResponse.RejectAdditionOfResources;
                            break;
                        }

                        // Not enough licenses purchased to ever satisfy this job.
                        SetProgressMessage("FlexLM error: Not enough licenses for " + featureName);
                        returnDecision = ActivationFilterResponse.FailJob;
                        break;
                    }
                    else if (numberRequested > total - inUse)
                    {
                        if (_growing)
                        {
                            // Ignore additional resources
                            returnDecision = ActivationFilterResponse.RejectAdditionOfResources;
                            break;
                        }

                        // Not enough resources to run this job on this pass. Reserve the licenses that are
                        // available and wait for more to become available
                        Cache.Reserve(featureName, total - inUse);
                        returnDecision = ActivationFilterResponse.DoNotRunKeepResourcesAllowOtherJobsToSchedule;
                    }
                    else
                    {
                        Cache.Reserve(featureName, numberRequested);
                    }
                }
                else
                {
                    if (_growing)
                    {
                        // Ignore additional resources
                        returnDecision = ActivationFilterResponse.RejectAdditionOfResources;
                        break;
                    }

                    // Requested a license we don't have
                    SetProgressMessage("FlexLM error: License " + featureName + " not found");
                    returnDecision = ActivationFilterResponse.FailJob;
                    break;
                }
            }

            // If we want the resources for this job, persist the updates
            if ((returnDecision == ActivationFilterResponse.DoNotRunKeepResourcesAllowOtherJobsToSchedule) ||
                (returnDecision == ActivationFilterResponse.StartJob))
            {
                Cache.Save();
            }

            return(returnDecision);
        }
Esempio n. 3
0
        /// <summary>
        /// Entry point for an activation filter.
        /// </summary>
        /// <param name="jobXml"></param>
        /// XML stream containing the job in question.
        /// <param name="schedulerPass"></param>
        /// <param name="jobIndex"></param>
        /// <param name="backfill"></param>
        /// <param name="resourceCount"></param>
        /// <returns></returns>
        public ActivationFilterResponse FilterActivation(Stream jobXml, int schedulerPass, int jobIndex, bool backfill, int resourceCount)
        {
            if (setupLogFile() != 0)
            {
                return(ActivationFilterResponse.FailJob);
            }

            ActivationFilterResponse retval = ActivationFilterResponse.FailJob;

            try {
                // If the job is submitted outside peak business hours, no change is necessary
                if (DuringOffHours())
                {
                    logFile.WriteLine("AF: During Off Peak Hours, job starting");
                    return(ActivationFilterResponse.StartJob);
                }

                // Currently during peak business hours
                // Check if user is authorized to start a job during these hours
                // If not, delay the start of the job until off peak hours are in play

                // Load the job file as an XmlDocument.
                XmlDocument doc = new XmlDocument();
                doc.Load(jobXml);

                XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
                nsMgr.AddNamespace("hpc", xmlNameSpace);

                // Find the job node in the XML document.
                XmlNode jobXML = doc.SelectSingleNode("/hpc:Job", nsMgr);

                if (jobXML == null)
                {
                    throw new Exception("No job in the xml file");
                }

                // Find the User attribute for the job.
                XmlAttributeCollection attrCol  = jobXML.Attributes;
                XmlAttribute           userAttr = attrCol["User"];
                string user = userAttr.Value;

                // If user does not have permission to run jobs during peak hours, adjust HoldUntil if needed
                if (!PeakHoursUser(user))
                {
                    string jobIdString = attrCol["Id"].Value;
                    int    jobId;
                    Int32.TryParse(jobIdString, out jobId);
                    if (jobId != 0)
                    {
                        using (IScheduler scheduler = new Scheduler()) {
                            scheduler.Connect("localhost");
                            ISchedulerJob job = scheduler.OpenJob(jobId);

                            DateTime peakEnd = DateTime.Today.AddHours((double)endhours);

                            // If the job is not already set to delay until off peak hours, set it
                            // This property should be null, but could be non-null if some other
                            // thread has set it after scheduling called the activation filter
                            if ((job.HoldUntil == null) || (job.HoldUntil < peakEnd))
                            {
                                job.SetHoldUntil(peakEnd);
                                job.Commit();
                                logFile.WriteLine("Delay job {0} until off peak hours", jobId);
                            }
                            else
                            {
                                logFile.WriteLine("Job {0} already set to {1}", jobId, job.HoldUntil);
                            }
                            scheduler.Close();
                        } // using scheduler
                    }
                    else
                    {
                        logFile.WriteLine("jobId == 0, delaying job by default duration");
                    }

                    retval = ActivationFilterResponse.HoldJobReleaseResourcesAllowOtherJobsToSchedule;
                }
                else
                {
                    logFile.WriteLine("Job to run during peak hours");
                    retval = ActivationFilterResponse.StartJob;
                }
            } catch (IOException e) {
                logFile.WriteLine("Error Loading the XmlFile");
                logFile.WriteLine(e.ToString());
                retval = ActivationFilterResponse.FailJob;
            } catch (Exception e) {
                logFile.WriteLine(e.ToString());
                retval = ActivationFilterResponse.FailJob;
            } finally {
                logFile.Close();
            }

            return(retval);
        }