示例#1
0
文件: timex.go 项目: jmptrader/golib
// NewCrontab creates a cron server.
func NewCrontab(freq time.Duration) *Crontab {
	c := &Crontab{
		jobs:        make(map[string]Job),
		commandChan: make(chan *command),
		ticker:      time.NewTicker(freq),
	}
	c.loop = loop.GoRecoverable(c.backendLoop, c.checkRecovering)
	return c
}
示例#2
0
// NewStandardBackend starts the standard monitoring backend.
func NewStandardBackend() Backend {
	m := &stdBackend{
		measuringC:             make(chan *stdMeasuring, 1024),
		ssvChangeC:             make(chan *stdSSVChange, 1024),
		retrieverRegistrationC: make(chan *stdRetrieverRegistration, 16),
		commandC:               make(chan *command),
	}
	m.backend = loop.GoRecoverable(m.backendLoop, m.checkRecovering)
	return m
}
示例#3
0
// newSystemMonitor starts the system monitor.
func newSystemMonitor() *systemMonitor {
	m := &systemMonitor{
		measuringChan:             make(chan *Measuring, 1000),
		ssvChangeChan:             make(chan *ssvChange, 1000),
		retrieverRegistrationChan: make(chan *retrieverRegistration, 10),
		commandChan:               make(chan *command),
	}
	m.backend = loop.GoRecoverable(m.backendLoop, m.checkRecovering)
	return m
}
示例#4
0
文件: cell.go 项目: tideland/gocells
// newCell create a new cell around a behavior.
func newCell(env *environment, id string, behavior Behavior) (*cell, error) {
	logger.Infof("cell '%s' starts", id)
	// Init cell runtime.
	c := &cell{
		env:               env,
		id:                id,
		measuringID:       identifier.Identifier("cells", env.id, "cell", id),
		behavior:          behavior,
		emitters:          newConnections(),
		subscribers:       newConnections(),
		emitTimeoutTicker: time.NewTicker(5 * time.Second),
	}
	// Set configuration.
	if bebs, ok := behavior.(BehaviorEventBufferSize); ok {
		size := bebs.EventBufferSize()
		if size < minEventBufferSize {
			size = minEventBufferSize
		}
		c.eventc = make(chan Event, size)
	} else {
		c.eventc = make(chan Event, minEventBufferSize)
	}
	if brf, ok := behavior.(BehaviorRecoveringFrequency); ok {
		number, duration := brf.RecoveringFrequency()
		if duration.Seconds()/float64(number) < 0.1 {
			number = minRecoveringNumber
			duration = minRecoveringDuration
		}
		c.recoveringNumber = number
		c.recoveringDuration = duration
	} else {
		c.recoveringNumber = minRecoveringNumber
		c.recoveringDuration = minRecoveringDuration
	}
	if bet, ok := behavior.(BehaviorEmitTimeout); ok {
		timeout := bet.EmitTimeout()
		switch {
		case timeout < minEmitTimeout:
			timeout = minEmitTimeout
		case timeout > maxEmitTimeout:
			timeout = maxEmitTimeout
		}
		c.emitTimeout = int(timeout.Seconds() / 5)
	} else {
		c.emitTimeout = int(maxEmitTimeout.Seconds() / 5)
	}
	// Init behavior.
	if err := behavior.Init(c); err != nil {
		return nil, errors.Annotate(err, ErrCellInit, errorMessages, id)
	}
	// Start backend.
	c.loop = loop.GoRecoverable(c.backendLoop, c.checkRecovering, id)
	return c, nil
}
示例#5
0
// TestEndRecoverings tests the regular internal stop of a recovered loop.
func TestEndRecoverings(t *testing.T) {
	assert := audit.NewTestingAssertion(t, true)
	done := false
	count := 0
	l := loop.GoRecoverable(generateRecoverNoErrorBackend(&done, &count), ignorePanics)

	time.Sleep(longDelay)

	status, _ := l.Error()
	assert.Equal(loop.Stopped, status)
}
示例#6
0
// TestStopRecoverings tests the regular stop of a recovered loop.
func TestStopRecoverings(t *testing.T) {
	assert := audit.NewTestingAssertion(t, true)
	done := false
	count := 0
	l := loop.GoRecoverable(generateRecoverPanicBackend(&done, &count), ignorePanics)

	time.Sleep(longDelay)

	assert.Nil(l.Stop(), "no error after simple stop")
	assert.True(done, "backend has done")

	status, _ := l.Error()

	assert.Equal(loop.Stopped, status, "loop is stopped")
}
示例#7
0
// TestRecoveringsError tests recoverings after errors
func TestRecoveringsError(t *testing.T) {
	assert := audit.NewTestingAssertion(t, true)
	done := false
	count := 0
	l := loop.GoRecoverable(generateRecoverErrorBackend(&done, &count), catchTimeout)

	time.Sleep(longDelay)

	assert.ErrorMatch(l.Stop(), "timed out", "error has to be 'timed out'")
	assert.True(done, "backend has done")

	status, _ := l.Error()

	assert.Equal(loop.Stopped, status, "loop is stopped")
}
示例#8
0
// TestRecoveringsPanic test recoverings after panics.
func TestRecoveringsPanic(t *testing.T) {
	assert := audit.NewTestingAssertion(t, true)
	done := false
	count := 0
	l := loop.GoRecoverable(generateRecoverPanicBackend(&done, &count), checkRecovering)

	time.Sleep(veryLongDelay)

	assert.ErrorMatch(l.Stop(), "too many panics")
	assert.True(done)
	assert.Equal(count, 5)

	status, _ := l.Error()

	assert.Equal(loop.Stopped, status)
}
示例#9
0
// Test recoverings after panics.
func TestRecoverings(t *testing.T) {
	assert := audit.NewTestingAssertion(t, true)
	done := false
	count := 0
	l := loop.GoRecoverable(generateSimplePanicBackend(&done, &count), checkRecovering)

	time.Sleep(veryLongDelay)

	assert.ErrorMatch(l.Stop(), "too many panics", "error has to be 'too many panics'")
	assert.True(done, "backend has done")
	assert.Equal(count, 5, "loop has to be restarted 5 times")

	status, _ := l.Error()

	assert.Equal(loop.Stopped, status, "loop is stopped")
}
示例#10
0
func ExampleRecoverFunc() {
	printChan := make(chan string)
	loopFunc := func(l loop.Loop) error {
		for {
			select {
			case <-l.ShallStop():
				return nil
			case str := <-printChan:
				println(str)
			}
		}
	}
	recoverFunc := func(rs loop.Recoverings) (loop.Recoverings, error) {
		if len(rs) >= 5 {
			return nil, errors.New("too many panics")
		}
		return rs, nil
	}
	loop.GoRecoverable(loopFunc, recoverFunc)
}