[google_cloud] Add caching to computeProjectId()
# Add caching to computeProjectId()
## Description
### Problem
`computeProjectId()` makes fresh calls to environment variables and the metadata server on every invocation. This is inefficient when the project ID is requested multiple times during the application lifecycle.
### Current Implementation
```dart
Future<String> computeProjectId() async {
final localValue = projectIdFromEnvironment(); // Checks env vars every time
if (localValue != null) {
return localValue;
}
final result = await projectIdFromMetadataServer(); // Network call every time
return result;
}
```
While environment variable lookups are fast, metadata server queries involve network I/O and should be cached.
### Proposed Solution
Add caching so discovery only happens once:
```dart
String? _cachedProjectId;
Future<String> computeProjectId() async {
if (_cachedProjectId != null) {
return _cachedProjectId!;
}
// ... existing discovery logic ...
// Cache the result
_cachedProjectId = result;
return result;
}
/// Clears the cached project ID.
///
/// This is primarily useful for testing scenarios where the project ID
/// might change between tests.
void clearProjectIdCache() {
_cachedProjectId = null;
}
```
### Use Case
Improves performance when project ID is accessed multiple times:
```dart
// First call: performs discovery
final projectId1 = await computeProjectId(); // Network call to metadata server
// Subsequent calls: returns cached value
final projectId2 = await computeProjectId(); // Instant
final projectId3 = await computeProjectId(); // Instant
// In tests: clear cache between tests
clearProjectIdCache();
```
### Implementation Notes
- The cache should be a simple module-level nullable variable
- The cache should be checked first, before any discovery attempts
- Provide a `clearProjectIdCache()` function for testing purposes
- The cache is held for the lifetime of the Dart process (acceptable since project ID doesn't change at runtime)
### Testing Considerations
Tests should call `clearProjectIdCache()` in `setUp()` or `tearDown()` to ensure test isolation:
```dart
tearDown(() {
clearProjectIdCache();
});
test('project ID from environment', () async {
// Test will have clean slate
});
```
### References
- Current implementation: [gcp_project.dart](https://github.com/invertase/functions-framework-dart/blob/main/google_cloud/lib/src/gcp_project.dart#L26-L34)
- Related to replacing `googleapis_auth_utils` functionality
0 条评论