Skip to content

Commit 96ac95d

Browse files
Other JVM logging can be performed from other thread (#14836)
1 parent fb447ae commit 96ac95d

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

lib/java/jvm-interop/src/main/java/org/enso/jvm/interop/impl/OtherJvmLogger.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22

33
import com.oracle.truffle.api.interop.InteropLibrary;
44
import java.util.ArrayList;
5+
import java.util.Collections;
6+
import java.util.EnumMap;
57
import java.util.List;
8+
import java.util.Map;
69
import java.util.Queue;
710
import java.util.ResourceBundle;
811
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -112,6 +115,8 @@ private String formatMsg() {
112115

113116
private final class LoggerImpl implements System.Logger {
114117
private final String name;
118+
private final Map<Level, Boolean> loggable =
119+
Collections.synchronizedMap(new EnumMap<>(Level.class));
115120

116121
LoggerImpl(String name) {
117122
this.name = name;
@@ -127,9 +132,18 @@ public boolean isLoggable(Level level) {
127132
if ("org.enso.persist".equals(name)) {
128133
return level.compareTo(Level.INFO) >= 0;
129134
}
135+
var prev = loggable.get(level);
136+
if (prev != null) {
137+
return prev;
138+
}
130139
var check = new LogCheck(name, level.getSeverity());
131-
var b = channel.execute(Boolean.class, check);
132-
return b;
140+
try {
141+
var b = channel.execute(Boolean.class, check);
142+
loggable.put(level, b);
143+
return b;
144+
} catch (WrongThreadException ex) {
145+
return true;
146+
}
133147
}
134148

135149
@Override
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package org.enso.base_test_helpers;
2+
3+
import java.util.concurrent.Callable;
4+
import java.util.concurrent.ExecutorService;
5+
import java.util.concurrent.Executors;
6+
7+
public class LoggerHelper {
8+
private static final System.Logger LOG = System.getLogger(LoggerHelper.class.getName());
9+
private static final ExecutorService EXEC =
10+
Executors.newSingleThreadExecutor(
11+
(r) -> {
12+
var t = new Thread(r, "LoggerHelper");
13+
t.setDaemon(true);
14+
return t;
15+
});
16+
17+
public static boolean isLoggableAsync(System.Logger.Level level) throws Exception {
18+
final Callable<Boolean> action =
19+
() -> {
20+
return LOG.isLoggable(level);
21+
};
22+
return EXEC.submit(action).get();
23+
}
24+
25+
public static void logAsync(System.Logger.Level level, String msg) throws Exception {
26+
final Callable<Void> action =
27+
() -> {
28+
LOG.log(level, msg);
29+
return null;
30+
};
31+
EXEC.submit(action).get();
32+
}
33+
}

test/Base_Tests/src/Logging_Spec.enso

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ from Standard.Test import all
77

88
import project.Enso_Bin_Utils
99

10+
polyglot java import java.lang.System.Logger.Level
11+
polyglot java import org.enso.base_test_helpers.LoggerHelper
12+
1013
type Type_In_Private_Module
1114

1215
add_specs suite_builder = suite_builder.group "Logging" group_builder->
@@ -24,6 +27,13 @@ add_specs suite_builder = suite_builder.group "Logging" group_builder->
2427
Type_In_Private_Module.log_message "Hidden message" Log_Level.Finest
2528
Type_In_Private_Module.log_message "Less hidden message" Log_Level.Fine
2629

30+
group_builder.specify "is logging asynchronously" <|
31+
LoggerHelper.isLoggableAsync Level.ERROR . should_be_true
32+
33+
group_builder.specify "log asynchronously" <|
34+
LoggerHelper.logAsync Level.TRACE "Not visible"
35+
LoggerHelper.logAsync Level.ERROR "Visible somewhere"
36+
2737
enso_logging_prj_lazy = Ref.new lazy=True <|
2838
prj_dir = tmp_root / "default_logging"
2939
prj_dir.create_directory

0 commit comments

Comments
 (0)