feat: add report material workflows and gateway safeguards
This commit is contained in:
@@ -9,10 +9,12 @@ import (
|
||||
|
||||
"cmpp-platform/gateway/internal/inbound"
|
||||
"cmpp-platform/gateway/internal/queue"
|
||||
"cmpp-platform/gateway/internal/ratelimit"
|
||||
"cmpp-platform/gateway/internal/upstream"
|
||||
)
|
||||
|
||||
type ConnectFunc func(context.Context, ConnectChannelCommand) (ConnectionStateCallback, error)
|
||||
type SubmitFunc func(context.Context, queue.SubmitCommand) (queue.SubmitResult, error)
|
||||
|
||||
type ConnectChannelCommand struct {
|
||||
SchemaVersion string `json:"schemaVersion"`
|
||||
@@ -54,7 +56,9 @@ type Server struct {
|
||||
APIBaseURL string
|
||||
HTTPClient *http.Client
|
||||
Connect ConnectFunc
|
||||
Submit SubmitFunc
|
||||
Upstream *upstream.Manager
|
||||
Limiter ratelimit.Limiter
|
||||
RecoveryCandidates func(context.Context) ([]inbound.DownstreamPresence, error)
|
||||
RecoveryStatuses func(context.Context) ([]inbound.DownstreamRecoveryStatus, error)
|
||||
}
|
||||
@@ -74,6 +78,9 @@ func Register(mux *http.ServeMux, server Server) {
|
||||
if server.Connect == nil {
|
||||
server.Connect = server.connectChannel
|
||||
}
|
||||
if server.Submit == nil {
|
||||
server.Submit = server.Upstream.Submit
|
||||
}
|
||||
mux.HandleFunc("/connections/connect", server.handleConnectChannel)
|
||||
mux.HandleFunc("/upstream/submit", server.handleUpstreamSubmit)
|
||||
mux.HandleFunc("/downstream/receipt", server.handleDownstreamReceipt)
|
||||
@@ -98,6 +105,12 @@ func (s Server) handleConnectChannel(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if configurer, ok := s.Limiter.(ratelimit.Configurer); ok {
|
||||
if err := configurer.Configure(r.Context(), command.ChannelID, command.Channel.RateLimitPerSecond); err != nil {
|
||||
http.Error(w, fmt.Sprintf("failed to configure gateway channel rate limit: %v", err), http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
status, err := s.Connect(r.Context(), command)
|
||||
if err != nil {
|
||||
@@ -119,7 +132,13 @@ func (s Server) handleUpstreamSubmit(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, fmt.Sprintf("invalid submit command: %v", err), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
result, err := s.Upstream.Submit(r.Context(), command)
|
||||
if s.Limiter != nil {
|
||||
if _, err := s.Limiter.Wait(r.Context(), command.ChannelID, command.Route.RateLimitPerSecond); err != nil {
|
||||
http.Error(w, fmt.Sprintf("gateway channel rate limit unavailable: %v", err), http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
}
|
||||
result, err := s.Submit(r.Context(), command)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadGateway)
|
||||
_ = json.NewEncoder(w).Encode(result)
|
||||
|
||||
Reference in New Issue
Block a user