# DEPRECATED

**This package has been deprecated and should not be used going forward.**

If you are a current user and are having issues with this package, please [contact the Fulton team](https://docs.fulton.twitch.a2z.com/#getting-help).

If you are looking for a new way to create a service, please consider [Fulton](https://docs.fulton.twitch.a2z.com/).

# twitchserver

[![GoDoc](http://godoc.internal.justin.tv/code.justin.tv/foundation/twitchserver?status.svg)](http://godoc.internal.justin.tv/code.justin.tv/foundation/twitchserver)

Enables quicker creation of production-ready HTTP servers in Twitch.
Goes well together with [twitchclient](https://git-aws.internal.justin.tv/foundation/twitchclient).

## Dependencies

`twitchserver` requires Go 1.8 or higher.

## Usage
```go
package main

import (
    "log"
    "code.justin.tv/foundation/twitchserver"
)

func main() {
    mux := twitchserver.NewServer()
    conf := twitchserver.NewConfig()

    twitchserver.AddDefaultSignalHandlers() // Enables graceful shutdown via OS signals SIGINT, SIGTERM, and SIGUSR2.
    err := twitchserver.ListenAndServe(mux, conf)
    if err != nil {
        log.Fatal(err)
    }
}
```

## Features

 * Out-of-the-box profiling
 * Health check endpoint `GET /debug/running` for load balancer health checks
 * Go runtime metrics (through gometrics)
 * Graceful shutdowns
 * Request tracing with x-ray
 * Integration with ctxlog
 * Error/panic logging with Rollbar
 * Integration with Trace (through Chitin)


## Upgrading from `twitchhttp`

`twitchserver` and `twitchclient` were extracted from [twitchhttp](https://git-aws.internal.justin.tv/common/twitchhttp). This split allows the client and server to evolve independently.

To Upgrade from `twitchhttp` to `twitchserver`:

 1. Update `twitchhttp` to the latest revision. Make sure to update dependencies like Chitin.
 2. Find-and-replace `twitchhttp` for `twitchserver` wherever it was used as server.

twitchserver and twitchclient were extracted from a split made on [twitchhttp](https://git-aws.internal.justin.tv/common/twitchhttp).

The dependency on goji is non-backwards-compatible (twitchhttp depends on the `net-context` branch, while twitchserver depends on `master`).
To upgrade, check the instructions on the [twitchhttp README](https://git-aws.internal.justin.tv/common/twitchhttp).

## Graceful Shutdowns

`twitchserver` has graceful shutdown behavior, powered by Go 1.8's `net/http` package.

Shutdown begins when the process receives a `SIGINT`, `SIGTERM`, or `SIGUSR2` signal from the OS when configured with `AddDefaultSignalHandlers()`.

Additional OS signals can notify the server of shutdown intent by registering them with `AddShutdownSignal()`.

For other cases, `Shutdown` and `ShutdownNow` methods are provided which shut down gracefully and ungracefully, respectively.

A timeout should always be specified when using graceful shutdown so that a server will not wait indefinitely while shutting down.

## Hooking into start/stop Server events
Twitch server supports hooks for PostStartup and PreShutdown.

* PostStartupHook - This event fires when the server is ready to start accepting traffic. I.e some short time after calling `twitchserver.ListenAndServe(mux, conf)`

* PreShutdownHook - This event fires just before the server starts gracefully shutting down. I.e just after it has received a SIGINT or a call to Shutdown was made. (Note when this event fires, health checks to `debug/running` will have started returning 503s.

Adding a hook can be done by a call to serverConf.RegisterPostStartupHook(hook func()) or serverConf.RegisterPreShutdownHook(hook func()). Both methods accept a function which will get executed when the event fires.

eg.


```go
import (
    "log"
    "code.justin.tv/foundation/twitchserver"
)

func main() {
    mux := twitchserver.NewServer()
    conf := twitchserver.NewConfig()

    twitchserver.AddDefaultSignalHandlers() // Enables graceful shutdown via OS signals SIGINT, SIGTERM, and SIGUSR2.

    conf.RegisterPreShutdownHook(handleServerGoingDown)

    err := twitchserver.ListenAndServe(mux, conf)
    if err != nil {
        log.Fatal(err)
    }
}

func handleServerGoingDown() func() {
  // Remove the host from the load balancer...
  log.Printf("Removing the host from the load balancer...")
  time.Sleep(time.Second * 10) // Wait 10 seconds
  log.Printf("Host removed from load balancer")
}
```


## Ctxlog Integration

twitchserver is integrated with [ctxlog](https://git-aws.internal.justin.tv/feeds/ctxlog), which offers two benefits

1. A request ID is propagated between services and stored in the request's context. One example usage is to prepend all
logs with a request id. You can then aggregate and index all of your logs across multiple services by that ID.
After that indexing is complete, it is simple to search for and read all of the log lines relevant to a request. twitchserver
will generate the ID for you, using an x-ray trace ID if it's available. If x-ray is not in use, a random ID will be generated.

2. Request logs can be elevated. Logging all possible debugging information for a high scale production system is impractical, but
it can be done with sampling. By sending the elevate header, `X-Ctxlog-Elevate: true` in a small percentage of requests,
all log lines for that request which use a compatible logging system may be elevated (for example from DEBUG to INFO).

In order to take advantage of these benefits, all `twitchclient` and `twitchserver` in the repository must be created with the
same ElevateKey and DimensionKey so the appropriate headers can be forwarded between services.

Examples are provided in [`example_server_test.go`](example_server_test.go).
