Skip to content

Commit a82fdbc

Browse files
committed
Added code snippet headings
1 parent b813428 commit a82fdbc

File tree

2 files changed

+71
-81
lines changed

2 files changed

+71
-81
lines changed

articles/cosmos-db/troubleshoot-java-async-sdk.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ The SDK uses the [Netty](https://netty.io/) IO library to communicate with Azure
8080
The Netty IO threads are meant to be used only for non-blocking Netty IO work. The SDK returns the API invocation result on one of the Netty IO threads to the app's code. If the app performs a long-lasting operation after it receives results on the Netty thread, the SDK might not have enough IO threads to perform its internal IO work. Such app coding might result in low throughput, high latency, and `io.netty.handler.timeout.ReadTimeoutException` failures. The workaround is to switch the thread when you know the operation takes time.
8181

8282
For example, take a look at the following code snippet. You might perform long-lasting work that takes more than a few milliseconds on the Netty thread. If so, you eventually can get into a state where no Netty IO thread is present to process IO work. As a result, you get a ReadTimeoutException failure.
83+
84+
### <a id="asyncjava2-readtimeout"></a>Async Java SDK V2 (Maven com.microsoft.azure::azure-cosmosdb)
85+
8386
```java
8487
@Test
8588
public void badCodeWithReadTimeoutException() throws Exception {
@@ -131,13 +134,19 @@ public void badCodeWithReadTimeoutException() throws Exception {
131134
assertThat(failureCount.get()).isGreaterThan(0);
132135
}
133136
```
134-
The workaround is to change the thread on which you perform work that takes time. Define a singleton instance of the scheduler for your app.
135-
```java
137+
The workaround is to change the thread on which you perform work that takes time. Define a singleton instance of the scheduler for your app.
138+
139+
### <a id="asyncjava2-scheduler"></a>Async Java SDK V2 (Maven com.microsoft.azure::azure-cosmosdb)
140+
141+
```java
136142
// Have a singleton instance of an executor and a scheduler.
137143
ExecutorService ex = Executors.newFixedThreadPool(30);
138144
Scheduler customScheduler = rx.schedulers.Schedulers.from(ex);
139-
```
140-
You might need to do work that takes time, for example, computationally heavy work or blocking IO. In this case, switch the thread to a worker provided by your `customScheduler` by using the `.observeOn(customScheduler)` API.
145+
```
146+
You might need to do work that takes time, for example, computationally heavy work or blocking IO. In this case, switch the thread to a worker provided by your `customScheduler` by using the `.observeOn(customScheduler)` API.
147+
148+
### <a id="asyncjava2-applycustomscheduler"></a>Async Java SDK V2 (Maven com.microsoft.azure::azure-cosmosdb)
149+
141150
```java
142151
Observable<ResourceResponse<Document>> createObservable = client
143152
.createDocument(getCollectionLink(), docDefinition, null, false);

articles/cosmos-db/troubleshoot-java-sdk-v4-sql.md

Lines changed: 58 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,9 @@ Java SDK v4 provides client-side logical representation to access the Azure Cosm
2222
Start with this list:
2323

2424
* Take a look at the [Common issues and workarounds] section in this article.
25-
* Look at the SDK, which is available [open source on GitHub](https://github.com/Azure/azure-cosmosdb-java). It has an [issues section](https://github.com/Azure/azure-cosmosdb-java/issues) that's actively monitored. Check to see if any similar issue with a workaround is already filed.
25+
* Look at the Java SDK in the Azure Cosmos DB monorepo, which is available [open source on GitHub](https://github.com/Azure/azure-sdk-for-java/tree/master/sdk/cosmos/azure-cosmos). It has an [issues section](https://github.com/Azure/azure-sdk-for-java/issues) that's actively monitored. Check to see if any similar issue with a workaround is already filed. One helpful tip is to filter issues by the *cosmos:v4-item* tag.
2626
* Review the [performance tips for Java SDK v4](), and follow the suggested practices.
27-
* Read the rest of this article, if you didn't find a solution. Then file a [GitHub issue](https://github.com/Azure/azure-sdk-for-java/issues).
27+
* Read the rest of this article, if you didn't find a solution. Then file a [GitHub issue](https://github.com/Azure/azure-sdk-for-java/issues). If there is an option to add tags to your GitHub issue, add a *cosmos:v4-item* tag.
2828

2929
## <a name="common-issues-workarounds"></a>Common issues and workarounds
3030

@@ -78,77 +78,62 @@ The SDK uses the [Netty](https://netty.io/) IO library to communicate with Azure
7878

7979
The Netty IO threads are meant to be used only for non-blocking Netty IO work. The SDK returns the API invocation result on one of the Netty IO threads to the app's code. If the app performs a long-lasting operation after it receives results on the Netty thread, the SDK might not have enough IO threads to perform its internal IO work. Such app coding might result in low throughput, high latency, and `io.netty.handler.timeout.ReadTimeoutException` failures. The workaround is to switch the thread when you know the operation takes time.
8080

81-
For example, take a look at the following code snippet. You might perform long-lasting work that takes more than a few milliseconds on the Netty thread. If so, you eventually can get into a state where no Netty IO thread is present to process IO work. As a result, you get a ReadTimeoutException failure.
81+
For example, take a look at the following code snippet which adds items to a container (look [here](create-sql-api-java.md) for guidance on setting up the database and container.) You might perform long-lasting work that takes more than a few milliseconds on the Netty thread. If so, you eventually can get into a state where no Netty IO thread is present to process IO work. As a result, you get a ReadTimeoutException failure.
82+
83+
### <a id="java4-readtimeout"></a>Java SDK V4 (Maven com.azure::azure-cosmos) Async API
84+
8285
```java
8386
@Test
8487
public void badCodeWithReadTimeoutException() throws Exception {
85-
int requestTimeoutInSeconds = 10;
86-
87-
ConnectionPolicy policy = new ConnectionPolicy();
88-
policy.setRequestTimeoutInMillis(requestTimeoutInSeconds * 1000);
89-
90-
AsyncDocumentClient testClient = new AsyncDocumentClient.Builder()
91-
.withServiceEndpoint(TestConfigurations.HOST)
92-
.withMasterKeyOrResourceToken(TestConfigurations.MASTER_KEY)
93-
.withConnectionPolicy(policy)
94-
.build();
95-
96-
int numberOfCpuCores = Runtime.getRuntime().availableProcessors();
97-
int numberOfConcurrentWork = numberOfCpuCores + 1;
98-
CountDownLatch latch = new CountDownLatch(numberOfConcurrentWork);
99-
AtomicInteger failureCount = new AtomicInteger();
100-
101-
for (int i = 0; i < numberOfConcurrentWork; i++) {
102-
Document docDefinition = getDocumentDefinition();
103-
Observable<ResourceResponse<Document>> createObservable = testClient
104-
.createDocument(getCollectionLink(), docDefinition, null, false);
105-
createObservable.subscribe(r -> {
106-
try {
107-
// Time-consuming work is, for example,
108-
// writing to a file, computationally heavy work, or just sleep.
109-
// Basically, it's anything that takes more than a few milliseconds.
110-
// Doing such operations on the IO Netty thread
111-
// without a proper scheduler will cause problems.
112-
// The subscriber will get a ReadTimeoutException failure.
113-
TimeUnit.SECONDS.sleep(2 * requestTimeoutInSeconds);
114-
} catch (Exception e) {
115-
}
116-
},
117-
118-
exception -> {
119-
//It will be io.netty.handler.timeout.ReadTimeoutException.
120-
exception.printStackTrace();
121-
failureCount.incrementAndGet();
122-
latch.countDown();
123-
},
124-
() -> {
125-
latch.countDown();
126-
});
127-
}
128-
129-
latch.await();
130-
assertThat(failureCount.get()).isGreaterThan(0);
88+
int requestTimeoutInSeconds = 10;
89+
ConnectionPolicy policy = new ConnectionPolicy();
90+
policy.setRequestTimeout(Duration.ofMillis(requestTimeoutInSeconds * 1000));
91+
AtomicInteger failureCount = new AtomicInteger();
92+
// Max number of concurrent item inserts is # CPU cores + 1
93+
Flux<Family> familyPub =
94+
Flux.just(Families.getAndersenFamilyItem(), Families.getWitherspoonFamilyItem(), Families.getCarltonFamilyItem());
95+
familyPub.flatMap(family -> {
96+
return container.createItem(family);
97+
}).flatMap(r -> {
98+
try {
99+
// Time-consuming work is, for example,
100+
// writing to a file, computationally heavy work, or just sleep.
101+
// Basically, it's anything that takes more than a few milliseconds.
102+
// Doing such operations on the IO Netty thread
103+
// without a proper scheduler will cause problems.
104+
// The subscriber will get a ReadTimeoutException failure.
105+
TimeUnit.SECONDS.sleep(2 * requestTimeoutInSeconds);
106+
} catch (Exception e) {
107+
}
108+
return Mono.empty();
109+
}).doOnError(Exception.class, exception -> {
110+
failureCount.incrementAndGet();
111+
}).blockLast();
112+
assert(failureCount.get() > 0);
131113
}
132114
```
133-
The workaround is to change the thread on which you perform work that takes time. Define a singleton instance of the scheduler for your app.
134-
```java
115+
116+
The workaround is to change the thread on which you perform work that takes time. Define a singleton instance of the scheduler for your app.
117+
118+
### <a id="java4-scheduler"></a>Java SDK V4 (Maven com.azure::azure-cosmos) Async API
119+
120+
```java
135121
// Have a singleton instance of an executor and a scheduler.
136122
ExecutorService ex = Executors.newFixedThreadPool(30);
137-
Scheduler customScheduler = rx.schedulers.Schedulers.from(ex);
138-
```
139-
You might need to do work that takes time, for example, computationally heavy work or blocking IO. In this case, switch the thread to a worker provided by your `customScheduler` by using the `.observeOn(customScheduler)` API.
123+
Scheduler customScheduler = Schedulers.fromExecutor(ex);
124+
```
125+
You might need to do work that takes time, for example, computationally heavy work or blocking IO. In this case, switch the thread to a worker provided by your `customScheduler` by using the `.publishOn(customScheduler)` API.
126+
127+
### <a id="java4-apply-custom-scheduler"></a>Java SDK V4 (Maven com.azure::azure-cosmos) Async API
128+
140129
```java
141-
Observable<ResourceResponse<Document>> createObservable = client
142-
.createDocument(getCollectionLink(), docDefinition, null, false);
143-
144-
createObservable
145-
.observeOn(customScheduler) // Switches the thread.
146-
.subscribe(
147-
// ...
148-
);
130+
container.createItem(family)
131+
.publishOn(customScheduler) // Switches the thread.
132+
.subscribe(
133+
// ...
134+
);
149135
```
150-
By using `observeOn(customScheduler)`, you release the Netty IO thread and switch to your own custom thread provided by the custom scheduler.
151-
This modification solves the problem. You won't get a `io.netty.handler.timeout.ReadTimeoutException` failure anymore.
136+
By using `publishOn(customScheduler)`, you release the Netty IO thread and switch to your own custom thread provided by the custom scheduler. This modification solves the problem. You won't get a `io.netty.handler.timeout.ReadTimeoutException` failure anymore.
152137

153138
### Connection pool exhausted issue
154139

@@ -163,31 +148,27 @@ The Azure Cosmos DB emulator HTTPS certificate is self-signed. For the SDK to wo
163148

164149
### Dependency Conflict Issues
165150

166-
```console
167-
Exception in thread "main" java.lang.NoSuchMethodError: rx.Observable.toSingle()Lrx/Single;
168-
```
169-
170-
The above exception suggests you have a dependency on an older version of RxJava lib (e.g., 1.2.2). Our SDK relies on RxJava 1.3.8 which has APIs not available in earlier version of RxJava.
151+
With Java SDK v4 Async API, you may find that your project has a dependency on an older version of Reactor (<3.3.0). Our SDK relies on Reactor 3.3.0 which has APIs not available in earlier versions of Reactor.
171152

172-
The workaround for such issuses is to identify which other dependency brings in RxJava-1.2.2 and exclude the transitive dependency on RxJava-1.2.2, and allow CosmosDB SDK bring the newer version.
153+
The workaround for such issues is to identify which other dependency brings in the old version of Reactor and exclude the transitive dependency on that older version, and allow CosmosDB SDK to bring in the newer version.
173154

174-
To identify which library brings in RxJava-1.2.2 run the following command next to your project pom.xml file:
155+
To identify which library brings in an older version of Reactor run the following command next to your project pom.xml file:
175156
```bash
176157
mvn dependency:tree
177158
```
178159
For more information, see the [maven dependency tree guide](https://maven.apache.org/plugins/maven-dependency-plugin/examples/resolving-conflicts-using-the-dependency-tree.html).
179160

180-
Once you identify RxJava-1.2.2 is transitive dependency of which other dependency of your project, you can modify the dependency on that lib in your pom file and exclude RxJava transitive dependency it:
161+
Once you which dependency of your project depends on an older version of Reactor, you can modify the dependency on that lib in your pom file and exclude the Reactor transitive dependency:
181162

182163
```xml
183164
<dependency>
184-
<groupId>${groupid-of-lib-which-brings-in-rxjava1.2.2}</groupId>
185-
<artifactId>${artifactId-of-lib-which-brings-in-rxjava1.2.2}</artifactId>
186-
<version>${version-of-lib-which-brings-in-rxjava1.2.2}</version>
165+
<groupId>${groupid-of-lib-which-brings-in-reactor}</groupId>
166+
<artifactId>${artifactId-of-lib-which-brings-in-reactor}</artifactId>
167+
<version>${version-of-lib-which-brings-in-reactor}</version>
187168
<exclusions>
188169
<exclusion>
189-
<groupId>io.reactivex</groupId>
190-
<artifactId>rxjava</artifactId>
170+
<groupId>io.projectreactor</groupId>
171+
<artifactId>reactor-core</artifactId>
191172
</exclusion>
192173
</exclusions>
193174
</dependency>

0 commit comments

Comments
 (0)