src.dualinventive.com/go/redis-proxy/internal/redis/io.go

112 lines
2.6 KiB
Go

package redis
import (
"fmt"
"strconv"
"src.dualinventive.com/go/dinet/ditime"
"src.dualinventive.com/go/dinet/rpc"
"src.dualinventive.com/go/dinet/rts"
"src.dualinventive.com/go/lib/dilog"
)
// Store a single DI-Net RPC message in the RTS cache
func (r *Redis) write(logger dilog.Logger, key, field string, value []byte) error {
logger.WithFields(dilog.Fields{
"field": field,
"value": string(value),
}).Debug("write")
c, err := r.getConn()
if err != nil {
return err
}
defer func() {
closeerr := c.Close()
// we are closing the connection so it is too late for errors.
_ = closeerr
}()
_, err = c.Do("HSET", key, field, value)
if err != nil {
return err
}
// Set last update in the root
_, err = c.Do("HSET", key, "last_update", strconv.FormatUint(uint64(ditime.Now()), 10))
return err
}
// writeSensorGPS writes a GPS entry of the device sensor in redis
func (r *Redis) writeSensorGPS(m *rpc.Msg, value rpc.GPSSensorData) error {
c, err := r.getConn()
if err != nil {
return err
}
defer func() {
closeerr := c.Close()
// we are closing the connection so it is too late for errors.
_ = closeerr
}()
// Set GPS
_, err = c.Do("GEOADD", rts.SensorGeohashKey, value.Longitude, value.Latitude, m.DeviceUID)
return err
}
// publish sends a Redis publish command to Redis
func (r *Redis) publish(m *rpc.Msg) error {
c, err := r.getConn()
if err != nil {
return err
}
defer func() {
closeerr := c.Close()
// we are closing the connection so it is too late for errors.
_ = closeerr
}()
var channel string
var message interface{}
// NOTE: the ordering should not be changed!
switch {
case rpc.ValidDeviceUID(m.DeviceUID):
// Message has device:uid || device:uid && project:id properties
channel = rts.ChanDevice
message = m.DeviceUID
case rpc.ValidProjectID(m.ProjectID):
// Message has project:id but not device:uid
channel = rts.ChanProject
message = m.ProjectID
default:
return nil
}
_, err = c.Do("PUBLISH", channel, message)
return err
}
// fieldName calculates the Redis HSET field name based on m.Class(), m.Method() and supplied id
func fieldName(m *rpc.Msg, id uint16) string {
if id > 0 && len(m.Method()) > 0 {
return fmt.Sprintf("%s:%d:%s", m.Class(), id, m.Method())
}
return string(m.ClassMethod)
}
// keyName calculates the Redis key field based on the device UID or project ID
func keyName(m *rpc.Msg) string {
var name string
// NOTE: the ordering should not be changed!
if rpc.ValidDeviceUID(m.DeviceUID) {
name = rts.KeyPrefixDevice + m.DeviceUID
} else if rpc.ValidProjectID(m.ProjectID) {
name = fmt.Sprintf("%s%d", rts.KeyPrefixProject, m.ProjectID)
}
return name
}