Skip to content

Commit

Permalink
Add data flow
Browse files Browse the repository at this point in the history
  • Loading branch information
joshcooper committed Dec 8, 2023
1 parent 4b00be7 commit 8c90493
Showing 1 changed file with 39 additions and 0 deletions.
39 changes: 39 additions & 0 deletions docs/data-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
## Data Flow

This shows the general data flow when a user run facter on the command to lookup facts `a.b` and `c`.

Generally, facter loads fact definitions (`LoadedFact`) to determine all of the things it could collect, including internal (aka core) facts, custom facts (implemented using the `Facter.add` API) and external facts (json, yaml, bash, etc). Each `LoadedFact` specifies a name like `os.family` and a class that can be called later to collect the values, e.g. `Facts::Linux::Os::Release`.

The `QueryParser` parse both user queries `a.b` and `c` and matches each query against all LoadedFacts, returning an array of `SearchedFacts`. These are more like SearchableFacts, since they haven't been searched yet.

Facter attempts to lookup the facts from the cache, otherwise it calls the `InternalFactManager` and `ExternalFactManager` to resolve the fact.

For internal facts, facter wraps each `SearchedFact` with a `CoreFact`. The `CoreFact` calls the `call\_the\_resolver` method on the class that the `SearchedFact` references. The `call\_the\_resolver` method then typically delegates to a resolver and returns the fact value which may be scalar or structured data. For example, `os.family` returns a string, but `gce` returns a Hash.

```mermaid
flowchart TD
CLI[facter a.b c] --> Facter[Facter.to_user_output]
Facter --> FactManager[FactManager#resolve_facts]
FactManager --> FactLoader[FactLoader.load]
FactLoader -->|internal| InternalFactLoader[InternalLoader.core_facts]
FactLoader -->|custom| CustomFactLoader[ExternalFactLoader.custom_facts]
FactLoader -->|external| ExternalFactLoader[ExternalFactLoader.external_facts]
InternalFactLoader --> QueryParser[QueryParser.parse]
CustomFactLoader --> QueryParser
ExternalFactLoader --> QueryParser
QueryParser -->|empty query| AllSearchable[All loaded facts are searchable]
QueryParser -->|not empty| SomeSearchable[Match query tokens to loaded facts]
AllSearchable --> SearchedFacts[Array of SearchedFacts]
SomeSearchable --> SearchedFacts
SearchedFacts --> CacheManager[CacheManager.resolve_facts]
CacheManager -->|internal| InternalFactManager[InternalFactManager.resolve_facts]
InternalFactManager --> CoreFact[CoreFact#create]
CoreFact --> SearchedFact[SearchedFact -> call_the_resolver]
SearchedFact --> Resolvers[Facter::Resolvers::*.resolve]
CacheManager -->|external| ExternalFactManager[ExternalFactManager.resolve_facts]
Resolvers --> ResolvedFacts[Array of ResolvedFacts]
ExternalFactManager --> ResolvedFacts
ResolvedFacts --> CacheFacts[CacheManager.cache_facts]
CacheFacts --> FilterFacts[FactFilter#filter_facts!]
FilterFacts --> Formatter
```

0 comments on commit 8c90493

Please sign in to comment.