Beispiel #1
0
func (c *Ring) pipelineExec(cmds []Cmder) error {
	var retErr error

	cmdsMap := make(map[string][]Cmder)
	for _, cmd := range cmds {
		name := c.hash.Get(hashtag.Key(c.cmdFirstKey(cmd)))
		if name == "" {
			cmd.setErr(errRingShardsDown)
			if retErr == nil {
				retErr = errRingShardsDown
			}
			continue
		}
		cmdsMap[name] = append(cmdsMap[name], cmd)
	}

	for i := 0; i <= c.opt.MaxRetries; i++ {
		failedCmdsMap := make(map[string][]Cmder)

		for name, cmds := range cmdsMap {
			client := c.shards[name].Client
			cn, err := client.conn()
			if err != nil {
				setCmdsErr(cmds, err)
				if retErr == nil {
					retErr = err
				}
				continue
			}

			if i > 0 {
				resetCmds(cmds)
			}
			failedCmds, err := execCmds(cn, cmds)
			client.putConn(cn, err, false)
			if err != nil && retErr == nil {
				retErr = err
			}
			if len(failedCmds) > 0 {
				failedCmdsMap[name] = failedCmds
			}
		}

		if len(failedCmdsMap) == 0 {
			break
		}
		cmdsMap = failedCmdsMap
	}

	return retErr
}
Beispiel #2
0
func (c *Ring) getClient(key string) (*Client, error) {
	c.mu.RLock()

	if c.closed {
		return nil, pool.ErrClosed
	}

	name := c.hash.Get(hashtag.Key(key))
	if name == "" {
		c.mu.RUnlock()
		return nil, errRingShardsDown
	}

	cl := c.shards[name].Client
	c.mu.RUnlock()
	return cl, nil
}