Skip to content

refactor(cache): lazy-load built-in definitions from cache on demand, add ExportBuiltInCache, and extend alzlibtool CLI#242

Merged
matt-FFFFFF merged 12 commits intomainfrom
fork-pr-241-copilot/237-improve-cache-integration
Mar 25, 2026
Merged

refactor(cache): lazy-load built-in definitions from cache on demand, add ExportBuiltInCache, and extend alzlibtool CLI#242
matt-FFFFFF merged 12 commits intomainfrom
fork-pr-241-copilot/237-improve-cache-integration

Conversation

@matt-FFFFFF
Copy link
Copy Markdown
Member

This PR replaces #241 to enable CI/CD checks with required secrets.

Original PR by @app/copilot-swe-agent


  • Add cache.NewCacheFromDefinitions constructor
  • Add AlzLib.ExportBuiltInCache() method
  • Add unit tests for ExportBuiltInCache
  • Extend alzlibtool cache create with library/architecture flags and --from-cache
  • Add --from-cache flag to alzlibtool generate architecture
  • Fix: deep-copy values in ExportBuiltInCache
  • Fix: reuse Azure clients per ensureReferencedPolicyDefinitions invocation
  • Fix: remove defer az.cache = nil from GetDefinitionsFromAzure (cache retained for AlzLib lifetime)
  • Fix: protect az.cache reads with az.mu.RLock() in policyDefinitionFromCache/policySetDefinitionFromCache
  • Fix: snapshot az.clients.policyClient under az.mu.RLock() in getBuiltInPolicies, getBuiltInPolicySets, and ensureReferencedPolicyDefinition
  • Fix: update ExportBuiltInCache docstring to include nil PolicyType in the inclusion criteria
Original prompt

The recent #237 pull request introduced a cache feature for the Azure/alzlib repository. However, the implementation overly simplified the feature, resulting in all Azure built-in definitions being cached and loaded into the alzlib struct. To optimize this, improvements are needed to wire the cache into the GetBuiltInDefinititions function, ensuring better integration. Additionally, the cache usage should be adjusted to allow the garbage collector (GC) to efficiently discard the cache afterwards.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: The recent #237 PR introduced a cache feature. I think the implementation was too simple in that it resulted in ALL azure built in definitions being cached (loaded into the alzlib struct).

Make improvements by wiring the cache into the GetBuiltInDefinititions and allowing the GC to discard the cache afterwards.

Assistant: A pull request will be created to refine the cache integration for optimizing the GetBuiltInDefinititions functionality. I'll notify you once this is completed.

This pull request was created from Copilot chat.


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI and others added 6 commits March 11, 2026 22:09
…ding and GC

- cache/cache.go: Add PolicyDefinitionVersionsByName and PolicySetDefinitionVersionsByName
  per-name lookup methods, avoiding full-map clone for individual lookups
- alzlib.go: Extend BuiltInCache interface with new per-name lookup methods
- alzlib.go: Add `cache BuiltInCache` field to AlzLib struct
- alzlib.go: AddCache now stores only the cache reference (lazy, not eager)
- alzlib.go: GetDefinitionsFromAzure defers az.cache = nil so GC can reclaim cache
- alzlib.go: getBuiltInPolicies checks cache before Azure; lazy-init Azure client
- alzlib.go: getBuiltInPolicySets checks cache before Azure; lazy-init Azure clients
- alzlib.go: ensureReferencedPolicyDefinitions removes upfront client creation
- alzlib.go: ensureReferencedPolicyDefinition checks AlzLib → cache → Azure in order
- alzlib.go: Extract policyDefinitionFromCache/policySetDefinitionFromCache helpers
- alzlib_test.go: Update mockBuiltInCache with new interface methods
- alzlib_test.go: Replace eager-load tests with lazy-load tests
- integrationtest/cache_test.go: Update TestCacheInitWithLibrary for lazy semantics
- docs/cache.md: Document lazy loading and GC behaviour

Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
…s constructor

- cache/cache.go: Add NewCacheFromDefinitions constructor that builds a Cache from
  existing PolicyDefinitionVersions/PolicySetDefinitionVersions maps
- alzlib.go: Add ExportBuiltInCache() method that collects only built-in and static
  definitions from the loaded AlzLib state, filtering out custom definitions
- alzlib.go: Add isBuiltInPolicyDefinitionVersions / isBuiltInPolicySetDefinitionVersions
  helpers for PolicyType-based filtering
- alzlib_test.go: Add 5 tests for ExportBuiltInCache covering the filter logic,
  save/reload round-trip, empty state, nil PolicyType, and static type

Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
…ary+architecture mode to cache create

- generate/architecture.go: add --from-cache flag; loads seed cache into AlzLib
  before Init/FromArchitecture to reduce Azure API calls
- cache/create.go: add --library, --architecture, --from-cache, --rootmg, --location
  flags; new architecture-scoped mode uses alzlib.ExportBuiltInCache() to produce
  a minimal cache; same path allowed for --from-cache and --output (in-place update)

Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
- ExportBuiltInCache: deep-copy *PolicyDefinitionVersions values so
  AlzLib mutations (e.g. SetAssignPermissionsOnDefinitionParameter)
  cannot affect the exported cache
- GetDefinitionsFromAzure: remove defer az.cache=nil; cache is now kept
  for AlzLib lifetime (callers release with AddCache(nil)). Fixes bug
  where only the first management group could use the cache.
- policyDefinitionFromCache / policySetDefinitionFromCache: snapshot
  az.cache under az.mu.RLock to prevent data race with AddCache
- ensureReferencedPolicyDefinitions: lazily create DefinitionsClient /
  DefinitionVersionsClient once per invocation and reuse across all
  policy-set sub-references instead of creating per cache miss
- Add TestExportBuiltInCacheIsDeepCopied and helper
  testBuiltInPolicyDefinitionWithParam
- Update AddCache docstring and docs/cache.md for new cache lifecycle

Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
…xportBuiltInCache docstring

- getBuiltInPolicies: snapshot az.clients.policyClient under az.mu.RLock()
  before the Azure fallback to prevent data race with AddPolicyClient
- getBuiltInPolicySets: same fix
- ensureReferencedPolicyDefinition: same fix
- ExportBuiltInCache: update docstring to accurately reflect that nil
  PolicyType is also included (treated as built-in), not only
  PolicyTypeBuiltIn and PolicyTypeStatic

Co-authored-by: matt-FFFFFF <16320656+matt-FFFFFF@users.noreply.github.com>
@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented Mar 13, 2026

Codecov Report

❌ Patch coverage is 36.91275% with 188 lines in your changes missing coverage. Please review.
✅ Project coverage is 47.57%. Comparing base (b7241fb) to head (bd327ed).

Files with missing lines Patch % Lines
cmd/alzlibtool/command/cache/create.go 0.00% 115 Missing ⚠️
alzlib.go 67.10% 42 Missing and 8 partials ⚠️
cache/cache.go 0.00% 12 Missing ⚠️
cmd/alzlibtool/command/generate/architecture.go 42.10% 10 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #242      +/-   ##
==========================================
- Coverage   48.43%   47.57%   -0.86%     
==========================================
  Files          54       54              
  Lines        4590     4847     +257     
==========================================
+ Hits         2223     2306      +83     
- Misses       2087     2255     +168     
- Partials      280      286       +6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

oZakari
oZakari previously approved these changes Mar 13, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors alzlib’s built-in definition caching to be lazy/on-demand during GetDefinitionsFromAzure, adds an API to export a minimal built-in cache from the currently loaded definitions, and extends alzlibtool to seed lookups from a cache file (and to create architecture-scoped caches).

Changes:

  • Switch AddCache to store a cache reference for lazy lookups during GetDefinitionsFromAzure (rather than eagerly loading everything).
  • Add AlzLib.ExportBuiltInCache() and cache.NewCacheFromDefinitions(...), plus tests for export/deep-copy behavior.
  • Extend alzlibtool cache create and alzlibtool generate architecture with --from-cache, and update docs/integration tests for lazy loading semantics.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
alzlib.go Implements lazy cache lookup in GetDefinitionsFromAzure, adds ExportBuiltInCache, and updates cache interface.
cache/cache.go Adds NewCacheFromDefinitions and by-name accessors for version collections.
cmd/alzlibtool/command/cache/create.go Adds library/architecture-scoped cache creation and --from-cache flag plumbing.
cmd/alzlibtool/command/generate/architecture.go Adds --from-cache to seed built-in definition lookups before Azure calls.
alzlib_test.go Updates cache-related tests and adds ExportBuiltInCache coverage.
integrationtest/cache_test.go Adjusts expectations to match lazy loading (built-ins appear after hierarchy build).
docs/cache.md Updates cache behavior documentation to describe lazy loading and explicit cache release.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread alzlib.go Outdated
Comment thread docs/cache.md Outdated
Comment thread cmd/alzlibtool/command/cache/create.go
Comment thread alzlib.go Outdated
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…eate, restrict --from-cache to architecture-scoped mode

- alzlib.go: properly handle 2 return values from policyDefinitionFromCache
  and policySetDefinitionFromCache (fixes compiler errors)
- cache create: remove --rootmg and --location flags, use internal defaults
- cache create: disallow --from-cache without --library/--architecture since
  full-scan bulk APIs fetch everything regardless and a seed cannot reduce work
- cache_test.go: fix TestCacheInitWithLibrary to use correct architecture name
  "simple" (matching simple-existingmg testdata) and adjust assertions
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR refactors the built-in definition cache to be lazy-loaded during GetDefinitionsFromAzure, adds the ability to export a minimal built-in cache from an initialized AlzLib, and extends alzlibtool to seed operations from an existing cache file.

Changes:

  • Switch AddCache from eager population to retaining a cache reference and resolving definitions on-demand in GetDefinitionsFromAzure.
  • Add AlzLib.ExportBuiltInCache() plus supporting cache APIs (cache.NewCacheFromDefinitions, *ByName lookups) and unit tests.
  • Extend alzlibtool (cache create, generate architecture) with --from-cache and library/architecture-scoped cache creation.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
integrationtest/cache_test.go Updates integration expectations to align with lazy cache behavior.
docs/cache.md Updates docs to reflect cache retention and explicit release via AddCache(nil).
cmd/alzlibtool/command/generate/architecture.go Adds --from-cache to seed built-in lookups during architecture generation.
cmd/alzlibtool/command/cache/create.go Adds architecture-scoped cache creation, seeding via --from-cache, and in-place update support.
cache/cache.go Adds NewCacheFromDefinitions and *VersionsByName methods to support lazy lookups and exports.
alzlib_test.go Adds/updates tests for lazy cache behavior and ExportBuiltInCache deep-copying/filtering.
alzlib.go Implements lazy cache-first resolution in built-in fetch paths and adds ExportBuiltInCache.

Comment thread alzlib.go Outdated
Comment thread alzlib.go Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

alzlib_test.go:1305

  • TestAddCacheDeepCopies doesn't currently exercise any mutation: testPolicyDefinition doesn't populate Properties.Parameters, so SetAssignPermissionsOnDefinitionParameter("anyParam") is a no-op and the test would pass even if cache entries were not deep-copied. To make this test meaningful, create a cached policy definition that includes the target parameter (or use the existing helper that builds a definition with parameters), then assert the cache copy remains unmodified after mutating AlzLib.
	// Mutate the definition in AlzLib via SetAssignPermissionsOnDefinitionParameter.
	// This should NOT affect the original cache.
	az.SetAssignPermissionsOnDefinitionParameter("deep-copy-pd", "anyParam")

	// Verify the original cache's definition is unmodified.
	origPd, err := pdvs.GetVersion(to.Ptr("1.0.*"))
	require.NoError(t, err)

	// The original should not have any AssignPermissions set on any parameter.
	if origPd.Properties.Parameters != nil {
		for _, p := range origPd.Properties.Parameters {
			if p.Metadata != nil && p.Metadata.AssignPermissions != nil {
				t.Fatal("cache definition was mutated - deep copy failed")
			}
		}
	}

Comment thread alzlib.go
@matt-FFFFFF matt-FFFFFF added this pull request to the merge queue Mar 25, 2026
Merged via the queue into main with commit 3181cd0 Mar 25, 2026
12 checks passed
@matt-FFFFFF matt-FFFFFF deleted the fork-pr-241-copilot/237-improve-cache-integration branch March 25, 2026 10:54
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.

6 participants