diff --git a/app/lib/admin/actions/exported_api_sync.dart b/app/lib/admin/actions/exported_api_sync.dart index fde5811a35..b595c60664 100644 --- a/app/lib/admin/actions/exported_api_sync.dart +++ b/app/lib/admin/actions/exported_api_sync.dart @@ -39,7 +39,7 @@ Optionally, write rewrite of all files using: final packagesOpt = options['packages'] ?? ''; final syncAll = packagesOpt == 'ALL'; if (syncAll) { - await apiExporter!.synchronizeExportedApi(forceWrite: forceWrite); + await apiExporter.synchronizeExportedApi(forceWrite: forceWrite); return { 'packages': 'ALL', 'forceWrite': forceWrite, @@ -50,7 +50,7 @@ Optionally, write rewrite of all files using: InvalidInputException.checkPackageName(p); } for (final p in packages) { - await apiExporter!.synchronizePackage(p, forceWrite: forceWrite); + await apiExporter.synchronizePackage(p, forceWrite: forceWrite); } return { 'packages': packages, diff --git a/app/lib/admin/actions/moderate_package.dart b/app/lib/admin/actions/moderate_package.dart index 3e3203ce97..03f659c597 100644 --- a/app/lib/admin/actions/moderate_package.dart +++ b/app/lib/admin/actions/moderate_package.dart @@ -83,7 +83,7 @@ Note: the action may take a longer time to complete as the public archive bucket await purgePackageCache(package); // sync exported API(s) - await apiExporter?.synchronizePackage(package, forceDelete: true); + await apiExporter.synchronizePackage(package, forceDelete: true); // retract or re-populate public archive files await packageBackend.tarballStorage.updatePublicArchiveBucket( diff --git a/app/lib/admin/actions/moderate_package_versions.dart b/app/lib/admin/actions/moderate_package_versions.dart index 9a653fbacc..f9e4fad43e 100644 --- a/app/lib/admin/actions/moderate_package_versions.dart +++ b/app/lib/admin/actions/moderate_package_versions.dart @@ -116,7 +116,7 @@ Set the moderated flag on a package version (updating the flag and the timestamp await purgePackageCache(package); // sync exported API(s) - await apiExporter?.synchronizePackage(package, forceDelete: true); + await apiExporter.synchronizePackage(package, forceDelete: true); // retract or re-populate public archive files await packageBackend.tarballStorage.updatePublicArchiveBucket( diff --git a/app/lib/fake/server/fake_server_entrypoint.dart b/app/lib/fake/server/fake_server_entrypoint.dart index 4bf9f82101..63c51b516e 100644 --- a/app/lib/fake/server/fake_server_entrypoint.dart +++ b/app/lib/fake/server/fake_server_entrypoint.dart @@ -174,7 +174,7 @@ Future _testProfile(shelf.Request rq) async { // ignore: invalid_use_of_visible_for_testing_member await importProfile(profile: profile); final analysis = (map['analysis'] as String?) ?? 'fake'; - await apiExporter!.synchronizeExportedApi(); + await apiExporter.synchronizeExportedApi(); await processTaskFakeLocalOrWorker(analysis); return shelf.Response.ok('{}'); } diff --git a/app/lib/package/api_export/api_exporter.dart b/app/lib/package/api_export/api_exporter.dart index bd0a7da03b..008cbcaaad 100644 --- a/app/lib/package/api_export/api_exporter.dart +++ b/app/lib/package/api_export/api_exporter.dart @@ -29,8 +29,8 @@ final Logger _log = Logger('api_export.api_exporter'); void registerApiExporter(ApiExporter value) => ss.register(#_apiExporter, value); -/// The active API Exporter service or null if it hasn't been initialized. -ApiExporter? get apiExporter => ss.lookup(#_apiExporter) as ApiExporter?; +/// The API Exporter service. +ApiExporter get apiExporter => ss.lookup(#_apiExporter) as ApiExporter; const _concurrency = 50; diff --git a/app/lib/package/backend.dart b/app/lib/package/backend.dart index f86dd6c9b8..f549de0b4f 100644 --- a/app/lib/package/backend.dart +++ b/app/lib/package/backend.dart @@ -1320,10 +1320,8 @@ class PackageBackend { if (activeConfiguration.isPublishedEmailNotificationEnabled) emailBackend.trySendOutgoingEmail(outgoingEmail), taskBackend.trackPackage(newVersion.package, updateDependents: true), - if (apiExporter != null) ...[ - apiExporter!.synchronizePackage(newVersion.package), - apiExporter!.synchronizeAllPackagesAtomFeed(), - ], + apiExporter.synchronizePackage(newVersion.package), + apiExporter.synchronizeAllPackagesAtomFeed(), ]); await tarballStorage.updateContentDispositionOnPublicBucket( newVersion.package, newVersion.version!); diff --git a/app/lib/service/entrypoint/analyzer.dart b/app/lib/service/entrypoint/analyzer.dart index ca12d77216..66de4fb611 100644 --- a/app/lib/service/entrypoint/analyzer.dart +++ b/app/lib/service/entrypoint/analyzer.dart @@ -9,7 +9,6 @@ import 'package:gcloud/service_scope.dart'; import 'package:logging/logging.dart'; import 'package:pub_dev/package/api_export/api_exporter.dart'; import 'package:pub_dev/search/backend.dart'; -import 'package:pub_dev/shared/configuration.dart'; import '../../analyzer/handlers.dart'; import '../../service/services.dart'; @@ -41,10 +40,8 @@ class AnalyzerCommand extends Command { // TODO: rewrite this loop to have a start/stop logic scheduleMicrotask(searchBackend.updateSnapshotInForeverLoop); - if (activeConfiguration.exportedApiBucketName != null) { - await apiExporter!.start(); - registerScopeExitCallback(() => apiExporter!.stop()); - } + await apiExporter.start(); + registerScopeExitCallback(() => apiExporter.stop()); await runHandler(logger, analyzerServiceHandler); }); diff --git a/app/lib/service/services.dart b/app/lib/service/services.dart index c34bdaeb10..e5c53fa6d5 100644 --- a/app/lib/service/services.dart +++ b/app/lib/service/services.dart @@ -243,14 +243,11 @@ Future _withPubServices(FutureOr Function() fn) async { registerAccountBackend(AccountBackend(dbService)); registerAdminBackend(AdminBackend(dbService)); registerAnnouncementBackend(AnnouncementBackend()); - if (activeConfiguration.exportedApiBucketName != null) { - registerApiExporter(ApiExporter( - dbService, - storageService: storageService, - bucket: - storageService.bucket(activeConfiguration.exportedApiBucketName!), - )); - } + registerApiExporter(ApiExporter( + dbService, + storageService: storageService, + bucket: storageService.bucket(activeConfiguration.exportedApiBucketName!), + )); registerAsyncQueue(AsyncQueue()); registerAuditBackend(AuditBackend(dbService)); registerConsentBackend(ConsentBackend(dbService)); diff --git a/app/lib/shared/configuration.dart b/app/lib/shared/configuration.dart index 66ee229772..73eaca45ed 100644 --- a/app/lib/shared/configuration.dart +++ b/app/lib/shared/configuration.dart @@ -416,7 +416,7 @@ final class Configuration { publicPackagesBucketName!, searchSnapshotBucketName!, taskResultBucketName!, - if (exportedApiBucketName != null) exportedApiBucketName!, + exportedApiBucketName!, ]); late final isProduction = projectId == 'dartlang-pub'; diff --git a/app/lib/tool/neat_task/pub_dev_tasks.dart b/app/lib/tool/neat_task/pub_dev_tasks.dart index 0b98da1b16..62089f6f92 100644 --- a/app/lib/tool/neat_task/pub_dev_tasks.dart +++ b/app/lib/tool/neat_task/pub_dev_tasks.dart @@ -133,7 +133,7 @@ List createPeriodicTaskSchedulers({ _daily( name: 'synchronize-exported-api', isRuntimeVersioned: true, - task: () async => await apiExporter?.synchronizeExportedApi(), + task: () async => await apiExporter.synchronizeExportedApi(), ), // Deletes moderated packages, versions, publishers and users. diff --git a/app/test/package/api_export/api_exporter_test.dart b/app/test/package/api_export/api_exporter_test.dart index b9f0aa07ba..9fa68d37cd 100644 --- a/app/test/package/api_export/api_exporter_test.dart +++ b/app/test/package/api_export/api_exporter_test.dart @@ -52,14 +52,14 @@ void main() { // we cannot use an isolated instance, we need to use the same setup. // However, for better control and consistency, we can remove all the // existing files from the bucket at the start of this test: - await apiExporter!.stop(); + await apiExporter.stop(); final bucket = storageService.bucket(activeConfiguration.exportedApiBucketName!); await _deleteAll(bucket); await _testExportedApiSynchronization( bucket, - apiExporter!.synchronizeExportedApi, + apiExporter.synchronizeExportedApi, ); }); @@ -75,21 +75,21 @@ void main() { // we cannot use an isolated instance, we need to use the same setup. // However, for better control and consistency, we can remove all the // existing files from the bucket at the start of this test: - await apiExporter!.stop(); + await apiExporter.stop(); final bucket = storageService.bucket(activeConfiguration.exportedApiBucketName!); await _deleteAll(bucket); - await apiExporter!.synchronizeExportedApi(); + await apiExporter.synchronizeExportedApi(); - await apiExporter!.start(); + await apiExporter.start(); await _testExportedApiSynchronization( bucket, () async => await clockControl.elapse(minutes: 15), ); - await apiExporter!.stop(); + await apiExporter.stop(); }, ); }