Skip to content

Instantly share code, notes, and snippets.

@klauspost
Created September 17, 2015 10:34
Show Gist options
  • Save klauspost/d6e28edc72063d4d2a4f to your computer and use it in GitHub Desktop.
Save klauspost/d6e28edc72063d4d2a4f to your computer and use it in GitHub Desktop.
package app
import (
"math/rand"
"time"
"github.com/revel/revel"
)
// randomDuration generates a duration between min and max duration.
func randomDuration(min, max time.Duration) time.Duration {
if max <= min {
revel.ERROR.Printf("randomDuration: Duration %v is not bigger than %v", max, min)
return min
}
r := rand.Int63n(int64(max)-int64(min)) + int64(min)
return time.Duration(r)
}
// BadConnectionFilter will add random delays return empty replies and even hang the connections
//
// Use "badconnection.enable" in revel configuration to enable the filter when it is inserted into
// the filter chain.
//
// Additional options are:
// - "badconnection.longdelay.percent": Percent chance you will get a random 1.5 to 20 second delay. Default: 25.
// - "badconnection.noreply.percent": Percent chance you will get an empty reply. Default: 15.
// - "badconnection.hang.percent": Percent chance you will get a hung connection (never returning a reply). Default: 5.
func BadConnectionFilter(c *revel.Controller, fc []revel.Filter) {
if revel.Config.BoolDefault("badconnection.enable", false) {
a := revel.Config.IntDefault("badconnection.base.min", 36)
b := revel.Config.IntDefault("badconnection.base.max", 150)
dur := randomDuration(time.Millisecond*time.Duration(a), time.Millisecond*time.Duration(b))
time.Sleep(dur)
// Long delay
r := rand.Uint32() % 100 // Gives 0 to 99 ( we only stall half the delay)
if r < uint32(revel.Config.IntDefault("badconnection.longdelay.percent", 25)) {
a = revel.Config.IntDefault("badconnection.longdelay.min", 1500) / 2
b = revel.Config.IntDefault("badconnection.longdelay.max", 15000) / 2
dur = randomDuration(time.Millisecond*time.Duration(a), time.Millisecond*time.Duration(b))
revel.TRACE.Printf("Sleeping for additional %s on %s\n", dur, c.Request.RequestURI)
time.Sleep(dur)
}
// Empty reply
r = rand.Uint32() % 200 // Gives 0 to 199
if r < uint32(revel.Config.IntDefault("badconnection.noreply.percent", 15)) {
revel.TRACE.Printf("Returning no response on %s, because\n", c.Request.RequestURI)
return
}
//Hung connection
r = rand.Uint32() % 200 // Gives 0 to 199
if r < uint32(revel.Config.IntDefault("badconnection.hang.percent", 5)) {
revel.TRACE.Printf("Hanging on %s\n", c.Request.RequestURI)
time.Sleep(time.Hour * 5000)
}
}
// Call next in filter chain
fc[0](c, fc[1:])
if revel.Config.BoolDefault("badconnection.enable", false) {
time.Sleep(randomDuration(time.Millisecond*36, time.Millisecond*150))
// Long delay
r := rand.Uint32() % 100 // Gives 0 to 99 ( we only stall half the delay)
if r < uint32(revel.Config.IntDefault("badconnection.longdelay.percent", 25)) {
a := revel.Config.IntDefault("badconnection.longdelay.min", 1500) / 2
b := revel.Config.IntDefault("badconnection.longdelay.max", 15000) / 2
dur := randomDuration(time.Millisecond*time.Duration(a), time.Millisecond*time.Duration(b))
revel.TRACE.Printf("Sleeping for additional %s on %s\n", dur, c.Request.RequestURI)
time.Sleep(dur)
}
// Empty reply
r = rand.Uint32() % 200 // Gives 0 to 199
if r < uint32(revel.Config.IntDefault("badconnection.noreply.percent", 15)) {
revel.TRACE.Printf("Returning no response on %s, because\n", c.Request.RequestURI)
return
}
//Hung connection
r = rand.Uint32() % 200 // Gives 0 to 199
if r < uint32(revel.Config.IntDefault("badconnection.hang.percent", 5)) {
revel.TRACE.Printf("Hanging on %s\n", c.Request.RequestURI)
time.Sleep(time.Hour * 5000)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment