mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
New iris.WithKeepAlive(time.Duration) Configurator is added as a helper to enable TCP listener featured with keep-alive
This commit is contained in:
parent
eec0cb8d51
commit
5994fd5d4e
|
@ -28,6 +28,10 @@ The codebase for Dependency Injection, Internationalization and localization and
|
||||||
|
|
||||||
## Fixes and Improvements
|
## 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 `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).
|
- New `FallbackView` feature, per-party or per handler chain. Example can be found at: [_examples/view/fallback](_examples/view/fallback).
|
||||||
|
|
|
@ -26,6 +26,8 @@ func newApp() *iris.Application {
|
||||||
Compress: false,
|
Compress: false,
|
||||||
// List the files inside the current requested directory if `IndexName` not found.
|
// List the files inside the current requested directory if `IndexName` not found.
|
||||||
ShowList: false,
|
ShowList: false,
|
||||||
|
// When ShowList is true you can configure if you want to show or hide hidden files.
|
||||||
|
ShowHidden: false,
|
||||||
Cache: iris.DirCacheOptions{
|
Cache: iris.DirCacheOptions{
|
||||||
// enable in-memory cache and pre-compress the files.
|
// enable in-memory cache and pre-compress the files.
|
||||||
Enable: true,
|
Enable: true,
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import "github.com/kataras/iris/v12"
|
||||||
"github.com/kataras/iris/v12"
|
|
||||||
)
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
app := iris.New()
|
app := iris.New()
|
||||||
|
@ -13,5 +11,9 @@ func main() {
|
||||||
|
|
||||||
// http://localhost:8080
|
// http://localhost:8080
|
||||||
// Identical to: app.Run(iris.Addr(":8080"))
|
// Identical to: app.Run(iris.Addr(":8080"))
|
||||||
|
|
||||||
app.Listen(":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))
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/kataras/golog"
|
"github.com/kataras/golog"
|
||||||
"github.com/kataras/iris/v12/context"
|
"github.com/kataras/iris/v12/context"
|
||||||
|
@ -200,6 +201,13 @@ func WithSocketSharding(app *Application) {
|
||||||
app.config.SocketSharding = true
|
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"
|
// WithoutServerError will cause to ignore the matched "errors"
|
||||||
// from the main application's `Run/Listen` function.
|
// from the main application's `Run/Listen` function.
|
||||||
//
|
//
|
||||||
|
@ -613,6 +621,12 @@ type Configuration struct {
|
||||||
//
|
//
|
||||||
// Defaults to false.
|
// Defaults to false.
|
||||||
SocketSharding bool `ini:"socket_sharding" json:"socketSharding" yaml:"SocketSharding" toml:"SocketSharding" env:"SOCKET_SHARDING"`
|
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.
|
// Tunneling can be optionally set to enable ngrok http(s) tunneling for this Iris app instance.
|
||||||
// See the `WithTunneling` Configurator too.
|
// See the `WithTunneling` Configurator too.
|
||||||
Tunneling TunnelingConfiguration `ini:"tunneling" json:"tunneling,omitempty" yaml:"Tunneling" toml:"Tunneling"`
|
Tunneling TunnelingConfiguration `ini:"tunneling" json:"tunneling,omitempty" yaml:"Tunneling" toml:"Tunneling"`
|
||||||
|
@ -894,6 +908,11 @@ func (c Configuration) GetSocketSharding() bool {
|
||||||
return c.SocketSharding
|
return c.SocketSharding
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetKeepAlive returns the KeepAlive field.
|
||||||
|
func (c Configuration) GetKeepAlive() time.Duration {
|
||||||
|
return c.KeepAlive
|
||||||
|
}
|
||||||
|
|
||||||
// GetDisablePathCorrection returns the DisablePathCorrection field.
|
// GetDisablePathCorrection returns the DisablePathCorrection field.
|
||||||
func (c Configuration) GetDisablePathCorrection() bool {
|
func (c Configuration) GetDisablePathCorrection() bool {
|
||||||
return c.DisablePathCorrection
|
return c.DisablePathCorrection
|
||||||
|
@ -1064,6 +1083,10 @@ func WithConfiguration(c Configuration) Configurator {
|
||||||
main.SocketSharding = v
|
main.SocketSharding = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if v := c.KeepAlive; v > 0 {
|
||||||
|
main.KeepAlive = v
|
||||||
|
}
|
||||||
|
|
||||||
if len(c.Tunneling.Tunnels) > 0 {
|
if len(c.Tunneling.Tunnels) > 0 {
|
||||||
main.Tunneling = c.Tunneling
|
main.Tunneling = c.Tunneling
|
||||||
}
|
}
|
||||||
|
@ -1215,6 +1238,7 @@ func DefaultConfiguration() Configuration {
|
||||||
return Configuration{
|
return Configuration{
|
||||||
LogLevel: "info",
|
LogLevel: "info",
|
||||||
SocketSharding: false,
|
SocketSharding: false,
|
||||||
|
KeepAlive: 0,
|
||||||
DisableStartupLog: false,
|
DisableStartupLog: false,
|
||||||
DisableInterruptHandler: false,
|
DisableInterruptHandler: false,
|
||||||
DisablePathCorrection: false,
|
DisablePathCorrection: false,
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
package context
|
package context
|
||||||
|
|
||||||
import "github.com/kataras/iris/v12/core/netutil"
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/kataras/iris/v12/core/netutil"
|
||||||
|
)
|
||||||
|
|
||||||
// ConfigurationReadOnly can be implemented
|
// ConfigurationReadOnly can be implemented
|
||||||
// by Configuration, it's being used inside the Context.
|
// by Configuration, it's being used inside the Context.
|
||||||
|
@ -14,6 +18,8 @@ type ConfigurationReadOnly interface {
|
||||||
GetLogLevel() string
|
GetLogLevel() string
|
||||||
// GetSocketSharding returns the SocketSharding field.
|
// GetSocketSharding returns the SocketSharding field.
|
||||||
GetSocketSharding() bool
|
GetSocketSharding() bool
|
||||||
|
// GetKeepAlive returns the KeepAlive field.
|
||||||
|
GetKeepAlive() time.Duration
|
||||||
// GetDisablePathCorrection returns the DisablePathCorrection field
|
// GetDisablePathCorrection returns the DisablePathCorrection field
|
||||||
GetDisablePathCorrection() bool
|
GetDisablePathCorrection() bool
|
||||||
// GetDisablePathCorrectionRedirection returns the DisablePathCorrectionRedirection field.
|
// GetDisablePathCorrectionRedirection returns the DisablePathCorrectionRedirection field.
|
||||||
|
|
|
@ -70,6 +70,9 @@ type Supervisor struct {
|
||||||
|
|
||||||
// See `iris.Configuration.SocketSharding`.
|
// See `iris.Configuration.SocketSharding`.
|
||||||
SocketSharding bool
|
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
|
// New returns a new host supervisor
|
||||||
|
@ -141,13 +144,17 @@ func (su *Supervisor) isWaiting() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (su *Supervisor) newListener() (net.Listener, error) {
|
func (su *Supervisor) newListener() (net.Listener, error) {
|
||||||
// this will not work on "unix" as network
|
var (
|
||||||
// because UNIX doesn't supports the kind of
|
l net.Listener
|
||||||
// restarts we may want for the server.
|
err error
|
||||||
//
|
)
|
||||||
// User still be able to call .Serve instead.
|
|
||||||
// l, err := netutil.TCPKeepAlive(su.Server.Addr, su.SocketSharding)
|
if su.KeepAlive > 0 {
|
||||||
l, err := netutil.TCP(su.Server.Addr, su.SocketSharding)
|
l, err = netutil.TCPKeepAlive(su.Server.Addr, su.SocketSharding, su.KeepAlive)
|
||||||
|
} else {
|
||||||
|
l, err = netutil.TCP(su.Server.Addr, su.SocketSharding)
|
||||||
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ import (
|
||||||
// A raw copy of standar library.
|
// A raw copy of standar library.
|
||||||
type tcpKeepAliveListener struct {
|
type tcpKeepAliveListener struct {
|
||||||
*net.TCPListener
|
*net.TCPListener
|
||||||
|
keepAliveDur time.Duration
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept accepts tcp connections aka clients.
|
// Accept accepts tcp connections aka clients.
|
||||||
|
@ -32,7 +33,7 @@ func (l tcpKeepAliveListener) Accept() (net.Conn, error) {
|
||||||
if err = tc.SetKeepAlive(true); err != nil {
|
if err = tc.SetKeepAlive(true); err != nil {
|
||||||
return tc, err
|
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, err
|
||||||
}
|
}
|
||||||
return tc, nil
|
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.
|
// 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") {
|
// if strings.HasPrefix(addr, "127.0.0.1") {
|
||||||
// // it's ipv4, use ipv4 tcp listener instead of the default ipv6. Don't.
|
// // it's ipv4, use ipv4 tcp listener instead of the default ipv6. Don't.
|
||||||
// ln, err = net.Listen("tcp4", addr)
|
// ln, err = net.Listen("tcp4", addr)
|
||||||
|
@ -61,7 +62,7 @@ func TCPKeepAlive(addr string, reuse bool) (ln net.Listener, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return tcpKeepAliveListener{ln.(*net.TCPListener)}, nil
|
return tcpKeepAliveListener{ln.(*net.TCPListener), keepAliveDur}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// UNIX returns a new unix(file) Listener.
|
// UNIX returns a new unix(file) Listener.
|
||||||
|
|
|
@ -106,7 +106,7 @@ type DirOptions struct {
|
||||||
// See `DirListRich` package-level function too.
|
// See `DirListRich` package-level function too.
|
||||||
DirList DirListFunc
|
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
|
ShowHidden bool
|
||||||
|
|
||||||
// Files downloaded and saved locally.
|
// Files downloaded and saved locally.
|
||||||
|
|
1
iris.go
1
iris.go
|
@ -893,6 +893,7 @@ func (app *Application) Run(serve Runner, withOrWithout ...Configurator) error {
|
||||||
|
|
||||||
app.ConfigureHost(func(host *Supervisor) {
|
app.ConfigureHost(func(host *Supervisor) {
|
||||||
host.SocketSharding = app.config.SocketSharding
|
host.SocketSharding = app.config.SocketSharding
|
||||||
|
host.KeepAlive = app.config.KeepAlive
|
||||||
})
|
})
|
||||||
|
|
||||||
app.tryStartTunneling()
|
app.tryStartTunneling()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user