Skip to content

Commit

Permalink
feat: add http streaming support
Browse files Browse the repository at this point in the history
  • Loading branch information
bsorrentino committed Jul 8, 2024
1 parent 9a339ce commit d57e917
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 0 deletions.
75 changes: 75 additions & 0 deletions jetty/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.bsc.langgraph4j</groupId>
<artifactId>langgraph4j-parent</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>

<artifactId>jetty</artifactId>

<packaging>war</packaging>
<name>Servlet 3 Webapp with Jetty Plugin</name>

<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty.version>12.0.11</jetty.version>
</properties>

<dependencyManagement>
<dependencies>
</dependencies>
</dependencyManagement>

<dependencies>

<!--
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
-->

<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.eclipse.jetty.ee10/jetty-ee10-servlet -->
<dependency>
<groupId>org.eclipse.jetty.ee10</groupId>
<artifactId>jetty-ee10-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>

<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution><goals><goal>java</goal></goals></execution>
</executions>
<configuration>
<mainClass>org.bsc.langgraph4j.JettyStreamingServer</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
74 changes: 74 additions & 0 deletions jetty/src/main/java/org/bsc/langgraph4j/JettyStreamingServer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package org.bsc.langgraph4j;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee10.servlet.ServletContextHandler;
import org.eclipse.jetty.ee10.servlet.ServletHolder;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.util.resource.ResourceFactory;

import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;

public class JettyStreamingServer {

public static void main(String[] args) throws Exception {
Server server = new Server();
ServerConnector connector = new ServerConnector(server);
connector.setPort(8080);
server.addConnector(connector);

ResourceHandler resourceHandler = new ResourceHandler();
Path publicResourcesPath = Paths.get( "jetty", "src", "main", "webapp" );
resourceHandler.setBaseResource(ResourceFactory.of(resourceHandler).newResource(publicResourcesPath));
resourceHandler.setDirAllowed(true);

ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
// Add the streaming servlet
context.addServlet(new ServletHolder(new StreamingServlet()), "/stream");

Handler.Sequence handlerList = new Handler.Sequence(resourceHandler, context );

server.setHandler(handlerList);

server.start();
server.join();
}

public static class StreamingServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");

final PrintWriter writer = response.getWriter();

// Start asynchronous processing
request.startAsync();

// Simulate a long-running process
new Thread(() -> {
try {
for (int i = 0; i < 10; i++) {
writer.println("Line " + i);
writer.flush();
TimeUnit.SECONDS.sleep(1);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
writer.close();
}
}).start();
}
}
}
33 changes: 33 additions & 0 deletions jetty/src/main/webapp/streaming.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<html>
<title>streaming</title>
<head>
</head>

<body>
<script>
async function* streamingFetch( fetchcall ) {

const response = await fetchcall();
// Attach Reader
const reader = response.body.getReader();
while (true) {
// wait for next encoded chunk
const { done, value } = await reader.read();
// check if stream is done
if (done) break;
// Decodes data chunk and yields it
yield (new TextDecoder().decode(value));
}
}

(async () => {

for await ( let chunk of streamingFetch( () => fetch('http://localhost:8080/stream') ) ) {
console.log( chunk )
}

})();
</script>

</body>
</html>
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
<module>agent-executor</module>
<module>image-to-diagram</module>
<module>adaptive-rag</module>
<module>jetty</module>
</modules>

<dependencyManagement>
Expand Down

0 comments on commit d57e917

Please sign in to comment.