Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added configuration for view precompilation. #846

Merged
merged 9 commits into from
Jun 23, 2020
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.Threading.Tasks;
using DotVVM.Framework.Compilation;
using DotVVM.Framework.Configuration;
using DotVVM.Framework.Hosting;
using DotVVM.Framework.Hosting.Middlewares;
Expand Down Expand Up @@ -65,14 +67,18 @@ private static DotvvmConfiguration UseDotVVM(this IApplicationBuilder app, strin

modifyConfiguration?.Invoke(config);
config.Freeze();

app.UseMiddleware<DotvvmMiddleware>(config, new List<IMiddleware> {
ActivatorUtilities.CreateInstance<DotvvmCsrfTokenMiddleware>(config.ServiceProvider),
ActivatorUtilities.CreateInstance<DotvvmLocalResourceMiddleware>(app.ApplicationServices),
DotvvmFileUploadMiddleware.TryCreate(app.ApplicationServices),
new DotvvmReturnedFileMiddleware(),
new DotvvmRoutingMiddleware()
}.Where(t => t != null).ToArray());

var compilationConfiguration = config.Markup.ViewCompilation;
compilationConfiguration.HandleViewCompilation(config);

return config;
}
}
Expand Down
10 changes: 9 additions & 1 deletion src/DotVVM.Framework.Hosting.Owin/AppBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using DotVVM.Framework.Compilation;
using DotVVM.Framework.Configuration;
using DotVVM.Framework.Hosting;
using DotVVM.Framework.Hosting.Middlewares;
Expand Down Expand Up @@ -65,6 +68,7 @@ private static DotvvmConfiguration UseDotVVM(this IAppBuilder app, string applic
s.TryAddSingleton<ICookieManager, ChunkingCookieManager>();
s.TryAddScoped<DotvvmRequestContextStorage>(_ => new DotvvmRequestContextStorage());
s.TryAddScoped<IDotvvmRequestContext>(services => services.GetRequiredService<DotvvmRequestContextStorage>().Context);
s.AddSingleton<IDotvvmViewCompilationService, DotvvmViewCompilationService>();
configurator?.ConfigureServices(new DotvvmServiceCollection(s));
}, serviceProviderFactoryMethod);
config.Debug = debug;
Expand All @@ -79,14 +83,18 @@ private static DotvvmConfiguration UseDotVVM(this IAppBuilder app, string applic

modifyConfiguration?.Invoke(config);
config.Freeze();

app.Use<DotvvmMiddleware>(config, new List<IMiddleware> {
ActivatorUtilities.CreateInstance<DotvvmCsrfTokenMiddleware>(config.ServiceProvider),
ActivatorUtilities.CreateInstance<DotvvmLocalResourceMiddleware>(config.ServiceProvider),
DotvvmFileUploadMiddleware.TryCreate(config.ServiceProvider),
new DotvvmReturnedFileMiddleware(),
new DotvvmRoutingMiddleware()
}.Where(t => t != null).ToArray());

var compilationConfiguration = config.Markup.ViewCompilation;
compilationConfiguration.HandleViewCompilation(config);

return config;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
{
"namespace": "DotVVM.Framework.Binding.HelperNamespace"
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"resources": {},
"security": {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
{
"namespace": "DotVVM.Framework.Binding.HelperNamespace"
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"resources": {},
"security": {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,10 @@
},
"Inherit": true
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"resources": {},
"security": {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@
},
"Inherit": true
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"resources": {
"DotVVM.Framework.ResourceManagement.InlineScriptResource": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@
{
"namespace": "DotVVM.Framework.Binding.HelperNamespace"
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"resources": {
"DotVVM.Framework.ResourceManagement.InlineScriptResource": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
{
"namespace": "DotVVM.Framework.Binding.HelperNamespace"
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"resources": {},
"security": {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
{
"namespace": "DotVVM.Framework.Binding.HelperNamespace"
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"resources": {
"DotVVM.Framework.ResourceManagement.InlineScriptResource": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
{
"namespace": "DotVVM.Framework.Binding.HelperNamespace"
}
]
],
"ViewCompilation": {
"compileInParallel": true
}
},
"routes": {
"route1": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Threading.Tasks;
using DotVVM.Framework.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace DotVVM.Framework.Compilation
{
public static class DotvvmViewCompilationServiceExtensions
{
public static Task Precompile(this ViewCompilationConfiguration compilationConfiguration,
DotvvmConfiguration config)
{
return Task.Run(async () => {
var compilationService = config.ServiceProvider.GetService<IDotvvmViewCompilationService>();
if (compilationConfiguration.BackgroundCompilationDelay != null)
{
await Task.Delay(compilationConfiguration.BackgroundCompilationDelay.Value);
}

await compilationService.CompileAll(
compilationConfiguration.CompileInParallel, false);
});
}

public static void HandleViewCompilation(this ViewCompilationConfiguration compilationConfiguration, DotvvmConfiguration config)
{
if (compilationConfiguration.Mode == ViewCompilationMode.Lazy)
return;

var getCompilationTask = compilationConfiguration.Precompile(config);
if (compilationConfiguration.Mode == ViewCompilationMode.DuringApplicationStart)
{
getCompilationTask.Wait();
}
}
}
}
21 changes: 21 additions & 0 deletions src/DotVVM.Framework/Compilation/ViewCompilationMode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace DotVVM.Framework.Compilation
{
public enum ViewCompilationMode
{
/// <summary>
/// Compilation will be done when do markup is first needed.
/// </summary>
Lazy,

/// <summary>
/// Compilation will run during application startup.
/// Application will start after compilation is done.
/// </summary>
DuringApplicationStart,

/// <summary>
/// Compilation will run after application started.
/// </summary>
AfterApplicationStart
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ public IList<BindingExtensionParameter> DefaultExtensionParameters
}
private IList<BindingExtensionParameter> _defaultExtensionParameters = new FreezableList<BindingExtensionParameter>();

public ViewCompilationConfiguration ViewCompilation { get; private set; } = new ViewCompilationConfiguration();


public void AddServiceImport(string identifier, Type type)
{
ThrowIfFrozen();
Expand Down Expand Up @@ -173,7 +176,10 @@ private void ThrowIfFrozen()
public void Freeze()
{
this.isFrozen = true;

ViewCompilation.Freeze();
_controls.Freeze();

foreach (var c in this.Controls)
c.Freeze();
_assemblies.Freeze();
Expand Down
73 changes: 73 additions & 0 deletions src/DotVVM.Framework/Configuration/ViewCompilationConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using System;
using DotVVM.Framework.Compilation;
using Newtonsoft.Json;

namespace DotVVM.Framework.Configuration
{
public sealed class ViewCompilationConfiguration
{
private bool isFrozen = false;
private ViewCompilationMode mode;
/// <summary>
/// Gets or sets the mode under which the view compilation (pages, controls, ... ) is done.
/// </summary>
[JsonProperty("mode")]
public ViewCompilationMode Mode
{
get => mode;
set {
ThrowIfFrozen();
mode = value;
}
}

private TimeSpan? backgroundCompilationDelay;
/// <summary>
/// Gets or sets the delay before view compilation will be done. This compilation delay can be set only in precompilation modes.
/// </summary>
[JsonProperty("backgroundCompilationDelay")]
public TimeSpan? BackgroundCompilationDelay
{
get => backgroundCompilationDelay;
set
{
ThrowIfFrozen();
backgroundCompilationDelay = value;
}
}
private bool compileInParallel = true;
/// <summary>
/// Gets or sets whether the view compilation will be performed in parallel or in series.
/// </summary>
[JsonProperty("compileInParallel")]
public bool CompileInParallel
{
get => compileInParallel;
set
{
ThrowIfFrozen();
compileInParallel = value;
}
}

public void Validate()
{
if (BackgroundCompilationDelay.HasValue && (Mode == ViewCompilationMode.Lazy || Mode==ViewCompilationMode.DuringApplicationStart))
{
throw new Exception($"{nameof(BackgroundCompilationDelay)} must be null in {nameof(ViewCompilationMode.Lazy)} {nameof(Mode)}.");
}
}

public void Freeze()
{
Validate();
this.isFrozen = true;
}

private void ThrowIfFrozen()
{
if (isFrozen)
throw FreezableUtils.Error(nameof(DotvvmMarkupConfiguration));
}
}
}
8 changes: 4 additions & 4 deletions src/DotVVM.Framework/Controls/UpdateProgress.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public static IEnumerable<ControlUsageError> ValidateUsage(ResolvedControl contr
{
if ((int)delayProperty.Value < 0)
{
yield return new ControlUsageError("Delay cannot be set to negative number.");
yield return new ControlUsageError($"{nameof(Delay)} cannot be set to negative number.");
}
}

Expand All @@ -102,15 +102,15 @@ public static IEnumerable<ControlUsageError> ValidateUsage(ResolvedControl contr
var excludedQueues = (control.GetValue(ExcludedQueuesProperty) as ResolvedPropertyValue)?.Value as string[];
if (includedQueues != null && excludedQueues != null)
{
yield return new ControlUsageError("The IncludedQueues and ExcludedQueues cannot be used together!");
yield return new ControlUsageError($"The {nameof(IncludedQueues)} and {nameof(ExcludedQueues)} cannot be used together!");
}
if (includedQueues != null && !ValidateQueueNames(includedQueues))
{
yield return new ControlUsageError("The IncludedQueues must contain comma-separated list of queue names (which can contain alphanumeric characters, underscore or dash)!");
yield return new ControlUsageError($"The {nameof(IncludedQueues)} must contain comma-separated list of queue names (which can contain alphanumeric characters, underscore or dash)!");
}
if (excludedQueues != null && !ValidateQueueNames(excludedQueues))
{
yield return new ControlUsageError("The ExcludedQueues must contain comma-separated list of queue names (which can contain alphanumeric characters, underscore or dash)!");
yield return new ControlUsageError($"The {nameof(ExcludedQueues)} must contain comma-separated list of queue names (which can contain alphanumeric characters, underscore or dash)!");
}
}

Expand Down