示例#1
0
文件: tools.go 项目: kung-foo/golib
// Scene is specified on the SceneManager interface.
func (m *cookieSceneManager) Scene(ctx Context) (scene.Scene, error) {
	cookie, err := ctx.Request().Cookie(sceneID)
	if err != nil && err != http.ErrNoCookie {
		return nil, err
	}
	request := &sceneRequest{
		responseChan: make(chan *sceneResponse, 1),
	}
	if err == http.ErrNoCookie {
		request.id = ""
	} else {
		request.id = cookie.Value
	}
	select {
	case m.requestChan <- request:
	case <-m.loop.IsStopping():
		return nil, errors.New(ErrSceneManagement, errorMessages, "stopping")
	}
	m.requestChan <- request
	select {
	case response := <-request.responseChan:
		cookie = &http.Cookie{
			Name:  sceneID,
			Value: response.id,
		}
		http.SetCookie(ctx.ResponseWriter(), cookie)
		return response.scene, nil
	case <-m.loop.IsStopping():
		return nil, errors.New(ErrSceneManagement, errorMessages, "stopping")
	}
}
示例#2
0
文件: scene.go 项目: kung-foo/golib
// WaitFlagLimited is specified on the Scene interface.
func (s *scene) WaitFlagLimited(topic string, timeout time.Duration) error {
	// Add signal channel.
	command := &envelope{
		kind: wait,
		signaling: &signaling{
			topic:      topic,
			signalChan: make(chan struct{}, 1),
		},
		respChan: make(chan *envelope, 1),
	}
	_, err := s.command(command)
	if err != nil {
		return err
	}
	// Wait for signal.
	var timeoutChan <-chan time.Time
	if timeout > 0 {
		timeoutChan = time.After(timeout)
	}
	select {
	case <-s.backend.IsStopping():
		err = s.Wait()
		if err == nil {
			err = errors.New(ErrSceneEnded, errorMessages)
		}
		return err
	case <-command.signaling.signalChan:
		return nil
	case <-timeoutChan:
		return errors.New(ErrWaitedTooLong, errorMessages, topic)
	}
}
示例#3
0
文件: scene.go 项目: kung-foo/golib
// backendLoop runs the backend loop of the scene.
func (s *scene) backendLoop(l loop.Loop) (err error) {
	// Defer cleanup.
	defer func() {
		cerr := s.cleanupAllProps()
		if err == nil {
			err = cerr
		}
	}()
	// Init timers.
	var watchdog <-chan time.Time
	var clapperboard <-chan time.Time
	if s.absolute > 0 {
		clapperboard = time.After(s.absolute)
	}
	// Run loop.
	for {
		if s.inactivity > 0 {
			watchdog = time.After(s.inactivity)
		}
		select {
		case <-l.ShallStop():
			return nil
		case timeout := <-watchdog:
			return errors.New(ErrTimeout, errorMessages, "inactivity", timeout)
		case timeout := <-clapperboard:
			return errors.New(ErrTimeout, errorMessages, "absolute", timeout)
		case command := <-s.commandChan:
			s.processCommand(command)
		}
	}
}
示例#4
0
文件: builder.go 项目: kung-foo/golib
// CommentNode implements the Builder interface.
func (nb *NodeBuilder) CommentNode(comment string) error {
	if nb.done {
		return errors.New(ErrBuilder, errorMessages, "building is already done")
	}
	if len(nb.stack) > 0 {
		nb.stack[len(nb.stack)-1].appendCommentNode(comment)
		return nil
	}
	return errors.New(ErrBuilder, errorMessages, "no opening tag for comment")
}
示例#5
0
文件: builder.go 项目: kung-foo/golib
// RawNode implements the Builder interface.
func (nb *NodeBuilder) RawNode(raw string) error {
	if nb.done {
		return errors.New(ErrBuilder, errorMessages, "building is already done")
	}
	if len(nb.stack) > 0 {
		nb.stack[len(nb.stack)-1].appendRawNode(raw)
		return nil
	}
	return errors.New(ErrBuilder, errorMessages, "no opening tag for raw text")
}
示例#6
0
// ValueAt returns the value at index.
func (rs *ResultSet) ValueAt(index int) (Value, error) {
	if len(rs.items) < index+1 {
		return nil, errors.New(ErrIllegalItemIndex, errorMessages, index, len(rs.items))
	}
	value, ok := rs.items[index].(Value)
	if !ok {
		return nil, errors.New(ErrIllegalItemType, errorMessages, index, "value")
	}
	return value, nil
}
示例#7
0
// ResultSetAt returns the nested result set at index.
func (rs *ResultSet) ResultSetAt(index int) (*ResultSet, error) {
	if len(rs.items) < index-1 {
		return nil, errors.New(ErrIllegalItemIndex, errorMessages, index, len(rs.items))
	}
	resultSet, ok := rs.items[index].(*ResultSet)
	if !ok {
		return nil, errors.New(ErrIllegalItemType, errorMessages, index, "result set")
	}
	return resultSet, nil
}
示例#8
0
文件: resp.go 项目: kung-foo/golib
// receiveResponse retrieves a response from the server.
func (r *resp) receiveResponse() *response {
	// Receive first line.
	line, err := r.reader.ReadBytes('\n')
	if err != nil {
		rerr := errors.Annotate(err, ErrConnectionBroken, errorMessages, "receive after "+r.cmd)
		return &response{receivingError, 0, nil, rerr}
	}
	content := line[1 : len(line)-2]
	// First byte defines kind.
	switch line[0] {
	case '+':
		// Status response.
		return &response{statusResponse, 0, line[:len(line)-2], nil}
	case '-':
		// Error response.
		return &response{errorResponse, 0, line[:len(line)-2], nil}
	case ':':
		// Integer response.
		return &response{integerResponse, 0, content, nil}
	case '$':
		// Bulk response or null bulk response.
		count, err := strconv.Atoi(string(content))
		if err != nil {
			return &response{receivingError, 0, nil, errors.Annotate(err, ErrServerResponse, errorMessages)}
		}
		if count == -1 {
			// Null bulk response.
			return &response{nullBulkResponse, 0, nil, nil}
		}
		// Receive the bulk data.
		toRead := count + 2
		buffer := make([]byte, toRead)
		n, err := io.ReadFull(r.reader, buffer)
		if err != nil {
			return &response{receivingError, 0, nil, err}
		}
		if n < toRead {
			return &response{receivingError, 0, nil, errors.New(ErrServerResponse, errorMessages)}
		}
		return &response{bulkResponse, 0, buffer[0:count], nil}
	case '*':
		// Array reply. Check for timeout.
		length, err := strconv.Atoi(string(content))
		if err != nil {
			return &response{receivingError, 0, nil, errors.Annotate(err, ErrServerResponse, errorMessages)}
		}
		if length == -1 {
			// Timeout.
			return &response{timeoutError, 0, nil, nil}
		}
		return &response{arrayResponse, length, nil, nil}
	}
	return &response{receivingError, 0, nil, errors.New(ErrInvalidResponse, errorMessages, string(line))}
}
示例#9
0
// checkIDs checks if the passed IDs are valid. It is only
// called internally, so no locking.
func (r *registry) checkIDs(emitterID string, subscriberIDs ...string) error {
	for _, subscriberID := range subscriberIDs {
		if subscriberID == emitterID {
			return errors.New(ErrInvalidID, errorMessages, subscriberID)
		}
		if _, ok := r.cellers[subscriberID]; !ok {
			return errors.New(ErrInvalidID, errorMessages, subscriberID)
		}
	}
	return nil
}
示例#10
0
文件: rss.go 项目: kung-foo/golib
// Validate checks if the enclosure is valid.
func (e *Enclosure) Validate() error {
	if e.Length < 1 {
		return errors.New(ErrValidation, errorMessages, "item enclosure length %d is too small", e.Length)
	}
	if e.Type == "" {
		return errors.New(ErrValidation, errorMessages, "item enclosure type must not be empty")
	}
	if _, err := url.Parse(e.URL); err != nil {
		return errors.Annotate(err, ErrParsing, errorMessages, "item enclosure url")
	}
	return nil
}
示例#11
0
// Respond is specified on the Event interface.
func (e *event) Respond(response interface{}) error {
	responseChanPayload, ok := e.Payload().Get(ResponseChanPayload)
	if !ok {
		return errors.New(ErrInvalidResponseEvent, errorMessages, "no response channel")
	}
	responseChan, ok := responseChanPayload.(chan interface{})
	if !ok {
		return errors.New(ErrInvalidResponseEvent, errorMessages, "invalid response channel")
	}
	responseChan <- response
	return nil
}
示例#12
0
文件: rss.go 项目: kung-foo/golib
// Validate checks if the cloud is valid.
func (c *Cloud) Validate() error {
	if c.Domain == "" {
		return errors.New(ErrValidation, errorMessages, "cloud domain must not be empty")
	}
	if c.Path == "" || c.Path[0] != '/' {
		return errors.New(ErrValidation, errorMessages, "cloud path %q must not be empty and has to start with a slash", c.Path)
	}
	if c.Port < 1 || c.Port > 65535 {
		return errors.New(ErrValidation, errorMessages, "cloud port %d is out of range", c.Port)
	}
	return nil
}
示例#13
0
文件: builder.go 项目: kung-foo/golib
// EndTagNode implements the Builder interface.
func (nb *NodeBuilder) EndTagNode() error {
	if nb.done {
		return errors.New(ErrBuilder, errorMessages, "building is already done")
	}
	switch l := len(nb.stack); l {
	case 0:
		return errors.New(ErrBuilder, errorMessages, "no opening tag")
	case 1:
		nb.done = true
	default:
		nb.stack[l-2].appendChild(nb.stack[l-1])
		nb.stack = nb.stack[:l-1]
	}
	return nil
}
示例#14
0
文件: rss.go 项目: kung-foo/golib
// Validate checks if the text input is valid.
func (t *TextInput) Validate() error {
	if t.Description == "" {
		return errors.New(ErrValidation, errorMessages, "text input description must not be empty")
	}
	if _, err := url.Parse(t.Link); err != nil {
		return errors.Annotate(err, ErrParsing, errorMessages, "text input link")
	}
	if t.Name == "" {
		return errors.New(ErrValidation, errorMessages, "text input name must not be empty")
	}
	if t.Title == "" {
		return errors.New(ErrValidation, errorMessages, "text input title must not be empty")
	}
	return nil
}
示例#15
0
// ScoredValues returns the alternating values as scored values slice. If
// withscores is false the result set contains no scores and so they are
// set to 0.0 in the returned scored values.
func (rs *ResultSet) ScoredValues(withscores bool) (ScoredValues, error) {
	svs := ScoredValues{}
	sv := ScoredValue{}
	for index, item := range rs.items {
		value, ok := item.(Value)
		if !ok {
			return nil, errors.New(ErrIllegalItemType, errorMessages, index, "value")
		}
		if withscores {
			// With scores, so alternating values and scores.
			if index%2 == 0 {
				sv.Value = value
			} else {
				score, err := value.Float64()
				if err != nil {
					return nil, err
				}
				sv.Score = score
				svs = append(svs, sv)
				sv = ScoredValue{}
			}
		} else {
			// No scores, only values.
			sv.Value = value
			svs = append(svs, sv)
			sv = ScoredValue{}
		}
	}
	return svs, nil
}
示例#16
0
文件: resp.go 项目: kung-foo/golib
// receiveResultSet receives all responses and converts them into a result set.
func (r *resp) receiveResultSet() (*ResultSet, error) {
	defer func() { r.cmd = "-none-" }()
	result := newResultSet()
	current := result
	for {
		response := r.receiveResponse()
		switch response.kind {
		case receivingError:
			return nil, response.err
		case timeoutError:
			return nil, errors.New(ErrTimeout, errorMessages)
		case statusResponse, errorResponse, integerResponse, bulkResponse, nullBulkResponse:
			current.append(response.value())
		case arrayResponse:
			switch {
			case current == result && current.Len() == 0:
				current.length = response.length
			case !current.allReceived():
				next := newResultSet()
				next.parent = current
				current.append(next)
				current = next
				current.length = response.length
			}
		}
		// Check if all values are received.
		current = current.nextResultSet()
		if current == nil {
			return result, nil
		}
	}
}
示例#17
0
// Get implements the Value interface.
func (v *value) Get() (string, error) {
	sv, err := v.changer.Value()
	if err != nil {
		return "", errors.New(ErrInvalidPath, errorMessages, pathToString(v.path))
	}
	return sv, nil
}
示例#18
0
文件: event.go 项目: tideland/gocells
// NewEvent creates a new event with the given topic and payload.
func NewEvent(topic string, payload interface{}, ctx context.Context) (Event, error) {
	if topic == "" {
		return nil, errors.New(ErrNoTopic, errorMessages)
	}
	p := NewPayload(payload)
	return &event{topic, p, ctx}, nil
}
示例#19
0
// BeginTagNode implements the sml.Builder interface.
func (b *configBuilder) BeginTagNode(tag string) error {
	switch {
	case b.values == nil && tag != "config":
		return errors.New(ErrIllegalConfigSource, errorMessages, `does not start with "config" node`)
	case b.values == nil:
		b.stack = collections.NewStringStack(tag)
		b.values = collections.NewKeyStringValueTree(tag, "", false)
	default:
		b.stack.Push(tag)
		changer := b.values.Create(b.stack.All()...)
		if changer.Error() != nil {
			return errors.New(ErrIllegalConfigSource, errorMessages, changer.Error())
		}
	}
	return nil
}
示例#20
0
// NewEvent creates a new event with the given topic and payload.
func NewEvent(topic string, payload interface{}, scene scene.Scene) (Event, error) {
	if topic == "" {
		return nil, errors.New(ErrNoTopic, errorMessages)
	}
	p := NewPayload(payload)
	return &event{topic, p, scene}, nil
}
示例#21
0
文件: stacks.go 项目: kung-foo/golib
// Peek implements the Stack interface.
func (s stack) Peek() (interface{}, error) {
	lv := len(s.values)
	if lv == 0 {
		return nil, errors.New(ErrEmpty, errorMessages)
	}
	v := s.values[lv-1]
	return v, nil
}
示例#22
0
文件: stacks.go 项目: kung-foo/golib
// Peek implements the StringStack interface.
func (s *stringStack) Peek() (string, error) {
	lv := len(s.values)
	if lv == 0 {
		return "", errors.New(ErrEmpty, errorMessages)
	}
	v := s.values[lv-1]
	return v, nil
}
示例#23
0
文件: timex.go 项目: jmptrader/golib
// checkRecovering checks if the backend can be recovered.
func (c *Crontab) checkRecovering(rs loop.Recoverings) (loop.Recoverings, error) {
	if rs.Frequency(12, time.Minute) {
		logger.Errorf("crontab cannot be recovered: %v", rs.Last().Reason)
		return nil, errors.New(ErrCrontabCannotBeRecovered, errorMessages, rs.Last().Reason)
	}
	logger.Warningf("crontab recovered: %v", rs.Last().Reason)
	return rs.Trim(12), nil
}
示例#24
0
文件: cell.go 项目: tideland/gocells
// ProcessEvent implements the Subscriber interface.
func (c *cell) ProcessEvent(event Event) error {
	emitTimeoutTicks := 0
	for {
		select {
		case c.eventc <- event:
			return nil
		case <-c.loop.IsStopping():
			return errors.New(ErrInactive, errorMessages, c.id)
		case <-c.emitTimeoutTicker.C:
			emitTimeoutTicks++
			if emitTimeoutTicks > c.emitTimeout {
				op := fmt.Sprintf("emitting %q to %q", event.Topic(), c.id)
				return errors.New(ErrTimeout, errorMessages, op)
			}
		}
	}
}
示例#25
0
文件: rss.go 项目: kung-foo/golib
// Validate checks if the skip hours are valid.
func (s *SkipHours) Validate() error {
	for _, hour := range s.Hours {
		if hour < 0 || hour > 23 {
			return errors.New(ErrValidation, errorMessages, "skip hour %d is out of range from 0 to 23", hour)
		}
	}
	return nil
}
示例#26
0
文件: context.go 项目: kung-foo/golib
// ReadGenericJSON is specified on the Context interface.
func (ctx *context) ReadGenericJSON() (map[string]interface{}, error) {
	if !ctx.HasContentType(ContentTypeJSON) {
		return nil, errors.New(ErrInvalidContentType, errorMessages, ContentTypeJSON)
	}
	data := map[string]interface{}{}
	err := ctx.ReadJSON(&data)
	return data, err
}
示例#27
0
文件: builder.go 项目: kung-foo/golib
// TextNode implements the Builder interface.
func (tb *KeyStringValueTreeBuilder) TextNode(text string) error {
	if tb.done {
		return errors.New(ErrBuilder, errorMessages, "building is already done")
	}
	value, err := tb.tree.At(tb.stack.All()...).Value()
	if err != nil {
		return errors.Annotate(err, ErrBuilder, errorMessages)
	}
	if value != "" {
		return errors.New(ErrBuilder, errorMessages, "node has multiple values")
	}
	text = strings.TrimSpace(text)
	if text != "" {
		_, err = tb.tree.At(tb.stack.All()...).SetValue(text)
	}
	return err
}
示例#28
0
// checkRecovering checks if the backend can be recovered.
func (b *stdBackend) checkRecovering(rs loop.Recoverings) (loop.Recoverings, error) {
	if rs.Frequency(12, time.Minute) {
		logger.Errorf("standard monitor cannot be recovered: %v", rs.Last().Reason)
		return nil, errors.New(ErrMonitoringCannotBeRecovered, errorMessages, rs.Last().Reason)
	}
	logger.Warningf("standard monitor recovered: %v", rs.Last().Reason)
	return rs.Trim(12), nil
}
示例#29
0
// subscribe subscribes cells to an emitter.
func (r *registry) subscribe(emitterID string, subscriberIDs ...string) error {
	r.mutex.Lock()
	defer r.mutex.Unlock()
	ec, ok := r.cells[emitterID]
	if !ok {
		return errors.New(ErrInvalidID, errorMessages, emitterID)
	}
	for _, subscriberID := range subscriberIDs {
		if sc, ok := r.cells[subscriberID]; ok {
			ec.subscribers.add(sc)
			sc.emitters.add(ec)
		} else {
			return errors.New(ErrInvalidID, errorMessages, subscriberID)
		}
	}
	return nil
}
示例#30
0
文件: cell.go 项目: jmptrader/golib
// updateSubscribers sets the subscribers of the cell.
func (c *cell) updateSubscribers(cells []*cell) error {
	select {
	case c.subscriberc <- cells:
	case <-c.loop.IsStopping():
		return errors.New(ErrInactive, errorMessages, c.id)
	}
	return nil
}