Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitb937332

Browse files
committed
Lazy loading Azure to prevent open telemetry race
1 parent31e7d46 commitb937332

File tree

4 files changed

+65
-36
lines changed

4 files changed

+65
-36
lines changed

‎apps/pwabuilder-google-play/app.ts‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ import express from 'express';
22
importrouterfrom'./routes/project.js';
33
importcorsfrom'cors';
44
importbodyParserfrom'body-parser';
5-
importpathfrom'path';
65

76
constapp=express();
87

98
app.use(bodyParser.json());
109
app.use(
11-
cors({
12-
origin:'*',
13-
})
10+
cors({
11+
origin:'*',
12+
})
1413
);
1514
app.use('/',router);
1615
app.use(express.static('static'));

‎apps/pwabuilder-google-play/server.ts‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
1+
// CRITICAL: Set OpenTelemetry environment variables FIRST to prevent conflicts
2+
process.env.APPLICATIONINSIGHTS_INSTRUMENTATION_LOGGING_LEVEL='off';
3+
process.env.APPLICATIONINSIGHTS_NO_DIAGNOSTIC_CHANNEL='true';
4+
process.env.APPLICATIONINSIGHTS_NO_STATSBEAT='true';
5+
process.env.AZURE_TRACING_DISABLED='true';
6+
process.env.APPLICATIONINSIGHTS_NO_AZURE_INSTRUMENTATION='true';
7+
// Disable OpenTelemetry completely to prevent Azure SDK conflicts
8+
process.env.OTEL_SDK_DISABLED='true';
9+
process.env.OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED='false';
10+
111
importdotenvfrom'dotenv';
212
importappfrom'./app.js';
313
import{setupAnalytics}from"./services/analytics.js";
14+
import{PackageJobProcessor}from'./services/packageJobProcessor.js';
415

516
constconfigResult=dotenv.config({
617
path:`./env/${app.get("env")}.env`
@@ -29,8 +40,6 @@ if (!jdk8Path || !androidDevToolsPath) {
2940

3041
setupAnalytics();
3142

32-
import{PackageJobProcessor}from'./services/packageJobProcessor.js';
33-
3443
// Kick off our background job processor.
3544
// This periodically polls Redis for new Google Play packaging jobs and processes them.
3645
constjobProcessor=newPackageJobProcessor();

‎apps/pwabuilder-google-play/services/analytics.ts‎

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,8 @@ enum AppInsightsStatus {
1010
varappInsightsStatus:AppInsightsStatus=AppInsightsStatus.DEFAULT;
1111
exportfunctionsetupAnalytics(){
1212
try{
13-
// Completely disable OpenTelemetry to prevent conflicts with Azure SDK
14-
process.env.APPLICATIONINSIGHTS_INSTRUMENTATION_LOGGING_LEVEL='off';
15-
process.env.APPLICATIONINSIGHTS_NO_DIAGNOSTIC_CHANNEL='true';
16-
process.env.APPLICATIONINSIGHTS_NO_STATSBEAT='true';
17-
// Disable Azure SDK OpenTelemetry instrumentation
18-
process.env.AZURE_TRACING_DISABLED='true';
19-
// Disable Application Insights auto-instrumentation of Azure SDK
20-
process.env.APPLICATIONINSIGHTS_NO_AZURE_INSTRUMENTATION='true';
13+
// Environment variables are set at application startup in server.ts
14+
// to ensure they're configured before any Azure packages are imported
2115

2216
appInsights.setup()
2317
.setDistributedTracingMode(DistributedTracingModes.AI)

‎apps/pwabuilder-google-play/services/azureStorageBlobService.ts‎

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
import{BlobServiceClient,ContainerClient}from"@azure/storage-blob";
2-
import{DefaultAzureCredential}from"@azure/identity";
3-
importpathfrom"path";
41
importfsfrom'fs-extra';
2+
importtype{BlobServiceClient,ContainerClient}from"@azure/storage-blob";
53

64
/**
75
* A service for uploading and downloading files. In local development, this will be a service that uses the local file system. Otherwise, this will be a service that uses Azure Storage blob containers.
@@ -13,33 +11,25 @@ export interface BlobStorage {
1311

1412
/**
1513
* Blob storage service that connects to PWABuilder's Azure Storage account for uploading and downloading files.
14+
* NOTE: we lazily initialize the Azure BlobServiceClient and ContainerClient to avoid loading Azure SDK packages too early, which can cause conflicts with OpenTelemetry in our environment. Without this, we'd see errors like, "Module @azure/core-tracing has been loaded before @azure/opentelemetry-instrumentation-azure-sdk so it might not work, please initialize it before requiring @azure/core-tracing'"
1615
*/
1716
exportclassAzureStorageBlobServiceimplementsBlobStorage{
18-
privateblobServiceClient:BlobServiceClient;
19-
privatecontainerClient:ContainerClient;
17+
privateblobServiceClientTask:Promise<BlobServiceClient>|null=null;
18+
privatecontainerClientTask:Promise<ContainerClient>|null=null;
2019
privatereadonlycontainerName="google-play-packages";
20+
privatereadonlyazureStorageAccountName:string;
21+
privatereadonlyazureManagedIdentityAppId:string;
2122

2223
constructor(){
23-
constaccountName=process.env.AZURE_STORAGE_ACCOUNT_NAME;
24-
if(!accountName){
24+
this.azureStorageAccountName=process.env.AZURE_STORAGE_ACCOUNT_NAME||"";
25+
if(!this.azureStorageAccountName){
2526
thrownewError("AZURE_STORAGE_ACCOUNT_NAME environment variable is not set.");
2627
}
2728

28-
constmanagedIdentityClientId=process.env.AZURE_MANAGED_IDENTITY_APPLICATION_ID;
29-
if(!managedIdentityClientId){
29+
this.azureManagedIdentityAppId=process.env.AZURE_MANAGED_IDENTITY_APPLICATION_ID||"";
30+
if(!this.azureManagedIdentityAppId){
3031
thrownewError("AZURE_MANAGED_IDENTITY_APPLICATION_ID environment variable is not set.");
3132
}
32-
33-
// Use user-assigned managed identity for authentication
34-
constcredential=newDefaultAzureCredential({
35-
managedIdentityClientId:managedIdentityClientId
36-
});
37-
this.blobServiceClient=newBlobServiceClient(
38-
`https://${accountName}.blob.core.windows.net`,
39-
credential
40-
);
41-
42-
this.containerClient=this.blobServiceClient.getContainerClient(this.containerName);
4333
}
4434

4535
/**
@@ -50,8 +40,9 @@ export class AzureStorageBlobService implements BlobStorage {
5040
*/
5141
asyncuploadFile(filePath:string,blobName:string):Promise<string>{
5242
try{
43+
constcontainerClient=awaitthis.initializeContainerClient();
5344
constblobSafeFileName=this.getBlobSafeFileName(blobName);
54-
constblockBlobClient=this.containerClient.getBlockBlobClient(blobSafeFileName);
45+
constblockBlobClient=containerClient.getBlockBlobClient(blobSafeFileName);
5546

5647
// Note: our Azure Blob Storage account is configured to automatically delete these after several hours.
5748
console.info(`Uploading file${filePath} to blob${blobSafeFileName}...`);
@@ -72,7 +63,8 @@ export class AzureStorageBlobService implements BlobStorage {
7263
*/
7364
asyncdownloadFileStream(blobName:string):Promise<NodeJS.ReadableStream>{
7465
try{
75-
constblockBlobClient=this.containerClient.getBlockBlobClient(blobName);
66+
constcontainerClient=awaitthis.initializeContainerClient();
67+
constblockBlobClient=containerClient.getBlockBlobClient(blobName);
7668

7769
console.info(`Downloading blob${blobName} as stream...`);
7870
constdownloadResponse=awaitblockBlobClient.download();
@@ -97,6 +89,41 @@ export class AzureStorageBlobService implements BlobStorage {
9789
.replace(/:/g,'-')
9890
.replace(/[^a-zA-Z0-9-_]/g,'');
9991
}
92+
93+
privateinitializeBlobServiceClient():Promise<BlobServiceClient>{
94+
if(!this.blobServiceClientTask){
95+
this.blobServiceClientTask=newPromise<BlobServiceClient>(async(resolve,reject)=>{
96+
try{
97+
// Dynamic imports to prevent early loading of Azure packages
98+
const{ BlobServiceClient}=awaitimport("@azure/storage-blob");
99+
const{ DefaultAzureCredential}=awaitimport("@azure/identity");
100+
101+
// Use user-assigned managed identity for authentication
102+
constcredential=newDefaultAzureCredential({
103+
managedIdentityClientId:this.azureManagedIdentityAppId
104+
});
105+
constclient=newBlobServiceClient(
106+
`https://${this.azureStorageAccountName}.blob.core.windows.net`,
107+
credential
108+
);
109+
resolve(client);
110+
}catch(error){
111+
reject(error);
112+
}
113+
});
114+
}
115+
116+
returnthis.blobServiceClientTask;
117+
}
118+
119+
privateinitializeContainerClient():Promise<ContainerClient>{
120+
if(!this.containerClientTask){
121+
this.containerClientTask=this.initializeBlobServiceClient()
122+
.then(blobService=>blobService.getContainerClient(this.containerName));
123+
}
124+
125+
returnthis.containerClientTask;
126+
}
100127
}
101128

102129
/**

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp