Skip to content

Ported over #15928 changes for 13.3 RC#16023

Merged
bergmania merged 4 commits intorelease/13.3.0from
v13/fix/pr-15928-redo-for-13.3-rc
Apr 16, 2024
Merged

Ported over #15928 changes for 13.3 RC#16023
bergmania merged 4 commits intorelease/13.3.0from
v13/fix/pr-15928-redo-for-13.3-rc

Conversation

@kjac
Copy link
Copy Markdown
Contributor

@kjac kjac commented Apr 10, 2024

Prerequisites

  • I have added steps to test this contribution in the description below

If there's an existing issue for this PR then this fixes #15827

Description

Due to some V14 branch merges, #15928 is unable to target V13.3, so I have moved over the changes to this PR. See #15928 for more details. All credits go to the original contributors ❤️

For the time being I have not moved over the Lazy dictionary changes, because I wanted to see how the other changes worked without Lazy. It seems to work just as fine. Please comment if they should be re-introduced.

Here's the K6 script execution (from #15827) on this branch:

image

The first execution is without this PR applied, second is with this PR applied.

@kjac kjac changed the base branch from contrib to release/13.3.0 April 10, 2024 10:38
@JasonElkin
Copy link
Copy Markdown
Contributor

JasonElkin commented Apr 10, 2024

Thanks @kjac,

The reason I added lazy was to to make the dictionary creation thread safe. The simple null check can result in race conditions that will wipe out the dictionary unnecessarily. Also, Lazy dries up the initialization code for the dictionary, which doesn't need to happen in two places.

Currently, all the interaction with the dictionary is idempotent so nothing breaks, but it doesn't have to be - this could blow up in future and cause side effects if the dictionary is used differently.

@JasonElkin
Copy link
Copy Markdown
Contributor

JasonElkin commented Apr 10, 2024

@kjac, @bergmania I've put back the GetOrAdd() call that I added in the previous PR as it will avoid extra writes to the dictionary if two (or more) threads try and add a non-existent entry at the same time.

@JasonElkin
Copy link
Copy Markdown
Contributor

One other thing I've noticed...

Does the Dictionary ever actually get instantiated here?

if (culture == string.Empty && segment == string.Empty)
{
if (_interInitialized)
{
return _interValue;
}
_interValue = PropertyType.ConvertSourceToInter(_content, _sourceValue, _isPreviewing);
_interInitialized = true;
return _interValue;
}
if (_sourceValues == null)
{
_sourceValues = InitializeConcurrentDictionary<CompositeStringStringKey, SourceInterValue>();
}

When in the constructor, the same condition determines if the dictionary is instantiated?

if (sourceValue.Culture == string.Empty && sourceValue.Segment == string.Empty)
{
_sourceValue = sourceValue.Value;
}
else
{
if (_sourceValues == null)
{
_sourceValues = InitializeConcurrentDictionary<CompositeStringStringKey, SourceInterValue>();
}

In local testing (albeit with a very limited amount of content and properties) L240 is never hit..

kjac added 2 commits April 11, 2024 08:48
…c' into v13/fix/pr-15928-redo-for-13.3-rc

# Conflicts:
#	src/Umbraco.PublishedCache.NuCache/Property.cs
Comment thread src/Umbraco.PublishedCache.NuCache/Property.cs
Comment thread src/Umbraco.PublishedCache.NuCache/Property.cs
{
_sourceValues = new Dictionary<CompositeStringStringKey, SourceInterValue>();
}
EnsureSourceValuesInitialized();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it ever possible to get here in a state where a null _sourceValues is useful here? This piece of code is very badly documented, but GetSourceValue seems to return null for SourceValue always when there are no source values passed in ctor?

Comment on lines +364 to +365
private readonly object _locko = new();
private ConcurrentDictionary<CompositeStringStringKey, CacheValue>? _values;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
private readonly object _locko = new();
private ConcurrentDictionary<CompositeStringStringKey, CacheValue>? _values;
private ConcurrentDictionary<CompositeStringStringKey, CacheValue>? _values = InitializeConcurrentDictionary<CompositeStringStringKey, CacheValue>();

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Nuklon,

We shouldn't allocate the dictionary up front. It does not need allocating for non-variant properties:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Nuklon,

We shouldn't allocate the dictionary up front. It does not need allocating for non-variant properties:

image

Hmm, I see. That can be checked with _sourceValueIsInvariant I think? If you add ctor with isInvariant parameter, and create dictionary then if necessary?

Comment on lines +376 to +379
lock (_locko)
{
_values ??= InitializeConcurrentDictionary<CompositeStringStringKey, CacheValue>();
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
lock (_locko)
{
_values ??= InitializeConcurrentDictionary<CompositeStringStringKey, CacheValue>();
}

@diger74
Copy link
Copy Markdown

diger74 commented Apr 15, 2024

Hi guys, thanks for porting this fix to v13, I appreciate it!
Would it be possible to add it to v12 as well, please?

@bergmania bergmania merged commit 6379f2f into release/13.3.0 Apr 16, 2024
@bergmania bergmania deleted the v13/fix/pr-15928-redo-for-13.3-rc branch April 16, 2024 06:55
Zeegaan added a commit that referenced this pull request May 22, 2024
* Updates JSON schema for Umbraco 10 with latest references for Forms and Deploy (#15918)

* Ported over #15928 changes for 13.3 RC (#16023)

* Ported over #15928 changes for 13.3 RC

* Use GetOrAdd()

* Lock dictionary initialization

---------

Co-authored-by: Jason Elkin <jasonelkin86@gmail.com>

* Make the API content response builder extendable (#16056)

* Make the API content response builder extendable

* DeliveryApiJsonTypeResolver needs to be extendable too

* bump rc to regular

* Bump to next minor

* Add blocks in RTE telemetry (#16104)

* Add blocks telemetry

* Use constants and update tests

* V13: Add property type information to telemetry (#16109)

* Add property type counts to telemetry

* Use constants and fix tests

* Update description

* V10: Fix for fallback file upload (#14892) (#15868)

* Fix for fallback file upload (#14892)

* Added check for file type

* Removed unneeded null checks and fixed tabs

* Cleaning

* Cleanups, cleanups, and removal of unneeded null checks

* Reverted removal of relationshipservice

* Revert null check removals (too risky)

---------

Co-authored-by: Ambert van Unen <AvanUnen@ilionx.com>
Co-authored-by: Laura Neto <12862535+lauraneto@users.noreply.github.com>

(cherry picked from commit 0b5d1f8)

* Fix up formatting

---------

Co-authored-by: Ambert van Unen <ambertvu@gmail.com>

* Implementors using Umbraco.Tests.Integration won't have to override GetLocalizedTextService

(cherry picked from commit b001668)
(cherry picked from commit 2bb56f1)

* Fix logic for retrieving lastKnownElement

(cherry picked from commit cae106b)

* bump version

* Bump version

* Bump version

* Since v13 properties can sometimes be of type IRichTextEditorIntermediateValue - this was unexpected in the XPath navigator code (#16121)

* Webhook log improvements (#16200)

* fix: include all headers in webhook log

* feat: return webhook log status from server

* feat: make webhook logs deep linkable

* feat: add webhook log pagination

* feat: improve webhook request/response body preview

* V13: Optimize custom MVC routing (#16218)

* Introduce EagerMatcherPolicy to conditionally bypass content routing

* Ensure that the candidate we disable dynamic routing for is valid

* Skip Umbraco endpoints

* Simplify logic a bit

* Move install logic to matcher

* Ensure that dynamic routing is still skipped when in upgrade state

* Fixup comments

* Reduce nesting a bit

* Don't show maintenance page when statically routed controllers are hít

* Remove excess check, since installer requests are statically routed

* V13: Optimize custom MVC routing (#16218)

* Introduce EagerMatcherPolicy to conditionally bypass content routing

* Ensure that the candidate we disable dynamic routing for is valid

* Skip Umbraco endpoints

* Simplify logic a bit

* Move install logic to matcher

* Ensure that dynamic routing is still skipped when in upgrade state

* Fixup comments

* Reduce nesting a bit

* Don't show maintenance page when statically routed controllers are hít

* Remove excess check, since installer requests are statically routed

(cherry picked from commit ba9ddd1)

* Property source level variation should only be applied when configured (#16270)

* Property source level variation should only be applied when configured (#16270)

(cherry picked from commit ab32bac)

* Merge pull request from GHSA-j74q-mv2c-rxmp

* Merge pull request from GHSA-j74q-mv2c-rxmp

* Merge pull request from GHSA-j74q-mv2c-rxmp

* Fix up after merge

* Remove obselete test

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
Co-authored-by: Jason Elkin <jasonelkin86@gmail.com>
Co-authored-by: Sven Geusens <sge@umbraco.dk>
Co-authored-by: Mole <nikolajlauridsen@protonmail.ch>
Co-authored-by: Ambert van Unen <ambertvu@gmail.com>
Co-authored-by: Lars-Erik <lars-erik@aabech.no>
Co-authored-by: Joshua Daniel Pratt Nielsen <jdpnielsen@gmail.com>
Co-authored-by: Bjarke Berg <mail@bergmania.dk>
Co-authored-by: Sebastiaan Janssen <sebastiaan@umbraco.com>
Co-authored-by: Rasmus John Pedersen <mail@rjp.dk>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Content Delivery API deadlocks when simultaneously requesting items referencing each other

6 participants