Skip to content

Commit

Permalink
feat: Add loom Support.
Browse files Browse the repository at this point in the history
  • Loading branch information
He-Pin committed Jan 11, 2025
1 parent 78031f7 commit d70974c
Show file tree
Hide file tree
Showing 18 changed files with 791 additions and 40 deletions.
19 changes: 14 additions & 5 deletions .github/workflows/actions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
java: [ '11', '17', '21' ]
name: Tests for Java ${{ matrix.Java }}
name: Tests local for Java ${{ matrix.Java }}
steps:
- uses: actions/checkout@v3
- name: Setup java
Expand All @@ -27,14 +27,18 @@ jobs:
- name: Run tests
run: |
set -eux
./mill -ikj1 --disable-ticker __.testLocal
if [ "${{ matrix.java }}" == "21" ]; then
JAVA_OPTS='--add-opens java.base/java.lang=ALL-UNNAMED -Dcask.virtual-thread.enabled=true' ./mill -ikj1 --disable-ticker __.testLocal
else
./mill -ikj1 --disable-ticker __.testLocal
fi
test-examples:
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '11', '17', '21' ]
name: Tests for Java ${{ matrix.Java }}
name: Tests examples for Java ${{ matrix.Java }}
steps:
- uses: actions/checkout@v3
- name: Setup java
Expand All @@ -45,8 +49,13 @@ jobs:
- name: Run tests
run: |
set -eux
./mill __.publishLocal
./mill -ikj1 --disable-ticker testExamples
if [ "${{ matrix.java }}" == "21" ]; then
./mill __.publishLocal
JAVA_OPTS='--add-opens java.base/java.lang=ALL-UNNAMED -Dcask.virtual-thread.enabled=true' ./mill -ikj1 --disable-ticker testExamples
else
./mill __.publishLocal
./mill -ikj1 --disable-ticker testExamples
fi
publish-sonatype:
if: github.repository == 'com-lihaoyi/cask' && contains(github.ref, 'refs/tags/')
Expand Down
111 changes: 109 additions & 2 deletions build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,116 @@ object cask extends Cross[CaskMainModule](scalaVersions) {
}
}

trait LocalModule extends CrossScalaModule{
override def millSourcePath = super.millSourcePath / "app"
trait BenchmarkModule extends CrossScalaModule {
def moduleDeps = Seq(cask(crossScalaVersion))
def ivyDeps = Agg[Dep](
)
}

object benchmark extends Cross[BenchmarkModule](build.scalaVersions) with RunModule {

def waitForServer(url: String, maxAttempts: Int = 120): Boolean = {
(1 to maxAttempts).exists { attempt =>
try {
Thread.sleep(3000)
println("Checking server... Attempt " + attempt)
os.proc("curl", "-s", "-o", "/dev/null", "-w", "%{http_code}", url)
.call(check = false)
.exitCode == 0
} catch {
case _: Throwable =>
Thread.sleep(3000)
false
}
}
}

def runBenchmark() = T.command {
if (os.proc("which", "wrk").call(check = false).exitCode != 0) {
println("Error: wrk is not installed. Please install wrk first.")
sys.exit(1)
}

val duration = "30s"
val threads = "4"
val connections = "100"
val url = "http://localhost:8080/"

println("Testing with regular threads...")

val projectRoot = T.workspace
println("projectRoot: " + projectRoot)

def runMillBackground(example: String, vt:Boolean) = {
println(s"Running $example with vt: $vt")

os.proc(
"mill",
s"example.$example.app[$scala213].run")
.spawn(
cwd = projectRoot,
env = Map("CASK_VIRTUAL_THREAD" -> vt.toString),
stdout = os.Inherit,
stderr = os.Inherit)
}

for (example <- Seq(
"staticFilesWithLoom",
"todoDbWithLoom",
"minimalApplicationWithLoom")) {

val regularApp = runMillBackground(example, vt = false)

println("Waiting for regular server to start...")
if (!waitForServer(url)) {
regularApp.destroy()
println("Failed to start regular server")
sys.exit(1)
}

println("target server started, starting run benchmark with wrk")
val regularResults = os.proc("wrk",
"-t", threads,
"-c", connections,
"-d", duration,
url
).call(stderr = os.Pipe)
regularApp.destroy()

println("\nRegular Threads Results:")
println(regularResults.out.text())

Thread.sleep(1000)
println("\nTesting with virtual threads, please use Java 21+...")
val virtualApp = runMillBackground(example, vt = true)

println("Waiting for virtual server to start...")
if (!waitForServer(url)) {
virtualApp.destroy()
println("Failed to start virtual server")
sys.exit(1)
}

println("target server started, starting run benchmark with wrk")
val virtualResults = os.proc("wrk",
"-t", threads,
"-c", connections,
"-d", duration,
url
).call(stderr = os.Pipe)
virtualApp.destroy()

println("\nVirtual Threads Results:")
println(virtualResults.out.text())
}

}
}

trait LocalModule extends CrossScalaModule{
override def millSourcePath = super.millSourcePath / "app"
def moduleDeps = Seq(cask(crossScalaVersion))
}

def zippedExamples = T {
val vcsState = VcsVersion.vcsState()
Expand All @@ -111,13 +215,16 @@ def zippedExamples = T {
build.example.httpMethods.millSourcePath,
build.example.minimalApplication.millSourcePath,
build.example.minimalApplication2.millSourcePath,
build.example.minimalApplicationWithLoom.millSourcePath,
build.example.redirectAbort.millSourcePath,
build.example.scalatags.millSourcePath,
build.example.staticFiles.millSourcePath,
build.example.staticFilesWithLoom.millSourcePath,
build.example.staticFiles2.millSourcePath,
build.example.todo.millSourcePath,
build.example.todoApi.millSourcePath,
build.example.todoDb.millSourcePath,
build.example.todoDbWithLoom.millSourcePath,
build.example.twirl.millSourcePath,
build.example.variableRoutes.millSourcePath,
build.example.queryParams.millSourcePath,
Expand Down
17 changes: 17 additions & 0 deletions cask/src/cask/internal/ThreadBlockingHandler.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package cask.internal

import io.undertow.server.{HttpHandler, HttpServerExchange}

import java.util.concurrent.Executor

/**
* A handler that dispatches the request to the given handler using the given executor.
* */
final class ThreadBlockingHandler(executor: Executor, handler: HttpHandler) extends HttpHandler {
require(executor ne null, "Executor should not be null")

def handleRequest(exchange: HttpServerExchange): Unit = {
exchange.startBlocking()
exchange.dispatch(executor, handler)
}
}
Loading

0 comments on commit d70974c

Please sign in to comment.