예제 #1
0
파일: bucket.go 프로젝트: arsham-f/Ceres
func AllBuckets(client *redis.Client) ([]*Bucket, error) {
	var ret []*Bucket

	keys, err := client.Cmd("KEYS", "*").Array()

	if err != nil {
		return nil, err
	}

	for _, key := range keys {
		keyval, err := key.Str()

		if err != nil {
			continue
		}

		b, err := GetBucket(client, keyval)

		if err != nil {
			continue
		}

		ret = append(ret, b)
	}

	return ret, nil
}
예제 #2
0
파일: pool.go 프로젝트: XUJiahua/radix.v2
// NewCustom is like New except you can specify a DialFunc which will be
// used when creating new connections for the pool. The common use-case is to do
// authentication for new connections.
func NewCustom(network, addr string, size int, df DialFunc) (*Pool, error) {
	var client *redis.Client
	var err error
	pool := make([]*redis.Client, 0, size)
	for i := 0; i < size; i++ {
		client, err = df(network, addr)
		if err != nil {
			for _, client = range pool {
				client.Close()
			}
			pool = pool[0:]
			break
		}
		pool = append(pool, client)
	}
	p := Pool{
		Network: network,
		Addr:    addr,
		pool:    make(chan *redis.Client, len(pool)),
		df:      df,
	}
	for i := range pool {
		p.pool <- pool[i]
	}
	return &p, err
}
예제 #3
0
파일: db.go 프로젝트: mc0/okq
func scanHelper(redisClient *redis.Client, pattern string, retCh chan string) error {
	cursor := "0"
	for {
		r := redisClient.Cmd("SCAN", cursor, "MATCH", pattern)
		if r.Err != nil {
			return r.Err
		}
		elems, err := r.Array()
		if err != nil {
			return err
		}

		results, err := elems[1].List()
		if err != nil {
			return err
		}

		for i := range results {
			retCh <- results[i]
		}

		if cursor, err = elems[0].Str(); err != nil {
			return err
		} else if cursor == "0" {
			return nil
		}
	}
}
예제 #4
0
파일: db_lua.go 프로젝트: mc0/okq
func luaHelper(
	c *redis.Client, cmd string, numKeys int, args ...interface{},
) *redis.Resp {

	cmd = strings.ToUpper(cmd)
	l, ok := luaScripts[cmd]
	if !ok {
		return redis.NewResp(fmt.Errorf("unknown lua script: %s", cmd))
	}

	realArgs := make([]interface{}, 0, len(args)+2)
	realArgs = append(realArgs, l.hash, numKeys)
	realArgs = append(realArgs, args...)

	r, notLoaded := luaEvalSha(c, realArgs)
	if !notLoaded {
		return r
	}

	if err := c.Cmd("SCRIPT", "LOAD", l.script).Err; err != nil {
		return r
	}

	r, _ = luaEvalSha(c, realArgs)
	return r
}
예제 #5
0
파일: db_lua.go 프로젝트: mc0/okq
// Performs and EVALSHA with the given args, returning the reply and whether or
// not that reply is due to the script for that sha not being loaded yet
func luaEvalSha(c *redis.Client, args []interface{}) (*redis.Resp, bool) {
	r := c.Cmd("EVALSHA", args...)
	if r.Err != nil {
		if r.IsType(redis.AppErr) {
			return r, strings.HasPrefix(r.Err.Error(), "NOSCRIPT")
		}
	}
	return r, false
}
예제 #6
0
파일: pool.go 프로젝트: XUJiahua/radix.v2
// Put returns a client back to the pool. If the pool is full the client is
// closed instead. If the client is already closed (due to connection failure or
// what-have-you) it will not be put back in the pool
func (p *Pool) Put(conn *redis.Client) {
	if conn.LastCritical == nil {
		select {
		case p.pool <- conn:
		default:
			conn.Close()
		}
	}
}
예제 #7
0
// Pings redis to check whether the connection works. A connectTo...() methods needs
// to be called before.
func (t *Transport) pingRedis(client *redis.Client) error {

	resp := client.Cmd("PING")
	if resp.Err != nil {
		msg := fmt.Sprintf("Cannot connect to Redis host '%s': %s", t.Address, resp.Err)
		log.Fatal(msg)
		return resp.Err
	}

	return nil
}
예제 #8
0
// Put putss the connection back in its pool. To be used alongside any of the
// Get* methods once use of the redis.Client is done
func (c *Cluster) Put(conn *redis.Client) {
	c.callCh <- func(c *Cluster) {
		p := c.pools[conn.Addr]
		if p == nil {
			conn.Close()
			return
		}

		p.Put(conn)
	}
}
예제 #9
0
파일: pool.go 프로젝트: XUJiahua/radix.v2
// Empty removes and calls Close() on all the connections currently in the pool.
// Assuming there are no other connections waiting to be Put back this method
// effectively closes and cleans up the pool.
func (p *Pool) Empty() {
	var conn *redis.Client
	for {
		select {
		case conn = <-p.pool:
			conn.Close()
		default:
			return
		}
	}
}
func migrateTowns(townsDb *sql.DB, redisCli *redis.Client) {
	var townsCount int
	err := townsDb.QueryRow(`SELECT COUNT(*) FROM towns`).Scan(&townsCount)
	if err != nil {
		log.Fatalf("migrate: towns: %v\n", err)
	}

	rows, err := townsDb.Query(`SELECT id, name, name_tr, region_id,
                                       regional_center, latitude,
                                       longitude, zoom FROM towns`)
	if err != nil {
		log.Fatalf("migrate: towns: %v\n", err)
	}

	currentTownIdx := 1
	for rows.Next() {
		town := new(Town)
		var regionId uint32 = 0
		err = rows.Scan(&town.Id, &town.Name, &town.NameTr,
			&regionId, &town.RegionalCenter,
			&town.Latitude, &town.Longitude, &town.Zoom)
		if err != nil {
			log.Fatal(err)
		}

		if regionId != 0 {
			town.RegionId = new(uint32)
			*town.RegionId = regionId
		}

		jsonData, err := json.Marshal(town)
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SET", "town:"+strconv.FormatUint(uint64(town.Id), 10), string(jsonData)).Err
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("GEOADD", "towns", town.Longitude, town.Latitude, town.Id).Err
		if err != nil {
			log.Fatal(err)
		}

		currentTownIdx++

		if currentTownIdx%500 == 0 {
			log.Printf("[%d/%d] Towns processed\n", currentTownIdx, townsCount)
		}
	}
	log.Printf("[%d/%d] Towns processed\n", townsCount, townsCount)
}
func migrateBanks(banksDb *sql.DB, redisCli *redis.Client) {
	var banksCount int
	err := banksDb.QueryRow(`SELECT COUNT(*) FROM banks`).Scan(&banksCount)
	if err != nil {
		log.Fatalf("migrate: banks: %v", err)
	}

	rows, err := banksDb.Query(`SELECT id, name, name_tr, name_tr_alt, town,
                                       licence, rating, tel FROM banks`)
	if err != nil {
		log.Fatalf("migrate: banks: %v", err)
	}

	currentBankIdx := 1
	for rows.Next() {
		bank := new(Bank)
		var nameTr sql.NullString
		err = rows.Scan(&bank.Id, &bank.Name, &nameTr, &bank.NameTrAlt,
			&bank.Town, &bank.Licence, &bank.Rating, &bank.Tel)
		if err != nil {
			log.Fatal(err)
		}

		if nameTr.Valid {
			bank.NameTr = nameTr.String
		} else {
			bank.NameTr = ""
		}

		jsonData, err := json.Marshal(bank)
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SET", "bank:"+strconv.FormatUint(uint64(bank.Id), 10), string(jsonData)).Err
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SADD", "banks", bank.Id).Err
		if err != nil {
			log.Fatal(err)
		}

		currentBankIdx++

		if currentBankIdx%100 == 0 {
			log.Printf("[%d/%d] Banks processed\n", currentBankIdx, banksCount)
		}
	}
	log.Printf("[%d/%d] Banks processed\n", banksCount, banksCount)
}
예제 #12
0
파일: bucket.go 프로젝트: arsham-f/Ceres
func CreateBucket(client *redis.Client, name string, length int) error {
	exists, err := client.Cmd("EXISTS", name).Int()

	if err != nil {
		return err
	}

	if exists == 1 {
		return errors.New("Bucket already exists")
	} else {
		return client.Cmd("SET", name, length, "NX").Err
	}
}
예제 #13
0
파일: bucket.go 프로젝트: arsham-f/Ceres
func GetBucket(client *redis.Client, name string) (*Bucket, error) {
	length, err := client.Cmd("GET", name).Str()
	if err != nil {
		return nil, err
	}

	b := new(Bucket)
	*b = Bucket{
		client,
		name,
		atoi(length),
	}

	return b, nil
}
func migrateRegions(townsDb *sql.DB, redisCli *redis.Client) {
	var regionsCount int
	err := townsDb.QueryRow(`SELECT COUNT(*) FROM regions`).Scan(&regionsCount)
	if err != nil {
		log.Fatalf("migrate: regions: %v\n", err)
	}

	rows, err := townsDb.Query(`SELECT id, name, name_tr,
                                       latitude, longitude, zoom FROM regions`)
	if err != nil {
		log.Fatalf("migrate: regions: %v\n", err)
	}

	currentRegionIdx := 1
	for rows.Next() {
		region := new(Region)
		err = rows.Scan(&region.Id, &region.Name, &region.NameTr,
			&region.Latitude, &region.Longitude, &region.Zoom)
		if err != nil {
			log.Fatal(err)
		}

		jsonData, err := json.Marshal(region)
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SET", "region:"+strconv.FormatUint(uint64(region.Id), 10), string(jsonData)).Err
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("GEOADD", "regions", region.Longitude, region.Latitude, region.Id).Err
		if err != nil {
			log.Fatal(err)
		}

		currentRegionIdx++

		if currentRegionIdx%500 == 0 {
			log.Printf("[%d/%d] Regions processed\n", currentRegionIdx, regionsCount)
		}
	}
	log.Printf("[%d/%d] Regions processed\n", regionsCount, regionsCount)
}
func preloadRedisScriptSrc(redisCli *redis.Client, srcFilePath string) string {
	context := "preloadRedisScripts: " + srcFilePath

	buf := bytes.NewBuffer(nil)
	file, err := os.Open(srcFilePath)
	if err != nil {
		log.Fatalf("%s => %v\n", context, err)
	}
	io.Copy(buf, file)
	file.Close()
	src := string(buf.Bytes())

	response := redisCli.Cmd("SCRIPT", "LOAD", src)
	if response.Err != nil {
		log.Fatalf("%s => %v\n", context, response.Err)
	}
	scriptSha, err := response.Str()
	if err != nil {
		log.Fatalf("%s => %v\n", context, err)
	}
	return scriptSha
}
예제 #16
0
파일: main.go 프로젝트: caeleel/mmr
func allElos(conn *redis.Client) map[string]float64 {
	result := conn.Cmd("HGETALL", "elo")
	if result.Err != nil {
		return nil
	}

	elos, err := result.Map()
	if err != nil {
		return nil
	}

	retval := make(map[string]float64)
	for player, elo := range elos {
		f, err := strconv.ParseFloat(elo, 64)
		if err != nil {
			conn.Cmd("HDEL", "elo", player)
		} else {
			retval[player] = f
		}
	}

	return retval
}
예제 #17
0
func processSubImages(conn *redis.Client, typeName string, key string) {
	var typeKey = "image:" + typeName + ":" + key
	keys, err := conn.Cmd("HKEYS", typeKey).List()
	if err != nil {
		log.Fatal("fetch all sub hash keys error")
	}
	for _, name := range keys {
		data, _ := conn.Cmd("HGET", typeKey, name).Bytes()
		fid := saveFileToFS(data)
		conn.Cmd("HSET", typeKey, name, fid)
	}
}
예제 #18
0
func (c *Cluster) clientCmd(
	client *redis.Client, cmd string, args []interface{}, ask bool,
	tried map[string]bool, haveReset bool,
) *redis.Resp {
	var err error
	var r *redis.Resp
	defer c.Put(client)

	if ask {
		r = client.Cmd("ASKING")
		ask = false
	}

	// If we asked and got an error, we continue on with error handling as we
	// would normally do. If we didn't ask or the ask succeeded we do the
	// command normally, and see how that goes
	if r == nil || r.Err == nil {
		r = client.Cmd(cmd, args...)
	}

	if err = r.Err; err == nil {
		return r
	}

	// At this point we have some kind of error we have to deal with. The above
	// code is what will be run 99% of the time and is pretty streamlined,
	// everything after this point is allowed to be hairy and gross

	haveTriedBefore := haveTried(tried, client.Addr)
	tried = justTried(tried, client.Addr)

	// Deal with network error
	if r.IsType(redis.IOErr) {
		// If this is the first time trying this node, try it again
		if !haveTriedBefore {
			if client, try2err := c.getConn("", client.Addr); try2err == nil {
				return c.clientCmd(client, cmd, args, false, tried, haveReset)
			}
		}
		// Otherwise try calling Reset() and getting a random client
		if !haveReset {
			if resetErr := c.Reset(); resetErr != nil {
				return errorRespf("Could not get cluster info: %s", resetErr)
			}
			client, getErr := c.getConn("", "")
			if getErr != nil {
				return errorResp(getErr)
			}
			return c.clientCmd(client, cmd, args, false, tried, true)
		}
		// Otherwise give up and return the most recent error
		return r
	}

	// Here we deal with application errors that are either MOVED or ASK
	msg := err.Error()
	moved := strings.HasPrefix(msg, "MOVED ")
	ask = strings.HasPrefix(msg, "ASK ")
	if moved || ask {
		_, addr := redirectInfo(msg)
		c.callCh <- func(c *Cluster) {
			select {
			case c.MissCh <- struct{}{}:
			default:
			}
		}

		// If we've already called Reset and we're getting MOVED again than the
		// cluster is having problems, likely telling us to try a node which is
		// not reachable. Not much which can be done at this point
		if haveReset {
			return errorRespf("Cluster doesn't make sense, %s might be gone", addr)
		}
		if resetErr := c.Reset(); resetErr != nil {
			return errorRespf("Could not get cluster info: %s", resetErr)
		}
		haveReset = true

		// At this point addr is whatever redis told us it should be. However,
		// if we can't get a connection to it we'll never actually mark it as
		// tried, resulting in an infinite loop. Here we mark it as tried
		// regardless of if it actually was or not
		tried = justTried(tried, addr)

		client, getErr := c.getConn("", addr)
		if getErr != nil {
			return errorResp(getErr)
		}
		return c.clientCmd(client, cmd, args, ask, tried, haveReset)
	}

	// It's a normal application error (like WRONG KEY TYPE or whatever), return
	// that to the client
	return r
}
func migrateCashpoints(cpDb *sql.DB, redisCli *redis.Client) {
	var cashpointsCount int
	err := cpDb.QueryRow(`SELECT COUNT(*) FROM cashpoints`).Scan(&cashpointsCount)
	if err != nil {
		log.Fatalf("migrate: cashpoints: %v\n", err)
	}

	rows, err := cpDb.Query(`SELECT id, type, bank_id, town_id,
                                    longitude, latitude,
                                    address, address_comment,
                                    metro_name, free_access,
                                    main_office, without_weekend,
                                    round_the_clock, works_as_shop,
                                    schedule_general, tel, additional,
                                    rub, usd, eur, cash_in FROM cashpoints`)
	if err != nil {
		log.Fatalf("migrate: cashpoints: %v\n", err)
	}

	currentCashpointIndex := 1
	for rows.Next() {
		cp := new(CashPoint)
		err = rows.Scan(&cp.Id, &cp.Type, &cp.BankId, &cp.TownId,
			&cp.Longitude, &cp.Latitude,
			&cp.Address, &cp.AddressComment,
			&cp.MetroName, &cp.FreeAccess,
			&cp.MainOffice, &cp.WithoutWeekend,
			&cp.RoundTheClock, &cp.WorksAsShop,
			&cp.Schedule, &cp.Tel, &cp.Additional,
			&cp.Rub, &cp.Usd, &cp.Eur, &cp.CashIn)
		if err != nil {
			log.Fatal(err)
		}

		cashpointIdStr := strconv.FormatUint(uint64(cp.Id), 10)
		townIdStr := strconv.FormatUint(uint64(cp.TownId), 10)
		bankIdStr := strconv.FormatUint(uint64(cp.BankId), 10)

		jsonData, err := json.Marshal(cp)
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SET", "cp:"+cashpointIdStr, string(jsonData)).Err
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SET", "cp:"+cashpointIdStr+":version", 1).Err
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("GEOADD", "cashpoints", cp.Longitude, cp.Latitude, cp.Id).Err
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SADD", "town:"+townIdStr+":cp", cp.Id).Err
		if err != nil {
			log.Fatal(err)
		}

		err = redisCli.Cmd("SADD", "bank:"+bankIdStr+":cp", cp.Id).Err
		if err != nil {
			log.Fatal(err)
		}

		currentCashpointIndex++

		if currentCashpointIndex%500 == 0 {
			log.Printf("[%d/%d] Cashpoints processed\n", currentCashpointIndex, cashpointsCount)
		}
	}
	log.Printf("[%d/%d] Cashpoints processed\n", cashpointsCount, cashpointsCount)
}
예제 #20
0
func cleanupRedis(client *redis.Client) {
	if client != nil {
		defer client.Close()
	}
}