mirror of
https://github.com/kataras/iris.git
synced 2025-02-02 15:30:36 +01:00
new context wrapper
This commit is contained in:
parent
3bd356734d
commit
4772177fef
|
@ -23,6 +23,8 @@ Developers are not forced to upgrade if they don't really need it. Upgrade whene
|
||||||
|
|
||||||
Changes apply to `main` branch.
|
Changes apply to `main` branch.
|
||||||
|
|
||||||
|
- A new way to customize the handler's parameter among with the `hero` and `mvc` packages. New `iris.NewContextWrapper` method and `iris.DefaultContextPool` struct were added to wrap a handler and use a custom context instead of the iris.Context directly.
|
||||||
|
|
||||||
- The `cache` sub-package has an update, after 4 years:
|
- The `cache` sub-package has an update, after 4 years:
|
||||||
|
|
||||||
- Add support for custom storage on `cache` package, through the `Handler#Store` method.
|
- Add support for custom storage on `cache` package, through the `Handler#Store` method.
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
* [Import from TOML](configuration/from-toml-file/main.go)
|
* [Import from TOML](configuration/from-toml-file/main.go)
|
||||||
* [Multi Environment Configuration](configuration/multi-environments) **NEW**
|
* [Multi Environment Configuration](configuration/multi-environments) **NEW**
|
||||||
* Routing
|
* Routing
|
||||||
|
* [Custom Context](routing/custom-context/main.go) **HOT/NEW**
|
||||||
* [Party Controller](routing/party-controller) **NEW**
|
* [Party Controller](routing/party-controller) **NEW**
|
||||||
* [Overview](routing/overview/main.go)
|
* [Overview](routing/overview/main.go)
|
||||||
* [Basic](routing/basic/main.go)
|
* [Basic](routing/basic/main.go)
|
||||||
|
|
74
_examples/routing/custom-context/main.go
Normal file
74
_examples/routing/custom-context/main.go
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/kataras/iris/v12"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// 1. Create the iris app instance.
|
||||||
|
app := iris.New()
|
||||||
|
|
||||||
|
/*
|
||||||
|
w := iris.NewContextWrapper(&iris.DefaultContextPool[*myCustomContext]{
|
||||||
|
AcquireFunc: func(ctx iris.Context) *myCustomContext {
|
||||||
|
return &myCustomContext{
|
||||||
|
Context: ctx,
|
||||||
|
// custom fields here...
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ReleaseFunc: func(t *myCustomContext) {
|
||||||
|
// do nothing
|
||||||
|
},
|
||||||
|
})
|
||||||
|
OR: */
|
||||||
|
// 2. Create the Context Wrapper which will be used to wrap the handlers
|
||||||
|
// that expect a *myCustomContext instead of iris.Context.
|
||||||
|
w := iris.NewContextWrapper(&myCustomContextPool{})
|
||||||
|
|
||||||
|
// 3. Register the handler(s) which expects a *myCustomContext instead of iris.Context.
|
||||||
|
// The `w.Handler` will wrap the handler and will call the `Acquire` and `Release`
|
||||||
|
// methods of the `myCustomContextPool` to get and release the *myCustomContext.
|
||||||
|
app.Get("/", w.Handler(index))
|
||||||
|
|
||||||
|
// 4. Start the server.
|
||||||
|
app.Listen(":8080")
|
||||||
|
}
|
||||||
|
|
||||||
|
func index(ctx *myCustomContext) {
|
||||||
|
ctx.HTML("<h1>Hello, World!</h1>")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a custom context.
|
||||||
|
type myCustomContext struct {
|
||||||
|
// It's just an embedded field which is set on AcquireFunc,
|
||||||
|
// so you can use myCustomContext with the same methods as iris.Context,
|
||||||
|
// override existing iris.Context's methods or add custom methods.
|
||||||
|
// You can use the `Context` field to access the original context.
|
||||||
|
iris.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *myCustomContext) HTML(format string, args ...interface{}) (int, error) {
|
||||||
|
c.Application().Logger().Info("HTML was called from custom Context")
|
||||||
|
|
||||||
|
return c.Context.HTML(format, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the context memory pool for your custom context,
|
||||||
|
// the pool must contain Acquire() T and Release(T) methods.
|
||||||
|
type myCustomContextPool struct{}
|
||||||
|
|
||||||
|
// Acquire returns a new custom context from the pool.
|
||||||
|
func (p *myCustomContextPool) Acquire(ctx iris.Context) *myCustomContext {
|
||||||
|
return &myCustomContext{
|
||||||
|
Context: ctx,
|
||||||
|
// custom fields here...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release puts a custom context back to the pool.
|
||||||
|
func (p *myCustomContextPool) Release(t *myCustomContext) {
|
||||||
|
// You can take advantage of this method to clear the context
|
||||||
|
// and re-use it on the Acquire method, use the sync.Pool.
|
||||||
|
//
|
||||||
|
// We do nothing for the shake of the exampel.
|
||||||
|
}
|
91
context_wrapper.go
Normal file
91
context_wrapper.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
package iris
|
||||||
|
|
||||||
|
// ContextPool is a pool of T.
|
||||||
|
//
|
||||||
|
// See `NewContextWrapper` and `ContextPool` for more.
|
||||||
|
type ContextPool[T any] interface {
|
||||||
|
Acquire(ctx Context) T
|
||||||
|
Release(T)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DefaultContextPool is a pool of T.
|
||||||
|
// It's used to acquire and release T.
|
||||||
|
// The T is acquired from the pool and released back to the pool after the handler's execution.
|
||||||
|
// The T is passed to the handler as an argument.
|
||||||
|
// The T is not shared between requests.
|
||||||
|
type DefaultContextPool[T any] struct {
|
||||||
|
AcquireFunc func(Context) T
|
||||||
|
ReleaseFunc func(T)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that DefaultContextPool[T] implements ContextPool[T].
|
||||||
|
var _ ContextPool[any] = (*DefaultContextPool[any])(nil)
|
||||||
|
|
||||||
|
// Acquire returns a new T from the pool's AcquireFunc.
|
||||||
|
func (p *DefaultContextPool[T]) Acquire(ctx Context) T {
|
||||||
|
acquire := p.AcquireFunc
|
||||||
|
if p.AcquireFunc == nil {
|
||||||
|
acquire = func(ctx Context) T {
|
||||||
|
var t T
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return acquire(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Release does nothing if the pool's ReleaseFunc is nil.
|
||||||
|
func (p *DefaultContextPool[T]) Release(t T) {
|
||||||
|
release := p.ReleaseFunc
|
||||||
|
if p.ReleaseFunc == nil {
|
||||||
|
release = func(t T) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
release(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ContextWrapper is a wrapper for handlers which expect a T instead of iris.Context.
|
||||||
|
//
|
||||||
|
// See the `NewContextWrapper` function for more.
|
||||||
|
type ContextWrapper[T any] struct {
|
||||||
|
pool ContextPool[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewContextWrapper returns a new ContextWrapper.
|
||||||
|
// If pool is nil, a default pool is used.
|
||||||
|
// The default pool's AcquireFunc returns a zero value of T.
|
||||||
|
// The default pool's ReleaseFunc does nothing.
|
||||||
|
// The default pool is used when the pool is nil.
|
||||||
|
// Use the `&iris.DefaultContextPool{...}` to pass a simple context pool.
|
||||||
|
//
|
||||||
|
// See the `Handler` method for more.
|
||||||
|
// Example: https://github.com/kataras/iris/tree/main/_examples/routing/custom-context
|
||||||
|
func NewContextWrapper[T any](pool ContextPool[T]) *ContextWrapper[T] {
|
||||||
|
if pool == nil {
|
||||||
|
pool = &DefaultContextPool[T]{
|
||||||
|
AcquireFunc: func(ctx Context) T {
|
||||||
|
var t T
|
||||||
|
return t
|
||||||
|
},
|
||||||
|
ReleaseFunc: func(t T) {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &ContextWrapper[T]{
|
||||||
|
pool: pool,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handler wraps the handler with the pool's Acquire and Release methods.
|
||||||
|
// It returns a new handler which expects a T instead of iris.Context.
|
||||||
|
// The T is the type of the pool.
|
||||||
|
// The T is acquired from the pool and released back to the pool after the handler's execution.
|
||||||
|
// The T is passed to the handler as an argument.
|
||||||
|
// The T is not shared between requests.
|
||||||
|
func (w *ContextWrapper[T]) Handler(handler func(T)) Handler {
|
||||||
|
return func(ctx Context) {
|
||||||
|
newT := w.pool.Acquire(ctx)
|
||||||
|
handler(newT)
|
||||||
|
w.pool.Release(newT)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user