mirror of
https://github.com/muety/wakapi.git
synced 2023-08-10 21:12:56 +03:00
chore: introduce heartbeat max age
This commit is contained in:
parent
b763c4acc6
commit
8e558d8dee
@ -128,6 +128,11 @@ You can specify configuration options either via a config file (default: `config
|
|||||||
| YAML Key / Env. Variable | Default | Description |
|
| YAML Key / Env. Variable | Default | Description |
|
||||||
|------------------------------------------------------------------------------|--------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
|------------------------------------------------------------------------------|--------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||||
| `env` /<br>`ENVIRONMENT` | `dev` | Whether to use development- or production settings |
|
| `env` /<br>`ENVIRONMENT` | `dev` | Whether to use development- or production settings |
|
||||||
|
| `app.aggregation_time`<br>`WAKAPI_AGGREGATION_TIME` | `02:15` | Time of day at which to periodically run summary generation for all users |
|
||||||
|
| `app.report_time_weekly`<br>`WAKAPI_REPORT_TIME_WEEKLY` | `fri,18:00` | Week day and time at which to send e-mail reports |
|
||||||
|
| `app.import_batch_size`<br>`WAKAPI_IMPORT_BATCH_SIZE` | `50` | Size of batches of heartbeats to insert to the database during importing from external services |
|
||||||
|
| `app.inactive_days`<br>`WAKAPI_INACTIVE_DAYS` | `7` | Number of days after which to consider a user inactive (only for metrics) |
|
||||||
|
| `app.heartbeat_max_age`<br>`WAKAPI_HEARTBEAT_MAX_AGE` | `4320h` | Maximum acceptable age of a heartbeat (see [`ParseDuration`](https://pkg.go.dev/time#ParseDuration)) |
|
||||||
| `app.custom_languages` | - | Map from file endings to language names |
|
| `app.custom_languages` | - | Map from file endings to language names |
|
||||||
| `app.avatar_url_template` | (see [`config.default.yml`](config.default.yml)) | URL template for external user avatar images (e.g. from [Dicebear](https://dicebear.com) or [Gravatar](https://gravatar.com)) |
|
| `app.avatar_url_template` | (see [`config.default.yml`](config.default.yml)) | URL template for external user avatar images (e.g. from [Dicebear](https://dicebear.com) or [Gravatar](https://gravatar.com)) |
|
||||||
| `server.port` /<br> `WAKAPI_PORT` | `3000` | Port to listen on |
|
| `server.port` /<br> `WAKAPI_PORT` | `3000` | Port to listen on |
|
||||||
|
@ -16,6 +16,7 @@ app:
|
|||||||
report_time_weekly: 'fri,18:00' # time at which to fan out weekly reports (format: '<weekday)>,<daytime>')
|
report_time_weekly: 'fri,18:00' # time at which to fan out weekly reports (format: '<weekday)>,<daytime>')
|
||||||
inactive_days: 7 # time of previous days within a user must have logged in to be considered active
|
inactive_days: 7 # time of previous days within a user must have logged in to be considered active
|
||||||
import_batch_size: 50 # maximum number of heartbeats to insert into the database within one transaction
|
import_batch_size: 50 # maximum number of heartbeats to insert into the database within one transaction
|
||||||
|
heartbeat_max_age: '4320h' # maximum acceptable age of a heartbeat (see https://pkg.go.dev/time#ParseDuration)
|
||||||
custom_languages:
|
custom_languages:
|
||||||
vue: Vue
|
vue: Vue
|
||||||
jsx: JSX
|
jsx: JSX
|
||||||
|
@ -68,6 +68,7 @@ type appConfig struct {
|
|||||||
ImportBackoffMin int `yaml:"import_backoff_min" default:"5" env:"WAKAPI_IMPORT_BACKOFF_MIN"`
|
ImportBackoffMin int `yaml:"import_backoff_min" default:"5" env:"WAKAPI_IMPORT_BACKOFF_MIN"`
|
||||||
ImportBatchSize int `yaml:"import_batch_size" default:"50" env:"WAKAPI_IMPORT_BATCH_SIZE"`
|
ImportBatchSize int `yaml:"import_batch_size" default:"50" env:"WAKAPI_IMPORT_BATCH_SIZE"`
|
||||||
InactiveDays int `yaml:"inactive_days" default:"7" env:"WAKAPI_INACTIVE_DAYS"`
|
InactiveDays int `yaml:"inactive_days" default:"7" env:"WAKAPI_INACTIVE_DAYS"`
|
||||||
|
HeartbeatMaxAge string `yaml:"heartbeat_max_age" default:"4320h" env:"WAKAPI_HEARTBEAT_MAX_AGE"`
|
||||||
CountCacheTTLMin int `yaml:"count_cache_ttl_min" default:"30" env:"WAKAPI_COUNT_CACHE_TTL_MIN"`
|
CountCacheTTLMin int `yaml:"count_cache_ttl_min" default:"30" env:"WAKAPI_COUNT_CACHE_TTL_MIN"`
|
||||||
AvatarURLTemplate string `yaml:"avatar_url_template" default:"api/avatar/{username_hash}.svg"`
|
AvatarURLTemplate string `yaml:"avatar_url_template" default:"api/avatar/{username_hash}.svg"`
|
||||||
CustomLanguages map[string]string `yaml:"custom_languages"`
|
CustomLanguages map[string]string `yaml:"custom_languages"`
|
||||||
@ -242,6 +243,11 @@ func (c *appConfig) GetWeeklyReportTime() string {
|
|||||||
return strings.Split(c.ReportTimeWeekly, ",")[1]
|
return strings.Split(c.ReportTimeWeekly, ",")[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *appConfig) HeartbeatsMaxAge() time.Duration {
|
||||||
|
d, _ := time.ParseDuration(c.HeartbeatMaxAge)
|
||||||
|
return d
|
||||||
|
}
|
||||||
|
|
||||||
func (c *dbConfig) IsSQLite() bool {
|
func (c *dbConfig) IsSQLite() bool {
|
||||||
return c.Dialect == "sqlite3"
|
return c.Dialect == "sqlite3"
|
||||||
}
|
}
|
||||||
@ -400,6 +406,9 @@ func Load(version string) *Config {
|
|||||||
if _, err := time.Parse("15:04", config.App.AggregationTime); err != nil {
|
if _, err := time.Parse("15:04", config.App.AggregationTime); err != nil {
|
||||||
logbuch.Fatal("invalid interval set for aggregation_time")
|
logbuch.Fatal("invalid interval set for aggregation_time")
|
||||||
}
|
}
|
||||||
|
if _, err := time.ParseDuration(config.App.HeartbeatMaxAge); err != nil {
|
||||||
|
logbuch.Fatal("invalid duration set for heartbeat_max_age")
|
||||||
|
}
|
||||||
|
|
||||||
Set(config)
|
Set(config)
|
||||||
return Get()
|
return Get()
|
||||||
|
@ -34,6 +34,11 @@ func (h *Heartbeat) Valid() bool {
|
|||||||
return h.User != nil && h.UserID != "" && h.User.ID == h.UserID && h.Time != CustomTime(time.Time{})
|
return h.User != nil && h.UserID != "" && h.User.ID == h.UserID && h.Time != CustomTime(time.Time{})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Heartbeat) Timely(maxAge time.Duration) bool {
|
||||||
|
now := time.Now()
|
||||||
|
return now.Sub(h.Time.T()) <= maxAge && h.Time.T().Before(now)
|
||||||
|
}
|
||||||
|
|
||||||
func (h *Heartbeat) Augment(languageMappings map[string]string) {
|
func (h *Heartbeat) Augment(languageMappings map[string]string) {
|
||||||
maxPrec := -1 // precision / mapping complexity -> more concrete ones shall take precedence
|
maxPrec := -1 // precision / mapping complexity -> more concrete ones shall take precedence
|
||||||
for ending, value := range languageMappings {
|
for ending, value := range languageMappings {
|
||||||
|
@ -86,7 +86,7 @@ func (h *HeartbeatApiHandler) Post(w http.ResponseWriter, r *http.Request) {
|
|||||||
hb.UserID = user.ID
|
hb.UserID = user.ID
|
||||||
hb.UserAgent = userAgent
|
hb.UserAgent = userAgent
|
||||||
|
|
||||||
if !hb.Valid() {
|
if !hb.Valid() || !hb.Timely(h.config.App.HeartbeatsMaxAge()) {
|
||||||
w.WriteHeader(http.StatusBadRequest)
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
w.Write([]byte("invalid heartbeat object"))
|
w.Write([]byte("invalid heartbeat object"))
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user