Skip to content

Commit d347be6

Browse files
authored
Merge pull request #61 from NikitaKatkov/reactive-blocking-annotations
[Non]BlockingContext annotations introduced
2 parents 737e045 + 67e32b7 commit d347be6

File tree

4 files changed

+175
-0
lines changed

4 files changed

+175
-0
lines changed

common/src/main/java/org/jetbrains/annotations/Blocking.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2000-2021 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package org.jetbrains.annotations;
218

319
import java.lang.annotation.*;

common/src/main/java/org/jetbrains/annotations/NonBlocking.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,19 @@
1+
/*
2+
* Copyright 2000-2021 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
117
package org.jetbrains.annotations;
218

319
import java.lang.annotation.*;
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright 2000-2021 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.annotations;
18+
19+
import java.lang.annotation.*;
20+
21+
/**
22+
* Indicates that the annotated executor (CoroutineContext, Scheduler)
23+
* allows blocking methods execution.<br><br>
24+
* <p>
25+
* If a given executor does not allow blocking calls, {@link NonBlockingExecutor} should be used.<br><br>
26+
* <p>
27+
*
28+
* Example 1 (Kotlin coroutines):
29+
* <pre>
30+
* {@code
31+
* class BlockingExampleService {
32+
* val dispatcher: @BlockingExecutor CoroutineContext
33+
* get() { ... }
34+
*
35+
* suspend fun foo() {
36+
* val result = withContext(dispatcher) {
37+
* blockingBuzz() // no IDE warning
38+
* }
39+
* }
40+
*
41+
* @Blocking fun blockingBuzz() { ... }
42+
* }
43+
* }
44+
* </pre><br>
45+
* <p>
46+
* Example 2 (Java with Reactor framework):
47+
* <pre>
48+
* {@code
49+
* class BlockingExampleService {
50+
* private static final @BlockingExecutor Scheduler blockingScheduler =
51+
* Schedulers.newBoundedElastic(4, 10, "executor");
52+
*
53+
* public Flux<String> foo(Flux<String> urls) {
54+
* return urls.publishOn(blockingScheduler)
55+
* .map(url -> blockingBuzz(url)); // no IDE warning
56+
* }
57+
*
58+
* @Blocking
59+
* private String blockingBuzz(String url) { ... }
60+
* }
61+
* }
62+
* </pre>
63+
* <p>
64+
* @see Blocking
65+
* @see NonBlocking
66+
*/
67+
@Documented
68+
@Retention(RetentionPolicy.CLASS)
69+
@Target({ElementType.TYPE, ElementType.TYPE_USE})
70+
public @interface BlockingExecutor {
71+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2000-2021 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.annotations;
18+
19+
import java.lang.annotation.*;
20+
21+
/**
22+
* Indicates that the annotated executor (CoroutineContext, Scheduler)
23+
* does not allow blocking methods execution.<br><br>
24+
* <p>
25+
*
26+
* If a given executor allows blocking calls, {@link BlockingExecutor} should be used.<br><br>
27+
* <p>
28+
*
29+
* Example 1 (Kotlin coroutines):
30+
* <pre>
31+
* {@code
32+
* class NonBlockingExampleService {
33+
* val dispatcher: @NonBlockingExecutor CoroutineContext
34+
* get() { ... }
35+
*
36+
* suspend fun foo() {
37+
* val result = withContext(dispatcher) {
38+
* blockingBuzz() // IDE warning: `Possibly blocking call in non-blocking context`
39+
* }
40+
* }
41+
*
42+
* @Blocking fun blockingBuzz() { ... }
43+
* }
44+
* }
45+
* </pre><br>
46+
* <p>
47+
* Example 2 (Java with Reactor framework):
48+
* <pre>
49+
* {@code
50+
* class NonBlockingExampleService {
51+
* private static final @NonBlockingExecutor Scheduler operationsScheduler =
52+
* Schedulers.newParallel("parallel");
53+
*
54+
* public Flux<String> foo(Flux<String> urls) {
55+
* return urls.publishOn(operationsScheduler)
56+
* .filter(url -> blockingBuzz(url) != null); // IDE warning: `Possibly blocking call in non-blocking context`
57+
* }
58+
*
59+
* @Blocking
60+
* private String blockingBuzz(String url) { ... }
61+
* }
62+
* }
63+
* </pre>
64+
* <p>
65+
* @see Blocking
66+
* @see NonBlocking
67+
*/
68+
@Documented
69+
@Retention(RetentionPolicy.CLASS)
70+
@Target({ElementType.TYPE, ElementType.TYPE_USE})
71+
public @interface NonBlockingExecutor {
72+
}

0 commit comments

Comments
 (0)