Skip to content

WIP kubeconfig refresh#59

Draft
ivankatliarchuk wants to merge 2 commits into
masterfrom
chore-refactore-kubeconfig-v1
Draft

WIP kubeconfig refresh#59
ivankatliarchuk wants to merge 2 commits into
masterfrom
chore-refactore-kubeconfig-v1

Conversation

@ivankatliarchuk
Copy link
Copy Markdown
Member

@ivankatliarchuk ivankatliarchuk commented Jan 19, 2026

What does it do ?

ref kubernetes-sigs#6076 (comment)

Motivation

More

  • Yes, this PR title follows Conventional Commits
  • Yes, I added unit tests
  • Yes, I updated end user documentation accordingly

Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@ivankatliarchuk ivankatliarchuk changed the title kubeconfig modificaitons WIP kubeconfig refresh Jan 19, 2026
@coveralls
Copy link
Copy Markdown

coveralls commented Jan 19, 2026

Pull Request Test Coverage Report for Build 21134393364

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • 1 unchanged line in 1 file lost coverage.
  • Overall coverage decreased (-0.005%) to 79.031%

Files with Coverage Reduction New Missed Lines %
openshift_route.go 1 84.78%
Totals Coverage Status
Change from base Build 21097227265: -0.005%
Covered Lines: 16078
Relevant Lines: 20344

💛 - Coveralls

@ivankatliarchuk ivankatliarchuk marked this pull request as draft January 19, 2026 10:32
Signed-off-by: ivan katliarchuk <ivan.katliarchuk@gmail.com>
@ivankatliarchuk
Copy link
Copy Markdown
Member Author

  Realistic AWS Provider Access Pattern (checking all 16 properties per endpoint):
  ┌───────────┬───────────┬───────────────┬─────────────┬──────────────┐
  │ Set Props │ Endpoints │ Slice (ns/op) │ Map (ns/op) │    Winner    │
  ├───────────┼───────────┼───────────────┼─────────────┼──────────────┤
  │ 0         │ 100       │ 1,033         │ 567         │ Map (1.8x)   │
  ├───────────┼───────────┼───────────────┼─────────────┼──────────────┤
  │ 0         │ 50000     │ 522K          │ 286K        │ Map (1.8x)   │
  ├───────────┼───────────┼───────────────┼─────────────┼──────────────┤
  │ 1         │ 100       │ 1,600         │ 12,857      │ Slice (8x)   │
  ├───────────┼───────────┼───────────────┼─────────────┼──────────────┤
  │ 1         │ 50000     │ 830K          │ 6.7M        │ Slice (8x)   │
  ├───────────┼───────────┼───────────────┼─────────────┼──────────────┤
  │ 2         │ 50000     │ 1.7M          │ 7.0M        │ Slice (4x)   │
  ├───────────┼───────────┼───────────────┼─────────────┼──────────────┤
  │ 3         │ 50000     │ 1.9M          │ 6.9M        │ Slice (3.5x) │
  ├───────────┼───────────┼───────────────┼─────────────┼──────────────┤
  │ 5         │ 50000     │ 2.5M          │ 6.9M        │ Slice (2.7x) │
  └───────────┴───────────┴───────────────┴─────────────┴──────────────┘
  Key findings:
  - Slice is dramatically faster (3-8x) when any properties are set
  - Map only wins when slice is nil (0 properties)
  - With realistic usage (1-5 properties set, provider checks all 16):
    - Linear scan through 1-5 elements is faster than hash computation
    - Most lookups are misses - slice quickly iterates through few elements
    - Map must compute full hash for every lookup, even for misses

  Conclusion: The current slice-based implementation is the right choice for real-world usage patterns. The map overhead from hashing longer keys like
  "aws/geolocation-subdivision-code" dominates when most lookups are misses.

@ivankatliarchuk
Copy link
Copy Markdown
Member Author

  Get Comparison (looking for property-2):
  ┌───────┬───────────┬───────────────┬─────────────┬───────────────────────────┐
  │ Props │ Endpoints │ Slice (ns/op) │ Map (ns/op) │          Winner           │
  ├───────┼───────────┼───────────────┼─────────────┼───────────────────────────┤
  │ 0     │ 100-1000  │ 63-618        │ 33-367      │ Map (~2x faster when nil) │
  ├───────┼───────────┼───────────────┼─────────────┼───────────────────────────┤
  │ 5     │ 100-50000 │ 880-1.6M      │ 775-1.3M    │ Map (~15-20% faster)      │
  ├───────┼───────────┼───────────────┼─────────────┼───────────────────────────┤
  │ 10    │ 100-10000 │ 881-161K      │ 816-136K    │ Map (~15% faster)         │
  ├───────┼───────────┼───────────────┼─────────────┼───────────────────────────┤
  │ 10    │ 50000     │ 2.5M          │ 2.8M        │ Slice                     │
  └───────┴───────────┴───────────────┴─────────────┴───────────────────────────┘
  Random Access (50% existing, 50% missing keys):
  ┌───────┬───────────┬───────────────┬─────────────┬────────────────────────┐
  │ Props │ Endpoints │ Slice (ns/op) │ Map (ns/op) │         Winner         │
  ├───────┼───────────┼───────────────┼─────────────┼────────────────────────┤
  │ 5     │ 100-50000 │ 691-764K      │ 949-1.0M    │ Slice (~20-35% faster) │
  ├───────┼───────────┼───────────────┼─────────────┼────────────────────────┤
  │ 10    │ 100-50000 │ 744-1.3M      │ 834-1.7M    │ Slice (~12-27% faster) │
  └───────┴───────────┴───────────────┴─────────────┴────────────────────────┘
  Key findings:
  - Map is faster for direct lookups (always searching for same key)
  - Slice is faster for random access patterns with mixed hit/miss
  - With 5-10 properties, the difference is modest
  - Both have zero allocations

@ivankatliarchuk
Copy link
Copy Markdown
Member Author

 Slice linear search with 3 properties, checking 6 keys:
  "same-zone" vs "alias"                    → 's' != 'a' → 1 byte compared, NEXT
  "same-zone" vs "aws/target-hosted-zone"   → 's' != 'a' → 1 byte compared, NEXT
  "same-zone" vs "aws/evaluate-target-health" → 's' != 'a' → 1 byte compared, NOT FOUND

  Total for miss: ~3 byte comparisons

  Map lookup for "aws/geolocation-subdivision-code" (33 chars):
  1. Hash ALL 33 bytes of the key
  2. Find bucket
  3. Compare with bucket entry (if any)

  Total: 33+ bytes processed minimum

  Summary of why slice wins:
  ┌──────────────────────────┬───────────────────────────────┬─────────────────────────────┐
  │          Factor          │             Slice             │             Map             │
  ├──────────────────────────┼───────────────────────────────┼─────────────────────────────┤
  │ Miss on different prefix │ 1-4 byte comparisons          │ Full key hash (10-33 bytes) │
  ├──────────────────────────┼───────────────────────────────┼─────────────────────────────┤
  │ Cache locality           │ Excellent (contiguous memory) │ Pointer chasing             │
  ├──────────────────────────┼───────────────────────────────┼─────────────────────────────┤
  │ CPU branch prediction    │ Predictable loop              │ Hash function overhead      │
  ├──────────────────────────┼───────────────────────────────┼─────────────────────────────┤
  │ Best case (early miss)   │ O(1) practically              │ O(key length) always        │

@ivankatliarchuk
Copy link
Copy Markdown
Member Author

Analysis: Slice vs Map for Provider-Specific Properties

  Summary Table (time in ms, checking all 16 AWS properties per endpoint)
  ┌───────────┬───────────┬────────────┬──────────┬────────┬─────────┐
  │ Set Props │ Endpoints │ Slice (ms) │ Map (ms) │ Winner │ Speedup │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 0         │ 100       │ 0.001      │ 0.0005   │ Map    │ 1.9x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 0         │ 200,000   │ 2.3        │ 1.6      │ Map    │ 1.4x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 1         │ 100       │ 0.002      │ 0.013    │ Slice  │ 8.4x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 1         │ 200,000   │ 3.7        │ 28.3     │ Slice  │ 7.6x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 2         │ 200,000   │ 6.9        │ 27.2     │ Slice  │ 3.9x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 3         │ 200,000   │ 7.8        │ 26.7     │ Slice  │ 3.4x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 5         │ 200,000   │ 10.3       │ 27.1     │ Slice  │ 2.6x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 16        │ 100       │ 0.008      │ 0.011    │ Slice  │ 1.3x    │
  ├───────────┼───────────┼────────────┼──────────┼────────┼─────────┤
  │ 16        │ 200,000   │ 18.2       │ 25.4     │ Slice  │ 1.4x    │
  └───────────┴───────────┴────────────┴──────────┴────────┴─────────┘
  Key Findings

  1. Map wins ONLY when slice is nil (0 properties set)
  - Map: O(1) nil check vs Slice: iterating empty slice
  - Speedup: ~1.5-2x faster

  2. Slice dominates in all realistic scenarios (1-16 properties)
  - With 1 property: 7-8x faster
  - With 2-3 properties: 3-4x faster
  - With 5 properties: 2.5-3x faster
  - With all 16 properties: 1.3-1.5x faster

  3. Slice performance scales linearly with properties set
  ┌────────────┬─────────────────────┐
  │ Properties │ 200K endpoints (ms) │
  ├────────────┼─────────────────────┤
  │ 1          │ 3.7                 │
  ├────────────┼─────────────────────┤
  │ 5          │ 10.3                │
  ├────────────┼─────────────────────┤
  │ 16         │ 18.2                │
  └────────────┴─────────────────────┘
  4. Map performance is nearly constant regardless of properties set
  - Always ~25-28ms for 200K endpoints
  - Hash overhead dominates

  Conclusion

  Keep the current slice-based implementation. It is:
  - 3-8x faster for typical usage (1-5 properties set)
  - 1.3x faster even when all 16 properties are set
  - Only loses when properties are nil (uncommon in practice)
  - Zero allocations in both cases

@ivankatliarchuk
Copy link
Copy Markdown
Member Author

  Real AWS Provider Usage Pattern

  Per endpoint, provider checks these properties:
  // In adjustEndpointAndNewAaaaIfNeeded / adjustAandAAAARecord / adjustCNAMERecord:
  ep.GetBoolProviderSpecificProperty(providerSpecificAlias)           // checked 2-3x!
  ep.GetBoolProviderSpecificProperty(providerSpecificEvaluateTargetHealth)

  // In newChange (called for every record change):
  ep.GetProviderSpecificProperty(providerSpecificWeight)
  ep.GetProviderSpecificProperty(providerSpecificRegion)
  ep.GetProviderSpecificProperty(providerSpecificFailover)
  ep.GetProviderSpecificProperty(providerSpecificMultiValueAnswer)
  ep.GetProviderSpecificProperty(providerSpecificGeolocationContinentCode)
  ep.GetProviderSpecificProperty(providerSpecificGeolocationCountryCode)
  ep.GetProviderSpecificProperty(providerSpecificGeolocationSubdivisionCode)
  ep.GetProviderSpecificProperty(providerSpecificHealthCheckID)

  // In geoProximity methods:
  ep.GetProviderSpecificProperty(providerSpecificGeoProximityLocationAWSRegion)
  ep.GetProviderSpecificProperty(providerSpecificGeoProximityLocationLocalZoneGroup)
  ep.GetProviderSpecificProperty(providerSpecificGeoProximityLocationBias)
  ep.GetProviderSpecificProperty(providerSpecificGeoProximityLocationCoordinates)

  // Plus:
  ep.GetProviderSpecificProperty(providerSpecificTargetHostedZone)

  Real-world scenario:
  - 12-16 property lookups per endpoint
  - Typical endpoint has 1-3 properties set (e.g., just alias=true and evaluate-target-health=true)
  - Most lookups are misses (property not found)

  Benchmark vs Reality
  ┌──────────────────────────┬──────────────────────┬──────────────────────┐
  │          Aspect          │    Our Benchmark     │    Real AWS Usage    │
  ├──────────────────────────┼──────────────────────┼──────────────────────┤
  │ Properties checked       │ 16                   │ 12-16                │
  ├──────────────────────────┼──────────────────────┼──────────────────────┤
  │ Properties typically set │ 0-5                  │ 1-3                  │
  ├──────────────────────────┼──────────────────────┼──────────────────────┤
  │ Miss ratio               │ 70-95%               │ 80-95%               │
  ├──────────────────────────┼──────────────────────┼──────────────────────┤
  │ Access pattern           │ Sequential check all │ Sequential check all │
  └──────────────────────────┴──────────────────────┴──────────────────────┘
  Our benchmark accurately reflects real-world usage.

  Conclusion

  For typical AWS usage (1-3 properties set, 12-16 checked):
  - Slice: ~3-4ms per 200K endpoints
  - Map: ~27ms per 200K endpoints
  - Slice is 7-8x faster

  The current slice implementation is optimal for this use case.

@ivankatliarchuk
Copy link
Copy Markdown
Member Author

  Go strings are: struct { data *byte, len int }

  Comparison Order:

  1. First: Compare lengths (integer comparison ~0.27ns)
    - If lengths differ → false immediately, NO byte comparison
  2. Only if lengths match: Compare bytes (exits at first mismatch)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants