code: func SaveDeviceSession(p *redis.Pool, s DeviceSession) error {
  	dsPB := deviceSessionToPB(s)
  	b, err := proto.Marshal(&dsPB)
  	if err != nil {
  		return errors.Wrap(err, "protobuf encode error")
  	}
  
  	c := p.Get()
  	defer c.Close()
  	exp := int64(deviceSessionTTL) / int64(time.Millisecond)
  
  	c.Send("MULTI")
  	c.Send("PSETEX", fmt.Sprintf(deviceSessionKeyTempl, s.DevEUI), exp, b)
  	c.Send("SADD", fmt.Sprintf(devAddrKeyTempl, s.DevAddr), s.DevEUI[:])
  	c.Send("PEXPIRE", fmt.Sprintf(devAddrKeyTempl, s.DevAddr), exp)
  	if s.PendingRejoinDeviceSession != nil {
  		c.Send("SADD", fmt.Sprintf(devAddrKeyTempl, s.PendingRejoinDeviceSession.DevAddr), s.DevEUI[:])
  		c.Send("PEXPIRE", fmt.Sprintf(devAddrKeyTempl, s.PendingRejoinDeviceSession.DevAddr), exp)
  	}
  	if _, err := c.Do("EXEC"); err != nil {
  		return errors.Wrap(err, "exec error")
  	}
  
  	log.WithFields(log.Fields{
  		"dev_eui":  s.DevEUI,
  		"dev_addr": s.DevAddr,
  	}).Info("device-session saved")
  
  	return nil
  }
docs: // SaveDeviceSession saves the device-session. In case it doesn't exist yet
  // it will be created.