') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Support use of fast-path serialization in combined JsonSerializerContexts. by eiriktsarpalis · Pull Request #80741 · dotnet/runtime · GitHub
Skip to content

Support use of fast-path serialization in combined JsonSerializerContexts. - #80741

Merged
eiriktsarpalis merged 2 commits into
dotnet:mainfrom
eiriktsarpalis:fix-fast-path-composition
Feb 8, 2023
Merged

Support use of fast-path serialization in combined JsonSerializerContexts.#80741
eiriktsarpalis merged 2 commits into
dotnet:mainfrom
eiriktsarpalis:fix-fast-path-composition

Conversation

@eiriktsarpalis

@eiriktsarpaliseiriktsarpalis commented Jan 17, 2023

Copy link
Copy Markdown
Member

Fixes#71933 by adding a new JsonTypeInfo.OriginatingResolver public property that is used by source generated JsonSerializerContext instances to register themselves with JsonTypeInfo instances that they generate. This information can be used to determine if the fast-path serialization delegate is compatible with the current configuration, even if the originating JsonSerializerContext is encapsulated behind a custom resolver.

@ghost

Copy link
Copy Markdown

Note regarding the new-api-needs-documentation label:

This serves as a reminder for when your PR is modifying a ref *.cs file and adding/modifying public APIs, to please make sure the API implementation in the src *.cs file is documented with triple slash comments, so the PR reviewers can sign off that change.

@eiriktsarpaliseiriktsarpalis self-assigned this Jan 17, 2023
@eiriktsarpaliseiriktsarpalis added this to the 8.0.0 milestone Jan 17, 2023
@ghost

Copy link
Copy Markdown

Tagging subscribers to this area: @dotnet/area-system-text-json, @gregsdennis
See info in area-owners.md if you want to be subscribed.

Issue Details

Fixes #71933 by adding a new JsonTypeInfo.OriginatingResolver public property that is used by source generated JsonSerializerContext instances to register themselves with JsonTypeInfo instances that they generate. This information can be used to determine if the fast-path serialization delegate is compatible with the current configuration, even if the originating JsonSerializerContext is encapsulated behind a custom resolver.

NB the new property hasn't been approved in API review yet.

Author:eiriktsarpalis
Assignees:-
Labels:

area-System.Text.Json, new-api-needs-documentation

Milestone:-

@krwq

krwq commented Jan 19, 2023

Copy link
Copy Markdown
Member

Do we actually need new API? I can see at least two ways we can do it without new API:

  • not assign SerializeHandler in cases where fast path should not be used - we can move the fast path checking logic to a generated context.
  • another option is we wrap every context with combined (as effective resolver, from user perspective they wouldn't know about it). Then combined one could check if all contexts are compatible between each other and with the options. Then combined context can decide if fast path can be used (so rather than checking if resolver is context we check if it's combined resolver and go from there)
    the second option might be easier and should be compatible with contexts generated in previous versions

@eiriktsarpalis

Copy link
Copy Markdown
MemberAuthor

not assign SerializeHandler in cases where fast path should not be used - we can move the fast path checking logic to a generated context.

That might just work actually. We could remove the runtime invalidation altogether and just decide if the fast path should be assigned at the context layer.

@eiriktsarpalis

Copy link
Copy Markdown
MemberAuthor

not assign SerializeHandler in cases where fast path should not be used - we can move the fast path checking logic to a generated context.

That might just work actually. We could remove the runtime invalidation altogether and just decide if the fast path should be assigned at the context layer.

Actually, I was wrong about this. We would still need to expose new API but even then this cannot account for contexts generated by older versions of the sdk; we still need to do this invalidation in the JsonTypeInfo layer.

@eiriktsarpalis
eiriktsarpalis marked this pull request as draft January 30, 2023 18:29
@eiriktsarpalis

Copy link
Copy Markdown
MemberAuthor

Converting to draft, as more infrastructural changes on JsonTypeInfo are required before we are able to implement proper invalidation.

@eiriktsarpalis
eiriktsarpalisforce-pushed the fix-fast-path-composition branch from e4a54f0 to 598634bCompareFebruary 3, 2023 23:44
@eiriktsarpalis
eiriktsarpalis marked this pull request as ready for review February 3, 2023 23:47
@eiriktsarpalis

Copy link
Copy Markdown
MemberAuthor

I've updated the PR and it should be ready for review again. @krwq & @layomia PTAL.

Comment on lines 667 to 682

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should you be checking IsConfigured here as well?

@eiriktsarpaliseiriktsarpalisFeb 8, 2023

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

It could be false if you're configuring recursive types. Checking IsConfigured on JsonPropertyInfo is a different story, it completes regardless of cycles.

@krwqkrwqFeb 8, 2023

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

should this also check for Modifiers.Count == 0 and GetType() == typeof(DefaultJsonTypeInfoResolver)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

In this case you don't need to, any customization to the particular JsonTypeInfo would get picked up by the IsModified property.

@eiriktsarpalis
eiriktsarpalisforce-pushed the fix-fast-path-composition branch from 0be172d to 09f8062CompareFebruary 8, 2023 14:26
krwq
krwq approved these changes Feb 8, 2023
@eiriktsarpalis
eiriktsarpalis merged commit 0304f1f into dotnet:mainFeb 8, 2023
@eiriktsarpalis
eiriktsarpalis deleted the fix-fast-path-composition branch February 8, 2023 19:44
@ghostghost locked as resolved and limited conversation to collaborators Mar 11, 2023
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

System.Text.Json fast path serialization not working with combined contexts

3 participants

@eiriktsarpalis@krwq@layomia