mirror of
https://github.com/kataras/iris.git
synced 2025-03-15 06:46:26 +01:00
Update to 6.0.9: Add PostInterrupt plugin. Read HISTORY.md
- Add `PostInterrupt` plugin, useful for customization of the **os.Interrupt** singal, before that Iris closed the server automatically. ```go iris.Plugins.PostInterrupt(func(s *Framework){ // when os.Interrupt signal is fired the body of this function will be fired, // you're responsible for closing the server with s.Close() // if that event is not registered then the framework // will close the server for you. /* Do any custom cleanup and finally call the s.Close() remember you have the iris.Plugins.PreClose(func(s *Framework)) event too so you can split your logic in two logically places. */ }) ```
This commit is contained in:
parent
c5f95ba78a
commit
5ad7c6e01f
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
|
@ -1,4 +1,4 @@
|
||||||
- Version : **6.0.8**
|
- Version : **6.0.9**
|
||||||
|
|
||||||
- Operating System:
|
- Operating System:
|
||||||
|
|
||||||
|
|
23
HISTORY.md
23
HISTORY.md
|
@ -2,6 +2,29 @@
|
||||||
|
|
||||||
**How to upgrade**: remove your `$GOPATH/src/github.com/kataras` folder, open your command-line and execute this command: `go get -u github.com/kataras/iris/iris`.
|
**How to upgrade**: remove your `$GOPATH/src/github.com/kataras` folder, open your command-line and execute this command: `go get -u github.com/kataras/iris/iris`.
|
||||||
|
|
||||||
|
## 6.0.8 -> 6.0.9
|
||||||
|
|
||||||
|
- Add `PostInterrupt` plugin, useful for customization of the **os.Interrupt** singal, before that Iris closed the server automatically.
|
||||||
|
|
||||||
|
```go
|
||||||
|
iris.Plugins.PostInterrupt(func(s *Framework){
|
||||||
|
// when os.Interrupt signal is fired the body of this function will be fired,
|
||||||
|
// you're responsible for closing the server with s.Close()
|
||||||
|
|
||||||
|
// if that event is not registered then the framework
|
||||||
|
// will close the server for you.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Do any custom cleanup and finally call the s.Close()
|
||||||
|
remember you have the iris.Plugins.PreClose(func(s *Framework)) event too
|
||||||
|
so you can split your logic in two logically places.
|
||||||
|
*/
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## 6.0.7 -> 6.0.8
|
## 6.0.7 -> 6.0.8
|
||||||
|
|
||||||
- Add `iris.UseTemplateFunc(functionName string, function interface{})`. You could always set custom template funcs by using each of [template engine's](https://github.com/kataras/go-template) configuration but this function will help newcomers to start creating their custom template funcs.
|
- Add `iris.UseTemplateFunc(functionName string, function interface{})`. You could always set custom template funcs by using each of [template engine's](https://github.com/kataras/go-template) configuration but this function will help newcomers to start creating their custom template funcs.
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<br/>
|
<br/>
|
||||||
|
|
||||||
|
|
||||||
<a href="https://github.com/kataras/iris/blob/master/HISTORY.md"><img src="https://img.shields.io/badge/%20version%20-%206.0.8%20-blue.svg?style=flat-square" alt="CHANGELOG/HISTORY"></a>
|
<a href="https://github.com/kataras/iris/blob/master/HISTORY.md"><img src="https://img.shields.io/badge/%20version%20-%206.0.9%20-blue.svg?style=flat-square" alt="CHANGELOG/HISTORY"></a>
|
||||||
|
|
||||||
<a href="https://github.com/iris-contrib/examples"><img src="https://img.shields.io/badge/%20examples-repository-3362c2.svg?style=flat-square" alt="Examples"></a>
|
<a href="https://github.com/iris-contrib/examples"><img src="https://img.shields.io/badge/%20examples-repository-3362c2.svg?style=flat-square" alt="Examples"></a>
|
||||||
|
|
||||||
|
@ -947,7 +947,7 @@ I recommend testing your API using this new library, [httpexpect](https://github
|
||||||
Versioning
|
Versioning
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Current: **v6.0.8**
|
Current: **v6.0.9**
|
||||||
|
|
||||||
Older: **[v5/fasthttp](https://github.com/kataras/iris/tree/5.0.0)**
|
Older: **[v5/fasthttp](https://github.com/kataras/iris/tree/5.0.0)**
|
||||||
|
|
||||||
|
|
64
iris.go
64
iris.go
|
@ -66,6 +66,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kataras/go-errors"
|
"github.com/kataras/go-errors"
|
||||||
|
@ -80,7 +81,7 @@ const (
|
||||||
// IsLongTermSupport flag is true when the below version number is a long-term-support version
|
// IsLongTermSupport flag is true when the below version number is a long-term-support version
|
||||||
IsLongTermSupport = false
|
IsLongTermSupport = false
|
||||||
// Version is the current version number of the Iris web framework
|
// Version is the current version number of the Iris web framework
|
||||||
Version = "6.0.8"
|
Version = "6.0.9"
|
||||||
|
|
||||||
banner = ` _____ _
|
banner = ` _____ _
|
||||||
|_ _| (_)
|
|_ _| (_)
|
||||||
|
@ -478,21 +479,51 @@ func (s *Framework) Serve(ln net.Listener) error {
|
||||||
}
|
}
|
||||||
// maybe a 'race' here but user should not call .Serve more than one time especially in more than one go routines...
|
// maybe a 'race' here but user should not call .Serve more than one time especially in more than one go routines...
|
||||||
s.ln = ln
|
s.ln = ln
|
||||||
|
// build the handler and all other components
|
||||||
s.Build()
|
s.Build()
|
||||||
|
// fire all PreListen plugins
|
||||||
s.Plugins.DoPreListen(s)
|
s.Plugins.DoPreListen(s)
|
||||||
|
|
||||||
// This didn't helped me ,here, but maybe can help you:
|
// catch any panics to the user defined logger.
|
||||||
// https://www.oreilly.com/learning/run-strikingly-fast-parallel-file-searches-in-go-with-sync-errgroup?utm_source=golangweekly&utm_medium=email
|
|
||||||
// new experimental package: errgroup
|
|
||||||
|
|
||||||
defer func() {
|
defer func() {
|
||||||
if err := recover(); err != nil {
|
if err := recover(); err != nil {
|
||||||
s.Logger.Panic(err)
|
s.Logger.Panic(err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
// start the server in goroutine, .Available will block instead
|
|
||||||
go func() { s.Must(s.srv.Serve(ln)) }()
|
// prepare for 'after serve' actions
|
||||||
|
var stop uint32
|
||||||
|
go func() {
|
||||||
|
// wait for the server's Serve func (309 mill is a lot or not, I found that this number is the perfect for most of the environments.)
|
||||||
|
time.Sleep(309 * time.Millisecond)
|
||||||
|
if atomic.LoadUint32(&stop) > 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// print the banner
|
||||||
|
// fire the PostListen plugins
|
||||||
|
// wait for system channel interrupt
|
||||||
|
// fire the PostInterrupt plugins or close and exit.
|
||||||
|
s.postServe()
|
||||||
|
}()
|
||||||
|
|
||||||
|
serverStartUpErr := s.srv.Serve(ln)
|
||||||
|
if serverStartUpErr != nil {
|
||||||
|
// if an error then it would be nice to stop the banner and all next plugin events.
|
||||||
|
atomic.AddUint32(&stop, 1)
|
||||||
|
}
|
||||||
|
// finally return the error or block here, remember,
|
||||||
|
// you can always use the iris.Available to 'see' if and when the server is up (virtually),
|
||||||
|
// until go1.8 these are our best options.
|
||||||
|
return serverStartUpErr
|
||||||
|
}
|
||||||
|
|
||||||
|
// runs only when server starts without errors
|
||||||
|
// what it does?
|
||||||
|
// 0. print the banner
|
||||||
|
// 1. fire the PostListen plugins
|
||||||
|
// 2. wait for system channel interrupt
|
||||||
|
// 3. fire the PostInterrupt plugins or close and exit.
|
||||||
|
func (s *Framework) postServe() {
|
||||||
|
|
||||||
if !s.Config.DisableBanner {
|
if !s.Config.DisableBanner {
|
||||||
bannerMessage := fmt.Sprintf("%s: Running at %s", time.Now().Format(s.Config.TimeFormat), s.Config.VHost)
|
bannerMessage := fmt.Sprintf("%s: Running at %s", time.Now().Format(s.Config.TimeFormat), s.Config.VHost)
|
||||||
|
@ -506,17 +537,22 @@ func (s *Framework) Serve(ln net.Listener) error {
|
||||||
s.Plugins.DoPostListen(s)
|
s.Plugins.DoPostListen(s)
|
||||||
|
|
||||||
go func() { s.Available <- true }()
|
go func() { s.Available <- true }()
|
||||||
|
|
||||||
ch := make(chan os.Signal, 1)
|
ch := make(chan os.Signal, 1)
|
||||||
signal.Notify(ch, os.Interrupt)
|
signal.Notify(ch, os.Interrupt)
|
||||||
<-ch
|
<-ch
|
||||||
if err := s.Close(); err != nil {
|
// catch custom plugin event for interrupt
|
||||||
if s.Config.IsDevelopment {
|
s.Plugins.DoPostInterrupt(s)
|
||||||
s.Logger.Printf("Error while closing the server: %s\n", err)
|
if !s.Plugins.PostInterruptFired() {
|
||||||
|
// if no PostInterrupt events fired, then I assume that the user doesn't cares
|
||||||
|
// so close the server automatically.
|
||||||
|
if err := s.Close(); err != nil {
|
||||||
|
if s.Config.IsDevelopment {
|
||||||
|
s.Logger.Printf("Error while closing the server: %s\n", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return err
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
os.Exit(1)
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Listen starts the standalone http server
|
// Listen starts the standalone http server
|
||||||
|
|
40
plugin.go
40
plugin.go
|
@ -89,6 +89,20 @@ type (
|
||||||
}
|
}
|
||||||
// PostListenFunc implements the simple function listener for the PostListen(*Framework)
|
// PostListenFunc implements the simple function listener for the PostListen(*Framework)
|
||||||
PostListenFunc func(*Framework)
|
PostListenFunc func(*Framework)
|
||||||
|
|
||||||
|
// pluginPostInterrupt implements the PostInterrupt(*Framework) method
|
||||||
|
pluginPostInterrupt interface {
|
||||||
|
// PostInterrupt it's being called only one time, when os.Interrupt system event catched
|
||||||
|
// graceful shutdown can be done here
|
||||||
|
//
|
||||||
|
// Read more here: https://github.com/kataras/iris/blob/master/HISTORY.md#608---609
|
||||||
|
PostInterrupt(*Framework)
|
||||||
|
}
|
||||||
|
// PostInterruptFunc implements the simple function listener for the PostInterrupt(*Framework)
|
||||||
|
//
|
||||||
|
// Read more here: https://github.com/kataras/iris/blob/master/HISTORY.md#608---609
|
||||||
|
PostInterruptFunc func(*Framework)
|
||||||
|
|
||||||
// pluginPreClose implements the PreClose(*Framework) method
|
// pluginPreClose implements the PreClose(*Framework) method
|
||||||
pluginPreClose interface {
|
pluginPreClose interface {
|
||||||
// PreClose it's being called only one time, BEFORE the Iris .Close method
|
// PreClose it's being called only one time, BEFORE the Iris .Close method
|
||||||
|
@ -139,6 +153,9 @@ type (
|
||||||
PostListen(PostListenFunc)
|
PostListen(PostListenFunc)
|
||||||
DoPostListen(*Framework)
|
DoPostListen(*Framework)
|
||||||
PostListenFired() bool
|
PostListenFired() bool
|
||||||
|
PostInterrupt(PostInterruptFunc)
|
||||||
|
DoPostInterrupt(*Framework)
|
||||||
|
PostInterruptFired() bool
|
||||||
PreClose(PreCloseFunc)
|
PreClose(PreCloseFunc)
|
||||||
DoPreClose(*Framework)
|
DoPreClose(*Framework)
|
||||||
PreCloseFired() bool
|
PreCloseFired() bool
|
||||||
|
@ -520,6 +537,29 @@ func (p *pluginContainer) PostListenFired() bool {
|
||||||
return p.Fired("postlisten") > 0
|
return p.Fired("postlisten") > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PostInterrupt adds a PostInterrupt plugin-function to the plugin flow container
|
||||||
|
//
|
||||||
|
// Read more here: https://github.com/kataras/iris/blob/master/HISTORY.md#608---609
|
||||||
|
func (p *pluginContainer) PostInterrupt(fn PostInterruptFunc) {
|
||||||
|
p.Add(fn)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DoPostInterrupt raise all plugins which has the PostInterrupt method
|
||||||
|
func (p *pluginContainer) DoPostInterrupt(station *Framework) {
|
||||||
|
for i := range p.activatedPlugins {
|
||||||
|
// check if this method exists on our plugin obj, these are optionaly and call it
|
||||||
|
if pluginObj, ok := p.activatedPlugins[i].(pluginPostInterrupt); ok {
|
||||||
|
pluginObj.PostInterrupt(station)
|
||||||
|
p.fire("postinterrupt")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// PostInterruptFired returns true if PostInterrupt event/ plugin type is fired at least one time
|
||||||
|
func (p *pluginContainer) PostInterruptFired() bool {
|
||||||
|
return p.Fired("postinterrupt") > 0
|
||||||
|
}
|
||||||
|
|
||||||
// PreClose adds a PreClose plugin-function to the plugin flow container
|
// PreClose adds a PreClose plugin-function to the plugin flow container
|
||||||
func (p *pluginContainer) PreClose(fn PreCloseFunc) {
|
func (p *pluginContainer) PreClose(fn PreCloseFunc) {
|
||||||
p.Add(fn)
|
p.Add(fn)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user