sermoni

"Service monitor" / cronjob status service
Log | Files | Refs

commit 5b39bcd43a1ff0dd6405d023e15d2fa7153a0957
parent bd996eec0a07992ae60d86323e47ba3b485ba11b
Author: Vetle Haflan <vetle.haflan@luxsave.com>
Date:   Mon,  8 Jun 2020 23:07:11 +0200

Use binary instead of strconv for byte <-> uint64

Should fix #12

Diffstat:
Minternal/database/database.go | 14+++++++-------
Minternal/events/events.go | 3+--
Minternal/services/services.go | 35++++++++++-------------------------
Minternal/services/services_test.go | 10----------
4 files changed, 18 insertions(+), 44 deletions(-)

diff --git a/internal/database/database.go b/internal/database/database.go @@ -1,10 +1,10 @@ package database import ( + "encoding/binary" "errors" "fmt" "log" - "strconv" "time" "go.etcd.io/bbolt" @@ -68,15 +68,15 @@ func GetDB() *bbolt.DB { // often repeated for IDs. It is assumed that the data will parse successfully // (i.e. type checking is performed in an earlier stage). // If the parsing fails, the function therefore panics -func BytesToUint64(byteData []byte) uint64 { - uint64Data, err := strconv.ParseUint(string(byteData), 10, 64) - check(err) - return uint64Data +func BytesToUint64(b []byte) uint64 { + return binary.BigEndian.Uint64(b) } // Uint64ToBytes converts a uint64 formatted number to a byte array -func Uint64ToBytes(uint64Data uint64) []byte { - return []byte(strconv.FormatUint(uint64Data, 10)) +func Uint64ToBytes(ui64 uint64) (b []byte) { + b = make([]byte, 8) + binary.BigEndian.PutUint64(b, ui64) + return } // PrintBucket simply prints the K-V pairs in the bucket diff --git a/internal/events/events.go b/internal/events/events.go @@ -5,7 +5,6 @@ import ( "fmt" "log" "sermoni/internal/database" - "strconv" "go.etcd.io/bbolt" ) @@ -84,7 +83,7 @@ func Add(event *Event) error { if err != nil { return err } - id := []byte(strconv.FormatUint(idInt, 10)) + id := database.Uint64ToBytes(idInt) event.ID = idInt // Create the event bucket and fill it with data from event diff --git a/internal/services/services.go b/internal/services/services.go @@ -1,12 +1,12 @@ package services import ( + "encoding/binary" "errors" "fmt" "log" "sermoni/internal/database" "sermoni/internal/events" - "strconv" "go.etcd.io/bbolt" ) @@ -43,7 +43,9 @@ func GetByToken(token string) *Service { // GetByID returns the service structure associated with the given uint64-formatted // service ID, if that service exists. Otherwise returns nil func GetByID(id uint64) *Service { - return get([]byte(strconv.FormatUint(id, 10))) + idb := make([]byte, 8) + binary.BigEndian.PutUint64(idb, id) + return get(idb) } // GetAll returns all services in the database (TODO) @@ -78,7 +80,7 @@ func GetAll() []*Service { // Delete deletes the given service if it exists, and all events for said service, if any func Delete(intID uint64) error { db := database.GetDB() - serviceID := []byte(strconv.FormatUint(intID, 10)) + serviceID := database.Uint64ToBytes(intID) return db.Update(func(tx *bbolt.Tx) (err error) { sb := tx.Bucket(database.BucketKeyServices) stb := tx.Bucket(database.BucketKeyServiceTokens) @@ -167,7 +169,7 @@ func Add(service *Service) error { if serviceIDint, err = b.NextSequence(); err != nil { return err } - serviceID = []byte(strconv.FormatUint(serviceIDint, 10)) + serviceID = database.Uint64ToBytes(serviceIDint) if sb, err = b.CreateBucket(serviceID); err != nil { return err } @@ -177,11 +179,11 @@ func Add(service *Service) error { if err = sb.Put(keyServiceDescription, []byte(service.Description)); err != nil { return err } - periodStr := strconv.FormatUint(service.ExpectationPeriod, 10) + periodStr := database.Uint64ToBytes(service.ExpectationPeriod) if err = sb.Put(keyServicePeriod, []byte(periodStr)); err != nil { return err } - maxEventsStr := strconv.FormatUint(service.MaxNumberEvents, 10) + maxEventsStr := database.Uint64ToBytes(service.MaxNumberEvents) if err = sb.Put(keyServiceMaxEvents, []byte(maxEventsStr)); err != nil { return err } @@ -198,7 +200,6 @@ func Add(service *Service) error { // fromBucket populates the service struct with data from the given service bucket // TODO: Consider failing on missing fields and generally choosing an approach more similar to Event.fromBucket func (service *Service) fromBucket(id []byte, sb *bbolt.Bucket) { - // Ignoring this error, because it shouldn't be possible idInt := database.BytesToUint64(id) service.ID = idInt if name := sb.Get(keyServiceName); name != nil { @@ -208,26 +209,10 @@ func (service *Service) fromBucket(id []byte, sb *bbolt.Bucket) { service.Description = string(description) } if period := sb.Get(keyServicePeriod); period != nil { - // Quick fix: Convert to string, then int - // Uses default value 0 if an error occurs - intPeriod, err := strconv.ParseUint(string(period), 10, 64) - if err == nil { - service.ExpectationPeriod = intPeriod - } else { - log.Println("Couldn't convert period to int for service") - service.ExpectationPeriod = 0 - } + service.ExpectationPeriod = database.BytesToUint64(period) } if maxevents := sb.Get(keyServiceMaxEvents); maxevents != nil { - // Quick fix: Convert to string, then int - // Uses default value 0 if an error occurs - intMaxEvents, err := strconv.ParseUint(string(maxevents), 10, 64) - if err == nil { - service.MaxNumberEvents = intMaxEvents - } else { - log.Println("Couldn't convert max num events to int for service") - service.MaxNumberEvents = 0 - } + service.MaxNumberEvents = database.BytesToUint64(maxevents) } } diff --git a/internal/services/services_test.go b/internal/services/services_test.go @@ -5,19 +5,9 @@ import ( "os" "sermoni/internal/config" "sermoni/internal/database" - "strconv" "testing" ) -// intID gets uint64 from bytes -func intID(id []byte) uint64 { - idInt, err := strconv.ParseUint(string(id), 10, 64) - if err != nil { - return 0 - } - return idInt -} - func (s1 *Service) equals(s2 *Service) bool { switch { case s1.ID != s2.ID: