This is an automated email from the ASF dual-hosted git repository.

miroslav pushed a commit to branch issue/OAK-10573_azure_write_timeout
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git

commit f0665d84507bac6fa42c9ab41419be33907e961e
Author: Miroslav Smiljanic <[email protected]>
AuthorDate: Wed Nov 29 17:57:23 2023 +0100

    OAK-10573 request options optimised for write operations
---
 .../oak/segment/azure/AzureJournalFile.java        | 15 ++++--
 .../oak/segment/azure/AzurePersistence.java        | 22 +-------
 .../segment/azure/AzureSegmentArchiveWriter.java   | 13 +++--
 .../segment/azure/util/AzureRequestOptions.java    | 63 ++++++++++++++++++++++
 4 files changed, 85 insertions(+), 28 deletions(-)

diff --git 
a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureJournalFile.java
 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureJournalFile.java
index b468e42b44..76b52de113 100644
--- 
a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureJournalFile.java
+++ 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureJournalFile.java
@@ -22,6 +22,9 @@ import com.microsoft.azure.storage.blob.CloudAppendBlob;
 import com.microsoft.azure.storage.blob.CloudBlob;
 import com.microsoft.azure.storage.blob.CloudBlobDirectory;
 import com.microsoft.azure.storage.blob.ListBlobItem;
+import com.microsoft.azure.storage.blob.DeleteSnapshotsOption;
+import com.microsoft.azure.storage.blob.BlobRequestOptions;
+import org.apache.jackrabbit.oak.segment.azure.util.AzureRequestOptions;
 import 
org.apache.jackrabbit.oak.segment.azure.util.CaseInsensitiveKeysMapAccess;
 import org.apache.jackrabbit.oak.segment.remote.WriteAccessController;
 import org.apache.jackrabbit.oak.segment.spi.persistence.JournalFile;
@@ -162,7 +165,11 @@ public class AzureJournalFile implements JournalFile {
 
         private int lineCount;
 
+        private final BlobRequestOptions writeOptimisedBlobRequestOptions;
+
         public AzureJournalWriter() throws IOException {
+            writeOptimisedBlobRequestOptions = 
AzureRequestOptions.optimiseForWriteOperations(directory.getServiceClient().getDefaultRequestOptions());
+
             List<CloudAppendBlob> blobs = getJournalBlobs();
             if (blobs.isEmpty()) {
                 try {
@@ -190,7 +197,7 @@ public class AzureJournalFile implements JournalFile {
                 writeAccessController.checkWritingAllowed();
 
                 for (CloudAppendBlob cloudAppendBlob : getJournalBlobs()) {
-                    cloudAppendBlob.delete();
+                    cloudAppendBlob.delete(DeleteSnapshotsOption.NONE, null, 
writeOptimisedBlobRequestOptions, null);
                 }
 
                 createNextFile(0);
@@ -229,11 +236,11 @@ public class AzureJournalFile implements JournalFile {
                     text.append(line).append("\n");
                 }
                 try {
-                    currentBlob.appendText(text.toString());
+                    currentBlob.appendText(text.toString(), null, null, 
writeOptimisedBlobRequestOptions, null);
                     currentBlob.getMetadata().put("lastEntry", 
entries.get(entries.size() - 1));
                     lineCount += entries.size();
                     currentBlob.getMetadata().put("lineCount", 
Integer.toString(lineCount));
-                    currentBlob.uploadMetadata();
+                    currentBlob.uploadMetadata(null, 
writeOptimisedBlobRequestOptions, null);
                 } catch (StorageException e) {
                     throw new IOException(e);
                 }
@@ -243,7 +250,7 @@ public class AzureJournalFile implements JournalFile {
         private void createNextFile(int suffix) throws IOException {
             try {
                 currentBlob = 
directory.getAppendBlobReference(getJournalFileName(suffix + 1));
-                currentBlob.createOrReplace();
+                currentBlob.createOrReplace(null, 
writeOptimisedBlobRequestOptions, null);
                 lineCount = 0;
             } catch (URISyntaxException | StorageException e) {
                 throw new IOException(e);
diff --git 
a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzurePersistence.java
 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzurePersistence.java
index eed07004e5..392a352915 100644
--- 
a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzurePersistence.java
+++ 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzurePersistence.java
@@ -34,6 +34,7 @@ import com.microsoft.azure.storage.blob.CloudAppendBlob;
 import com.microsoft.azure.storage.blob.CloudBlobDirectory;
 import com.microsoft.azure.storage.blob.CloudBlockBlob;
 import com.microsoft.azure.storage.blob.ListBlobItem;
+import org.apache.jackrabbit.oak.segment.azure.util.AzureRequestOptions;
 import org.apache.jackrabbit.oak.segment.remote.WriteAccessController;
 import org.apache.jackrabbit.oak.segment.spi.monitor.FileStoreMonitor;
 import org.apache.jackrabbit.oak.segment.spi.monitor.IOMonitor;
@@ -70,26 +71,7 @@ public class AzurePersistence implements 
SegmentNodeStorePersistence {
     public AzurePersistence(CloudBlobDirectory segmentStoreDirectory) {
         this.segmentstoreDirectory = segmentStoreDirectory;
 
-        BlobRequestOptions defaultRequestOptions = 
segmentStoreDirectory.getServiceClient().getDefaultRequestOptions();
-        if (defaultRequestOptions.getRetryPolicyFactory() == null) {
-            int retryAttempts = Integer.getInteger(RETRY_ATTEMPTS_PROP, 
DEFAULT_RETRY_ATTEMPTS);
-            if (retryAttempts > 0) {
-                Integer retryBackoffSeconds = 
Integer.getInteger(RETRY_BACKOFF_PROP, DEFAULT_RETRY_BACKOFF_SECONDS);
-                defaultRequestOptions.setRetryPolicyFactory(new 
RetryLinearRetry((int) TimeUnit.SECONDS.toMillis(retryBackoffSeconds), 
retryAttempts));
-            }
-        }
-        if (defaultRequestOptions.getMaximumExecutionTimeInMs() == null) {
-            int timeoutExecution = Integer.getInteger(TIMEOUT_EXECUTION_PROP, 
DEFAULT_TIMEOUT_EXECUTION);
-            if (timeoutExecution > 0) {
-                defaultRequestOptions.setMaximumExecutionTimeInMs((int) 
TimeUnit.SECONDS.toMillis(timeoutExecution));
-            }
-        }
-        if (defaultRequestOptions.getTimeoutIntervalInMs() == null) {
-            int timeoutInterval = Integer.getInteger(TIMEOUT_INTERVAL_PROP, 
DEFAULT_TIMEOUT_INTERVAL);
-            if (timeoutInterval > 0) {
-                defaultRequestOptions.setTimeoutIntervalInMs((int) 
TimeUnit.SECONDS.toMillis(timeoutInterval));
-            }
-        }
+        
AzureRequestOptions.applyDefaultRequestOptions(segmentStoreDirectory.getServiceClient().getDefaultRequestOptions());
     }
 
     @Override
diff --git 
a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureSegmentArchiveWriter.java
 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureSegmentArchiveWriter.java
index 3df0eaafa6..e9bbbb322a 100644
--- 
a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureSegmentArchiveWriter.java
+++ 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/AzureSegmentArchiveWriter.java
@@ -25,12 +25,14 @@ import java.io.IOException;
 import java.net.URISyntaxException;
 import java.util.concurrent.TimeUnit;
 
+import com.microsoft.azure.storage.blob.BlobRequestOptions;
 import org.apache.jackrabbit.guava.common.base.Stopwatch;
 import com.microsoft.azure.storage.StorageException;
 import com.microsoft.azure.storage.blob.CloudBlobDirectory;
 import com.microsoft.azure.storage.blob.CloudBlockBlob;
 
 import org.apache.jackrabbit.oak.commons.Buffer;
+import org.apache.jackrabbit.oak.segment.azure.util.AzureRequestOptions;
 import org.apache.jackrabbit.oak.segment.remote.WriteAccessController;
 import org.apache.jackrabbit.oak.segment.azure.util.Retrier;
 import 
org.apache.jackrabbit.oak.segment.remote.AbstractRemoteSegmentArchiveWriter;
@@ -47,10 +49,13 @@ public class AzureSegmentArchiveWriter extends 
AbstractRemoteSegmentArchiveWrite
             
Integer.getInteger("azure.segment.archive.writer.retries.intervalMs", 5000)
     );
 
+    private final BlobRequestOptions writeOptimisedBlobRequestOptions;
+
     public AzureSegmentArchiveWriter(CloudBlobDirectory archiveDirectory, 
IOMonitor ioMonitor, FileStoreMonitor monitor, WriteAccessController 
writeAccessController) {
         super(ioMonitor, monitor);
         this.archiveDirectory = archiveDirectory;
         this.writeAccessController = writeAccessController;
+        this.writeOptimisedBlobRequestOptions = 
AzureRequestOptions.optimiseForWriteOperations(archiveDirectory.getServiceClient().getDefaultRequestOptions());
     }
 
     @Override
@@ -71,8 +76,8 @@ public class AzureSegmentArchiveWriter extends 
AbstractRemoteSegmentArchiveWrite
         Stopwatch stopwatch = Stopwatch.createStarted();
         try {
             blob.setMetadata(AzureBlobMetadata.toSegmentMetadata(indexEntry));
-            blob.uploadFromByteArray(data, offset, size);
-            blob.uploadMetadata();
+            blob.uploadFromByteArray(data, offset, size, null, 
writeOptimisedBlobRequestOptions, null);
+            blob.uploadMetadata(null, writeOptimisedBlobRequestOptions, null);
         } catch (StorageException e) {
             throw new IOException(e);
         }
@@ -97,7 +102,7 @@ public class AzureSegmentArchiveWriter extends 
AbstractRemoteSegmentArchiveWrite
             try {
                 writeAccessController.checkWritingAllowed();
 
-                getBlob(getName() + extension).uploadFromByteArray(data, 0, 
data.length);
+                getBlob(getName() + extension).uploadFromByteArray(data, 0, 
data.length, null, writeOptimisedBlobRequestOptions, null);
             } catch (StorageException e) {
                 throw new IOException(e);
             }
@@ -110,7 +115,7 @@ public class AzureSegmentArchiveWriter extends 
AbstractRemoteSegmentArchiveWrite
             try {
                 writeAccessController.checkWritingAllowed();
 
-                getBlob("closed").uploadFromByteArray(new byte[0], 0, 0);
+                getBlob("closed").uploadFromByteArray(new byte[0], 0, 0, null, 
writeOptimisedBlobRequestOptions, null);
             } catch (StorageException e) {
                 throw new IOException(e);
             }
diff --git 
a/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/util/AzureRequestOptions.java
 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/util/AzureRequestOptions.java
new file mode 100644
index 0000000000..485612371d
--- /dev/null
+++ 
b/oak-segment-azure/src/main/java/org/apache/jackrabbit/oak/segment/azure/util/AzureRequestOptions.java
@@ -0,0 +1,63 @@
+package org.apache.jackrabbit.oak.segment.azure.util;
+
+import com.microsoft.azure.storage.RetryLinearRetry;
+import com.microsoft.azure.storage.blob.BlobRequestOptions;
+
+import java.util.concurrent.TimeUnit;
+
+public class AzureRequestOptions {
+
+    private static final String RETRY_ATTEMPTS_PROP = 
"segment.azure.retry.attempts";
+    private static final int DEFAULT_RETRY_ATTEMPTS = 5;
+
+    private static final String RETRY_BACKOFF_PROP = 
"segment.azure.retry.backoff";
+    private static final int DEFAULT_RETRY_BACKOFF_SECONDS = 5;
+
+    private static final String TIMEOUT_EXECUTION_PROP = 
"segment.timeout.execution";
+    private static final int DEFAULT_TIMEOUT_EXECUTION = 30;
+
+    private static final String TIMEOUT_INTERVAL_PROP = 
"segment.timeout.interval";
+    private static final int DEFAULT_TIMEOUT_INTERVAL = 1;
+
+    private static final String WRITE_TIMEOUT_EXECUTION_PROP = 
"segment.write.timeout.execution";
+
+    private static final String WRITE_TIMEOUT_INTERVAL_PROP = 
"segment.write.timeout.interval";
+
+    public static void applyDefaultRequestOptions(BlobRequestOptions 
blobRequestOptions) {
+        if (blobRequestOptions.getRetryPolicyFactory() == null) {
+            int retryAttempts = Integer.getInteger(RETRY_ATTEMPTS_PROP, 
DEFAULT_RETRY_ATTEMPTS);
+            if (retryAttempts > 0) {
+                Integer retryBackoffSeconds = 
Integer.getInteger(RETRY_BACKOFF_PROP, DEFAULT_RETRY_BACKOFF_SECONDS);
+                blobRequestOptions.setRetryPolicyFactory(new 
RetryLinearRetry((int) TimeUnit.SECONDS.toMillis(retryBackoffSeconds), 
retryAttempts));
+            }
+        }
+        if (blobRequestOptions.getMaximumExecutionTimeInMs() == null) {
+            int timeoutExecution = Integer.getInteger(TIMEOUT_EXECUTION_PROP, 
DEFAULT_TIMEOUT_EXECUTION);
+            if (timeoutExecution > 0) {
+                blobRequestOptions.setMaximumExecutionTimeInMs((int) 
TimeUnit.SECONDS.toMillis(timeoutExecution));
+            }
+        }
+        if (blobRequestOptions.getTimeoutIntervalInMs() == null) {
+            int timeoutInterval = Integer.getInteger(TIMEOUT_INTERVAL_PROP, 
DEFAULT_TIMEOUT_INTERVAL);
+            if (timeoutInterval > 0) {
+                blobRequestOptions.setTimeoutIntervalInMs((int) 
TimeUnit.SECONDS.toMillis(timeoutInterval));
+            }
+        }
+    }
+
+    public static BlobRequestOptions 
optimiseForWriteOperations(BlobRequestOptions blobRequestOptions) {
+        BlobRequestOptions writeOptimisedBlobRequestOptions = new 
BlobRequestOptions(blobRequestOptions);
+
+        Integer writeTimeoutExecution = 
Integer.getInteger(WRITE_TIMEOUT_EXECUTION_PROP);
+        if (writeTimeoutExecution != null) {
+            
writeOptimisedBlobRequestOptions.setMaximumExecutionTimeInMs(writeTimeoutExecution);
+        }
+
+        Integer writeTimeoutInterval = 
Integer.getInteger(WRITE_TIMEOUT_INTERVAL_PROP);
+        if (writeTimeoutInterval != null) {
+            
writeOptimisedBlobRequestOptions.setTimeoutIntervalInMs(writeTimeoutInterval);
+        }
+
+        return writeOptimisedBlobRequestOptions;
+    }
+}

Reply via email to