Skip to content

Commit 3615c92

Browse files
authored
feat: DH-19901: Use grpc-java in JS API (#7878)
This is in part a backport from DHE, bringing grpc-java and protobuf-java support to the JS API. Removes the need to load dh-internal.js by compiling the Java protos and grpc services to JS, allowing easier code reuse and sharing, supporting more gRPC features, and removing the need to work around limitations around longs, headers, etc. Some of these changes will allow us to simplify DHE to better share code after this merges and is released. Some grpc-java semantics are not exactly the same as in a JVM - Context's threadlocals won't play nicely with browser Promises for example, so must be explicitly propagated when used. More cleanup is possible than has been done here - BiDiStream should no longer be necessary, but can just be a normal pair of StreamObservers. All of web/client-backplane can be deleted, but that would substantially bloat this patch, so I've left it out for now. Fixes DH-17942 Fixes DH-21675
1 parent cd8aed9 commit 3615c92

104 files changed

Lines changed: 3686 additions & 2551 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

buildSrc/src/main/groovy/GwtTools.groovy

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ class GwtTools {
5959
checkAssertions = true
6060
setExtraArgs('-includeJsInteropExports', 'io.deephaven.*')
6161
if (gwtDev) {
62+
extraArgs = [
63+
'-includeJsInteropExports', 'io.deephaven.*',
64+
'-setProperty', 'gwt.logging.logLevel=FINE',
65+
'-setProperty', 'jre.logging.logLevel=ALL',
66+
]
6267
saveSource = true
6368
extra = extras
6469
logLevel = 'INFO'
@@ -80,6 +85,8 @@ class GwtTools {
8085
def libs = p.getExtensions().getByType(VersionCatalogsExtension).named("libs")
8186
def gwtVersion = libs.findVersion("gwt").map(VersionConstraint::getRequiredVersion).orElseThrow()
8287
def gwtJettyVersion = libs.findVersion("gwtJetty").map(VersionConstraint::getRequiredVersion).orElseThrow()
88+
def protobufVers = libs.findVersion('protobuf-gwt').get().requiredVersion
89+
def grpcVers = libs.findVersion('grpc-gwt').get().requiredVersion
8390

8491
gwt.gwtVersion = gwtVersion
8592
gwt.jettyVersion = gwtJettyVersion
@@ -91,7 +98,22 @@ class GwtTools {
9198
.using(sub.module("org.gwtproject:gwt-user:${gwtVersion}"))
9299
sub.substitute(sub.module("com.google.gwt:gwt-dev"))
93100
.using(sub.module("org.gwtproject:gwt-dev:${gwtVersion}"))
101+
sub.substitute(sub.module('com.google.protobuf:protobuf-java'))
102+
.using(sub.module("com.vertispan.protobuf:protobuf-gwt:${protobufVers}"))
103+
sub.substitute(sub.module('io.grpc:grpc-api'))
104+
.using(sub.module("com.vertispan.grpc:grpc-gwt:${grpcVers}"))
105+
sub.substitute(sub.module('io.grpc:grpc-core'))
106+
.using(sub.module("com.vertispan.grpc:grpc-gwt:${grpcVers}"))
107+
sub.substitute(sub.module('io.grpc:grpc-stub'))
108+
.using(sub.module("com.vertispan.grpc:grpc-gwt:${grpcVers}"))
109+
sub.substitute(sub.module('io.grpc:grpc-protobuf'))
110+
.using(sub.module("com.vertispan.grpc:grpc-gwt:${grpcVers}"))
111+
sub.substitute(sub.module('io.grpc:grpc-protobuf-stub'))
112+
.using(sub.module("com.vertispan.grpc:grpc-gwt:${grpcVers}"))
94113
}
114+
115+
c.exclude(group: 'io.grpc', module: 'grpc-netty')
116+
c.exclude(group: 'com.google.protobuf', module: 'protobuf-java-util')
95117
}
96118
String warPath = new File(p.buildDir, 'gwt').absolutePath
97119

@@ -114,7 +136,7 @@ class GwtTools {
114136
/** Fail compilation if any input file contains an error. */
115137
strict = true
116138
/** Specifies Java source level. ("1.6", "1.7")*/
117-
sourceLevel = "11"
139+
sourceLevel = "17"
118140
/** The number of local workers to use when compiling permutations. */
119141
localWorkers = 1
120142
/** Emit extra information allow chrome dev tools to display Java identifiers in many places instead of JavaScript functions. (NONE, ONLY_METHOD_NAME, ABBREVIATED, FULL)*/

extensions/protobuf/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,6 @@ spotless {
4646

4747
protobuf {
4848
protoc {
49-
artifact = "com.google.protobuf:protoc:${libs.versions.protobuf.get()}"
49+
artifact = libs.protoc.get().toString()
5050
}
5151
}

gradle/libs.versions.toml

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ deephaven-hash = "0.5.0"
2727
deephaven-suan-shu = "0.1.1"
2828
dev-dirs = "26"
2929
dsi = "8.5.18"
30-
elemental = "1.2.3"
30+
elemental = "1.3.2"
3131
f4b6a3 = "6.1.1"
3232
flatbuffers = "25.2.10"
3333
freemarker = "2.3.34"
@@ -42,7 +42,12 @@ groovy = "3.0.25"
4242
grpc = "1.76.2"
4343
netty = "4.1.132.Final"
4444

45-
guava = "33.4.8-jre"
45+
protobuf-gwt='4.33.2-2'
46+
grpc-gwt='1.76.2-2'
47+
48+
grpc-web-gwt-fetch='1.2.0'
49+
50+
guava = "33.5.0-jre"
4651
gwt = "2.12.2"
4752
# used by GwtTools
4853
gwtJetty = "9.4.44.v20210927"
@@ -63,7 +68,7 @@ jetbrains = "26.1.0"
6368
jetty = "12.0.33"
6469
jetty11 = "11.0.20"
6570
jpy = "1.3.0"
66-
jsinterop = "2.0.2"
71+
jsinterop = "2.1.0"
6772
# google is annoying, and have different versions released for the same groupId
6873
jsinterop-base = "1.1.1"
6974
logback = "1.5.32"
@@ -203,7 +208,12 @@ netty-bom = { module = "io.netty:netty-bom", version.ref = "netty" }
203208

204209
google-rpc-protos = { module="com.google.api.grpc:proto-google-common-protos", version.ref="google-rpc-protos" }
205210

211+
protobuf-gwt = { module = 'com.vertispan.protobuf:protobuf-gwt', version.ref = 'protobuf-gwt' }
212+
grpc-gwt = { module = 'com.vertispan.grpc:grpc-gwt', version.ref = 'grpc-gwt' }
213+
grpc-gwt-fetch = { module = 'com.vertispan.grpc:grpc-web-gwt-fetch', version.ref = 'grpc-web-gwt-fetch' }
214+
206215
guava = { module = "com.google.guava:guava", version.ref = "guava" }
216+
guava-gwt = { module = "com.google.guava:guava-gwt", version.ref = "guava" }
207217

208218
gwt-user = { module = "org.gwtproject:gwt-user", version.ref = "gwt" }
209219

@@ -300,6 +310,7 @@ postgresql = { module = "org.postgresql:postgresql", version.ref = "postgresql"
300310

301311
protobuf-java = { module = "com.google.protobuf:protobuf-java", version.ref = "protobuf" }
302312
protobuf-java-util = { module = "com.google.protobuf:protobuf-java-util", version.ref = "protobuf" }
313+
protoc = { module = "com.google.protobuf:protoc", version.ref = "protobuf" }
303314

304315
randelshofer-fastdoubleparser = { module = "ch.randelshofer:fastdoubleparser", version.ref = "randelshofer" }
305316

grpc-java/grpc-servlet-websocket-jakarta/src/main/java/io/grpc/servlet/web/websocket/MultiplexedWebSocketServerStream.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,9 @@ public void onMessage(ByteBuffer message) throws IOException {
220220
}
221221

222222
// Having already stripped the control flow byte, the rest of the payload is our request message
223-
stream.inboundDataReceived(ReadableBuffers.wrap(message), false);
223+
ByteBuffer copy = ByteBuffer.allocate(message.remaining());
224+
copy.put(message);
225+
stream.inboundDataReceived(ReadableBuffers.wrap(copy.flip()), false);
224226
}
225227

226228
@Override
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<module>
2+
<source path="" />
3+
</module>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<module>
2+
<inherits name="io.grpc.Grpc" />
3+
<source path="script" />
4+
<source path="grpc" />
5+
</module>

web/client-api/client-api.gradle

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ configurations {
3939

4040
dependencies {
4141
gwt libs.gwt.user
42-
gwt platform(libs.grpc.bom)
43-
gwt libs.grpc.api
42+
api libs.protobuf.gwt
43+
api libs.grpc.gwt
44+
api libs.grpc.gwt.fetch
45+
api libs.guava.gwt
4446

4547
gwt project(':engine-chunk')
4648
gwt project(':extensions-barrage')
@@ -63,9 +65,12 @@ dependencies {
6365
gwt libs.vertispan.nio.gwt
6466
gwt libs.vertispan.flatbuffers.gwt
6567

66-
js project(path: ':proto:raw-js-openapi', configuration: 'js')
68+
gwt project(':proto:proto-backplane-grpc')
69+
70+
gwt libs.arrow.flight.core
6771

6872
gwt libs.guava
73+
gwt libs.guava.gwt
6974

7075
gwt libs.elemental.core
7176
gwt libs.elemental.promise

web/client-api/gradle.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
io.deephaven.project.ProjectType=JAVA_PUBLIC
2+
languageLevel=17
3+
testLanguageLevel=17

web/client-api/src/main/java/io/deephaven/web/DeephavenApi.gwt.xml

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,27 @@
44
<inherits name="elemental2.dom.Dom"/>
55
<inherits name="com.google.flatbuffers.FlatBuffers"/>
66
<inherits name="org.apache.arrow.flatbuf.FlightFlatbufFormat"/>
7+
<inherits name="org.apache.arrow.flight.impl.FlightProto"/>
78
<inherits name="io.deephaven.barrage.flatbuf.BarrageFlatbufFormat"/>
89

910
<inherits name="io.deephaven.base.Base" />
1011
<inherits name="io.deephaven.Util" />
1112
<inherits name="io.deephaven.io.IO" />
1213
<inherits name="io.deephaven.chunk.Chunk" />
1314
<inherits name="io.deephaven.extensions.barrage.Barrage" />
15+
<inherits name="io.deephaven.flightjs.protocol.BrowserFlight" />
16+
<inherits name="io.deephaven.proto.backplane.DeephavenCoreProto" />
17+
18+
<inherits name="com.vertispan.grpc.fetch.Fetch" />
19+
20+
<inherits name="com.google.gwt.logging.Logging"/>
1421

1522
<define-property name="dh.dev" values="true, false" />
1623
<source path="client" />
1724
<source path="shared" />
1825
<super-source path="super" />
1926
<set-property name="dh.dev" value="false" />
2027

21-
<inherits name="io.deephaven.javascript.proto.dhinternal.DeephavenInternal" />
22-
2328
<inherits name="com.google.gwt.i18n.I18N" />
2429
<inherits name="io.deephaven.web.DeephavenSharedApi" />
2530

@@ -29,6 +34,13 @@
2934
<add-linker name="dh_linker" />
3035

3136
<set-configuration-property name="user.agent.runtimeWarning" value="false"/>
37+
<set-configuration-property name="document.compatMode.severity" value="IGNORE"/>
38+
<set-property name="gwt.uncaughtexceptionhandler.windowonerror" value="IGNORE"/>
3239

3340
<set-property name="jsinterop.checks" value="ENABLED"/>
41+
42+
<!-- Limit to one permutation, which we'll assume to be "safari" - this is what chromium registers as as well,
43+
and for our purposes firefox will be compatible too.
44+
-->
45+
<set-property name="user.agent" value="safari" />
3446
</module>

web/client-api/src/main/java/io/deephaven/web/DeephavenJsApiLinkerTemplate.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ bindTo($wnd, globalThis);
2222
var window = $wnd;
2323
var dh = {};
2424
$wnd.dh = dh;
25-
import {dhinternal} from './dh-internal.js';
26-
$wnd.dhinternal = dhinternal;
2725
var $gwt_version = "__GWT_VERSION__";
2826
__JAVASCRIPT_RESULT__
2927
gwtOnLoad(null, '__MODULE_NAME__', null);

0 commit comments

Comments
 (0)