Skip to content

Commit 6295db7

Browse files
committed
WIP: GRPC: nothing work
1 parent 0280cee commit 6295db7

49 files changed

Lines changed: 2329 additions & 92 deletions

Some content is hidden

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

dump.txt

Lines changed: 423 additions & 0 deletions
Large diffs are not rendered by default.

jooby/src/main/java/io/jooby/Context.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,6 +1088,15 @@ default Value lookup(String name) {
10881088
*/
10891089
Context setResponseHeader(@NonNull String name, @NonNull String value);
10901090

1091+
/**
1092+
* Set response trailer header.
1093+
*
1094+
* @param name Header name.
1095+
* @param value Header value.
1096+
* @return This context.
1097+
*/
1098+
Context setResponseTrailer(@NonNull String name, @NonNull String value);
1099+
10911100
/**
10921101
* Remove a response header.
10931102
*
@@ -1238,6 +1247,13 @@ Context responseStream(
12381247
*
12391248
* @return HTTP channel as chunker. Usually for chunked response.
12401249
*/
1250+
Sender responseSender(boolean startResponse);
1251+
1252+
/**
1253+
* HTTP response channel as chunker. Mark the response as started.
1254+
*
1255+
* @return HTTP channel as chunker. Usually for chunked response.
1256+
*/
12411257
Sender responseSender();
12421258

12431259
/**

jooby/src/main/java/io/jooby/DefaultContext.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,11 @@ default Context render(@NonNull Object value) {
554554
}
555555
}
556556

557+
@Override
558+
default Sender responseSender() {
559+
return responseSender(true);
560+
}
561+
557562
@Override
558563
default OutputStream responseStream(@NonNull MediaType contentType) {
559564
setResponseType(contentType);

jooby/src/main/java/io/jooby/ForwardingContext.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,12 @@ public Context setResponseHeader(@NonNull String name, @NonNull Date value) {
10911091
return this;
10921092
}
10931093

1094+
@Override
1095+
public Context setResponseTrailer(@NonNull String name, @NonNull String value) {
1096+
ctx.setResponseHeader(name, value);
1097+
return this;
1098+
}
1099+
10941100
@Override
10951101
public Context setResponseHeader(@NonNull String name, @NonNull Instant value) {
10961102
ctx.setResponseHeader(name, value);
@@ -1217,6 +1223,11 @@ public Sender responseSender() {
12171223
return ctx.responseSender();
12181224
}
12191225

1226+
@Override
1227+
public Sender responseSender(boolean startResponse) {
1228+
return ctx.responseSender(startResponse);
1229+
}
1230+
12201231
@Override
12211232
public PrintWriter responseWriter() {
12221233
return ctx.responseWriter();

jooby/src/main/java/io/jooby/Sender.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ default Sender write(@NonNull String data, @NonNull Callback callback) {
7373
return write(data, StandardCharsets.UTF_8, callback);
7474
}
7575

76+
/**
77+
* Set response trailer header.
78+
*
79+
* @param name Header name.
80+
* @param value Header value.
81+
* @return This context.
82+
*/
83+
Sender setTrailer(@NonNull String name, @NonNull String value);
84+
7685
/**
7786
* Write a string chunk. Chunk is flushed immediately.
7887
*

jooby/src/main/java/io/jooby/internal/HeadContext.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,11 @@ public Sender write(@NonNull Output output, @NonNull Callback callback) {
190190
return this;
191191
}
192192

193+
@Override
194+
public Sender setTrailer(@NonNull String name, @NonNull String value) {
195+
return this;
196+
}
197+
193198
@Override
194199
public void close() {}
195200
}

list.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
INFO [2026-01-07 18:40:39,944] [worker-91] JettySubscription read data started
2+
INFO [2026-01-07 18:40:39,945] [worker-91] JettySubscription byte read: 00000000033a012a
3+
INFO [2026-01-07 18:40:39,945] [worker-91] GrpcRequestBridge deframe 3a012a
4+
INFO [2026-01-07 18:40:39,946] [worker-91] GrpcRequestBridge asking for more request(1)
5+
INFO [2026-01-07 18:40:39,984] [grpc-default-executor-1] UnifiedGrpcBridge onNext Send 12033a012a32460a120a10746573742e43686174536572766963650a250a23677270632e7265666c656374696f6e2e76312e5365727665725265666c656374696f6e0a090a0747726565746572
6+
INFO [2026-01-07 18:40:44,114] [grpc-default-executor-0] UnifiedGrpcBridge error io.grpc.StatusRuntimeException: UNAVAILABLE: Channel shutdownNow invoked
7+
8+
INFO [2026-01-07 18:40:44,114] [Thread-0] GrpcServer Stopped GrpcServer
9+
INFO [2026-01-07 18:40:44,117] [worker-88] JettySubscription read data started
10+
INFO [2026-01-07 18:40:44,117] [worker-88] JettySubscription last reach
11+
INFO [2026-01-07 18:40:44,117] [worker-88] JettySubscription handle complete

modules/jooby-bom/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,11 @@
115115
<artifactId>jooby-graphql</artifactId>
116116
<version>${project.version}</version>
117117
</dependency>
118+
<dependency>
119+
<groupId>io.jooby</groupId>
120+
<artifactId>jooby-grpc</artifactId>
121+
<version>${project.version}</version>
122+
</dependency>
118123
<dependency>
119124
<groupId>io.jooby</groupId>
120125
<artifactId>jooby-gson</artifactId>

modules/jooby-grpc/pom.xml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
3+
4+
<modelVersion>4.0.0</modelVersion>
5+
6+
<parent>
7+
<groupId>io.jooby</groupId>
8+
<artifactId>modules</artifactId>
9+
<version>4.0.14-SNAPSHOT</version>
10+
</parent>
11+
<artifactId>jooby-grpc</artifactId>
12+
<name>jooby-grpc</name>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>io.jooby</groupId>
17+
<artifactId>jooby</artifactId>
18+
<version>${jooby.version}</version>
19+
</dependency>
20+
21+
<dependency>
22+
<groupId>io.grpc</groupId>
23+
<artifactId>grpc-protobuf</artifactId>
24+
<version>${grpc.version}</version>
25+
</dependency>
26+
<dependency>
27+
<groupId>io.grpc</groupId>
28+
<artifactId>grpc-stub</artifactId>
29+
<version>${grpc.version}</version>
30+
</dependency>
31+
<dependency>
32+
<groupId>io.grpc</groupId>
33+
<artifactId>grpc-inprocess</artifactId>
34+
<version>${grpc.version}</version>
35+
</dependency>
36+
37+
<!-- Test dependencies -->
38+
<dependency>
39+
<groupId>org.junit.jupiter</groupId>
40+
<artifactId>junit-jupiter-engine</artifactId>
41+
<scope>test</scope>
42+
</dependency>
43+
44+
<dependency>
45+
<groupId>org.jacoco</groupId>
46+
<artifactId>org.jacoco.agent</artifactId>
47+
<classifier>runtime</classifier>
48+
<scope>test</scope>
49+
</dependency>
50+
51+
<dependency>
52+
<groupId>org.mockito</groupId>
53+
<artifactId>mockito-core</artifactId>
54+
<scope>test</scope>
55+
</dependency>
56+
</dependencies>
57+
</project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Jooby https://jooby.io
3+
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
4+
* Copyright 2014 Edgar Espina
5+
*/
6+
package io.jooby.grpc;
7+
8+
import java.nio.ByteBuffer;
9+
import java.util.function.Consumer;
10+
11+
public class GrpcDeframer {
12+
private enum State {
13+
HEADER,
14+
PAYLOAD
15+
}
16+
17+
private State state = State.HEADER;
18+
private final ByteBuffer headerBuffer = ByteBuffer.allocate(5);
19+
private ByteBuffer payloadBuffer;
20+
21+
public void process(byte[] data, Consumer<byte[]> onMessage) {
22+
ByteBuffer input = ByteBuffer.wrap(data);
23+
while (input.hasRemaining()) {
24+
if (state == State.HEADER) {
25+
while (headerBuffer.hasRemaining() && input.hasRemaining()) {
26+
headerBuffer.put(input.get());
27+
}
28+
if (!headerBuffer.hasRemaining()) {
29+
headerBuffer.flip();
30+
headerBuffer.get(); // skip compressed flag
31+
int length = headerBuffer.getInt();
32+
if (length == 0) {
33+
onMessage.accept(new byte[0]);
34+
headerBuffer.clear();
35+
} else {
36+
payloadBuffer = ByteBuffer.allocate(length);
37+
state = State.PAYLOAD;
38+
}
39+
}
40+
} else if (state == State.PAYLOAD) {
41+
while (payloadBuffer.hasRemaining() && input.hasRemaining()) {
42+
payloadBuffer.put(input.get());
43+
}
44+
if (!payloadBuffer.hasRemaining()) {
45+
onMessage.accept(payloadBuffer.array());
46+
headerBuffer.clear();
47+
payloadBuffer = null;
48+
state = State.HEADER;
49+
}
50+
}
51+
}
52+
}
53+
}

0 commit comments

Comments
 (0)