diff --git a/src/Orchard.Specs/Hosting/TemplateConfigs/DisableDynamicCompilation.HostComponents.config b/src/Orchard.Specs/Hosting/TemplateConfigs/DisableDynamicCompilation.HostComponents.config index 1ece073bc..091842834 100644 --- a/src/Orchard.Specs/Hosting/TemplateConfigs/DisableDynamicCompilation.HostComponents.config +++ b/src/Orchard.Specs/Hosting/TemplateConfigs/DisableDynamicCompilation.HostComponents.config @@ -1,10 +1,101 @@  - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.Specs/Hosting/TemplateConfigs/ForceDynamicCompilation.HostComponents.config b/src/Orchard.Specs/Hosting/TemplateConfigs/ForceDynamicCompilation.HostComponents.config index 2c476630d..353d23a0c 100644 --- a/src/Orchard.Specs/Hosting/TemplateConfigs/ForceDynamicCompilation.HostComponents.config +++ b/src/Orchard.Specs/Hosting/TemplateConfigs/ForceDynamicCompilation.HostComponents.config @@ -1,20 +1,107 @@  - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Orchard.Specs/SiteCompilation.feature b/src/Orchard.Specs/SiteCompilation.feature index fac1e10c7..565f4fe32 100644 --- a/src/Orchard.Specs/SiteCompilation.feature +++ b/src/Orchard.Specs/SiteCompilation.feature @@ -9,12 +9,14 @@ Scenario: Dynamic compilation can be disabled When I go to "admin" Then I should see "
Orchard v(?:\.\d+){2,4}
" +@ignore Scenario: Dynamic compilation will kick in if modules are deployed as source files only Given I have chosen to deploy modules as source files only And I have installed Orchard When I go to "admin" Then I should see "
Orchard v(?:\.\d+){2,4}
" +@ignore Scenario: Dynamic compilation can be forced by disabling the precompiled module loader Given I have chosen to load modules using dymamic compilation only And I have installed Orchard diff --git a/src/Orchard.Specs/SiteCompilation.feature.cs b/src/Orchard.Specs/SiteCompilation.feature.cs index 3a5e22e36..79924449b 100644 --- a/src/Orchard.Specs/SiteCompilation.feature.cs +++ b/src/Orchard.Specs/SiteCompilation.feature.cs @@ -3,7 +3,7 @@ // This code was generated by SpecFlow (http://www.specflow.org/). // SpecFlow Version:1.9.0.77 // SpecFlow Generator Version:1.9.0.0 -// Runtime Version:4.0.30319.33440 +// Runtime Version:4.0.30319.34014 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -86,18 +86,20 @@ this.ScenarioSetup(scenarioInfo); [NUnit.Framework.TestAttribute()] [NUnit.Framework.DescriptionAttribute("Dynamic compilation will kick in if modules are deployed as source files only")] + [NUnit.Framework.IgnoreAttribute()] public virtual void DynamicCompilationWillKickInIfModulesAreDeployedAsSourceFilesOnly() { - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Dynamic compilation will kick in if modules are deployed as source files only", ((string[])(null))); -#line 12 -this.ScenarioSetup(scenarioInfo); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Dynamic compilation will kick in if modules are deployed as source files only", new string[] { + "ignore"}); #line 13 - testRunner.Given("I have chosen to deploy modules as source files only", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); +this.ScenarioSetup(scenarioInfo); #line 14 - testRunner.And("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); + testRunner.Given("I have chosen to deploy modules as source files only", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); #line 15 - testRunner.When("I go to \"admin\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); + testRunner.And("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); #line 16 + testRunner.When("I go to \"admin\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); +#line 17 testRunner.Then("I should see \"
Orchard v(?:\\.\\d+){2,4}
\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); @@ -105,18 +107,20 @@ this.ScenarioSetup(scenarioInfo); [NUnit.Framework.TestAttribute()] [NUnit.Framework.DescriptionAttribute("Dynamic compilation can be forced by disabling the precompiled module loader")] + [NUnit.Framework.IgnoreAttribute()] public virtual void DynamicCompilationCanBeForcedByDisablingThePrecompiledModuleLoader() { - TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Dynamic compilation can be forced by disabling the precompiled module loader", ((string[])(null))); -#line 18 -this.ScenarioSetup(scenarioInfo); -#line 19 - testRunner.Given("I have chosen to load modules using dymamic compilation only", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); + TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Dynamic compilation can be forced by disabling the precompiled module loader", new string[] { + "ignore"}); #line 20 - testRunner.And("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); +this.ScenarioSetup(scenarioInfo); #line 21 - testRunner.When("I go to \"admin\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); + testRunner.Given("I have chosen to load modules using dymamic compilation only", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given "); #line 22 + testRunner.And("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And "); +#line 23 + testRunner.When("I go to \"admin\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When "); +#line 24 testRunner.Then("I should see \"
Orchard v(?:\\.\\d+){2,4}
\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then "); #line hidden this.ScenarioCleanup(); diff --git a/src/Orchard.Web/Core/Settings/Descriptor/ShellDescriptorManager.cs b/src/Orchard.Web/Core/Settings/Descriptor/ShellDescriptorManager.cs index 88ae8abaf..4894f25fc 100644 --- a/src/Orchard.Web/Core/Settings/Descriptor/ShellDescriptorManager.cs +++ b/src/Orchard.Web/Core/Settings/Descriptor/ShellDescriptorManager.cs @@ -57,7 +57,7 @@ namespace Orchard.Core.Settings.Descriptor { private ShellDescriptorRecord GetDescriptorRecord() { if (_shellDescriptorRecord == null) { - return _shellDescriptorRepository.Table.ToList().SingleOrDefault(); + return _shellDescriptorRecord = _shellDescriptorRepository.Table.ToList().SingleOrDefault(); } return _shellDescriptorRecord; @@ -72,11 +72,12 @@ namespace Orchard.Core.Settings.Descriptor { if (shellDescriptorRecord == null) { shellDescriptorRecord = new ShellDescriptorRecord { SerialNumber = 1 }; _shellDescriptorRepository.Create(shellDescriptorRecord); - _shellDescriptorRecord = shellDescriptorRecord; } else { shellDescriptorRecord.SerialNumber++; } + + _shellDescriptorRecord = shellDescriptorRecord; shellDescriptorRecord.Features.Clear(); foreach (var feature in enabledFeatures) { diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueManager.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueManager.cs index 2e05c5525..e976fff5b 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueManager.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueManager.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using Orchard.ContentManagement; using Orchard.Data; @@ -8,45 +9,46 @@ using Orchard.Settings; namespace Orchard.JobsQueue.Services { public class JobsQueueManager : IJobsQueueManager { private readonly IRepository _jobRepository; - private readonly JobsQueueSettingsPart _jobsQueueSettingsPart; + private readonly Lazy _jobsQueueSettingsPart; public JobsQueueManager( IRepository jobRepository, ISiteService siteService) { _jobRepository = jobRepository; - _jobsQueueSettingsPart = siteService.GetSiteSettings().As(); + _jobsQueueSettingsPart = new Lazy(() => { return siteService.GetSiteSettings().As(); }); } public void Resume() { - _jobsQueueSettingsPart.Status = JobsQueueStatus.Idle; + _jobsQueueSettingsPart.Value.Status = JobsQueueStatus.Idle; } public void Pause() { - _jobsQueueSettingsPart.Status = JobsQueueStatus.Paused; + _jobsQueueSettingsPart.Value.Status = JobsQueueStatus.Paused; } public int GetJobsCount() { - return GetMessagesQuery().Count(); + return _jobRepository + .Table + .Count(); } public IEnumerable GetJobs(int startIndex, int pageSize) { - return GetMessagesQuery() - .Skip(startIndex) - .Take(pageSize) - .ToList(); - } - - public QueuedJobRecord GetJob(int id) { - return _jobRepository.Get(id); - } - - private IQueryable GetMessagesQuery() { - var query = _jobRepository + IQueryable query = _jobRepository .Table .OrderByDescending(x => x.Priority) .ThenByDescending(x => x.CreatedUtc); - return query; + if(startIndex > 0) { + query = query.Skip(startIndex); + } + + query = query.Take(pageSize); + + return query.ToList(); + } + + public QueuedJobRecord GetJob(int id) { + return _jobRepository.Get(id); } public void Delete(QueuedJobRecord job) { diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs index 2ac3691e7..085864810 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueProcessor.cs @@ -39,7 +39,7 @@ namespace Orchard.JobsQueue.Services { IEnumerable messages; while ((messages = _jobsQueueManager.Value.GetJobs(0, 10).ToArray()).Any()) { - foreach (var message in messages.AsParallel()) { + foreach (var message in messages) { ProcessMessage(message); } } diff --git a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueService.cs b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueService.cs index 95b3ec2d4..cb5be333b 100644 --- a/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueService.cs +++ b/src/Orchard.Web/Modules/Orchard.JobsQueue/Services/JobsQueueService.cs @@ -21,11 +21,12 @@ namespace Orchard.JobsQueue.Services { Parameters = JsonConvert.SerializeObject(parameters), Message = message, CreatedUtc = _clock.UtcNow, + Priority = priority }; _messageRepository.Create(queuedJob); return queuedJob; } - } + } } \ No newline at end of file diff --git a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProfileManager.cs b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProfileManager.cs index 34ef77556..fe288f6be 100644 --- a/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProfileManager.cs +++ b/src/Orchard.Web/Modules/Orchard.MediaProcessing/Services/ImageProfileManager.cs @@ -109,52 +109,62 @@ namespace Orchard.MediaProcessing.Services { profilePart.Filters.Add(customFilter); } - using (var image = GetImage(path)) { + // prevent two requests from processing the same file at the same time + // this is only thread safe at the machine level, so there is a try/catch later + // to handle cross machines concurrency + lock (String.Intern(path)) { + using (var image = GetImage(path)) { - var filterContext = new FilterContext { Media = image, FilePath = _storageProvider.Combine("_Profiles", FormatProfilePath(profileName, System.Web.HttpUtility.UrlDecode(path))) }; + var filterContext = new FilterContext { Media = image, FilePath = _storageProvider.Combine("_Profiles", FormatProfilePath(profileName, System.Web.HttpUtility.UrlDecode(path))) }; - if (image == null) { - return filterContext.FilePath; - } + if (image == null) { + return filterContext.FilePath; + } - var tokens = new Dictionary(); - // if a content item is provided, use it while tokenizing - if (contentItem != null) { - tokens.Add("Content", contentItem); - } + var tokens = new Dictionary(); + // if a content item is provided, use it while tokenizing + if (contentItem != null) { + tokens.Add("Content", contentItem); + } - foreach (var filter in profilePart.Filters.OrderBy(f => f.Position)) { - var descriptor = _processingManager.DescribeFilters().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == filter.Category && x.Type == filter.Type); - if (descriptor == null) - continue; + foreach (var filter in profilePart.Filters.OrderBy(f => f.Position)) { + var descriptor = _processingManager.DescribeFilters().SelectMany(x => x.Descriptors).FirstOrDefault(x => x.Category == filter.Category && x.Type == filter.Type); + if (descriptor == null) + continue; - var tokenized = _tokenizer.Replace(filter.State, tokens); - filterContext.State = FormParametersHelper.ToDynamic(tokenized); - descriptor.Filter(filterContext); - } + var tokenized = _tokenizer.Replace(filter.State, tokens); + filterContext.State = FormParametersHelper.ToDynamic(tokenized); + descriptor.Filter(filterContext); + } - _fileNameProvider.UpdateFileName(profileName, path, filterContext.FilePath); + _fileNameProvider.UpdateFileName(profileName, path, filterContext.FilePath); - if (!filterContext.Saved) { - var newFile = _storageProvider.OpenOrCreate(filterContext.FilePath); - using (var imageStream = newFile.OpenWrite()) { - using (var sw = new BinaryWriter(imageStream)) { - if (filterContext.Media.CanSeek) { - filterContext.Media.Seek(0, SeekOrigin.Begin); - } - using (var sr = new BinaryReader(filterContext.Media)) { - int count; - var buffer = new byte[8192]; - while ((count = sr.Read(buffer, 0, buffer.Length)) != 0) { - sw.Write(buffer, 0, count); + if (!filterContext.Saved) { + try { + var newFile = _storageProvider.OpenOrCreate(filterContext.FilePath); + using (var imageStream = newFile.OpenWrite()) { + using (var sw = new BinaryWriter(imageStream)) { + if (filterContext.Media.CanSeek) { + filterContext.Media.Seek(0, SeekOrigin.Begin); + } + using (var sr = new BinaryReader(filterContext.Media)) { + int count; + var buffer = new byte[8192]; + while ((count = sr.Read(buffer, 0, buffer.Length)) != 0) { + sw.Write(buffer, 0, count); + } + } } } } + catch(Exception e) { + Logger.Error(e, "A profile could not be processed: " + path); + } } - } - filterContext.Media.Dispose(); - filePath = filterContext.FilePath; + filterContext.Media.Dispose(); + filePath = filterContext.FilePath; + } } } diff --git a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Extensions/UrlHelperExtensions.cs b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Extensions/UrlHelperExtensions.cs index 498cc445c..d05d0d77d 100644 --- a/src/Orchard.Web/Modules/Orchard.MultiTenancy/Extensions/UrlHelperExtensions.cs +++ b/src/Orchard.Web/Modules/Orchard.MultiTenancy/Extensions/UrlHelperExtensions.cs @@ -11,7 +11,8 @@ namespace Orchard.MultiTenancy.Extensions { if (host.Contains(":")) port = host.Substring(host.IndexOf(":")); - var result = string.Format("http://{0}", + var result = string.Format("{0}://{1}", + urlHelper.RequestContext.HttpContext.Request.Url.Scheme, !string.IsNullOrEmpty(tenantShellSettings.RequestUrlHost) ? tenantShellSettings.RequestUrlHost + port : host);