#go #gorilla
#Вперед #горилла
Вопрос:
Я довольно новичок в Go и не смог найти никакой информации об этом, возможно, в настоящее время это просто невозможно.
Я пытаюсь удалить или заменить мультиплексный маршрут (используя http.NewServeMux, или мультиплексирование gorilla.Маршрутизатор). Моя конечная цель — иметь возможность включать / отключать маршрут или набор маршрутов без необходимости перезапуска программы.
Вероятно, я могу выполнить это на основе от обработчика к обработчику и просто вернуть 404, если эта функция «отключена», но я предпочел бы найти более общий способ сделать это, поскольку я хотел бы реализовать его для каждого маршрута в моем приложении.
Или мне было бы лучше просто отслеживать отключенные шаблоны URL и использовать некоторое промежуточное программное обеспечение для предотвращения выполнения обработчика?
Если кто-то может хотя бы указать мне правильное направление, я обязательно опубликую примеры кода решения, предполагающего, что оно есть. Спасибо!
Ответ №1:
Встроенного способа нет, но его достаточно легко реализовать.
type HasHandleFunc interface { //this is just so it would work for gorilla and http.ServerMux
HandleFunc(pattern string, handler func(w http.ResponseWriter, req *http.Request))
}
type Handler struct {
http.HandlerFunc
Enabled bool
}
type Handlers map[string]*Handler
func (h Handlers) ServeHTTP(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if handler, ok := h[path]; ok amp;amp; handler.Enabled {
handler.ServeHTTP(w, r)
} else {
http.Error(w, "Not Found", http.StatusNotFound)
}
}
func (h Handlers) HandleFunc(mux HasHandleFunc, pattern string, handler http.HandlerFunc) {
h[pattern] = amp;Handler{handler, true}
mux.HandleFunc(pattern, h.ServeHTTP)
}
func main() {
mux := http.NewServeMux()
handlers := Handlers{}
handlers.HandleFunc(mux, "/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("this will show once"))
handlers["/"].Enabled = false
})
http.Handle("/", mux)
http.ListenAndServe(":9020", nil)
}
Ответ №2:
Да, вы можете.
Один из способов сделать это — иметь sturct, который реализует http.Handle
интерфейс с методом ServeHTTP
. Затем пусть структура содержит другой мультиплексор, подобный gorilla, и, наконец, имеет атомарный переключатель для включения / отключения подпрограммы
Это рабочий пример того, что я имею в виду:
package main
import (
"fmt"
"github.com/gorilla/mux"
"net/http"
"sync/atomic"
)
var recording int32
func isRecording() bool {
return atomic.LoadInt32(amp;recording) != 0
}
func setRecording(shouldRecord bool) {
if shouldRecord {
atomic.StoreInt32(amp;recording, 1)
} else {
atomic.StoreInt32(amp;recording, 0)
}
}
type SwitchHandler struct {
mux http.Handler
}
func (s *SwitchHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if isRecording() {
fmt.Printf("Switch Handler is Recordingn")
s.mux.ServeHTTP(w, r)
return
}
fmt.Printf("Switch Handler is NOT Recordingn")
w.WriteHeader(http.StatusNotFound)
fmt.Fprintf(w, "NOT Recordingn")
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/success/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Recordingn")
})
handler := amp;SwitchHandler{mux: router}
setRecording(false)
http.Handle("/", handler)
http.ListenAndServe(":8080", nil)
}
Ответ №3:
Согласно https://github.com/gorilla/mux/issues/82 предлагается поменять маршрутизатор местами вместо удаления маршрутов. Существующие соединения останутся открытыми.