func (s *Service) FetchValidUserSession(sessionID string) (*user.Session, error) {
	c := s.Pool.Get()
	defer c.Close()
	exists, err := redis.Bool(c.Do("EXISTS", sessionID))
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, nil
	}
	var userID string
	var json string
	var expiresAtSeconds int64
	reply, err := redis.Values(c.Do("HMGET", sessionID, "UserID", "JSON", "ExpiresAtSeconds"))
	if err != nil {
		return nil, err
	}
	if len(reply) < 3 {
		return nil, ErrRetrievingSession
	}
	for idx := range reply {
		if reply[idx] == nil {
			return nil, ErrRetrievingSession
		}
	}
	if _, err := redis.Scan(reply, &userID, &json, &expiresAtSeconds); err != nil {
		return nil, err
	}
	return &user.Session{
		ID:        sessionID,
		UserID:    userID,
		JSON:      json,
		ExpiresAt: time.Unix(expiresAtSeconds, 0),
	}, nil
}
FetchValidUserSession returns a valid user session or an err if the session has expired or does not exist. \
If a valid session does not exist, this function should return a nil pointer
package store
import (
	"errors"
	"time"
	"github.com/adam-hanna/sessions/user"
	"github.com/garyburd/redigo/redis"
)
const (
	DefaultConnectionAddress = ":6379"
	DefaultMaxIdleConnections = 3
	DefaultIdleTimeoutDuration = 10 * time.Second
)
var (
	ErrRetrievingSession = errors.New("error retrieving session data from store")
)
type Service struct {
	Pool *redis.Pool
}
type Options struct {
	ConnectionAddress    string
	MaxIdleConnections   int
	MaxActiveConnections int
	IdleTimeoutDuration  time.Duration
}
func New(options Options) *Service {
	setDefaultOptions(&options)
	return &Service{
		Pool: &redis.Pool{
			MaxActive:   options.MaxActiveConnections,
			MaxIdle:     options.MaxIdleConnections,
			IdleTimeout: options.IdleTimeoutDuration,
			Dial:        func() (redis.Conn, error) { return redis.Dial("tcp", options.ConnectionAddress) },
		},
	}
}
func (s *Service) SaveUserSession(userSession *user.Session) error {
	c := s.Pool.Get()
	defer c.Close()
	if _, err := c.Do("HMSET", userSession.ID, "UserID", userSession.UserID, "JSON", userSession.JSON, "ExpiresAtSeconds", userSession.ExpiresAt.Unix()); err != nil {
		return err
	}
	if _, err := c.Do("EXPIREAT", userSession.ID, userSession.ExpiresAt.Unix()); err != nil {
		return err
	}
	return nil
}
func (s *Service) DeleteUserSession(sessionID string) error {
	c := s.Pool.Get()
	defer c.Close()
	aLongTimeAgo := time.Now().Add(-1000 * time.Hour)
	if _, err := c.Do("EXPIREAT", sessionID, aLongTimeAgo.Unix()); err != nil {
		return err
	}
	return nil
}