func TriggerBatchProcessing(c appengine.Context, article ArticleId) error { // Instead of submitting a task to match incoming bids, resulting in one task per bid, // we collect bids for up to two seconds and batch-process them afterwards. semaphoreKey := "semaphore-" + string(article) if semaphore, err := memcache.Increment(c, semaphoreKey, 1, 0); err != nil { return err } else if semaphore >= 2 { c.Infof("Batch processing already triggered for article %v", article) memcache.IncrementExisting(c, semaphoreKey, -1) return nil } else { time.Sleep(1 * time.Second) c.Infof("Starting batch processing...") memcache.IncrementExisting(c, semaphoreKey, -1) time_before := time.Now() matchingErr := MatchIncomingBids(c, article) time_after := time.Now() duration := time_after.Sub(time_before) if duration > 1000*time.Millisecond { c.Errorf("Batch processing finished after %v. Limit exceeded!", duration) } else if duration > 500*time.Millisecond { c.Warningf("Batch processing finished after %v. Limit in danger.", duration) } else { c.Infof("Batch processing finished after %v.", duration) } return matchingErr } }
func IncrExisting(c TransactionContext, key string, delta int64) (newValue uint64, err error) { k, err := Keyify(key) if err != nil { return } if newValue, err = memcache.IncrementExisting(c, k, delta); err != nil { err = errors.Errorf("Error doing IncrementExisting %#v: %v", k, err) return } return }