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

Dereference Architecture 2.0 #3915

Closed
char0n opened this issue Mar 12, 2024 · 0 comments
Closed

Dereference Architecture 2.0 #3915

char0n opened this issue Mar 12, 2024 · 0 comments
Assignees
Labels
ApiDOM documentation Improvements or additions to documentation

Comments

@char0n
Copy link
Member

char0n commented Mar 12, 2024

Foundational theory

Before transcluding the referenced fragment into the ApiDOM tree, it is crawled again recursively. This step ensures that all nested references within the fragment are resolved correctly and helps in detecting and managing any potential cycles introduced by the transclusion process. This recursive approach is key to accurately handling complex ApiDOM trees that may contain nested references or potential cycles.

When the original referenced structure is crawled again in its original position, the process checks for circular references by using the tracking mechanisms called ancestor lineage. If a structure is identified as being part of the current traversal path (indicating a cycle), the process can handle it according to the predefined logic, such as replacing it with a specific value or handling it based on the options provided for circular references. This ensures that even when revisiting parts of the ApiDOM tree, the integrity of the dereferencing process is maintained, and infinite recursion is avoided.

Structures may be traversed repeatedly to ensure all references are correctly resolved, including handling potential circular references. This repeated traversal is essential for thoroughly processing and dereferencing the entire ApiDOM tree, especially in complex trees with nested and interconnected references. The process aims to ensure completeness and integrity of the dereferenced schema.

If we do not need to detect and handle circular references and are intentionally creating cycles through transclusion, we might not need to re-traverse the referenced structure for cycle detection. Without the requirement to detect cycles, we can transclude references directly into the ApiDOM tree, simplifying the process. However, these cycles might impact the consumers of our ApiDOM tree, as they could lead to infinite loops or other issues in applications not equipped to handle such structures.

In a scenario where multiple references point to the same value, the actual dereferencing of the value to replace the reference with its content happens once, leveraging caching to avoid redundant work. However, for cycle detection purposes, each occurrence of a reference in the schema is crawled through, to ensure that newly introduced references do not create unintended circular dependencies, even if they point to an already dereferenced value. This approach helps maintain the schema's integrity while optimizing the dereferencing process.

Dereference modes

Three distinct dereference modes have been identified when creating POC for the foundational theory: ignore, replace, error

Ignore mode

This mode doesn't care if dereferencing introduces cycles to the ApiDOM tree. It's the fastest mode available and implements recursive traversal prevention mechanism to avoid infinite traversals. Ignore mode can produce ApiDOM both as acyclic directed tree and cyclic directed graph.

Replace mode

Replace mode is the slowest one as it implements cycle tracking mechanism along with recursive traversal prevention mechanism. Before transcluding the dereferenced value, repeated traversal is performed on the entire transluded value and if cycle is detected, the cycle is by default replaced by RefElement which contains ID of element it references. Custom replacer can be supplied to bypass the default cycle replacement mechanism. Replace mode can produce only ApiDOM as acyclic directed tree.

ApiDOM acyclic directed tree can be subsequently run through the additional RefElement removal mechanism that will translate all RefElements into real JavaScript cycles.

Error mode

Error mode throws error as soon as it detects the first cycle. It interrupts the the traversal and prevents it to continue.

Immutability

Dereferencing can be performed in both immutable and mutable modes. Internally we're leveraging the fact that JavaScript allows mutable operations to be performed on values. Technically dereferencing is performed exclusively by mutations. When run in immutable mode, the input ApiDOM trees are deep cloned before they are dereferenced. And his is how immutability of dereferencing (if requested) is achieved.

@char0n char0n self-assigned this Mar 12, 2024
@char0n char0n added documentation Improvements or additions to documentation ApiDOM labels Mar 12, 2024
@char0n char0n closed this as completed Mar 13, 2024
char0n added a commit to swagger-api/swagger-js that referenced this issue Apr 17, 2024
char0n added a commit to swagger-api/swagger-js that referenced this issue Apr 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ApiDOM documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

1 participant