Skip to content

Commit

Permalink
Swap Lazy for Try in spider (#21)
Browse files Browse the repository at this point in the history
When deploying an app on fly.io, I noticed what seemed like a deadlock
when deploying on 1 cpu machine. No issue when scaling to 2 cpu. Not
sure if it's related, but Lazy can/will use a lot of virtual threads, so
swap those parts of spider out for plain Trys to see if it helps.
  • Loading branch information
alterationx10 authored Dec 29, 2024
1 parent 208dfcb commit f9accae
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 41 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package dev.wishingtree.branch.spider.server

import com.sun.net.httpserver.*
import dev.wishingtree.branch.lzy.Lazy
import dev.wishingtree.branch.lzy.abstractions.Semigroup
import dev.wishingtree.branch.spider.HttpMethod
import dev.wishingtree.branch.macaroni.fs.PathOps.*

import java.time.{Duration, Instant}
import java.nio.file.Path
import scala.jdk.CollectionConverters.*
import scala.util.*

/** A base trait for handling requests, rooted at a specific path.
*/
Expand Down Expand Up @@ -39,27 +40,28 @@ trait ContextHandler(val path: String) {
private[spider] inline def httpHandler: HttpHandler = {
(exchange: HttpExchange) =>
{
Lazy
.fn {
HttpMethod
.fromString(exchange.getRequestMethod.toUpperCase)
.map(v =>
v -> Path.of(exchange.getRequestURI.getPath).relativeTo("/")
)
.filter(contextRouter.isDefinedAt)
.map(contextRouter)
.getOrElse(notFoundRequestHandler)

val requestHandler: RequestHandler[?, ?] =
HttpMethod.fromString(exchange.getRequestMethod.toUpperCase) match {
case Some(method) =>
val path = Path.of(exchange.getRequestURI.getPath).relativeTo("/")
contextRouter
.lift(method -> path)
.getOrElse(notFoundRequestHandler)
case None =>
notFoundRequestHandler
}
.flatMap(_.lzyRun(exchange))
.recover { e =>
Lazy.fn {
val msg = e.getMessage.getBytes()

Try(requestHandler.tryRun(exchange)) match {
case Success(value) => ()
case Failure(exception) =>
Try {
val msg = exception.getMessage.getBytes()
exchange.sendResponseHeaders(500, msg.length)
exchange.getResponseBody.write(msg)
exchange.getResponseBody.close()
}
}
.runSync()
}

exchange.close()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package dev.wishingtree.branch.spider.server

import com.sun.net.httpserver.HttpExchange
import dev.wishingtree.branch.lzy.Lazy

import scala.jdk.CollectionConverters.*
import scala.util.Try

/** A base trait to extend for handling a Request and returning a Response.
* @tparam I
Expand All @@ -28,44 +28,45 @@ trait RequestHandler[I, O](using
*/
private final def decodeRequest(
exchange: HttpExchange
): Lazy[Request[I]] =
): Try[Request[I]] =
for {
headers <- Lazy
.fn {
exchange.getRequestHeaders.asScala
.map((k, v) => k -> v.asScala.toList)
.toMap
}
rawBody <- Lazy.fn(exchange.getRequestBody.readAllBytes())
body <- Lazy.fn(requestDecoder(rawBody))
headers <- Try {
exchange.getRequestHeaders.asScala
.map((k, v) => k -> v.asScala.toList)
.toMap
}
rawBody <- Try(exchange.getRequestBody.readAllBytes())
body <- Try(requestDecoder(rawBody))
} yield Request(exchange.getRequestURI, headers, body)

/** Send the Response to the HttpExchange.
*/
private final def sendResponse(response: Response[O])(
exchange: HttpExchange
): Lazy[Unit] = {
): Try[Unit] = {
for {
responseBody <- Lazy.fn(responseEncoder(response.body))
_ <- Lazy.fn {
responseBody <- Try(responseEncoder(response.body))
_ <- Try {
response.headers.foreach { (k, v) =>
exchange.getResponseHeaders.set(k, v.mkString(","))
}
}
_ <-
Lazy.fn(
exchange.sendResponseHeaders(response.statusCode, responseBody.length)
)
_ <- Lazy.fn(exchange.getResponseBody.write(responseBody))
_ <- Try {
exchange.sendResponseHeaders(
response.statusCode,
responseBody.length
)
}
_ <- Try(exchange.getResponseBody.write(responseBody))
} yield ()
}

private[spider] inline final def lzyRun(
private[spider] final def tryRun(
exchange: HttpExchange
): Lazy[Unit] = {
): Try[Unit] = {
for {
request <- decodeRequest(exchange)
response <- Lazy.fn(this.handle(request))
response <- Try(this.handle(request))
_ <- sendResponse(response)(exchange)
} yield ()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.wishingtree.branch.spider.server

import com.sun.net.httpserver.{HttpHandler, HttpServer}
import dev.wishingtree.branch.lzy.LazyRuntime
import com.sun.net.httpserver.HttpServer
import dev.wishingtree.branch.macaroni.runtimes.BranchExecutors

import java.net.InetSocketAddress

Expand All @@ -22,7 +22,7 @@ trait SpiderApp {
final given server: HttpServer =
HttpServer.create(new InetSocketAddress(port), backlog)

server.setExecutor(LazyRuntime.executorService)
server.setExecutor(BranchExecutors.executorService)

Runtime.getRuntime.addShutdownHook {
new Thread(() => server.stop(5))
Expand Down

0 comments on commit f9accae

Please sign in to comment.