From 89a5de0105957d6a78c392c24eaae6b7d0d6d74c Mon Sep 17 00:00:00 2001 From: Maddie Zhan Date: Sat, 18 Sep 2021 02:19:14 +0800 Subject: [PATCH] Support in-memory telemetry/stats database --- README.md | 2 +- database/database.go | 3 +++ database/memory/memory.go | 51 +++++++++++++++++++++++++++++++++++++++ settings.toml | 2 +- 4 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 database/memory/memory.go diff --git a/README.md b/README.md index 8261592..6ed2d35 100644 --- a/README.md +++ b/README.md @@ -106,7 +106,7 @@ manually, you can install newer version of Go into your `GOPATH`: # redact IP addresses redact_ip_addresses=false - # database type for statistics data, currently supports: none, bolt, mysql, postgresql + # database type for statistics data, currently supports: none, memory, bolt, mysql, postgresql # if none is specified, no telemetry/stats will be recorded, and no result PNG will be generated database_type="postgresql" database_hostname="localhost" diff --git a/database/database.go b/database/database.go index e2d16ef..de2e7e7 100644 --- a/database/database.go +++ b/database/database.go @@ -3,6 +3,7 @@ package database import ( "github.com/librespeed/speedtest/config" "github.com/librespeed/speedtest/database/bolt" + "github.com/librespeed/speedtest/database/memory" "github.com/librespeed/speedtest/database/mysql" "github.com/librespeed/speedtest/database/none" "github.com/librespeed/speedtest/database/postgresql" @@ -29,6 +30,8 @@ func SetDBInfo(conf *config.Config) { DB = mysql.Open(conf.DatabaseHostname, conf.DatabaseUsername, conf.DatabasePassword, conf.DatabaseName) case "bolt": DB = bolt.Open(conf.DatabaseFile) + case "memory": + DB = memory.Open("") case "none": DB = none.Open("") default: diff --git a/database/memory/memory.go b/database/memory/memory.go new file mode 100644 index 0000000..ac8bf1d --- /dev/null +++ b/database/memory/memory.go @@ -0,0 +1,51 @@ +package memory + +import ( + "errors" + "sync" + "time" + + "github.com/librespeed/speedtest/database/schema" +) + +const ( + // just enough records to return for FetchLast100 + maxRecords = 100 +) + +type Memory struct { + lock sync.RWMutex + records []schema.TelemetryData +} + +func Open(_ string) *Memory { + return &Memory{} +} + +func (mem *Memory) Insert(data *schema.TelemetryData) error { + mem.lock.Lock() + defer mem.lock.Unlock() + data.Timestamp = time.Now() + mem.records = append(mem.records, *data) + if len(mem.records) > maxRecords { + mem.records = mem.records[len(mem.records)-maxRecords:] + } + return nil +} + +func (mem *Memory) FetchByUUID(uuid string) (*schema.TelemetryData, error) { + mem.lock.RLock() + defer mem.lock.RUnlock() + for _, record := range mem.records { + if record.UUID == uuid { + return &record, nil + } + } + return nil, errors.New("record not found") +} + +func (mem *Memory) FetchLast100() ([]schema.TelemetryData, error) { + mem.lock.RLock() + defer mem.lock.RUnlock() + return mem.records, nil +} diff --git a/settings.toml b/settings.toml index fb081ac..79a1b8e 100644 --- a/settings.toml +++ b/settings.toml @@ -18,7 +18,7 @@ statistics_password="PASSWORD" # redact IP addresses redact_ip_addresses=false -# database type for statistics data, currently supports: none, bolt, mysql, postgresql +# database type for statistics data, currently supports: none, memory, bolt, mysql, postgresql # if none is specified, no telemetry/stats will be recorded, and no result PNG will be generated database_type="bolt" database_hostname=""