-
Notifications
You must be signed in to change notification settings - Fork 8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How remove route ? online!!! #776
Comments
Why ? What is your scenario? |
i need to remove the routes online and add the routing rules online |
@monikaYZ did you mean altering your application routes on-the-fly? |
and I did not find the corresponding method。 |
@widnyana Yes! |
@monikaYZ I'm afraid you can't do that. since your app source code are compiled to binary. you need to alter your source code, recompile, and deploy it again. |
pardon me if I miss-interpret your question. |
I need to do a configuration service, and configure memory |
if your service runs behind nginx, maybe you can alter nginx config to set api online/offline |
You really should try to write a more verbose description for this issue before hand. |
@monikaYZ I understand what you mean. He means to inject/remove dynamic handlers into Gin router. Although is possible to inject them after starting the server, there is no API for removing them. There may be some concurrency problems if you change the I'm also facing that problem, and developing a custom solution which I'll post to https://github.com/gin-contrib/graceful when ready. I'll keep this issue open until then. |
Hi there I have multiple devices which each one after registration get a token(hash string) and uses that in order to communicate with server. So I need to add/remove routes when a token add/remove from system... Again, is it possible to add/remove routes at runtime? Thanks in advance |
Hi @bonjefir, |
Similar use case here, I would like to attach routing subtrees in order to make entire sections available or unavailable dynamically. Restarting the http handler is not a problem. |
same problem. I don't know which url should be route before i load config from cloud; and if cloud config changes, i need remove/add router on the fly. Now, i can just enable all router but return 404 when config changed. |
same problem. it is perfect that gin supports altering handler in the routeTree.for dynamicly reloading handler. |
I need the feature, also. |
Nginx CAN do this more conveniently. If your app are running on production, add/remove routes in your code at runtime is danger. |
Unless you need to load application modules and join them to a single API. But I found that creating generic endpoints and then manually using a forked version of httprouter to match the loaded ones works best, so this is not a problem for me anymore. |
I need the feature, also. |
Here is the way to implement change routes dynamically by change the whole handler. https://gist.github.com/wudi/eb778531ff83ee1273f58aa7ddb353fe |
I added the following in // Remove ...
func (engine *Engine) Remove(path string, tbRemoved HandlerFunc) {
for _, tree := range engine.trees {
for i, children := range tree.root.children {
for _, h := range children.handlers {
if reflect.ValueOf(h) == reflect.ValueOf(tbRemoved) && children.path == path {
tree.root.children = remove(tree.root.children, i)
}
}
}
}
}
func remove(s []*node, index int) []*node {
return append(s[:index], s[index+1:]...)
} Is totally unsafe and causes panicrecovery but works ... |
Also need this. |
I'm currently using this solution described in fiber Edit: I've been searching a lot in web routers frameworks, but the most similar as I need has some problems with this feature because it's unsafe... You could use fiber solution if it's enough, but if you really need add/remove routes on-the-fly I strongly recommend Iris |
you can reset gin.Engine and *http.Server |
Maybe you can use the method of directly reloading the router package main
import (
"fmt"
"log"
"net/http"
"sync/atomic"
"time"
"github.com/gin-gonic/gin"
)
type APP struct {
globalRouter atomic.Pointer[gin.Engine]
}
func (app *APP) ReloadRouter(r *gin.Engine) {
app.globalRouter.Store(r)
}
func (app *APP) ServeHTTP(w http.ResponseWriter, r *http.Request) {
router := app.globalRouter.Load()
if router != nil {
router.ServeHTTP(w, r)
} else {
w.WriteHeader(http.StatusInternalServerError)
}
}
func main() {
// global router
globalAPP := APP{}
// test handle creator
newTestHandle := func(index int) gin.HandlerFunc {
return func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"message": fmt.Sprintf("Hello, %d", index)})
}
}
// new router creater
newRouter := func(handleMap map[string]gin.HandlerFunc) *gin.Engine {
r := gin.Default()
for path, handle := range handleMap {
r.Handle(http.MethodGet, path, handle)
}
return r
}
// create old router
oldRouter := newRouter(map[string]gin.HandlerFunc{
"test1": newTestHandle(1),
"test2": newTestHandle(2),
})
globalAPP.ReloadRouter(oldRouter)
go func() {
// change router 20 second
time.Sleep(20 * time.Second)
newRouter := newRouter(map[string]gin.HandlerFunc{
"test1": newTestHandle(3),
})
globalAPP.ReloadRouter(newRouter)
}()
// create http server
srv := &http.Server{
Addr: ":8080",
Handler: &globalAPP,
}
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("listen: %s\n", err)
}
} with curl test [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /test1 --> main.main.main.func1.func4 (3 handlers)
[GIN-debug] GET /test2 --> main.main.main.func1.func5 (3 handlers)
[GIN] 2024/09/26 - 21:59:58 | 200 | 44.611µs | 127.0.0.1 | GET "/test1"
[GIN] 2024/09/26 - 22:00:04 | 200 | 32.793µs | 127.0.0.1 | GET "/test2"
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
[GIN-debug] GET /test1 --> main.main.func3.main.func1.1 (3 handlers)
[GIN] 2024/09/26 - 22:00:16 | 404 | 639ns | 127.0.0.1 | GET "/test2"
[GIN] 2024/09/26 - 22:04:26 | 404 | 481ns | 127.0.0.1 | GET "/test2" |
How can i remove route ? online!!!
The text was updated successfully, but these errors were encountered: