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

Add Async method to ContentDefinitionManager to prevent possible thread starvation #14668

Merged
merged 28 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
62341f3
Add Async method to ContentDefinitionManager to prevent possible thre…
MikeAlhayek Nov 11, 2023
b3d0634
Address more warnings
MikeAlhayek Nov 11, 2023
cd2bbb7
more warnings
MikeAlhayek Nov 11, 2023
b021f19
Address more warnings
MikeAlhayek Nov 11, 2023
07af98e
More warnings
MikeAlhayek Nov 11, 2023
c0148fd
Should be all the warnings.
MikeAlhayek Nov 12, 2023
4703c2e
cleanup and document the changes.
MikeAlhayek Nov 12, 2023
68025fe
Fix build
MikeAlhayek Nov 12, 2023
919a40f
Update index providers
MikeAlhayek Nov 12, 2023
8b169ee
Final update after auditing the PR
MikeAlhayek Nov 12, 2023
84b3e9c
Update docs
MikeAlhayek Nov 12, 2023
e044e54
update edit view
MikeAlhayek Nov 12, 2023
9c1e59d
Fix errors
MikeAlhayek Nov 12, 2023
1c6def8
update the index providers to use Map async
MikeAlhayek Nov 13, 2023
55ed397
Merge remote-tracking branch 'origin/main' into ma/use-async
jtkech Nov 20, 2023
71b5a7b
wip
jtkech Nov 20, 2023
0df91e5
wip
jtkech Nov 20, 2023
5dde514
Clean up and remove unnecessary calls
MikeAlhayek Nov 21, 2023
fa6198c
Use INamedContentDefinitionRecord
MikeAlhayek Nov 21, 2023
fb7970e
Merge remote-tracking branch 'origin/main' into ma/use-async
MikeAlhayek Nov 21, 2023
d12d07c
Cleanup
MikeAlhayek Nov 22, 2023
fe492e2
wip
jtkech Nov 23, 2023
b8002f8
tweaks
jtkech Nov 23, 2023
422aaad
Order methods as in Interface
jtkech Nov 23, 2023
88c4c20
tweaks
jtkech Nov 23, 2023
b6592ea
Minor change
jtkech Nov 23, 2023
4874844
Minor formatting
jtkech Nov 23, 2023
7e8d0f4
Minor changes
jtkech Nov 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public async Task<IActionResult> Index()
if (model.CanManageDashboard || await _authorizationService.AuthorizeAsync(User, Permissions.AccessAdminDashboard))
{
var wrappers = new List<DashboardWrapper>();
var widgetContentTypes = GetDashboardWidgets();
var widgetContentTypes = await GetDashboardWidgetsAsync();

var widgets = await _adminDashboardService.GetWidgetsAsync(x => x.Published);
foreach (var widget in widgets)
Expand Down Expand Up @@ -99,7 +99,7 @@ public async Task<IActionResult> Manage()
});

var dashboardCreatable = new List<SelectListItem>();
var widgetContentTypes = GetDashboardWidgets();
var widgetContentTypes = await GetDashboardWidgetsAsync();

var userId = User.FindFirstValue(ClaimTypes.NameIdentifier);

Expand Down Expand Up @@ -202,8 +202,8 @@ public async Task<IActionResult> Update([FromForm] DashboardPartViewModel[] part
return RedirectToAction(nameof(Manage));
}

private Dictionary<string, ContentTypeDefinition> GetDashboardWidgets()
=> _contentDefinitionManager.ListTypeDefinitions()
private async Task<Dictionary<string, ContentTypeDefinition>> GetDashboardWidgetsAsync()
=> (await _contentDefinitionManager.ListTypeDefinitionsAsync())
.Where(t => t.StereotypeEquals("DashboardWidget"))
.ToDictionary(ctd => ctd.Name, ctd => ctd);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public async Task<int> CreateAsync()
"Position")
);

_contentDefinitionManager.AlterPartDefinition("DashboardPart", builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync("DashboardPart", builder => builder
.Attachable()
.WithDescription("Provides a way to add widgets to a dashboard.")
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
Expand Down Expand Up @@ -61,7 +60,7 @@ public async override Task UpdatedAsync(UpdateContentContext context, AliasPart
return;
}

var pattern = GetPattern(part);
var pattern = await GetPatternAsync(part);

if (!string.IsNullOrEmpty(pattern))
{
Expand Down Expand Up @@ -122,9 +121,9 @@ public override async Task CloningAsync(CloneContentContext context, AliasPart p
/// <summary>
/// Get the pattern from the AliasPartSettings property for its type.
/// </summary>
private string GetPattern(AliasPart part)
private async Task<string> GetPatternAsync(AliasPart part)
{
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType);
var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.PartDefinition.Name, nameof(AliasPart)));
var pattern = contentTypePartDefinition.GetSettings<AliasPartSettings>().Pattern;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public AliasPartIndexProvider(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
}

public override Task UpdatedAsync(UpdateContentContext context)
public override async Task UpdatedAsync(UpdateContentContext context)
{
var part = context.ContentItem.As<AliasPart>();

Expand All @@ -43,19 +43,19 @@ public override Task UpdatedAsync(UpdateContentContext context)
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

// Search for this part.
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType);
if (!contentTypeDefinition.Parts.Any(ctpd => ctpd.Name == nameof(AliasPart)))
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType);
if (!contentTypeDefinition.Parts.Any(ctd => ctd.Name == nameof(AliasPart)))
{
context.ContentItem.Remove<AliasPart>();
_partRemoved.Add(context.ContentItem.ContentItemId);
}
}

return Task.CompletedTask;
}

public string CollectionName { get; set; }

public Type ForType() => typeof(ContentItem);

public void Describe(IDescriptor context) => Describe((DescribeContext<ContentItem>)context);

public void Describe(DescribeContext<ContentItem> context)
Expand Down
5 changes: 3 additions & 2 deletions src/OrchardCore.Modules/OrchardCore.Alias/Migrations.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using OrchardCore.Alias.Indexes;
using OrchardCore.Alias.Models;
using OrchardCore.ContentManagement.Metadata;
Expand All @@ -16,9 +17,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager)
_contentDefinitionManager = contentDefinitionManager;
}

public int Create()
public async Task<int> CreateAsync()
{
_contentDefinitionManager.AlterPartDefinition(nameof(AliasPart), builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(AliasPart), builder => builder
.Attachable()
.WithDescription("Provides a way to define custom aliases for content items."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,21 @@ public ArchiveLaterPartIndexProvider(IServiceProvider serviceProvider)
_serviceProvider = serviceProvider;
}

public override Task UpdatedAsync(UpdateContentContext context)
public override async Task UpdatedAsync(UpdateContentContext context)
{
var part = context.ContentItem.As<ArchiveLaterPart>();

if (part != null)
{
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(context.ContentItem.ContentType);
if (!contentTypeDefinition.Parts.Any(pd => pd.Name == nameof(ArchiveLaterPart)))
{
context.ContentItem.Remove<ArchiveLaterPart>();
_partRemoved.Add(context.ContentItem.ContentItemId);
}
}

return Task.CompletedTask;
}

public string CollectionName { get; set; }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Threading.Tasks;
using OrchardCore.ArchiveLater.Indexes;
using OrchardCore.ArchiveLater.Models;
using OrchardCore.ContentManagement.Metadata;
Expand All @@ -17,9 +18,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager)
_contentDefinitionManager = contentDefinitionManager;
}

public int Create()
public async Task<int> CreateAsync()
{
_contentDefinitionManager.AlterPartDefinition(nameof(ArchiveLaterPart), builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync(nameof(ArchiveLaterPart), builder => builder
.Attachable()
.WithDescription("Adds the ability to schedule content items to be archived at a given future date and time."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ public async override Task CloningAsync(CloneContentContext context, AutoroutePa

public override Task GetContentItemAspectAsync(ContentItemAspectContext context, AutoroutePart part)
{
return context.ForAsync<RouteHandlerAspect>(aspect =>
return context.ForAsync<RouteHandlerAspect>(async aspect =>
{
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType);
var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.PartDefinition.Name, "AutoroutePart"));
var settings = contentTypePartDefinition.GetSettings<AutoroutePartSettings>();
if (settings.ManageContainedItemRoutes)
Expand All @@ -163,8 +163,6 @@ public override Task GetContentItemAspectAsync(ContentItemAspectContext context,
aspect.Absolute = part.Absolute;
aspect.Disabled = part.Disabled;
}

return Task.CompletedTask;
});
}

Expand Down Expand Up @@ -380,7 +378,7 @@ private async Task GenerateContainerPathFromPatternAsync(AutoroutePart part)
return;
}

var pattern = GetPattern(part);
var pattern = await GetPatternAsync(part);

if (!string.IsNullOrEmpty(pattern))
{
Expand Down Expand Up @@ -422,9 +420,9 @@ private async Task GenerateContainerPathFromPatternAsync(AutoroutePart part)
/// <summary>
/// Get the pattern from the AutoroutePartSettings property for its type.
/// </summary>
private string GetPattern(AutoroutePart part)
private async Task<string> GetPatternAsync(AutoroutePart part)
{
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(part.ContentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(part.ContentItem.ContentType);
var contentTypePartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.PartDefinition.Name, nameof(AutoroutePart)));
var pattern = contentTypePartDefinition.GetSettings<AutoroutePartSettings>().Pattern;

Expand Down
9 changes: 5 additions & 4 deletions src/OrchardCore.Modules/OrchardCore.Autoroute/Migrations.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Threading.Tasks;
using OrchardCore.Autoroute.Core.Indexes;
using OrchardCore.Autoroute.Models;
using OrchardCore.ContentManagement.Metadata;
Expand All @@ -16,9 +17,9 @@ public Migrations(IContentDefinitionManager contentDefinitionManager)
_contentDefinitionManager = contentDefinitionManager;
}

public int Create()
public async Task<int> CreateAsync()
{
_contentDefinitionManager.AlterPartDefinition("AutoroutePart", builder => builder
await _contentDefinitionManager.AlterPartDefinitionAsync("AutoroutePart", builder => builder
.Attachable()
.WithDescription("Provides a custom url for your content item."));

Expand All @@ -37,9 +38,9 @@ public int Create()

// Migrate PartSettings. This only needs to run on old content definition schemas.
// This code can be removed in a later version.
public int UpdateFrom1()
public async Task<int> UpdateFrom1Async()
{
_contentDefinitionManager.MigratePartSettings<AutoroutePart, AutoroutePartSettings>();
await _contentDefinitionManager.MigratePartSettingsAsync<AutoroutePart, AutoroutePartSettings>();

return 2;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,25 +27,24 @@ IContentManager contentManager

public async Task<string> GetRouteAsync(SitemapBuilderContext context, ContentItem contentItem)
{
var ctd = ListRoutableTypeDefinitions()?
.FirstOrDefault(rctd => rctd.Name == contentItem.ContentType);
var ctd = (await ListRoutableTypeDefinitionsAsync())?.FirstOrDefault(ctd => ctd.Name == contentItem.ContentType);

if (ctd != null)
{
var contentItemMetadata = await _contentManager.PopulateAspectAsync<ContentItemMetadata>(contentItem);
var routes = contentItemMetadata.DisplayRouteValues;

// UrlHelper.Action includes BasePath automatically if present.
// If content item is assigned as home route, Urlhelper resolves as site root.
// If content item is assigned as home route, UrlHelper resolves as site root.
return context.HostPrefix + context.UrlHelper.Action(routes["Action"].ToString(), routes);
}

return null;
}

public IEnumerable<ContentTypeDefinition> ListRoutableTypeDefinitions()
public async Task<IEnumerable<ContentTypeDefinition>> ListRoutableTypeDefinitionsAsync()
{
return _contentDefinitionManager.ListTypeDefinitions()
return (await _contentDefinitionManager.ListTypeDefinitionsAsync())
.Where(ctd => ctd.Parts.Any(p => p.Name == nameof(AutoroutePart)));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public async Task<IActionResult> SearchContentItems(string part, string field, s
return BadRequest("Part and field are required parameters");
}

var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields
var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields
.FirstOrDefault(f => f.Name == field);

var fieldSettings = partFieldDefinition?.GetSettings<ContentPickerFieldSettings>();
Expand All @@ -57,7 +57,7 @@ public async Task<IActionResult> SearchContentItems(string part, string field, s

if (fieldSettings.DisplayedStereotypes != null && fieldSettings.DisplayedStereotypes.Length > 0)
{
contentTypes = _contentDefinitionManager.ListTypeDefinitions()
contentTypes = (await _contentDefinitionManager.ListTypeDefinitionsAsync())
.Where(contentType =>
{
var hasStereotype = contentType.TryGetStereotype(out var stereotype);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task<IActionResult> SearchLocalizationSets(string part, string fiel
return BadRequest("Part and field are required parameters");
}

var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields
var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields
.FirstOrDefault(f => f.Name == field);

var fieldSettings = partFieldDefinition?.GetSettings<LocalizationSetContentPickerFieldSettings>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
Expand Down Expand Up @@ -53,7 +52,7 @@ public async Task<IActionResult> SearchUsers(string part, string field, string c
return Forbid();
}

var partFieldDefinition = _contentDefinitionManager.GetPartDefinition(part)?.Fields
var partFieldDefinition = (await _contentDefinitionManager.GetPartDefinitionAsync(part))?.Fields
.FirstOrDefault(f => f.Name == field);

var fieldSettings = partFieldDefinition?.GetSettings<UserPickerFieldSettings>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ private static async Task<object> RenderHtml(IResolveFieldContext<HtmlField> ctx
var paths = jsonPath.Split('.');
var partName = paths[0];
var fieldName = paths[1];
var contentTypeDefinition = contentDefinitionManager.GetTypeDefinition(ctx.Source.ContentItem.ContentType);
var contentTypeDefinition = await contentDefinitionManager.GetTypeDefinitionAsync(ctx.Source.ContentItem.ContentType);
var contentPartDefinition = contentTypeDefinition.Parts.FirstOrDefault(x => string.Equals(x.Name, partName));
var contentPartFieldDefintion = contentPartDefinition.PartDefinition.Fields.FirstOrDefault(x => string.Equals(x.Name, fieldName));
var settings = contentPartFieldDefintion.GetSettings<HtmlFieldSettings>();
var contentPartFieldDefinition = contentPartDefinition.PartDefinition.Fields.FirstOrDefault(x => string.Equals(x.Name, fieldName));
var settings = contentPartFieldDefinition.GetSettings<HtmlFieldSettings>();

var html = ctx.Source.Html;

Expand All @@ -59,7 +59,7 @@ private static async Task<object> RenderHtml(IResolveFieldContext<HtmlField> ctx
Html = ctx.Source.Html,
Field = ctx.Source,
Part = ctx.Source.ContentItem.Get<ContentPart>(partName),
PartFieldDefinition = contentPartFieldDefintion
PartFieldDefinition = contentPartFieldDefinition
};
var liquidTemplateManager = serviceProvider.GetRequiredService<ILiquidTemplateManager>();
var htmlEncoder = serviceProvider.GetService<HtmlEncoder>();
Expand All @@ -72,7 +72,7 @@ private static async Task<object> RenderHtml(IResolveFieldContext<HtmlField> ctx
new Context
{
["ContentItem"] = ctx.Source.ContentItem,
["PartFieldDefinition"] = contentPartFieldDefintion
["PartFieldDefinition"] = contentPartFieldDefinition
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public BooleanFieldIndexProvider(IServiceProvider serviceProvider)
public override void Describe(DescribeContext<ContentItem> context)
{
context.For<BooleanFieldIndex>()
.Map(contentItem =>
.Map(async contentItem =>
{
// Remove index records of soft deleted items.
if (!contentItem.Published && !contentItem.Latest)
Expand All @@ -47,7 +47,7 @@ public override void Describe(DescribeContext<ContentItem> context)
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

// Search for BooleanField
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType);

// This can occur when content items become orphaned, particularly layer widgets when a layer is removed, before its widgets have been unpublished.
if (contentTypeDefinition == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public ContentPickerFieldIndexProvider(IServiceProvider serviceProvider)
public override void Describe(DescribeContext<ContentItem> context)
{
context.For<ContentPickerFieldIndex>()
.Map(contentItem =>
.Map(async contentItem =>
{
// Remove index records of soft deleted items.
if (!contentItem.Published && !contentItem.Latest)
Expand All @@ -47,7 +47,7 @@ public override void Describe(DescribeContext<ContentItem> context)
_contentDefinitionManager ??= _serviceProvider.GetRequiredService<IContentDefinitionManager>();

// Search for ContentPickerField
var contentTypeDefinition = _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType);
var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType);

// This can occur when content items become orphaned, particularly layer widgets when a layer is removed, before its widgets have been unpublished.
if (contentTypeDefinition == null)
Expand Down
Loading