Ejemplo n.º 1
0
        public override void Run()
        {
            WorkerTrace.TraceEvent(TraceEventType.Information, 0, "Running");
            WorkerTrace.TraceEvent(TraceEventType.Information, 1, string.Format("Worker assembly: {0}", Assembly.GetExecutingAssembly().FullName));

            WorkerTrace.TraceEvent(TraceEventType.Start, 2, "Initializing FetchWorker...");

            try
            {
                Initialize();
            }
            catch (Exception exc)
            {
                WorkerTrace.TraceEvent(TraceEventType.Critical, 2, string.Format("FetchWorker initialization failed: {0}", exc.ToString()));
                throw;
            }
            WorkerTrace.TraceEvent(TraceEventType.Stop, 2, "FetchWorker initialization complete");

            int      heavyJobsPermitedCount           = int.Parse(RoleEnvironment.GetConfigurationSettingValue("HeavyJobsPermitedCount"));
            int      lightJobExecutionPermitedTimeSec = int.Parse(RoleEnvironment.GetConfigurationSettingValue("LightJobExecutionTimeLimitSec"));
            TimeSpan daysBeforeJobDeletion;

            {
                double days = 0;
                if (!double.TryParse(RoleEnvironment.GetConfigurationSettingValue("DaysBeforeJobDeletion"), out days))
                {
                    days = 60;
                    WorkerTrace.TraceEvent(TraceEventType.Warning, 3, string.Format("{0}: Bad \"DaysBeforeJobDeletion\" setting! Default value (60) is used.", JobManager.CleanUpJobHash));
                }
                daysBeforeJobDeletion = TimeSpan.FromDays(days);
            }
            while (true)
            {
                //Scheduling cleanup
                if (instanceIndex == 0)
                {
                    var utcnow = DateTime.UtcNow;
                    if (utcnow - lastCleanUpTime >= cleanupTimeSpan)
                    {
                        manager.SubmitCleanUp();
                        lastCleanUpTime = utcnow;
                        WorkerTrace.TraceEvent(TraceEventType.Information, 4, "Clean up job submited");
                    }
                }
                current = manager.PeekLockJob(stopRequested, int.Parse(RoleEnvironment.GetConfigurationSettingValue("JobQueuePollingMilisec")), heavyJobsPermitedCount,
                                              (job, context) =>
                {
                    if (job.Hash.Trim() == JobManager.CleanUpJobHash)
                    {
                        return(new CleanUpJob(job, context, manager, daysBeforeJobDeletion, new JobSettings()
                        {
                            PermitedHeavyPartWorkers = heavyJobsPermitedCount, LightJobExecutionPermitedTimeSec = lightJobExecutionPermitedTimeSec, TouchPeriodInSeconds = touchPeriodInSeconds
                        }));
                    }
                    else
                    {
                        return(new ComputationJob(job, context, configProvider, new JobSettings()
                        {
                            PermitedHeavyPartWorkers = heavyJobsPermitedCount, LightJobExecutionPermitedTimeSec = lightJobExecutionPermitedTimeSec, TouchPeriodInSeconds = touchPeriodInSeconds
                        }, manager.ResultDataSetUri(job.Hash, true)));
                    }
                });
                if (current == null)
                {
                    break;
                }
                try
                {
                    WorkerTrace.TraceEvent(TraceEventType.Start, 5, string.Format("{0}: start processing", current.ToShortString()));
                    current.Perform();
                }
                catch (Exception exc)
                {
                    WorkerTrace.TraceEvent(TraceEventType.Error, 14, string.Format("{0}: error processing: {1}", current.ToShortString(), exc.ToString()));

                    current.Complete(false);

                    Exception toCheckForOutOfMemory = exc;
                    do
                    {
                        if (toCheckForOutOfMemory.GetType() == typeof(OutOfMemoryException))
                        {
                            WorkerTrace.TraceEvent(TraceEventType.Critical, 15, string.Format("{0}:Requesting role instance recycling due to OutOfMemory exception during calculation", current.ToShortString()));
                            if (current != null)
                            {
                                current.Abandon();
                            }
                            Thread.Sleep(25);
                            RoleEnvironment.RequestRecycle();
                        }
                        toCheckForOutOfMemory = toCheckForOutOfMemory.InnerException;
                    } while (toCheckForOutOfMemory != null);
                }
                finally
                {
                    if (current != null)
                    {
                        current.Dispose(); //dispose stops TouchThread
                    }
                    current = null;
                }
            }
        }