A thread-safe Golang library that accepts a json serialized string of the form below and maintains an average time for each action.
These inputs:
{"action":"jump", "time":100}
{"action":"run", "time":75}
{"action":"jump", "time":200}
Would lead to this output:
[{"action":"jump","avg":150},{"action":"run","avg":75}]
I have never before written anything in GoLang, but it has elegant support for concurrency and json, which are core aspects of this project. It is also used by the folks that will be inspecting this project. You've been warned!
This module is intended to be imported from a go program.
Calls to AddAction
and GetStats
may be made concurrently.
go get github.com/aschult5/actiontime
From go doc
package actiontime // import "github.com/aschult5/actiontime"
Package actiontime takes actions and times as json, tracking average times.
Input is received as a json string, per requirements.
var ErrBadInput = errors.New("actiontime: Malformed input data")
var MaxActionLen = 32
type Stats struct{ ... }
From go doc actiontime.Stats
package actiontime // import "github.com/aschult5/actiontime"
type Stats struct {
// Has unexported fields.
}
Stats tracks passed actions' average times.
func (a *Stats) AddAction(input string) error
func (a *Stats) GetStats() string
package main
import (
"fmt"
"github.com/aschult5/actiontime"
)
func main() {
var a actiontime.Stats
a.AddAction(`{"action":"jump", "time":100}`)
a.AddAction(`{"action":"fall", "time":100}`)
a.AddAction(`{"action":"jump", "time":200}`)
a.AddAction(`{"action":"fall", "time":200}`)
a.AddAction(`{"action":"sit", "time":500}`)
a.AddAction(`{"action":"stand", "time":700}`)
fmt.Println(a.GetStats())
}
Possible output:
[{"action":"stand","avg":700},{"action":"jump","avg":150},{"action":"fall","avg":150},{"action":"sit","avg":500}]
go test [-v] [-race] [-short]
Note: Testing-race
without -short
may timeout.
Some test case files will need to be manually generated, as they create large files that probably don't belong in revision control.
You will be prompted with the command if you run go test
.
go test -bench . -benchmem -benchtime 10s -run=^$
See travis-ci for latest benchmark results.
go test -coverprofile=coverage.txt -covermode=atomic
go tool cover -func coverage.txt
See codecov for code coverage history.
See python3 ./tools/testgenerator.py --help
Generated tests will have to be manually integrated by adding a new Test* case to statsimpl_test.go
actiontime.statsImpl
exists to separate the interface from its implementation. This reduces actiontime.Stats
to a simple message transcoder and input validator.time
may only be a json number greater than 0 that fits into a float64action
may only be a json string of length between 1 and actiontime.MaxActionLen
charactersaction
values is reasonably small, i.e. will fit into memorytime
valuesGetStats
does not need to be strictly chronologically-accurate
AddAction
should be treated as a sensitive transaction, e.g. a bank deposit or withdrawalAddAction
will have little effectGetStats
See github.com/aschult5/actiontime/issues