コード例 #1
1
ファイル: time_index.go プロジェクト: rwcarlsen/cas
// IndexNear returns the index of the blob created closed to time t. The actual
// blob ref can be retrieved by passing the index to RefAt.
func (ti *TimeIndex) IndexNear(t time.Time) int {
	ti.lock.RLock()
	defer ti.lock.RUnlock()

	down, up := 0, len(ti.entries)-1
	if up < 0 {
		return -1
	}

	pivot, done := split(down, up)
	for !done {
		pivt := ti.entries[pivot].tm

		if t.After(pivt) {
			down, up = pivot, up
		} else {
			down, up = down, pivot
		}

		pivot, done = split(down, up)
	}

	lowt := ti.entries[down].tm
	upt := ti.entries[up].tm
	lowdiff := int64(time.Since(lowt)) - int64(time.Since(t))
	updiff := int64(time.Since(t)) - int64(time.Since(upt))
	if updiff < lowdiff {
		return up
	}
	return down
}
コード例 #2
0
ファイル: fernet.go プロジェクト: bmizerany/fernet
// if msg is nil, decrypts in place and returns a slice of tok.
func verify(msg, tok []byte, ttl time.Duration, now time.Time, k *Key) []byte {
	if len(tok) < 1 || tok[0] != version {
		return nil
	}
	n := len(tok) - sha256.Size
	var hmac [sha256.Size]byte
	genhmac(hmac[:0], tok[:n], k.signBytes())
	if subtle.ConstantTimeCompare(tok[n:], hmac[:]) != 1 {
		return nil
	}
	ts := time.Unix(int64(binary.BigEndian.Uint64(tok[1:])), 0)
	if now.After(ts.Add(ttl)) || ts.After(now.Add(maxClockSkew)) {
		return nil
	}
	pay := tok[payOffset : len(tok)-sha256.Size]
	if len(pay)%aes.BlockSize != 0 {
		return nil
	}
	if msg != nil {
		copy(msg, pay)
		pay = msg
	}
	bc, _ := aes.NewCipher(k.cryptBytes())
	iv := tok[9:][:aes.BlockSize]
	cipher.NewCBCDecrypter(bc, iv).CryptBlocks(pay, pay)
	return unpad(pay)
}
コード例 #3
0
ファイル: rateinterval.go プロジェクト: bhepp/cgrates
// Returns wheter the Timing is active at the specified time
func (rit *RITiming) IsActiveAt(t time.Time) bool {
	// check for years
	if len(rit.Years) > 0 && !rit.Years.Contains(t.Year()) {
		return false
	}
	// check for months
	if len(rit.Months) > 0 && !rit.Months.Contains(t.Month()) {
		return false
	}
	// check for month days
	if len(rit.MonthDays) > 0 && !rit.MonthDays.Contains(t.Day()) {
		return false
	}
	// check for weekdays
	if len(rit.WeekDays) > 0 && !rit.WeekDays.Contains(t.Weekday()) {
		return false
	}
	//log.Print("Time: ", t)

	//log.Print("Left Margin: ", rit.getLeftMargin(t))
	// check for start hour
	if t.Before(rit.getLeftMargin(t)) {
		return false
	}

	//log.Print("Right Margin: ", rit.getRightMargin(t))
	// check for end hour
	if t.After(rit.getRightMargin(t)) {
		return false
	}
	return true
}
コード例 #4
0
ファイル: account_key.go プロジェクト: pedronis/snappy
// isKeyValidAt returns whether the account key is valid at 'when' time.
func (ak *AccountKey) isKeyValidAt(when time.Time) bool {
	valid := when.After(ak.since) || when.Equal(ak.since)
	if valid && !ak.until.IsZero() {
		valid = when.Before(ak.until)
	}
	return valid
}
コード例 #5
0
ファイル: rulecache.go プロジェクト: phuslu/adblock
func (c *RuleCache) buildAll(refresh bool) (*RuleSet, time.Time, error) {
	matcher := adblock.NewMatcher()
	rules := []string{}
	read := 0
	oldest := time.Time{}
	for _, url := range c.urls {
		r, date, err := c.load(url, refresh)
		if err != nil {
			return nil, oldest, err
		}
		if oldest.After(date) {
			oldest = date
		}
		log.Printf("building rules from %s", url)
		built, n, err := buildOne(r, matcher)
		r.Close()
		if err != nil {
			return nil, oldest, err
		}
		rules = append(rules, built...)
		read += n
	}
	log.Printf("blacklists built: %d / %d added\n", len(rules), read)
	return &RuleSet{
		Rules:   rules,
		Matcher: matcher,
	}, oldest, nil
}
コード例 #6
0
ファイル: Period.go プロジェクト: iizotop/kmg
// start must before or equal end
func NewPeriod(Start time.Time, End time.Time) (period Period, err error) {
	if Start.After(End) {
		err = fmt.Errorf("[kmgTime.NewPeriod] Start.After(End) Start:%s End:%s", Start, End)
		return
	}
	return Period{Start: Start, End: End}, nil
}
コード例 #7
0
ファイル: timeseries.go プロジェクト: 2722/lantern
// ComputeRange computes a specified number of values into a slice using
// the observations recorded over the specified time period. The return
// values are approximate if the start or finish times don't fall on the
// bucket boundaries at the same level or if the number of buckets spanning
// the range is not an integral multiple of num.
func (ts *timeSeries) ComputeRange(start, finish time.Time, num int) []Observable {
	if start.After(finish) {
		log.Printf("timeseries: start > finish, %v>%v", start, finish)
		return nil
	}

	if num < 0 {
		log.Printf("timeseries: num < 0, %v", num)
		return nil
	}

	results := make([]Observable, num)

	for _, l := range ts.levels {
		if !start.Before(l.end.Add(-l.size * time.Duration(ts.numBuckets))) {
			ts.extract(l, start, finish, num, results)
			return results
		}
	}

	// Failed to find a level that covers the desired range.  So just
	// extract from the last level, even if it doesn't cover the entire
	// desired range.
	ts.extract(ts.levels[len(ts.levels)-1], start, finish, num, results)

	return results
}
コード例 #8
0
ファイル: gametime.go プロジェクト: gdelaney/WMS
func isGametime(t time.Time) bool {
	var start, end time.Time
	year := t.Year()
	month := t.Month()
	day := t.Day()
	hour := t.Hour()
	loc := t.Location()
	switch t.Weekday() {
	case time.Monday, time.Tuesday, time.Wednesday, time.Thursday:
		start = time.Date(year, month, day, 20, 0, 0, 0, loc)
		end = time.Date(year, month, day, 23, 59, 59, 999999999, loc)
	case time.Friday:
		start = time.Date(year, month, day, 19, 0, 0, 0, loc)
		end = time.Date(year, month, day+1, 2, 59, 59, 999999999, loc)
	case time.Saturday:
		if hour < 3 {
			start = time.Date(year, month, day-1, 23, 59, 59, 999999999, loc)
			end = time.Date(year, month, day, 2, 59, 59, 999999999, loc)
		} else {
			start = time.Date(year, month, day, 15, 0, 0, 0, loc)
			end = time.Date(year, month, day+1, 2, 59, 59, 999999999, loc)
		}
	case time.Sunday:
		if hour < 3 {
			start = time.Date(year, month, day-1, 23, 59, 59, 999999999, loc)
			end = time.Date(year, month, day, 2, 59, 59, 999999999, loc)
		} else {
			start = time.Date(year, month, day, 17, 0, 0, 0, loc)
			end = time.Date(year, month, day, 23, 59, 59, 999999999, loc)
		}
	}
	return (t.After(start) && t.Before(end))
}
コード例 #9
0
ファイル: api.go プロジェクト: ajres/gateload
func logPushToSubscriberTime(createdTime *time.Time, wakeup time.Time) {
	if wakeup.After(*createdTime) {
		OperationCallback("PushToSubscriberBackfill", wakeup, nil)
	} else {
		OperationCallback("PushToSubscriberInteractive", *createdTime, nil)
	}
}
コード例 #10
0
ファイル: utils.go プロジェクト: catanm/gms
func LinkGpsToImages(track m.Track) {
	var possibleImages []m.Image
	m.GetDB("Image").Find(bson.M{"date": bson.M{"$lte": track.MaxDate, "$gte": track.MinDate}, "user": track.User}).All(&possibleImages)

	if len(possibleImages) == 0 {
		return
	}

	var best m.Coordinate

	var before time.Time
	var after time.Time

	for i := 0; i < len(possibleImages); i++ {
		before = possibleImages[i].Date.Add(time.Duration(-10 * time.Second))
		after = possibleImages[i].Date.Add(time.Duration(10 * time.Second))

		for j := 0; j < len(track.Coordinates); j++ {
			if before.Before(track.Coordinates[j].Date) && after.After(track.Coordinates[j].Date) {
				best = track.Coordinates[j]
				break
			}
		}
		if best.Lat != "" && best.Lon != "" {
			possibleImages[i].Lat = best.Lat
			possibleImages[i].Lon = best.Lon
			err := m.GetDB("Image").UpdateId(possibleImages[i].Id, possibleImages[i])
			if err != nil {
				log.Error("LinkGpdToImages, update, " + err.Error())
			}
		}
	}
}
コード例 #11
0
ファイル: filter.go プロジェクト: kpabba/rclone
// Include returns whether this object should be included into the
// sync or not
func (f *Filter) Include(remote string, size int64, modTime time.Time) bool {
	// filesFrom takes precedence
	if f.files != nil {
		_, include := f.files[remote]
		return include
	}
	if !f.ModTimeFrom.IsZero() && modTime.Before(f.ModTimeFrom) {
		return false
	}
	if !f.ModTimeTo.IsZero() && modTime.After(f.ModTimeTo) {
		return false
	}
	if f.MinSize != 0 && size < f.MinSize {
		return false
	}
	if f.MaxSize != 0 && size > f.MaxSize {
		return false
	}
	for _, rule := range f.rules {
		if rule.Match(remote) {
			return rule.Include
		}
	}
	return true
}
コード例 #12
0
ファイル: calls.go プロジェクト: kevinburke/twilio-go
// GetCallsInRange gets an Iterator containing calls in the range [start, end),
// optionally further filtered by data. GetCallsInRange panics if start is not
// before end. Any date filters provided in data will be ignored. If you have
// an end, but don't want to specify a start, use twilio.Epoch for start. If
// you have a start, but don't want to specify an end, use twilio.HeatDeath for
// end.
//
// Assumes that Twilio returns resources in chronological order, latest
// first. If this assumption is incorrect, your results will not be correct.
//
// Returned CallPages will have at most PageSize results, but may have fewer,
// based on filtering.
func (c *CallService) GetCallsInRange(start time.Time, end time.Time, data url.Values) CallPageIterator {
	if start.After(end) {
		panic("start date is after end date")
	}
	d := url.Values{}
	if data != nil {
		for k, v := range data {
			d[k] = v
		}
	}
	d.Del("StartTime")
	d.Del("Page") // just in case
	if start != Epoch {
		startFormat := start.UTC().Format(APISearchLayout)
		d.Set("StartTime>", startFormat)
	}
	if end != HeatDeath {
		// If you specify "StartTime<=YYYY-MM-DD", the *latest* result returned
		// will be midnight (the earliest possible second) on DD. We want all
		// of the results for DD so we need to specify DD+1 in the API.
		//
		// TODO validate midnight-instant math more closely, since I don't think
		// Twilio returns the correct results for that instant.
		endFormat := end.UTC().Add(24 * time.Hour).Format(APISearchLayout)
		d.Set("StartTime<", endFormat)
	}
	iter := NewPageIterator(c.client, d, callsPathPart)
	return &callDateIterator{
		start: start,
		end:   end,
		p:     iter,
	}
}
コード例 #13
0
ファイル: times.go プロジェクト: dropbox/dbxcli
// CustomRelTime formats a time into a relative string.
//
// It takes two times two labels and a table of relative time formats.
// In addition to the generic time delta string (e.g. 5 minutes), the
// labels are used applied so that the label corresponding to the
// smaller time is applied.
func CustomRelTime(a, b time.Time, albl, blbl string, magnitudes []RelTimeMagnitude) string {
	lbl := albl
	diff := b.Sub(a)

	if a.After(b) {
		lbl = blbl
		diff = a.Sub(b)
	}

	n := sort.Search(len(magnitudes), func(i int) bool {
		return magnitudes[i].D >= diff
	})

	mag := magnitudes[n]
	args := []interface{}{}
	escaped := false
	for _, ch := range mag.Format {
		if escaped {
			switch ch {
			case 's':
				args = append(args, lbl)
			case 'd':
				args = append(args, diff/mag.DivBy)
			}
			escaped = false
		} else {
			escaped = ch == '%'
		}
	}
	return fmt.Sprintf(mag.Format, args...)
}
コード例 #14
0
ファイル: fernet.go プロジェクト: uhoh-itsmaciek/fernet-1
func verify(p []byte, ttl time.Duration, now time.Time, k *Key) []byte {
	if *k == (Key{}) {
		return nil
	}
	tok := b64dec(p)
	r := bytes.NewBuffer(tok)
	var h struct {
		HMAC     [sha256.Size]byte
		IssuedAt int64
		IV       [aes.BlockSize]byte
	}
	err := binary.Read(r, binary.BigEndian, &h)
	if err != nil {
		return nil
	}
	if subtle.ConstantTimeCompare(h.HMAC[:], genhmac(tok[len(h.HMAC):], k.signBytes())) != 1 {
		return nil
	}
	ts := time.Unix(h.IssuedAt, 0)
	if now.After(ts.Add(ttl)) || ts.After(now.Add(maxClockSkew)) {
		return nil
	}
	msg := r.Bytes()
	if len(msg)%aes.BlockSize != 0 {
		return nil
	}
	bc, _ := aes.NewCipher(k.cryptBytes())
	cipher.NewCBCDecrypter(bc, h.IV[:]).CryptBlocks(msg, msg)
	return unpad(msg)
}
コード例 #15
0
ファイル: user.go プロジェクト: niemeyer/snapd
// ValidAt returns whether the system-user is valid at 'when' time.
func (su *SystemUser) ValidAt(when time.Time) bool {
	valid := when.After(su.since) || when.Equal(su.since)
	if valid {
		valid = when.Before(su.until)
	}
	return valid
}
コード例 #16
0
ファイル: main.go プロジェクト: carriercomm/logsclient
// downloadLogs connects to log downloading service and saves
// logs to local disk.
func downloadLogs() {
	var (
		// Global interval to download.
		startT = time.Unix(*start, 0).UTC()
		endT   = time.Unix(*end, 0).UTC()

		// Interval to download for current file. Rounds down to the closest minute
		// to ensure that you do not get files that cross intervals
		s = startT.Truncate(time.Minute)
		e time.Time
	)
	for {
		if !s.Before(endT) {
			return
		}
		e = s.Add(*interval)
		if e.After(endT) {
			e = endT
		}
		saveLogs(s, e)
		// saves the checkpoint file after the file is successfully downloaded
		saveCheckpoint(e)
		s = s.Add(*interval)
	}
}
コード例 #17
0
ファイル: time.go プロジェクト: 0x263b/Porygon2
// RelTime formats a time into a relative string.
//
// It takes two times and two labels.  In addition to the generic time
// delta string (e.g. 5 minutes), the labels are used applied so that
// the label corresponding to the smaller time is applied.
//
// RelTime(timeInPast, timeInFuture, "earlier", "later") -> "3 weeks earlier"
func RelTime(a, b time.Time, albl, blbl string) string {
	lbl := albl
	diff := b.Unix() - a.Unix()

	after := a.After(b)
	if after {
		lbl = blbl
		diff = a.Unix() - b.Unix()
	}

	n := sort.Search(len(magnitudes), func(i int) bool {
		return magnitudes[i].d > diff
	})

	mag := magnitudes[n]
	args := []interface{}{}
	escaped := false
	for _, ch := range mag.format {
		if escaped {
			switch ch {
			case '%':
			case 's':
				args = append(args, lbl)
			case 'd':
				args = append(args, diff/mag.divby)
			}
			escaped = false
		} else {
			escaped = ch == '%'
		}
	}
	return fmt.Sprintf(mag.format, args...)
}
コード例 #18
0
ファイル: dedupermain.go プロジェクト: dylanpoe/golang.org
// loopFetchOnly is a version of loop that includes only the logic
// that calls Fetch.
func (s *sub) loopFetchOnly() {
	// STARTFETCHONLY OMIT
	var pending []Item // appended by fetch; consumed by send
	var next time.Time // initially January 1, year 0
	var err error
	for {
		var fetchDelay time.Duration // initally 0 (no delay)
		if now := time.Now(); next.After(now) {
			fetchDelay = next.Sub(now)
		}
		startFetch := time.After(fetchDelay)

		select {
		case <-startFetch:
			var fetched []Item
			fetched, next, err = s.fetcher.Fetch()
			if err != nil {
				next = time.Now().Add(10 * time.Second)
				break
			}
			pending = append(pending, fetched...)
		}
	}
	// STOPFETCHONLY OMIT
}
コード例 #19
0
ファイル: timeseries.go プロジェクト: 2722/lantern
// advance cycles the buckets at each level until the latest bucket in
// each level can hold the time specified.
func (ts *timeSeries) advance(t time.Time) {
	if !t.After(ts.levels[0].end) {
		return
	}
	for i := 0; i < len(ts.levels); i++ {
		level := ts.levels[i]
		if !level.end.Before(t) {
			break
		}

		// If the time is sufficiently far, just clear the level and advance
		// directly.
		if !t.Before(level.end.Add(level.size * time.Duration(ts.numBuckets))) {
			for _, b := range level.buckets {
				ts.resetObservation(b)
			}
			level.end = time.Unix(0, (t.UnixNano()/level.size.Nanoseconds())*level.size.Nanoseconds())
		}

		for t.After(level.end) {
			level.end = level.end.Add(level.size)
			level.newest = level.oldest
			level.oldest = (level.oldest + 1) % ts.numBuckets
			ts.resetObservation(level.buckets[level.newest])
		}

		t = level.end
	}
}
コード例 #20
0
ファイル: intervals.go プロジェクト: ubleipzig/oaimi
func (w Window) makeWindows(left, right TimeShiftFunc) []Window {
	var ws []Window
	if w.From.After(w.Until) {
		return ws
	}
	var start, end time.Time
	from := w.From
	for {
		switch {
		case len(ws) == 0:
			start = now.New(w.From).BeginningOfDay()
		default:
			start = left(from)
		}
		end = right(from)
		if end.After(w.Until) {
			// discard end and use the end of day of until
			ws = append(ws, Window{From: start, Until: now.New(w.Until).EndOfDay()})
			break
		}
		ws = append(ws, Window{From: start, Until: end})
		from = end.Add(oneDay)
	}
	return ws
}
コード例 #21
0
ファイル: loader.go プロジェクト: mikhailborodin/gopnik
func LoadPerf(fName string, since, until time.Time) ([]PerfLogEntry, error) {
	fIn, err := os.Open(fName)
	if err != nil {
		return nil, err
	}
	defer fIn.Close()

	dec := json.NewDecoder(fIn)
	var result []PerfLogEntry
	for {
		var entry PerfLogEntry
		err = dec.Decode(&entry)
		if err != nil {
			if strings.Contains(err.Error(), "EOF") {
				break
			} else {
				return nil, fmt.Errorf("Decode error: %v", err)
			}
		} else {
			if !since.Equal(time.Time{}) && since.After(entry.Timestamp) {
				continue
			}
			if !until.Equal(time.Time{}) && until.Before(entry.Timestamp) {
				continue
			}
			result = append(result, entry)
		}
	}
	return result, nil
}
コード例 #22
0
ファイル: chtimes.go プロジェクト: CNDonny/scope
// Chtimes changes the access time and modified time of a file at the given path
func Chtimes(name string, atime time.Time, mtime time.Time) error {
	unixMinTime := time.Unix(0, 0)
	unixMaxTime := maxTime

	// If the modified time is prior to the Unix Epoch, or after the
	// end of Unix Time, os.Chtimes has undefined behavior
	// default to Unix Epoch in this case, just in case

	if atime.Before(unixMinTime) || atime.After(unixMaxTime) {
		atime = unixMinTime
	}

	if mtime.Before(unixMinTime) || mtime.After(unixMaxTime) {
		mtime = unixMinTime
	}

	if err := os.Chtimes(name, atime, mtime); err != nil {
		return err
	}

	// Take platform specific action for setting create time.
	if err := setCTime(name, mtime); err != nil {
		return err
	}

	return nil
}
コード例 #23
0
ファイル: day.go プロジェクト: CyCoreSystems/ipc-schedule
// ActiveAt says whether the given time is
// wihtin the schedule of this Day schedule.
func (d *Day) ActiveAt(t time.Time) bool {
	if loc, err := d.GetLocation(); loc != nil && err == nil {
		t = t.In(loc)
	}
	start, stop := d.Times(t)
	return t.After(start) && t.Before(stop)
}
コード例 #24
0
// SetReadDeadline implements the net.PacketConn.SetReadDeadline method.
func (p *packetConn) SetReadDeadline(t time.Time) error {
	p.timeoutMu.Lock()

	// Set nonblocking I/O so we can time out reads and writes
	//
	// This is set only if timeouts are used, because a server probably
	// does not want timeouts by default, and a client can request them
	// itself if needed.
	var err error

	// If already nonblocking and the zero-value for t is entered, disable
	// nonblocking mode
	if p.nonblocking && t.IsZero() {
		err = p.s.SetNonblock(false)
		p.nonblocking = false
	} else if !p.nonblocking && t.After(time.Now()) {
		// If not nonblocking and t is after current time, enable nonblocking
		// mode
		err = p.s.SetNonblock(true)
		p.nonblocking = true
	}

	p.rtimeout = t
	p.timeoutMu.Unlock()

	return err
}
コード例 #25
0
ファイル: in_memory.go プロジェクト: mikedanese/heapster
func (ts *timeStore) Delete(start, end time.Time) error {
	ts.rwLock.Lock()
	defer ts.rwLock.Unlock()
	if ts.buffer.Len() == 0 {
		return nil
	}
	if (end != time.Time{}) && !end.After(start) {
		return fmt.Errorf("end time %v is not after start time %v", end, start)
	}
	// Assuming that deletes will happen more frequently for older data.
	elem := ts.buffer.Back()
	for elem != nil {
		entry := elem.Value.(TimePoint)
		if (end != time.Time{}) && entry.Timestamp.After(end) {
			// If we have reached an entry which is more recent than 'end' stop iterating.
			break
		}
		oldElem := elem
		elem = elem.Prev()

		// Skip entried which are before start.
		if !entry.Timestamp.Before(start) {
			ts.buffer.Remove(oldElem)
		}
	}
	return nil
}
コード例 #26
0
ファイル: engine.go プロジェクト: glycerine/ekanite
// createIndex creates an index with a given start and end time and adds the
// created index to the Engine's store. It must be called under lock.
func (e *Engine) createIndex(startTime, endTime time.Time) (*Index, error) {
	// There cannot be two indexes with the same start time, since this would mean
	// two indexes with the same path. So if an index already exists with the requested
	// start time, use that index's end time as the start time.
	var idx *Index
	for _, i := range e.indexes {
		if i.startTime == startTime {
			idx = i
			break
		}
	}
	if idx != nil {
		startTime = idx.endTime // XXX This could still align with another start time! Needs some sort of loop.
		assert(!startTime.After(endTime), "new start time after end time")
	}

	i, err := NewIndex(e.path, startTime, endTime, e.NumShards)
	if err != nil {
		return nil, err
	}
	e.indexes = append(e.indexes, i)
	sort.Sort(e.indexes)

	e.Logger.Printf("index %s created with %d shards, start time: %s, end time: %s",
		i.Path(), e.NumShards, i.StartTime(), i.EndTime())
	return i, nil
}
コード例 #27
0
ファイル: signature.go プロジェクト: postfix/name_pending
// KeyExpired returns whether sig is a self-signature of a key that has
// expired.
func (sig *Signature) KeyExpired(currentTime time.Time) bool {
	if sig.KeyLifetimeSecs == nil {
		return false
	}
	expiry := sig.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second)
	return currentTime.After(expiry)
}
コード例 #28
0
ファイル: channel_buffer.go プロジェクト: vivienschilis/eddy
func (self *ChannelBuffer) hasExpired(now time.Time) bool {
	e := self.newest()
	if e == nil {
		return false
	}
	return now.After(time.Unix(0, e.At).Add(time.Duration(e.TTL) * time.Second))
}
コード例 #29
0
ファイル: server.go プロジェクト: dnaeon/etcd
func (s *EtcdServer) parseProposeCtxErr(err error, start time.Time) error {
	switch err {
	case context.Canceled:
		return ErrCanceled
	case context.DeadlineExceeded:
		curLeadElected := s.r.leadElectedTime()
		prevLeadLost := curLeadElected.Add(-2 * time.Duration(s.Cfg.ElectionTicks) * time.Duration(s.Cfg.TickMs) * time.Millisecond)
		if start.After(prevLeadLost) && start.Before(curLeadElected) {
			return ErrTimeoutDueToLeaderFail
		}

		lead := types.ID(atomic.LoadUint64(&s.r.lead))
		switch lead {
		case types.ID(raft.None):
			// TODO: return error to specify it happens because the cluster does not have leader now
		case s.ID():
			if !isConnectedToQuorumSince(s.r.transport, start, s.ID(), s.cluster.Members()) {
				return ErrTimeoutDueToConnectionLost
			}
		default:
			if !isConnectedSince(s.r.transport, start, lead) {
				return ErrTimeoutDueToConnectionLost
			}
		}

		return ErrTimeout
	default:
		return err
	}
}
コード例 #30
0
ファイル: shift.go プロジェクト: jaffee/sked
func (i *Interval) SetEnd(t time.Time) error {
	if !t.After(i.Start()) {
		return errors.New("End must be after start.")
	}
	i.EndTime = t
	return nil
}