func (c *Client) ReleaseSession(ctx context.Context, sess Session) {
	c.smu.Lock()
	defer c.smu.Unlock()
	c.sessions[sess.name] = &sessionInfo{inUse: false, lastUsed: time.Now().UTC()}
}
ReleaseSession will make the session available in the cache again. Call this after
first acquiring a session.
package spannerr
import (
	"context"
	"encoding/json"
	"net/http"
	"sync"
	"time"
	"github.com/pkg/errors"
	"golang.org/x/oauth2"
	"golang.org/x/oauth2/google"
	spanner "google.golang.org/api/spanner/v1"
	"google.golang.org/appengine"
)
type (
	Client struct {
		smu      sync.Mutex
		sessions map[string]*sessionInfo
		conn        string
		maxSessions int
	}
	Session struct {
		name string
		sess *spanner.ProjectsInstancesDatabasesSessionsService
	}
	Param struct {
		Name string
		Value interface{}
		Type string
		ArrayElementType string
	}
	sessionInfo struct {
		inUse    bool
		lastUsed time.Time
	}
)
func NewClient(project, instances, database string, maxSessions int) *Client {
	return &Client{
		conn:        "projects/" + project + "/instances/" + instances + "/databases/" + database,
		maxSessions: maxSessions,
		sessions:    map[string]*sessionInfo{},
	}
}
var idleTimeout = 45 * time.Minute
func (c *Client) AcquireSession(ctx context.Context) (*Session, error) {
	c.smu.Lock()
	defer c.smu.Unlock()
	if len(c.sessions) < c.maxSessions {
		sess, err := c.newSession(ctx)
		if err != nil {
			return nil, err
		}
		c.sessions[sess.name] = &sessionInfo{inUse: true}
		return sess, nil
	}
	for name, info := range c.sessions {
		if info.inUse {
			continue
		}
		if time.Now().UTC().Sub(info.lastUsed) > idleTimeout {
			delete(c.sessions, name)
			sess, err := c.newSession(ctx)
			if err != nil {
				return nil, err
			}
			c.sessions[sess.name] = &sessionInfo{inUse: true}
			return sess, nil
		}
		c.sessions[name] = &sessionInfo{inUse: true}
		svc, err := newSpanner(ctx)
		if err != nil {
			return nil, errors.Wrap(err, "unable to init spanner service")
		}
		return &Session{name: name, sess: svc.Projects.Instances.Databases.Sessions},
			nil
	}
	return nil, errors.Errorf("all %d sessions are in use. you may need to increase your session pool size.",
		len(c.sessions))
}
func (c *Client) newSession(ctx context.Context) (*Session, error) {
	svc, err := newSpanner(ctx)
	if err != nil {
		return nil, errors.Wrap(err, "unable to init spanner service")
	}
	sess := svc.Projects.Instances.Databases.Sessions
	resp, err := sess.Create(c.conn, &spanner.CreateSessionRequest{}).Do()
	if err != nil {
		return nil, errors.Wrap(err, "unable to init spanner session")
	}
	return &Session{name: resp.Name, sess: sess}, nil
}