public void Initialize() { if (!DataSetFactory.ContainsProvider("memory")) { DataSetFactory.Register(typeof(MemoryDataSet)); } if (!DataSetFactory.ContainsProvider("ab")) { DataSetFactory.Register(typeof(AzureBlobDataSet)); } string customTempLocalResourcePath = RoleEnvironment.GetLocalResource("localStorage1").RootPath; Environment.SetEnvironmentVariable("TMP", customTempLocalResourcePath); Environment.SetEnvironmentVariable("TEMP", customTempLocalResourcePath); string jobsDatabaseConnectionString = RoleEnvironment.GetConfigurationSettingValue("FetchClimate.JobsDatabaseConnectionString"); string jobsStorageConnectionString = RoleEnvironment.GetConfigurationSettingValue("FetchClimate.JobsStorageConnectionString"); foreach (TraceListener item in Trace.Listeners) { if (!(item is DefaultTraceListener)) // The default trace listener is always in any TraceSource.Listeners collection. { AutoRegistratingTraceSource.RegisterTraceListener(item); WorkerTrace.TraceEvent(TraceEventType.Information, 19, string.Format("TraceListener \"{0}\" registered for accepting data from all AutoRegistratingTraceSources", item.ToString())); } } JobManager.InitializeJobTable(jobsDatabaseConnectionString, false); configProvider = new SqlExtendedConfigurationProvider( RoleEnvironment.GetConfigurationSettingValue("ConfigurationDatabaseConnectionString")); WorkerTrace.TraceEvent(TraceEventType.Information, 6, string.Format("Connected to configuration database. Latest timestamp {0}", configProvider.GetConfiguration(DateTime.MaxValue).TimeStamp)); azureGAC = new AssemblyStore(RoleEnvironment.GetConfigurationSettingValue("FetchWorker.AssemblyStoreConnectionString")); //overriding bug-containing default azure provider with the fixed one Type t = typeof(DataSetFactory); var dict = (System.Collections.IDictionary)t.InvokeMember("providersByName", BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.GetField, null, null, null); dict.Remove("az"); DataSetFactory.Register(typeof(Microsoft.Research.Science.Data.Azure.AzureDataSet)); WorkerTrace.TraceEvent(TraceEventType.Verbose, 9, "Available Scientific DataSet providers:\n" + DataSetFactory.RegisteredToString()); if (int.TryParse(RoleEnvironment.GetConfigurationSettingValue("JobTouchPeriod"), out touchPeriodInSeconds)) { WorkerTrace.TraceEvent(TraceEventType.Verbose, 10, string.Format("Touch period for processing job is set to {0}", touchPeriodInSeconds)); } else { WorkerTrace.TraceEvent(TraceEventType.Warning, 11, string.Format("Failed to read touch period from config. Parsing of value failed. touch period is set to {0}", touchPeriodInSeconds)); } manager = new JobManager(jobsDatabaseConnectionString, jobsStorageConnectionString); //Scheduling cleanup string instanceId = RoleEnvironment.CurrentRoleInstance.Id; int.TryParse(instanceId.Substring(instanceId.LastIndexOf(".") + 1), out instanceIndex); if (instanceIndex == 0) { double cleanPeriod = 0; if (!double.TryParse(RoleEnvironment.GetConfigurationSettingValue("HoursBetweenCleanup"), out cleanPeriod)) { cleanPeriod = 23; WorkerTrace.TraceEvent(TraceEventType.Warning, 12, "Failed to parse period between clean-ups from configuration. Setting it to default 23 hours."); } cleanupTimeSpan = TimeSpan.FromHours(cleanPeriod); lastCleanUpTime = manager.LastCleanUpTime; DateTime now = DateTime.UtcNow; if (now - lastCleanUpTime >= cleanupTimeSpan) { manager.SubmitCleanUp(); lastCleanUpTime = now; } } WorkerTrace.TraceEvent(TraceEventType.Verbose, 13, string.Format("starting Allocated memory: {0}Mb", GC.GetTotalMemory(false) / 1024 / 1024)); }
/// <summary> /// Instantiates an Engine and uses the the instance to perform the request prepared in the constructor of the ComputationJob class. /// </summary> public override void Perform() { base.Perform(); Process currentP = Process.GetCurrentProcess(); currentP.Refresh(); JobManager.JobManagerTrace.TraceVerbose(string.Format("{0}:Start of job mem stats: working set {1}Mb, GC.allocated {2}Mb, PrivateMem {3}Mb", this.ToShortString(), Environment.WorkingSet / 1024 / 1024, GC.GetTotalMemory(false) / 1024 / 1024, currentP.PrivateMemorySize64 / 1024 / 1024)); var config = configProvider.GetConfiguration(this.Request.ReproducibilityTimestamp); JobManager.JobManagerTrace.TraceVerbose("{0}: FE type determined {1}. Loading FE assembly", this.ToShortString(), config.FetchEngineTypeName); var feType = Type.GetType(config.FetchEngineTypeName); if (feType == null) { throw new InvalidOperationException("Cannot load fetch engine type " + feType); } JobManager.JobManagerTrace.TraceVerbose("{0}: FE assembly loaded", this.ToShortString()); var feConst = feType.GetConstructor(new Type[1] { typeof(IExtendedConfigurationProvider) }); if (feConst == null) { throw new InvalidOperationException("The FE constrictor with needed signature is not found. Are the currently running service assemblies and math assemblies from AzureGAC built with different Core assemblies?"); } JobManager.JobManagerTrace.TraceVerbose("{0}: FE assembly loaded", this.ToShortString()); var fe = (IFetchEngine)feConst.Invoke(new object[1] { configProvider }); JobManager.JobManagerTrace.TraceVerbose("{0}: FE instance constructed", this.ToShortString()); IFetchResponseWithProvenance result = null; System.Threading.ManualResetEvent isDone = new System.Threading.ManualResetEvent(false); bool isWorkingThreadAborted = false; Exception executionException = null; //TODO: seems like spawning a thread is not necessary anymore -- check! workingThread = new System.Threading.Thread(new System.Threading.ThreadStart(() => { try { Stopwatch sw = new Stopwatch(); sw.Start(); result = fe.PerformRequestAsync(this.Request).Result; sw.Stop(); JobManager.JobManagerTrace.TraceVerbose("{0}: FE processed the request in {1}. Writing data to blob...", this.ToShortString(), sw.Elapsed); if (result.Provenance != null) { this.PutProvenance(result.Provenance); } this.PutValues(result.Values); this.PutUncertaties(result.Uncertainty); } catch (ThreadAbortException) { JobManager.JobManagerTrace.TraceInfo("{0}: Working thread is aborted (due to heavy part calculation cancelation?)", this.ToShortString()); isWorkingThreadAborted = true; } catch (Exception exc) { JobManager.JobManagerTrace.TraceError("{0}: Exception in working thread: {1}", this.ToShortString(), exc.ToString()); executionException = exc; } finally { isDone.Set(); } } )); workingThread.IsBackground = true; JobManager.JobManagerTrace.TraceInfo("{0}: Starting working thread", this.ToShortString()); workingThread.Start(); isDone.WaitOne(); JobManager.JobManagerTrace.TraceInfo("{0}: Working thread signaled that it is finished. Joining it", this.ToShortString()); workingThread.Join(); JobManager.JobManagerTrace.TraceVerbose("{0}: Joined worker thread", this.ToShortString()); if (isWorkingThreadAborted) { this.Abandon(); } else { this.Complete(executionException == null); } JobManager.JobManagerTrace.TraceInfo("{0}: marked as {1}", this.ToShortString(), isWorkingThreadAborted ? "Pending" : "Complete"); currentP.Refresh(); JobManager.JobManagerTrace.TraceVerbose(string.Format("{0}:End of job mem stats: working set {1}Mb, GC.allocated {2}Mb, PrivateMem {3}Mb", this.ToShortString(), Environment.WorkingSet / 1024 / 1024, GC.GetTotalMemory(false) / 1024 / 1024, currentP.PrivateMemorySize64 / 1024 / 1024)); }