Skip to content

Search Param UrlLookup and TypeLookup mismatch fix#5386

Closed
jestradaMS wants to merge 19 commits intomainfrom
users/jestrada/searchparamlookupobjectfix
Closed

Search Param UrlLookup and TypeLookup mismatch fix#5386
jestradaMS wants to merge 19 commits intomainfrom
users/jestrada/searchparamlookupobjectfix

Conversation

@jestradaMS
Copy link
Contributor

@jestradaMS jestradaMS commented Feb 12, 2026

Description

This pull request addresses a concurrency bug in the FHIR search parameter definition logic and makes related improvements to ensure the consistency and correctness of search parameter handling. The primary change is to ensure that a single canonical instance of each SearchParameterInfo is used across all lookups, preventing issues where updates to search parameter status would not propagate correctly. Additionally, there are minor adjustments to test configurations and a correction to a search parameter type in R5.

Concurrency and Consistency Improvements:

  • Refactored SearchParameterDefinitionBuilder to use a ConcurrentDictionary<string, SearchParameterInfo> for the URI dictionary and ensure atomic creation and retrieval of SearchParameterInfo instances via GetOrAdd. This guarantees that both UrlLookup and TypeLookup reference the same object, preventing inconsistencies due to race conditions. [1] [2] [3]
  • Updated the BuildSearchParameterDefinition method and its recursive calls to accept and use the shared uriDictionary, ensuring canonicalization throughout the search parameter inheritance chain. [1] [2] [3]
  • Modified the logic for adding search parameters to the type lookup so that it always uses the canonical instance from the URI dictionary, ensuring that status and other updates are visible everywhere. [1] [2]

FHIR Search Parameter Type Correction:

  • Changed the type of the Resource-type search parameter from "special" to "token" in the R5 search parameters JSON, aligning with system support and maintaining compatibility with previous FHIR versions.

Test Configuration Adjustments:

  • Increased the delay between polling attempts in the reindex E2E tests from 1 second to 5 seconds, likely to reduce flakiness or rate limiting issues.
  • Raised the initial collection throughput for Cosmos DB in integration tests from 1500 to 5000, potentially to improve test reliability or performance.

Related issues

Addresses AB#183574

Testing

Describe how this change was tested.

FHIR Team Checklist

  • Update the title of the PR to be succinct and less than 65 characters
  • Add a milestone to the PR for the sprint that it is merged (i.e. add S47)
  • Tag the PR with the type of update: Bug, Build, Dependencies, Enhancement, New-Feature or Documentation
  • Tag the PR with Open source, Azure API for FHIR (CosmosDB or common code) or Azure Healthcare APIs (SQL or common code) to specify where this change is intended to be released.
  • Tag the PR with Schema Version backward compatible or Schema Version backward incompatible or Schema Version unchanged if this adds or updates Sql script which is/is not backward compatible with the code.
  • When changing or adding behavior, if your code modifies the system design or changes design assumptions, please create and include an ADR.
  • CI is green before merge Build Status
  • Review squash-merge requirements

Semver Change (docs)

Patch|Skip|Feature|Breaking (reason)

@jestradaMS jestradaMS requested a review from a team as a code owner February 12, 2026 23:20
@jestradaMS jestradaMS changed the title [DO NOT REVIEW] UrlLookup and TypeLookup mismatch fix [DO NOT REVIEW] Search Param UrlLookup and TypeLookup mismatch fix Feb 12, 2026
@jestradaMS jestradaMS changed the title [DO NOT REVIEW] Search Param UrlLookup and TypeLookup mismatch fix Search Param UrlLookup and TypeLookup mismatch fix Feb 12, 2026
@jestradaMS jestradaMS added this to the FY26\Q3\2Wk\2Wk17 milestone Feb 13, 2026
@jestradaMS jestradaMS added Bug-Reliability Reliability related bugs. Azure API for FHIR Label denotes that the issue or PR is relevant to the Azure API for FHIR Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs No-PaaS-breaking-change No-ADR ADR not needed labels Feb 13, 2026
@jestradaMS
Copy link
Contributor Author

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 1 pipeline(s).

@@ -357,30 +353,45 @@ private static HashSet<SearchParameterInfo> BuildSearchParameterDefinition(
var searchParameterDictionary = new ConcurrentDictionary<string, ConcurrentQueue<SearchParameterInfo>>();
foreach (SearchParameterInfo searchParam in results)
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider changing searchParam name here instead of changing it in many places below

// URL http://hl7.org/fhir/SearchParameter/Resource-type with type Special,
// while ResourceTypeSearchParameter uses the same URL with type Token.
// Choosing the wrong type causes parser failures for _type queries.
SearchParameterInfo canonicalParam = searchParam;
Copy link
Contributor

Choose a reason for hiding this comment

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

Consider using name that closer identifies what search param origin is. Like searchParamFromUriLookup

// while ResourceTypeSearchParameter uses the same URL with type Token.
// Choosing the wrong type causes parser failures for _type queries.
SearchParameterInfo canonicalParam = searchParam;
if (searchParam.Url != null &&
Copy link
Contributor

@SergeyGaluzo SergeyGaluzo Feb 13, 2026

Choose a reason for hiding this comment

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

Is searchParam valid at this point? If so, why do we check that Uri is not null?

@SergeyGaluzo
Copy link
Contributor

SergeyGaluzo commented Feb 14, 2026

How about changing our lookup data structures such that it is impossible to get different instances of SearchParameterInfo (SPI) by design?
Imagine that TypeLookup does not have SPI at the bottom but only Uri string. In all the cases when we need to get SPI from TypeLookup we would just need to do extra lookup in UriLookup. There is no way get incorrect data in SPI's from TypeLookup and UriLookup because SPI is "stored" in a single place by definition.

@SergeyGaluzo
Copy link
Contributor

This PR solves atomicity of cache writes for UriLookup. We still don't maintain other 2 data structures (TypeLookup and hash lookup) atomically with UriLookup. It would be interesting to know the reasons for cache components to be out of sync. Is it racing writes or incorrect write workflow?. Please keep in mind that we most likely should remove racing writes and will keep all updates single directional and single threaded (from the database to cache) to have identical logic across all VMs.

@jestradaMS jestradaMS marked this pull request as draft February 19, 2026 15:44
@jestradaMS jestradaMS closed this Feb 19, 2026
@jestradaMS jestradaMS deleted the users/jestrada/searchparamlookupobjectfix branch February 19, 2026 19:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Azure API for FHIR Label denotes that the issue or PR is relevant to the Azure API for FHIR Azure Healthcare APIs Label denotes that the issue or PR is relevant to the FHIR service in the Azure Healthcare APIs Bug-Reliability Reliability related bugs. No-ADR ADR not needed No-PaaS-breaking-change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants