New iris.WithKeepAlive(time.Duration) Configurator is added as a helper to enable TCP listener featured with keep-alive

This commit is contained in:
Gerasimos (Makis) Maropoulos 2021-01-31 21:24:15 +02:00
parent eec0cb8d51
commit 5994fd5d4e
No known key found for this signature in database
GPG Key ID: 5DBE766BD26A54E7
9 changed files with 62 additions and 15 deletions

View File

@ -28,6 +28,10 @@ The codebase for Dependency Injection, Internationalization and localization and
## Fixes and Improvements
- New `Configuration.KeepAlive` and `iris.WithKeepAlive(time.Duration) Configurator` added as helpers to start the server using a tcp listener featured with keep-alive.
- New `DirOptions.ShowHidden bool` is added by [@tuhao1020](https://github.com/tuhao1020) at [PR #1717](https://github.com/kataras/iris/pull/1717) to show or hide the hidden files when `ShowList` is set to true.
- New `Context.ReadJSONStream` method and `JSONReader` options for `Context.ReadJSON` and `Context.ReadJSONStream`, see the [example](_examples/request-body/read-json-stream/main.go).
- New `FallbackView` feature, per-party or per handler chain. Example can be found at: [_examples/view/fallback](_examples/view/fallback).

View File

@ -26,6 +26,8 @@ func newApp() *iris.Application {
Compress: false,
// List the files inside the current requested directory if `IndexName` not found.
ShowList: false,
// When ShowList is true you can configure if you want to show or hide hidden files.
ShowHidden: false,
Cache: iris.DirCacheOptions{
// enable in-memory cache and pre-compress the files.
Enable: true,

View File

@ -1,8 +1,6 @@
package main
import (
"github.com/kataras/iris/v12"
)
import "github.com/kataras/iris/v12"
func main() {
app := iris.New()
@ -13,5 +11,9 @@ func main() {
// http://localhost:8080
// Identical to: app.Run(iris.Addr(":8080"))
app.Listen(":8080")
// To listen using keep alive tcp connection listener,
// set the KeepAlive duration configuration instead:
// app.Listen(":8080", iris.WithKeepAlive(3*time.Minute))
}

View File

@ -8,6 +8,7 @@ import (
"path/filepath"
"runtime"
"strings"
"time"
"github.com/kataras/golog"
"github.com/kataras/iris/v12/context"
@ -200,6 +201,13 @@ func WithSocketSharding(app *Application) {
app.config.SocketSharding = true
}
// WithKeepAlive sets the `Configuration.KeepAlive` field to the given duration.
func WithKeepAlive(keepAliveDur time.Duration) Configurator {
return func(app *Application) {
app.config.KeepAlive = keepAliveDur
}
}
// WithoutServerError will cause to ignore the matched "errors"
// from the main application's `Run/Listen` function.
//
@ -613,6 +621,12 @@ type Configuration struct {
//
// Defaults to false.
SocketSharding bool `ini:"socket_sharding" json:"socketSharding" yaml:"SocketSharding" toml:"SocketSharding" env:"SOCKET_SHARDING"`
// KeepAlive sets the TCP connection's keep-alive duration.
// If set to greater than zero then a tcp listener featured keep alive
// will be used instead of the simple tcp one.
//
// Defaults to 0.
KeepAlive time.Duration `ini:"keepalive" json:"keepAlive" yaml:"KeepAlive" toml:"KeepAlive" env:"KEEP_ALIVE"`
// Tunneling can be optionally set to enable ngrok http(s) tunneling for this Iris app instance.
// See the `WithTunneling` Configurator too.
Tunneling TunnelingConfiguration `ini:"tunneling" json:"tunneling,omitempty" yaml:"Tunneling" toml:"Tunneling"`
@ -894,6 +908,11 @@ func (c Configuration) GetSocketSharding() bool {
return c.SocketSharding
}
// GetKeepAlive returns the KeepAlive field.
func (c Configuration) GetKeepAlive() time.Duration {
return c.KeepAlive
}
// GetDisablePathCorrection returns the DisablePathCorrection field.
func (c Configuration) GetDisablePathCorrection() bool {
return c.DisablePathCorrection
@ -1064,6 +1083,10 @@ func WithConfiguration(c Configuration) Configurator {
main.SocketSharding = v
}
if v := c.KeepAlive; v > 0 {
main.KeepAlive = v
}
if len(c.Tunneling.Tunnels) > 0 {
main.Tunneling = c.Tunneling
}
@ -1215,6 +1238,7 @@ func DefaultConfiguration() Configuration {
return Configuration{
LogLevel: "info",
SocketSharding: false,
KeepAlive: 0,
DisableStartupLog: false,
DisableInterruptHandler: false,
DisablePathCorrection: false,

View File

@ -1,6 +1,10 @@
package context
import "github.com/kataras/iris/v12/core/netutil"
import (
"time"
"github.com/kataras/iris/v12/core/netutil"
)
// ConfigurationReadOnly can be implemented
// by Configuration, it's being used inside the Context.
@ -14,6 +18,8 @@ type ConfigurationReadOnly interface {
GetLogLevel() string
// GetSocketSharding returns the SocketSharding field.
GetSocketSharding() bool
// GetKeepAlive returns the KeepAlive field.
GetKeepAlive() time.Duration
// GetDisablePathCorrection returns the DisablePathCorrection field
GetDisablePathCorrection() bool
// GetDisablePathCorrectionRedirection returns the DisablePathCorrectionRedirection field.

View File

@ -70,6 +70,9 @@ type Supervisor struct {
// See `iris.Configuration.SocketSharding`.
SocketSharding bool
// If more than zero then tcp keep alive listener is attached instead of the simple TCP listener.
// See `iris.Configuration.KeepAlive`
KeepAlive time.Duration
}
// New returns a new host supervisor
@ -141,13 +144,17 @@ func (su *Supervisor) isWaiting() bool {
}
func (su *Supervisor) newListener() (net.Listener, error) {
// this will not work on "unix" as network
// because UNIX doesn't supports the kind of
// restarts we may want for the server.
//
// User still be able to call .Serve instead.
// l, err := netutil.TCPKeepAlive(su.Server.Addr, su.SocketSharding)
l, err := netutil.TCP(su.Server.Addr, su.SocketSharding)
var (
l net.Listener
err error
)
if su.KeepAlive > 0 {
l, err = netutil.TCPKeepAlive(su.Server.Addr, su.SocketSharding, su.KeepAlive)
} else {
l, err = netutil.TCP(su.Server.Addr, su.SocketSharding)
}
if err != nil {
return nil, err
}

View File

@ -21,6 +21,7 @@ import (
// A raw copy of standar library.
type tcpKeepAliveListener struct {
*net.TCPListener
keepAliveDur time.Duration
}
// Accept accepts tcp connections aka clients.
@ -32,7 +33,7 @@ func (l tcpKeepAliveListener) Accept() (net.Conn, error) {
if err = tc.SetKeepAlive(true); err != nil {
return tc, err
}
if err = tc.SetKeepAlivePeriod(3 * time.Minute); err != nil {
if err = tc.SetKeepAlivePeriod(l.keepAliveDur); err != nil {
return tc, err
}
return tc, nil
@ -49,7 +50,7 @@ func TCP(addr string, reuse bool) (net.Listener, error) {
}
// TCPKeepAlive returns a new tcp keep alive Listener and an error on failure.
func TCPKeepAlive(addr string, reuse bool) (ln net.Listener, err error) {
func TCPKeepAlive(addr string, reuse bool, keepAliveDur time.Duration) (ln net.Listener, err error) {
// if strings.HasPrefix(addr, "127.0.0.1") {
// // it's ipv4, use ipv4 tcp listener instead of the default ipv6. Don't.
// ln, err = net.Listen("tcp4", addr)
@ -61,7 +62,7 @@ func TCPKeepAlive(addr string, reuse bool) (ln net.Listener, err error) {
if err != nil {
return nil, err
}
return tcpKeepAliveListener{ln.(*net.TCPListener)}, nil
return tcpKeepAliveListener{ln.(*net.TCPListener), keepAliveDur}, nil
}
// UNIX returns a new unix(file) Listener.

View File

@ -106,7 +106,7 @@ type DirOptions struct {
// See `DirListRich` package-level function too.
DirList DirListFunc
// show hidden files or directories or not when `ShowList` is true
// Show hidden files or directories or not when `ShowList` is true.
ShowHidden bool
// Files downloaded and saved locally.

View File

@ -893,6 +893,7 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error {
app.ConfigureHost(func(host *Supervisor) {
host.SocketSharding = app.config.SocketSharding
host.KeepAlive = app.config.KeepAlive
})
app.tryStartTunneling()