Beispiel #1
0
func add(r *http.Request, u_id uint64) (uint64, error) {
	// get an id
	id, err := NoeqClient.GenOne()
	if err != nil {
		log.Println("noeq err", err)
		return 0, err
	}
	// get the data
	uri := r.FormValue("uri")
	title := r.FormValue("title")
	description := r.FormValue("description")
	keywords := r.FormValue("keywords")
	if len(keywords) == 0 {
		keywords = uri
	}
	// try to set it
	res, rerr := RedisClient.Setnx("discussions:"+uri, id)
	if rerr != nil {
		log.Println("redis err", rerr)
		return 0, rerr
	} else if !res {
		// someone beat us to it
		log.Println("exists err", err)
		return getId(uri)
	}
	// add to solr
	ds := make([]interface{}, 1)
	ds[1] = &DiscussionDoc{
		Id:          id,
		Uri:         strings.Split(uri, "/"),
		Title:       title,
		Description: description,
		Keywords:    keywords,
	}
	_, err = SolrDiscuss.Update(ds)
	if err != nil {
		// roll it back
		log.Println("solr err", err)
		RedisClient.Del("discussions:" + uri)
		return 0, rerr
	}
	prc := godis.NewPipeClientFromClient(RedisClient)
	prc.Multi()
	// set the discussion record
	var discussionData = make(map[string]string)
	discussionData[fmt.Sprintf("discussion:%d:uri", id)] = uri
	discussionData[fmt.Sprintf("discussion:%d:u_id", id)] = strconv.FormatUint(u_id, 10)
	discussionData[fmt.Sprintf("discussion:%d:title", id)] = title
	discussionData[fmt.Sprintf("discussion:%d:description", id)] = description
	discussionData[fmt.Sprintf("discussion:%d:keywords", id)] = keywords
	rerr = prc.Mset(discussionData)
	if rerr != nil {
		// roll it back
		prc.Discard()
		RedisClient.Del("discussions:" + uri)
		// roll back solr too
		return 0, rerr
	}
	err = defaultDiscussion(prc, id)
	if err != nil {
		prc.Discard()
		RedisClient.Del("discussions:" + uri)
		// roll back solr too
		return 0, rerr
	}
	err = defaultCreator(prc, u_id, id)
	if err != nil {
		prc.Discard()
		RedisClient.Del("discussions:" + uri)
		// roll back solr too
		return 0, rerr
	}
	prc.Exec()
	return id, nil
}
Beispiel #2
0
func add(r *http.Request, u_id uint64) (uint64, error) {
	// get an id
	ids, err := shared.NoeqClient.Gen(2)
	if err != nil {
		return 0, err
	}
	t_id := ids[0]
	p_id := ids[1]
	ts := strconv.FormatInt(time.Now().Unix(), 10)

	// get the data
	ds_id := r.FormValue("d_id")
	title := r.FormValue("title")
	post := r.FormValue("post")

	if ds_id == "" {
		return 0, fmt.Errorf("Need a discussion id")
	} else if post == "" {
		return 0, fmt.Errorf("Need a post")
	}
	d_id, err := strconv.ParseUint(ds_id, 10, 64)
	if err != nil {
		return 0, err
	}

	// add to solr
	var ps []interface{}
	p := &shared.PostDoc{
		Id:    p_id,
		DId:   d_id,
		TId:   t_id,
		Title: title,
		Post:  post,
	}
	ps = append(ps, p)
	_, err = shared.SolrPosts.Update(ps)
	if err != nil {
		log.Println("SOLR ERROR:", err)
		// roll it back
		return 0, err
	}

	// set the discussion record
	prc := godis.NewPipeClientFromClient(shared.RedisClient)
	prc.Multi()

	var topicData = make(map[string]string)
	topicData[fmt.Sprintf("topic:%d:d_id", t_id)] = ds_id
	topicData[fmt.Sprintf("topic:%d:u_id", t_id)] = strconv.FormatUint(u_id, 10)
	topicData[fmt.Sprintf("topic:%d:last_u_id", t_id)] = strconv.FormatUint(u_id, 10)
	topicData[fmt.Sprintf("topic:%d:title", t_id)] = title
	topicData[fmt.Sprintf("topic:%d:last_p_id", t_id)] = strconv.FormatUint(p_id, 10)
	topicData[fmt.Sprintf("topic:%d:lastpost", t_id)] = ts
	topicData[fmt.Sprintf("topic:%d:score", t_id)] = "1000"
	topicData[fmt.Sprintf("post:%d:d_id", p_id)] = ds_id
	topicData[fmt.Sprintf("post:%d:t_id", p_id)] = strconv.FormatUint(t_id, 10)
	topicData[fmt.Sprintf("post:%d:u_id", p_id)] = strconv.FormatUint(u_id, 10)
	topicData[fmt.Sprintf("post:%d:post", p_id)] = post
	topicData[fmt.Sprintf("post:%d:ts", p_id)] = ts
	topicData[fmt.Sprintf("post:%d:score", p_id)] = "1000"
	rerr := prc.Mset(topicData)
	if rerr != nil {
		// roll it back
		prc.Discard()
		return 0, rerr
	}
	// go routine?
	_, rerr = prc.Zadd(fmt.Sprintf("topic:%d:posts", t_id), 1000, p_id)
	if rerr != nil {
		// roll it back
		prc.Discard()
		return 0, rerr
	}
	_, rerr = prc.Incr(fmt.Sprintf("topic:%d:numposts", t_id))
	if rerr != nil {
		// roll it back
		prc.Discard()
		return 0, rerr
	}
	_, rerr = prc.Zadd(fmt.Sprintf("discussion:%d:topics", d_id), 1000, t_id)
	if rerr != nil {
		// roll it back
		prc.Discard()
		return 0, rerr
	}
	_, rerr = prc.Incr(fmt.Sprintf("discussion:%d:numtopics", d_id))
	if rerr != nil {
		// roll it back
		prc.Discard()
		return 0, rerr
	}
	prc.Sadd(fmt.Sprintf("topic:%d:users", t_id), u_id)
	// update some user stats
	prc.Sadd(fmt.Sprintf("user:%d:topics:%d", u_id, d_id), t_id)
	prc.Sadd(fmt.Sprintf("user:%d:posts:%d", u_id, t_id), p_id)
	// /go routine?
	prc.Exec()
	return t_id, nil
}
Beispiel #3
0
func add(r *http.Request, u_id uint64) (uint64, error) {
	// get an id
	id, err := NoeqClient.GenOne()
	if err != nil {
		return 0, err
	}
	// get the data
	ts_id := r.FormValue("t_id")
	ps_id := r.FormValue("p_id")
	post := r.FormValue("post")
	if ts_id == "" {
		return 0, fmt.Errorf("Need a thread id")
	} else if post == "" {
		return 0, fmt.Errorf("Need a post")
	}
	var (
		t_id uint64 = 0
		p_id uint64 = 0
	)
	t_id, err = strconv.ParseUint(ts_id, 10, 64)
	if err != nil {
		return 0, err
	}
	if ps_id != "" {
		p_id, err = strconv.ParseUint(ps_id, 10, 64)
		if err != nil {
			return 0, err
		}
	}
	ts := strconv.FormatInt(time.Now().Unix(), 10)
	// get the discussion id for completeness
	de, rerr := RedisClient.Get(fmt.Sprintf("topic:%d:d_id", t_id))
	if rerr != nil {
		return 0, rerr
	}
	d_id := uint64(de.Int64())
	// add to solr
	var ps []interface{}
	p := &PostDoc{
		Id:   id,
		DId:  d_id,
		TId:  t_id,
		Post: post,
	}
	if p_id != 0 {
		p.PId = p_id
	}
	ps = append(ps, p)
	_, err = SolrPosts.Update(ps)
	if err != nil {
		log.Println("SOLR ERROR:", err)
		// roll it back
		return 0, rerr
	}

	// set the discussion record
	prc := godis.NewPipeClientFromClient(RedisClient)
	prc.Multi()

	var postData = make(map[string]string)
	postData[fmt.Sprintf("topic:%d:last_p_id", t_id)] = strconv.FormatUint(id, 10)
	postData[fmt.Sprintf("topic:%d:last_u_id", t_id)] = strconv.FormatUint(u_id, 10)
	postData[fmt.Sprintf("topic:%d:lastpost", t_id)] = ts
	postData[fmt.Sprintf("post:%d:d_id", id)] = de.String()
	postData[fmt.Sprintf("post:%d:t_id", id)] = ts_id
	postData[fmt.Sprintf("post:%d:u_id", id)] = strconv.FormatUint(u_id, 10)
	postData[fmt.Sprintf("post:%d:post", id)] = post
	postData[fmt.Sprintf("post:%d:ts", id)] = ts
	postData[fmt.Sprintf("post:%d:score", id)] = "1000"
	if p_id == 0 {
		// top level post
		_, rerr := prc.Zadd(fmt.Sprintf("topic:%d:posts", t_id), 1000, id)
		if rerr != nil {
			// roll it back
			prc.Discard()
			return 0, rerr
		}
	} else {
		// reply to a post
		postData[fmt.Sprintf("post:%d:p_id", id)] = ps_id
		_, rerr := prc.Zadd(fmt.Sprintf("post:%d:posts", p_id), 1000, id)
		if rerr != nil {
			// roll it back
			prc.Discard()
			return 0, rerr
		}
		_, rerr = prc.Incr(fmt.Sprintf("post:%d:numposts", p_id))
		if rerr != nil {
			// roll it back
			prc.Discard()
			return 0, rerr
		}
		// figure out where to bump this guy
		ks := make([]string, 2)
		ks[0] = fmt.Sprintf("post:%d:t_id", p_id)
		ks[1] = fmt.Sprintf("post:%d:p_id", p_id)
		fs, _ := RedisClient.Mget(ks...)
		pt_id := uint64(fs.Elems[0].Elem.Int64())
		pp_id := uint64(fs.Elems[1].Elem.Int64())
		if pp_id > 0 {
			// a reply also
			prc.Zincrby(fmt.Sprintf("posts:%d:posts", pp_id), 1, p_id)
		} else {
			// top level
			prc.Zincrby(fmt.Sprintf("topic:%d:posts", pt_id), 1, p_id)
		}
	}
	prc.Zincrby(fmt.Sprintf("discussion:%d:topics", d_id), 1, t_id)
	prc.Sadd(fmt.Sprintf("user:%d:posts:%d", u_id, t_id), id)
	prc.Sadd(fmt.Sprintf("topic:%d:users", t_id), u_id)
	_, rerr = prc.Incr(fmt.Sprintf("topic:%d:numposts", t_id))
	if rerr != nil {
		// roll it back
		prc.Discard()
		return 0, rerr
	}
	rerr = prc.Mset(postData)
	if rerr != nil {
		// roll it back
		prc.Discard()
		return 0, rerr
	}
	prc.Exec()
	return id, nil
}