Skip to content
A low-level, high performance HTTP server.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
gradle/wrapper
src
.gitignore
LICENSE
README.md
build.gradle
gradlew
gradlew.bat
settings.gradle

README.md

Pronghorn HTTP Server

The Pronghorn HTTP Server is a low-level, high performance HTTP server written in Kotlin. It utilizes the Pronghorn Coroutine Framework to fully utilize available system resources with minimal overhead. No external dependencies are required, however, functionality can be enhanced through optional plugins which may contain external dependencies.

Note: The Pronghorn HTTP Server is early in development, and is in many ways a testbed for the Pronghorn Coroutine Framework. As such it is not currently recommended in production environments. Documentation will improve as it matures.

Use Cases

Pronghorn is best suited for applications where high throughput and/or low latency with minimal cpu overhead are critical requirements.

Quick Start

The following is the simple Hello World server example using Pronghorn.

fun main(args: Array<String>) {
    val helloWorldResponse = HttpResponses.OK("Hello, World!", CommonContentTypes.TextPlain)
    val helloWorldHandler = StaticHttpRequestHandler(helloWorldResponse)

    val server = HttpServer("localhost", 8080)
    server.registerUrlHandler("/hello", helloWorldHandler)
    server.start()
}

Configuration

Alternatively to the above, The HttpServer class can be constructed with an instance of HttpServerConfig

val config = HttpServerConfig(address = ..., ...)
val server = HttpServer(config)

Full Configuration Options

  • address - The address to bind to.
  • workerCount - The number of worker threads to utilize, should likely be the number of cores available (default: number of logical cpu cores)
  • sendServerHeader - If true, the Server header is automatically sent with each response (default: true)
  • sendDateHeader - If true, the Date header is automatically sent with each response (default: true)
  • serverName - The value to send in the Server response header if sendServerHeader is true (default: "Pronghorn")
  • reusableBufferSize - The size of pooled read/write buffers, should be at least as large as the average expected request (default: 64 KiB)
  • reusePort - If true, the SO_REUSEPORT socket option is used and each worker uses a dedicated socket (default: auto-detected)
  • listenBacklog - The value for the accept queue for the server socket (default: 128)
  • acceptGrouping - How many connections should be accepted in a batch, usually equal to the listen backlog (default: 128)
  • maxPipelinedRequests - The maximum number of http requests allowed to be pipelined on a single connection (default: 64)
  • maxRequestSize - The maximum acceptable size of a single http request (default: 1 MiB)
  • useDirectByteBuffers - Whether socket read/write buffers should be direct ByteBuffers (default: true)

Plugins

Pronghorn ships with three optional plugins

SLF4J Logging Plugin

Utilizes the popular SLF4J library for logging. See https://www.slf4j.org/manual.html for more information.

JCTools Collections Plugin

This plugin offers high performance alternatives for collection types used at critical points throughout Pronghorn. The excellent JCTools library provides wait free and lock less implementations of many concurrent data structures. Utilizing these in place of Java standard library collections results in performance improvements for some workloads.

OpenHFT Hashing Plugin

This plugin utilizes the OpenHFT Zero Allocation Hashing library to provide high performance hashing ByteArrays. This improves Pronghorn performance under some workloads and configurations.

Enabling Plugins

There are two ways to configure Pronghorn to utilize a plugin implementation.

Resource File Plugin Configuration

By default Pronghorn looks for a resource file named "pronghorn.properties" in Java properties file format. The keys of this file should be the Plugin class for which an implementation is being specified, with the value being the implementation.

For example, if all of the above plugin dependencies have been included, the pronghorn.properties file would appear as:

pronghorn.plugins.LoggingPlugin       = tech.pronghorn.plugins.Slf4jLoggingPlugin
pronghorn.plugins.SpscQueuePlugin     = tech.pronghorn.plugins.JCToolsSpscQueuePlugin
pronghorn.plugins.MpscQueuePlugin     = tech.pronghorn.plugins.JCToolsMpscQueuePlugin
pronghorn.plugins.ConcurrentMapPlugin = tech.pronghorn.plugins.JCToolsConcurrentMapPlugin
pronghorn.plugins.ConcurrentSetPlugin = tech.pronghorn.plugins.JCToolsConcurrentSetPlugin
pronghorn.plugins.ArrayHasherPlugin   = tech.pronghorn.plugins.OpenHFTArrayHasherPlugin

Programmatic Plugin Configuration

Alternatively, plugins can be configured programmatically utilizing the setPlugin method as in this example:

LoggingPlugin.setPlugin(Slf4jLoggingPlugin)

License

Copyright 2017 Pronghorn Technology LLC

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

You can’t perform that action at this time.