[HTTP] added custom project beacon size (#926)

* feat(backend): added project beacon size select on each sessionStart request
This commit is contained in:
Alexander 2023-01-18 12:36:34 +01:00 committed by GitHub
parent dcde8574ea
commit a6e4779652
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 6 deletions

View file

@ -152,12 +152,15 @@ func (e *Router) startSessionHandlerWeb(w http.ResponseWriter, r *http.Request)
}
}
// Save information about session beacon size
e.addBeaconSize(tokenData.ID, p.BeaconSize)
ResponseWithJSON(w, &StartSessionResponse{
Token: e.services.Tokenizer.Compose(*tokenData),
UserUUID: userUUID,
SessionID: strconv.FormatUint(tokenData.ID, 10),
ProjectID: strconv.FormatUint(uint64(p.ProjectID), 10),
BeaconSizeLimit: e.cfg.BeaconSizeLimit,
BeaconSizeLimit: e.getBeaconSize(tokenData.ID),
StartTimestamp: int64(flakeid.ExtractTimestamp(tokenData.ID)),
Delay: tokenData.Delay,
})
@ -177,7 +180,7 @@ func (e *Router) pushMessagesHandlerWeb(w http.ResponseWriter, r *http.Request)
return
}
bodyBytes, err := e.readBody(w, r, e.cfg.BeaconSizeLimit)
bodyBytes, err := e.readBody(w, r, e.getBeaconSize(sessionData.ID))
if err != nil {
log.Printf("error while reading request body: %s", err)
ResponseWithError(w, http.StatusRequestEntityTooLarge, err)

View file

@ -12,9 +12,15 @@ import (
http2 "openreplay/backend/internal/http/services"
"openreplay/backend/internal/http/util"
"openreplay/backend/pkg/monitoring"
"sync"
"time"
)
type BeaconSize struct {
size int64
time time.Time
}
type Router struct {
router *mux.Router
cfg *http3.Config
@ -22,6 +28,8 @@ type Router struct {
requestSize syncfloat64.Histogram
requestDuration syncfloat64.Histogram
totalRequests syncfloat64.Counter
mutex *sync.RWMutex
beaconSizeCache map[uint64]*BeaconSize // Cache for session's beaconSize
}
func NewRouter(cfg *http3.Config, services *http2.ServicesBuilder, metrics *monitoring.Metrics) (*Router, error) {
@ -34,14 +42,53 @@ func NewRouter(cfg *http3.Config, services *http2.ServicesBuilder, metrics *moni
return nil, fmt.Errorf("metrics is empty")
}
e := &Router{
cfg: cfg,
services: services,
cfg: cfg,
services: services,
mutex: &sync.RWMutex{},
beaconSizeCache: make(map[uint64]*BeaconSize),
}
e.initMetrics(metrics)
e.init()
go e.clearBeaconSizes()
return e, nil
}
func (e *Router) addBeaconSize(sessionID uint64, size int64) {
if size <= 0 {
return
}
e.mutex.Lock()
defer e.mutex.Unlock()
e.beaconSizeCache[sessionID] = &BeaconSize{
size: size,
time: time.Now(),
}
}
func (e *Router) getBeaconSize(sessionID uint64) int64 {
e.mutex.RLock()
defer e.mutex.RUnlock()
if beaconSize, ok := e.beaconSizeCache[sessionID]; ok {
beaconSize.time = time.Now()
return beaconSize.size
}
return e.cfg.BeaconSizeLimit
}
func (e *Router) clearBeaconSizes() {
for {
time.Sleep(time.Minute * 2)
now := time.Now()
e.mutex.Lock()
for sid, bs := range e.beaconSizeCache {
if now.Sub(bs.time) > time.Minute*3 {
delete(e.beaconSizeCache, sid)
}
}
e.mutex.Unlock()
}
}
func (e *Router) init() {
e.router = mux.NewRouter()

View file

@ -7,12 +7,12 @@ import (
func (conn *Conn) GetProjectByKey(projectKey string) (*Project, error) {
p := &Project{ProjectKey: projectKey}
if err := conn.c.QueryRow(`
SELECT max_session_duration, sample_rate, project_id
SELECT max_session_duration, sample_rate, project_id, beacon_size
FROM projects
WHERE project_key=$1 AND active = true
`,
projectKey,
).Scan(&p.MaxSessionDuration, &p.SampleRate, &p.ProjectID); err != nil {
).Scan(&p.MaxSessionDuration, &p.SampleRate, &p.ProjectID, &p.BeaconSize); err != nil {
return nil, err
}
return p, nil

View file

@ -8,6 +8,7 @@ type Project struct {
MaxSessionDuration int64
SampleRate byte
SaveRequestPayloads bool
BeaconSize int64
Metadata1 *string
Metadata2 *string
Metadata3 *string