Skip to content

Commit 7c55e0f

Browse files
committed
addressed PR feedback
1 parent 928a09a commit 7c55e0f

3 files changed

Lines changed: 39 additions & 18 deletions

File tree

exporthistory/src/main/java/com/microsoft/durabletask/exporthistory/activities/ExportInstanceHistoryActivity.java

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ public class ExportInstanceHistoryActivity implements TaskActivity {
5353
private final DurableTaskClient client;
5454
private final ExportHistoryStorageOptions storageOptions;
5555

56+
// Lazily initialized and cached to avoid rebuilding per invocation
57+
private volatile BlobContainerClient cachedContainerClient;
58+
private volatile String cachedContainerName;
59+
5660
public ExportInstanceHistoryActivity(DurableTaskClient client, ExportHistoryStorageOptions storageOptions) {
5761
this.client = client;
5862
this.storageOptions = storageOptions;
@@ -150,11 +154,7 @@ private void uploadToBlob(
150154
ExportFormatKind kind,
151155
String instanceId) throws IOException {
152156

153-
BlobServiceClient serviceClient = new BlobServiceClientBuilder()
154-
.connectionString(this.storageOptions.getConnectionString())
155-
.buildClient();
156-
BlobContainerClient containerClient = serviceClient.getBlobContainerClient(containerName);
157-
containerClient.createIfNotExists();
157+
BlobContainerClient containerClient = getOrCreateContainerClient(containerName);
158158

159159
BlobClient blobClient = containerClient.getBlobClient(blobPath);
160160
Map<String, String> metadata = Collections.singletonMap("instanceId", instanceId);
@@ -185,4 +185,24 @@ private void uploadToBlob(
185185
blobClient.uploadWithResponse(uploadOptions, null, null);
186186
}
187187
}
188+
189+
private BlobContainerClient getOrCreateContainerClient(String containerName) {
190+
// Double-checked locking: reuse the cached client if the container name matches
191+
if (this.cachedContainerClient != null && containerName.equals(this.cachedContainerName)) {
192+
return this.cachedContainerClient;
193+
}
194+
synchronized (this) {
195+
if (this.cachedContainerClient != null && containerName.equals(this.cachedContainerName)) {
196+
return this.cachedContainerClient;
197+
}
198+
BlobServiceClient serviceClient = new BlobServiceClientBuilder()
199+
.connectionString(this.storageOptions.getConnectionString())
200+
.buildClient();
201+
BlobContainerClient containerClient = serviceClient.getBlobContainerClient(containerName);
202+
containerClient.createIfNotExists();
203+
this.cachedContainerName = containerName;
204+
this.cachedContainerClient = containerClient;
205+
return containerClient;
206+
}
207+
}
188208
}

exporthistory/src/main/java/com/microsoft/durabletask/exporthistory/client/DefaultExportHistoryJobClient.java

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,21 @@ public void create(@Nonnull ExportJobCreationOptions options) {
4848
throw new IllegalArgumentException("options must not be null.");
4949
}
5050

51-
// Build options with destination from storage options if not set
52-
ExportDestination destination = options.getDestination();
53-
if (destination == null) {
54-
String prefix = options.getMode().name().toLowerCase() + "-" + this.jobId + "/";
55-
destination = new ExportDestination(
56-
this.storageOptions.getContainerName(),
57-
this.storageOptions.getPrefix() != null ? this.storageOptions.getPrefix() : prefix);
58-
}
59-
60-
// Create options with resolved destination
51+
// Resolve destination by independently falling back each field:
52+
// prefix: user destination → storageOptions → auto-generated per-job default
53+
// container: user destination → storageOptions
54+
String defaultPrefix = options.getMode().name().toLowerCase() + "-" + this.jobId + "/";
55+
ExportDestination userDest = options.getDestination();
56+
String prefix = userDest != null && userDest.getPrefix() != null ? userDest.getPrefix()
57+
: this.storageOptions.getPrefix() != null ? this.storageOptions.getPrefix()
58+
: defaultPrefix;
59+
String container = userDest != null && userDest.getContainer() != null ? userDest.getContainer()
60+
: this.storageOptions.getContainerName();
61+
ExportDestination destination = new ExportDestination(container, prefix);
62+
63+
// Create options with resolved destination, always using this client's bound jobId
6164
ExportJobCreationOptions resolvedOptions = new ExportJobCreationOptions(
62-
options.getJobId(),
65+
this.jobId,
6366
options.getMode(),
6467
options.getCompletedTimeFrom(),
6568
options.getCompletedTimeTo(),

exporthistory/src/main/java/com/microsoft/durabletask/exporthistory/client/ExportJobQueryPageable.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ public Iterable<ExportJobQueryResult> byPage() {
8080
return () -> new Iterator<ExportJobQueryResult>() {
8181
private String continuationToken = baseQuery != null ? baseQuery.getContinuationToken() : null;
8282
private boolean hasMorePages = true;
83-
private boolean firstPage = true;
8483

8584
@Override
8685
public boolean hasNext() {
@@ -103,7 +102,6 @@ public ExportJobQueryResult next() {
103102
ExportJobQueryResult result = queryExecutor.apply(query);
104103
this.continuationToken = result.getContinuationToken();
105104
this.hasMorePages = this.continuationToken != null && !this.continuationToken.isEmpty();
106-
this.firstPage = false;
107105
return result;
108106
}
109107
};

0 commit comments

Comments
 (0)