func main() { runtime.GOMAXPROCS(runtime.NumCPU()) var config workload.Config workload.ReadConfig(&config) admin := api.SyncGatewayClient{} admin.Init(config.Hostname, config.Database) users := [][]interface{}{} for user := range workload.UserIterator(config.NumPullers, config.NumPushers) { cookie := createSession(&admin, user, config) users = append(users, []interface{}{user, cookie}) } rampUpDelay := config.RampUpIntervalMs / (config.NumPullers + config.NumPushers) rampUpDelayMs := time.Duration(rampUpDelay) * time.Millisecond wg := sync.WaitGroup{} for _, user := range users { wg := sync.WaitGroup{} go runUser(user[0].(workload.User), config, user[1].(http.Cookie), &wg) wg.Add(1) time.Sleep(rampUpDelayMs) } if config.RunTimeMs > 0 { time.Sleep(time.Duration(config.RunTimeMs-config.RampUpIntervalMs) * time.Millisecond) log.Println("Shutting down clients") } else { wg.Wait() } }
func createSession(admin *api.SyncGatewayClient, user workload.User, config workload.Config) http.Cookie { userMeta := api.UserAuth{Name: user.Name, Password: "******", AdminChannels: []string{user.Channel}} admin.AddUser(user.Name, userMeta) session := api.Session{Name: user.Name, TTL: 2592000} // 1 month return admin.CreateSession(user.Name, session) }
func main() { runtime.GOMAXPROCS(runtime.NumCPU()) var config workload.Config workload.ReadConfig(&config) s := seriesly.SerieslyClient{} s.Init(config.SerieslyHostname, "sync_latency"+config.SerieslyDatabase) c := api.SyncGatewayClient{} c.Init(config.Hostname, config.Database) user := api.UserAuth{"collector", "password", []string{"stats"}} c.AddUser(user.Name, user) session := api.Session{Name: user.Name, TTL: 2592000} cookie := c.CreateSession(user.Name, session) c.AddCookie(&cookie) activeSamplers = 0 for doc := range workload.DocIterator(0, DocsPerUser, config.DocSize, "stats") { if activeSamplers < MaxSamplers { activeSamplers++ go measureLatency(&c, &s, doc) } time.Sleep(time.Duration(1000) * time.Millisecond) } }
func runUser(user workload.User, config workload.Config, cookie http.Cookie, wg *sync.WaitGroup) { c := api.SyncGatewayClient{} c.Init(config.Hostname, config.Database) c.AddCookie(&cookie) log.Printf("Starting new %s (%s)", user.Type, user.Name) if user.Type == "pusher" { go workload.RunPusher(&c, user.Channel, config.DocSize, user.SeqId, config.SleepTimeMs, wg) } else { go workload.RunPuller(&c, user.Channel, user.Name, wg) } }
func RunPusher(c *api.SyncGatewayClient, channel string, size, seqId, sleepTime int, wg *sync.WaitGroup) { defer wg.Done() for doc := range DocIterator(seqId*DocsPerUser, (seqId+1)*DocsPerUser, size, channel) { revsDiff := map[string][]string{ doc.Id: []string{doc.Rev}, } c.PostRevsDiff(revsDiff) docs := map[string]interface{}{ "docs": []api.Doc{doc}, "new_edits": false, } c.PostBulkDocs(docs) time.Sleep(time.Duration(sleepTime) * time.Millisecond) } }
func RunPuller(c *api.SyncGatewayClient, channel, name string, wg *sync.WaitGroup) { defer wg.Done() lastSeq := fmt.Sprintf("%s:%d", channel, int(math.Max(c.GetLastSeq()-MaxFirstFetch, 0))) lastSeq = readFeed(c, "normal", lastSeq) checkpointSeqId := int64(0) for { timer := time.AfterFunc(CheckpointInverval, func() { checkpoint := api.Checkpoint{LastSequence: lastSeq} chechpointHash := fmt.Sprintf("%s-%s", name, Hash(strconv.FormatInt(checkpointSeqId, 10))) c.SaveCheckpoint(chechpointHash, checkpoint) checkpointSeqId += 1 }) lastSeq = readFeed(c, "longpoll", lastSeq) timer.Stop() } }
func readFeed(c *api.SyncGatewayClient, feedType, lastSeq string) string { feed := c.GetChangesFeed(feedType, lastSeq) ids := []string{} for _, doc := range feed["results"].([]interface{}) { ids = append(ids, doc.(map[string]interface{})["id"].(string)) } if len(ids) == 1 { c.GetSingleDoc(ids[0]) } else { for docs := range RevsIterator(ids) { c.GetBulkDocs(docs) } } return feed["last_seq"].(string) }
func measurePullLatency(c *api.SyncGatewayClient, doc api.Doc) (int64, float64) { t0 := time.Now() c.GetSingleDoc(doc.Id) t1 := time.Now().Round(100 * time.Microsecond) return t0.UnixNano(), float64(t1.Sub(t0.Round(100*time.Microsecond))) / math.Pow10(6) }