Browse Source

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

pull/1729/head
Gerasimos (Makis) Maropoulos 6 months ago
parent
commit
5994fd5d4e
No known key found for this signature in database GPG Key ID: 5DBE766BD26A54E7
9 changed files with 62 additions and 15 deletions
  1. +4
    -0
      HISTORY.md
  2. +2
    -0
      _examples/file-server/basic/main.go
  3. +5
    -3
      _examples/http-server/listen-addr/main.go
  4. +24
    -0
      configuration.go
  5. +7
    -1
      context/configuration.go
  6. +14
    -7
      core/host/supervisor.go
  7. +4
    -3
      core/netutil/tcp.go
  8. +1
    -1
      core/router/fs.go
  9. +1
    -0
      iris.go

+ 4
- 0
HISTORY.md 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).


+ 2
- 0
_examples/file-server/basic/main.go 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,


+ 5
- 3
_examples/http-server/listen-addr/main.go 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))
}

+ 24
- 0
configuration.go 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,


+ 7
- 1
context/configuration.go 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.


+ 14
- 7
core/host/supervisor.go 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
}


+ 4
- 3
core/netutil/tcp.go 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.


+ 1
- 1
core/router/fs.go 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.


+ 1
- 0
iris.go 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()


Loading…
Cancel
Save