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 }
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 }
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 }