func (pipe *Pipeline) Discard() error {
	defer pipe.mu.Unlock()
	pipe.mu.Lock()
	if pipe.isClosed() {
		return pool.ErrClosed
	}
	pipe.cmds = pipe.cmds[:0]
	return nil
}
Discard resets the pipeline and discards queued commands.
package redis
import (
	"sync"
	"sync/atomic"
	"gopkg.in/redis.v3/internal/pool"
)
type Pipeline struct {
	commandable
	client baseClient
	mu   sync.Mutex  
	cmds []Cmder
	closed int32
}
func (c *Client) Pipeline() *Pipeline {
	pipe := &Pipeline{
		client: c.baseClient,
		cmds:   make([]Cmder, 0, 10),
	}
	pipe.commandable.process = pipe.process
	return pipe
}
func (c *Client) Pipelined(fn func(*Pipeline) error) ([]Cmder, error) {
	pipe := c.Pipeline()
	if err := fn(pipe); err != nil {
		return nil, err
	}
	cmds, err := pipe.Exec()
	_ = pipe.Close()
	return cmds, err
}
func (pipe *Pipeline) process(cmd Cmder) {
	pipe.mu.Lock()
	pipe.cmds = append(pipe.cmds, cmd)
	pipe.mu.Unlock()
}
func (pipe *Pipeline) Close() error {
	atomic.StoreInt32(&pipe.closed, 1)
	pipe.Discard()
	return nil
}
func (pipe *Pipeline) isClosed() bool {
	return atomic.LoadInt32(&pipe.closed) == 1
}