<commit_before>package jiq

import (
	"io"
	"io/ioutil"
	"strings"

	"github.com/nsf/termbox-go"
)

const (
	DefaultY     int    = 1
	FilterPrompt string = "[Filter]> "
)

type Engine struct {
	json          string
	query         *Query
	args          []string
	term          *Terminal
	complete      []string
	keymode       bool
	candidates    []string
	candidatemode bool
	candidateidx  int
	contentOffset int
	queryConfirm  bool
	cursorOffsetX int
}

func NewEngine(s io.Reader, args []string) *Engine {
	j, err := ioutil.ReadAll(s)
	if err != nil {
		return &Engine{}
	}
	e := &Engine{
		json:          string(j),
		term:          NewTerminal(FilterPrompt, DefaultY),
		query:         NewQuery([]rune("")),
		args:          args,
		complete:      []string{"", ""},
		keymode:       false,
		candidates:    []string{},
		candidatemode: false,
		candidateidx:  0,
		contentOffset: 0,
		queryConfirm:  false,
		cursorOffsetX: 0,
	}
	return e
}

type EngineResult struct {
	Content string
	Qs      string
	Err     error
}

func (e *Engine) Run() *EngineResult {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()

	var contents []string

	for {
		contents = e.getContents()
		e.setCandidateData()
		e.queryConfirm = false

		ta := &TerminalDrawAttributes{
			Query:           e.query.StringGet(),
			CursorOffsetX:   e.cursorOffsetX,
			Contents:        contents,
			CandidateIndex:  e.candidateidx,
			ContentsOffsetY: e.contentOffset,
			Complete:        e.complete[0],
			Candidates:      e.candidates,
		}

		e.term.draw(ta)

		switch ev := termbox.PollEvent(); ev.Type {
		case termbox.EventKey:
			switch ev.Key {
			case 0:
				e.inputChar(ev.Ch)
			case termbox.KeySpace:
				e.inputChar(32)
			case termbox.KeyBackspace, termbox.KeyBackspace2:
				e.deleteChar()
			case termbox.KeyDelete:
				e.deleteNextChar()
			case termbox.KeyTab:
				e.tabAction()
			case termbox.KeyArrowLeft, termbox.KeyCtrlB:
				e.moveCursorBackward()
			case termbox.KeyArrowRight, termbox.KeyCtrlF:
				e.moveCursorForward()
			case termbox.KeyHome, termbox.KeyCtrlA:
				e.moveCursorToTop()
			case termbox.KeyEnd, termbox.KeyCtrlE:
				e.moveCursorToEnd()
			case termbox.KeyCtrlK:
				e.scrollToAbove()
			case termbox.KeyCtrlJ:
				e.scrollToBelow()
			case termbox.KeyCtrlL:
				e.toggleKeymode()
			case termbox.KeyCtrlW:
				e.deleteWordBackward()
			case termbox.KeyEsc:
				e.escapeCandidateMode()
			case termbox.KeyEnter:
				if !e.candidatemode {
					cc, err := jqrun(e.query.StringGet(), e.json, e.args)

					return &EngineResult{
						Content: cc,
						Qs:      e.query.StringGet(),
						Err:     err,
					}
				}
				e.confirmCandidate()
			case termbox.KeyCtrlC:
				return &EngineResult{}
			default:
			}
		case termbox.EventError:
			panic(ev.Err)
			break
		default:
		}
	}
}

func (e *Engine) getContents() []string {
	var contents []string

	cc, _ := jqrun(e.query.StringGet(), e.json, e.args)

	if e.keymode {
		contents = e.candidates
	} else {
		contents = strings.Split(cc, "\n")
	}
	return contents
}

func (e *Engine) setCandidateData() {
	if l := len(e.candidates); e.complete[0] == "" && l > 1 {
		if e.candidateidx >= l {
			e.candidateidx = 0
		}
	} else {
		e.candidatemode = false
	}
	if !e.candidatemode {
		e.candidateidx = 0
		e.candidates = []string{}
	}
}

func (e *Engine) confirmCandidate() {
	_, _ = e.query.PopKeyword()
	_ = e.query.StringAdd(".")
	q := e.query.StringAdd(e.candidates[e.candidateidx])
	e.cursorOffsetX = len(q)
	e.queryConfirm = true
}

func (e *Engine) deleteChar() {
	if e.cursorOffsetX > 0 {
		_ = e.query.Delete(e.cursorOffsetX - 1)
		e.cursorOffsetX -= 1
	}
}
func (e *Engine) deleteNextChar() {
	e.query.Delete(e.cursorOffsetX)
}
func (e *Engine) scrollToBelow() {
	e.contentOffset++
}
func (e *Engine) scrollToAbove() {
	if o := e.contentOffset - 1; o >= 0 {
		e.contentOffset = o
	}
}
func (e *Engine) toggleKeymode() {
	e.keymode = !e.keymode
}
func (e *Engine) deleteWordBackward() {
	if k, _ := e.query.StringPopKeyword(); k != "" && !strings.Contains(k, "[") {
		_ = e.query.StringAdd(".")
	}
	e.cursorOffsetX = len(e.query.Get())
}
func (e *Engine) tabAction() {
	if !e.candidatemode {
		e.candidatemode = true
		if e.query.StringGet() == "" {
			_ = e.query.StringAdd(".")
		} else if e.complete[0] != e.complete[1] && e.complete[0] != "" {
			if k, _ := e.query.StringPopKeyword(); !strings.Contains(k, "[") {
				_ = e.query.StringAdd(".")
			}
			_ = e.query.StringAdd(e.complete[1])
		} else {
			_ = e.query.StringAdd(e.complete[0])
		}
	} else {
		e.candidateidx = e.candidateidx + 1
	}
	e.cursorOffsetX = len(e.query.Get())
}
func (e *Engine) escapeCandidateMode() {
	e.candidatemode = false
}
func (e *Engine) inputChar(ch rune) {
	b := len(e.query.Get())
	q := e.query.StringInsert(string(ch), e.cursorOffsetX)
	if b < len(q) {
		e.cursorOffsetX += 1
	}
}

func (e *Engine) moveCursorBackward() {
	if e.cursorOffsetX > 0 {
		e.cursorOffsetX -= 1
	}
}
func (e *Engine) moveCursorForward() {
	if len(e.query.Get()) > e.cursorOffsetX {
		e.cursorOffsetX += 1
	}
}
func (e *Engine) moveCursorWordBackwark() {
}
func (e *Engine) moveCursorWordForward() {
}
func (e *Engine) moveCursorToTop() {
	e.cursorOffsetX = 0
}
func (e *Engine) moveCursorToEnd() {
	e.cursorOffsetX = len(e.query.Get())
}
<commit_msg>remove some bizarre ctrl+key keymaps. add pgup, pgdown.<commit_after>package jiq

import (
	"io"
	"io/ioutil"
	"strings"

	"github.com/nsf/termbox-go"
)

const (
	DefaultY     int    = 1
	FilterPrompt string = "[Filter]> "
)

type Engine struct {
	json          string
	query         *Query
	args          []string
	term          *Terminal
	complete      []string
	keymode       bool
	candidates    []string
	candidatemode bool
	candidateidx  int
	contentOffset int
	queryConfirm  bool
	cursorOffsetX int
}

func NewEngine(s io.Reader, args []string) *Engine {
	j, err := ioutil.ReadAll(s)
	if err != nil {
		return &Engine{}
	}
	e := &Engine{
		json:          string(j),
		term:          NewTerminal(FilterPrompt, DefaultY),
		query:         NewQuery([]rune("")),
		args:          args,
		complete:      []string{"", ""},
		keymode:       false,
		candidates:    []string{},
		candidatemode: false,
		candidateidx:  0,
		contentOffset: 0,
		queryConfirm:  false,
		cursorOffsetX: 0,
	}
	return e
}

type EngineResult struct {
	Content string
	Qs      string
	Err     error
}

func (e *Engine) Run() *EngineResult {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()

	var contents []string

	for {
		contents = e.getContents()
		e.setCandidateData()
		e.queryConfirm = false

		ta := &TerminalDrawAttributes{
			Query:           e.query.StringGet(),
			CursorOffsetX:   e.cursorOffsetX,
			Contents:        contents,
			CandidateIndex:  e.candidateidx,
			ContentsOffsetY: e.contentOffset,
			Complete:        e.complete[0],
			Candidates:      e.candidates,
		}

		e.term.draw(ta)

		switch ev := termbox.PollEvent(); ev.Type {
		case termbox.EventKey:
			switch ev.Key {
			case 0:
				e.inputChar(ev.Ch)
			case termbox.KeySpace:
				e.inputChar(32)
			case termbox.KeyBackspace, termbox.KeyBackspace2:
				e.deleteChar()
			case termbox.KeyDelete:
				e.deleteNextChar()
			case termbox.KeyTab:
				e.tabAction()
			case termbox.KeyArrowLeft:
				e.moveCursorBackward()
			case termbox.KeyArrowRight:
				e.moveCursorForward()
			case termbox.KeyHome, termbox.KeyCtrlA:
				e.moveCursorToTop()
			case termbox.KeyEnd:
				e.moveCursorToEnd()
			case termbox.KeyCtrlK, termbox.KeyPgup:
				e.scrollToAbove()
			case termbox.KeyCtrlJ, termbox.KeyPgdn:
				e.scrollToBelow()
			case termbox.KeyCtrlL:
				e.toggleKeymode()
			case termbox.KeyCtrlW:
				e.deleteWordBackward()
			case termbox.KeyEsc:
				e.escapeCandidateMode()
			case termbox.KeyEnter:
				if !e.candidatemode {
					cc, err := jqrun(e.query.StringGet(), e.json, e.args)

					return &EngineResult{
						Content: cc,
						Qs:      e.query.StringGet(),
						Err:     err,
					}
				}
				e.confirmCandidate()
			case termbox.KeyCtrlC:
				return &EngineResult{}
			default:
			}
		case termbox.EventError:
			panic(ev.Err)
			break
		default:
		}
	}
}

func (e *Engine) getContents() []string {
	var contents []string

	cc, _ := jqrun(e.query.StringGet(), e.json, e.args)

	if e.keymode {
		contents = e.candidates
	} else {
		contents = strings.Split(cc, "\n")
	}
	return contents
}

func (e *Engine) setCandidateData() {
	if l := len(e.candidates); e.complete[0] == "" && l > 1 {
		if e.candidateidx >= l {
			e.candidateidx = 0
		}
	} else {
		e.candidatemode = false
	}
	if !e.candidatemode {
		e.candidateidx = 0
		e.candidates = []string{}
	}
}

func (e *Engine) confirmCandidate() {
	_, _ = e.query.PopKeyword()
	_ = e.query.StringAdd(".")
	q := e.query.StringAdd(e.candidates[e.candidateidx])
	e.cursorOffsetX = len(q)
	e.queryConfirm = true
}

func (e *Engine) deleteChar() {
	if e.cursorOffsetX > 0 {
		_ = e.query.Delete(e.cursorOffsetX - 1)
		e.cursorOffsetX -= 1
	}
}
func (e *Engine) deleteNextChar() {
	e.query.Delete(e.cursorOffsetX)
}
func (e *Engine) scrollToBelow() {
	e.contentOffset++
}
func (e *Engine) scrollToAbove() {
	if o := e.contentOffset - 1; o >= 0 {
		e.contentOffset = o
	}
}
func (e *Engine) toggleKeymode() {
	e.keymode = !e.keymode
}
func (e *Engine) deleteWordBackward() {
	if k, _ := e.query.StringPopKeyword(); k != "" && !strings.Contains(k, "[") {
		_ = e.query.StringAdd(".")
	}
	e.cursorOffsetX = len(e.query.Get())
}
func (e *Engine) tabAction() {
	if !e.candidatemode {
		e.candidatemode = true
		if e.query.StringGet() == "" {
			_ = e.query.StringAdd(".")
		} else if e.complete[0] != e.complete[1] && e.complete[0] != "" {
			if k, _ := e.query.StringPopKeyword(); !strings.Contains(k, "[") {
				_ = e.query.StringAdd(".")
			}
			_ = e.query.StringAdd(e.complete[1])
		} else {
			_ = e.query.StringAdd(e.complete[0])
		}
	} else {
		e.candidateidx = e.candidateidx + 1
	}
	e.cursorOffsetX = len(e.query.Get())
}
func (e *Engine) escapeCandidateMode() {
	e.candidatemode = false
}
func (e *Engine) inputChar(ch rune) {
	b := len(e.query.Get())
	q := e.query.StringInsert(string(ch), e.cursorOffsetX)
	if b < len(q) {
		e.cursorOffsetX += 1
	}
}

func (e *Engine) moveCursorBackward() {
	if e.cursorOffsetX > 0 {
		e.cursorOffsetX -= 1
	}
}
func (e *Engine) moveCursorForward() {
	if len(e.query.Get()) > e.cursorOffsetX {
		e.cursorOffsetX += 1
	}
}
func (e *Engine) moveCursorWordBackwark() {
}
func (e *Engine) moveCursorWordForward() {
}
func (e *Engine) moveCursorToTop() {
	e.cursorOffsetX = 0
}
func (e *Engine) moveCursorToEnd() {
	e.cursorOffsetX = len(e.query.Get())
}
<|endoftext|>


<commit_before>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ogletest

import (
	"fmt"
	"reflect"
)

// Equals returns a matcher that matches any value v such that v == x, with the
// exception that if x is a numeric type, Equals(x) will match equivalent
// numeric values of any type.
func Equals(x interface{}) Matcher {
	return &equalsMatcher{x}
}

type equalsMatcher struct {
	expected interface{}
}

////////////////////////////////////////////////////////////
// Numeric types
////////////////////////////////////////////////////////////

func isSignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Int && k <= reflect.Int64
}

func isUnsignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Uint && k <= reflect.Uint64
}

func isInteger(v reflect.Value) bool {
	return isSignedInteger(v) || isUnsignedInteger(v)
}

func isFloat(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Float32 || k == reflect.Float64
}

func isComplex(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Complex64 || k == reflect.Complex128
}

func checkAgainstFloat32(e float32, c reflect.Value) (res MatchResult, err string) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		if float32(c.Int()) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if float32(c.Uint()) == e {
			res = MATCH_TRUE
		}

	case isFloat(c):
		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match float32(0.1).
		if float32(c.Float()) == e {
			res = MATCH_TRUE
		}

	case isComplex(c):
		comp := c.Complex()
		rl := real(comp)
		im := imag(comp)

		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match (0.1 + 0i).
		if im == 0 && float32(rl) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = "which is not numeric"
	}

	return
}

func checkAgainstComplex64(e complex64, c reflect.Value) (res MatchResult, err string) {
	res = MATCH_FALSE
	realPart := real(e)
	imaginaryPart := imag(e)

	switch {
	case isInteger(c) || isFloat(c):
		// If we have no imaginary part, then we should just compare against the
		// real part. Otherwise, we can't be equal.
		if imaginaryPart != 0 {
			res = MATCH_FALSE
			return
		}

		return checkAgainstFloat32(realPart, c)

	case isComplex(c):
		// Compare using complex64 to avoid a false sense of precision; otherwise
		// e.g. Equals(0.1 + 0i) won't match float32(0.1).
		if complex64(c.Complex()) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = "which is not numeric"
	}

	return
}

////////////////////////////////////////////////////////////
// Public implementation
////////////////////////////////////////////////////////////

func (m *equalsMatcher) Matches(candidate interface{}) (MatchResult, string) {
	e := reflect.ValueOf(m.expected)
	c := reflect.ValueOf(candidate)

	switch e.Kind() {
	case reflect.Float32:
		return checkAgainstFloat32(float32(e.Float()), c)

	case reflect.Complex64:
		return checkAgainstComplex64(complex64(e.Complex()), c)
	}

	return MATCH_UNDEFINED, "TODO"
}

func (m *equalsMatcher) Description() string {
	return fmt.Sprintf("%v", m.expected)
}
<commit_msg>Implemented float64 matching.<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ogletest

import (
	"fmt"
	"reflect"
)

// Equals returns a matcher that matches any value v such that v == x, with the
// exception that if x is a numeric type, Equals(x) will match equivalent
// numeric values of any type.
func Equals(x interface{}) Matcher {
	return &equalsMatcher{x}
}

type equalsMatcher struct {
	expected interface{}
}

////////////////////////////////////////////////////////////
// Numeric types
////////////////////////////////////////////////////////////

func isSignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Int && k <= reflect.Int64
}

func isUnsignedInteger(v reflect.Value) bool {
	k := v.Kind()
	return k >= reflect.Uint && k <= reflect.Uint64
}

func isInteger(v reflect.Value) bool {
	return isSignedInteger(v) || isUnsignedInteger(v)
}

func isFloat(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Float32 || k == reflect.Float64
}

func isComplex(v reflect.Value) bool {
	k := v.Kind()
	return k == reflect.Complex64 || k == reflect.Complex128
}

func checkAgainstFloat32(e float32, c reflect.Value) (res MatchResult, err string) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		if float32(c.Int()) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if float32(c.Uint()) == e {
			res = MATCH_TRUE
		}

	case isFloat(c):
		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match float32(0.1).
		if float32(c.Float()) == e {
			res = MATCH_TRUE
		}

	case isComplex(c):
		comp := c.Complex()
		rl := real(comp)
		im := imag(comp)

		// Compare using float32 to avoid a false sense of precision; otherwise
		// e.g. Equals(float32(0.1)) won't match (0.1 + 0i).
		if im == 0 && float32(rl) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = "which is not numeric"
	}

	return
}

func checkAgainstFloat64(e float64, c reflect.Value) (res MatchResult, err string) {
	res = MATCH_FALSE

	switch {
	case isSignedInteger(c):
		if float64(c.Int()) == e {
			res = MATCH_TRUE
		}

	case isUnsignedInteger(c):
		if float64(c.Uint()) == e {
			res = MATCH_TRUE
		}

	case isFloat(c):
		if c.Float() == e {
			res = MATCH_TRUE
		}

	case isComplex(c):
		comp := c.Complex()
		rl := real(comp)
		im := imag(comp)

		if im == 0 && rl == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = "which is not numeric"
	}

	return
}

func checkAgainstComplex64(e complex64, c reflect.Value) (res MatchResult, err string) {
	res = MATCH_FALSE
	realPart := real(e)
	imaginaryPart := imag(e)

	switch {
	case isInteger(c) || isFloat(c):
		// If we have no imaginary part, then we should just compare against the
		// real part. Otherwise, we can't be equal.
		if imaginaryPart != 0 {
			res = MATCH_FALSE
			return
		}

		return checkAgainstFloat32(realPart, c)

	case isComplex(c):
		// Compare using complex64 to avoid a false sense of precision; otherwise
		// e.g. Equals(0.1 + 0i) won't match float32(0.1).
		if complex64(c.Complex()) == e {
			res = MATCH_TRUE
		}

	default:
		res = MATCH_UNDEFINED
		err = "which is not numeric"
	}

	return
}

////////////////////////////////////////////////////////////
// Public implementation
////////////////////////////////////////////////////////////

func (m *equalsMatcher) Matches(candidate interface{}) (MatchResult, string) {
	e := reflect.ValueOf(m.expected)
	c := reflect.ValueOf(candidate)

	switch e.Kind() {
	case reflect.Float32:
		return checkAgainstFloat32(float32(e.Float()), c)

	case reflect.Float64:
		return checkAgainstFloat64(e.Float(), c)

	case reflect.Complex64:
		return checkAgainstComplex64(complex64(e.Complex()), c)
	}

	return MATCH_UNDEFINED, "TODO"
}

func (m *equalsMatcher) Description() string {
	return fmt.Sprintf("%v", m.expected)
}
<|endoftext|>


<commit_before>// Copyright (C) 2013 Space Monkey, Inc.

package errors

import (
    "flag"
    "fmt"
    "log"
    "runtime"
    "strings"
)

var (
    stackLogSize = flag.Int("errors.stack_trace_log_length", 4096,
        "The max stack trace byte length to log")
    stackCaptureSize = flag.Int("errors.stack_trace_capture_length", 2048,
        "The max stack trace byte length to capture")
)

type ErrorClassFlags uint64

const (
    LogOnCreation ErrorClassFlags = 1 << iota
    CaptureStack
)

type ErrorClass struct {
    parent *ErrorClass
    name   string
    flags  ErrorClassFlags
}

var (
    // base error classes. To construct your own error class, use New.
    SystemError = &ErrorClass{
        parent: nil,
        name:   "System Error"}
    HierarchicalError = &ErrorClass{
        parent: nil,
        name:   "Error",
        flags:  CaptureStack}
)

// NewSpecified creates an error class for making specific errors. Regardless
// of where the error class is in the error class hierarchy, the error class
// flags for this error class are final, and no other context is used to
// determine the final operating set.
func NewSpecified(ec *ErrorClass, name string, flags ErrorClassFlags) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: flags}
}

// NewWith creates an error class for making specific errors. NewWith takes the
// parent's error class flags, appends them to the provided flags, and
// configures the new error class to use them.
func NewWith(ec *ErrorClass, name string, flags_to_add ErrorClassFlags) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: ec.flags | flags_to_add}
}

// NewWithout creates an error class for making specific errors. NewWithout
// takes the parent's error class flags, ensures the provided flags are
// stripped, and configures the new error class to use the resulting set.
func NewWithout(ec *ErrorClass, name string, flags_to_remove ErrorClassFlags) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: ec.flags & ^flags_to_remove}
}

// New is like NewWith or NewWithout without any flags provided.
func New(ec *ErrorClass, name string) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: ec.flags}
}

func (e *ErrorClass) Is(parent *ErrorClass) bool {
    for check := e; check != nil; check = check.parent {
        if check == parent {
            return true
        }
    }
    return false
}

type Error struct {
    err   error
    class *ErrorClass
    stack []byte
}

func (e *ErrorClass) Wrap(err error, classes ...*ErrorClass) error {
    if err == nil {
        return nil
    }
    if ec, ok := err.(*Error); ok {
        if ec.Is(e) {
            return err
        }
        for _, class := range classes {
            if ec.Is(class) {
                return err
            }
        }
    }
    rv := &Error{err: err, class: e}
    if e.flags&CaptureStack > 0 {
        buf := make([]byte, *stackCaptureSize)
        rv.stack = buf[:runtime.Stack(buf, false)]
    }
    if e.flags&LogOnCreation > 0 {
        LogWithStack(rv.Error())
    }
    return rv
}

func (e *ErrorClass) New(format string, args ...interface{}) error {
    return e.Wrap(fmt.Errorf(format, args...))
}

func (e *Error) Error() string {
    message := strings.TrimRight(e.err.Error(), "\n ")
    if strings.Contains(message, "\n") {
        message = fmt.Sprintf("%s:\n  %s", e.class.name,
            strings.Replace(message, "\n", "\n  ", -1))
    } else {
        message = fmt.Sprintf("%s: %s", e.class.name, message)
    }
    if e.stack == nil {
        return message
    }
    return fmt.Sprintf("%s\n\n%s backtrace: %s", message, e.class.name, e.stack)
}

func (e *Error) WrappedErr() error {
    return e.err
}

func (e *Error) Class() *ErrorClass {
    return e.class
}

func (e *Error) Stack() []byte {
    return e.stack
}

func WrappedErr(err error) error {
    cast, ok := err.(*Error)
    if !ok {
        return err
    }
    return cast.WrappedErr()
}

func (e *Error) Is(ec *ErrorClass) bool {
    return e.class.Is(ec)
}

func (e *ErrorClass) Contains(err error) bool {
    cast, ok := err.(*Error)
    if !ok {
        return SystemError == e
    }
    return cast.Is(e)
}

func LogWithStack(message string) {
    buf := make([]byte, *stackLogSize)
    buf = buf[:runtime.Stack(buf, false)]
    log.Printf("%s\n%s", message, buf)
}

var (
    // useful error classes
    NotImplementedError = NewSpecified(nil, "Not Implemented Error", LogOnCreation|CaptureStack)
    ProgrammerError     = NewSpecified(nil, "Programmer Error", LogOnCreation|CaptureStack)
)
<commit_msg>space monkey internal commit export<commit_after>// Copyright (C) 2013 Space Monkey, Inc.

package errors

import (
    "flag"
    "fmt"
    "log"
    "runtime"
    "strings"
)

var (
    stackLogSize = flag.Int("errors.stack_trace_log_length", 4096,
        "The max stack trace byte length to log")
    stackCaptureSize = flag.Int("errors.stack_trace_capture_length", 2048,
        "The max stack trace byte length to capture")
)

type ErrorClassFlags uint64

const (
    LogOnCreation ErrorClassFlags = 1 << iota
    CaptureStack
)

type ErrorClass struct {
    parent *ErrorClass
    name   string
    flags  ErrorClassFlags
}

var (
    // base error classes. To construct your own error class, use New.
    SystemError = &ErrorClass{
        parent: nil,
        name:   "System Error"}
    HierarchicalError = &ErrorClass{
        parent: nil,
        name:   "Error",
        flags:  CaptureStack}
)

// NewSpecified creates an error class for making specific errors. Regardless
// of where the error class is in the error class hierarchy, the error class
// flags for this error class are final, and no other context is used to
// determine the final operating set.
func NewSpecified(ec *ErrorClass, name string, flags ErrorClassFlags) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: flags}
}

// NewWith creates an error class for making specific errors. NewWith takes the
// parent's error class flags, appends them to the provided flags, and
// configures the new error class to use them.
func NewWith(ec *ErrorClass, name string, flags_to_add ErrorClassFlags) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: ec.flags | flags_to_add}
}

// NewWithout creates an error class for making specific errors. NewWithout
// takes the parent's error class flags, ensures the provided flags are
// stripped, and configures the new error class to use the resulting set.
func NewWithout(ec *ErrorClass, name string, flags_to_remove ErrorClassFlags) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: ec.flags & ^flags_to_remove}
}

// New is like NewWith or NewWithout without any flags provided.
func New(ec *ErrorClass, name string) *ErrorClass {
    if ec == nil {
        ec = HierarchicalError
    }
    return &ErrorClass{parent: ec, name: name, flags: ec.flags}
}

func (e *ErrorClass) Parent() *ErrorClass {
    return e.parent
}

func (e *ErrorClass) Is(parent *ErrorClass) bool {
    for check := e; check != nil; check = check.parent {
        if check == parent {
            return true
        }
    }
    return false
}

type Error struct {
    err   error
    class *ErrorClass
    stack []byte
}

func (e *ErrorClass) Wrap(err error, classes ...*ErrorClass) error {
    if err == nil {
        return nil
    }
    if ec, ok := err.(*Error); ok {
        if ec.Is(e) {
            return err
        }
        for _, class := range classes {
            if ec.Is(class) {
                return err
            }
        }
    }
    rv := &Error{err: err, class: e}
    if e.flags&CaptureStack > 0 {
        buf := make([]byte, *stackCaptureSize)
        rv.stack = buf[:runtime.Stack(buf, false)]
    }
    if e.flags&LogOnCreation > 0 {
        LogWithStack(rv.Error())
    }
    return rv
}

func (e *ErrorClass) New(format string, args ...interface{}) error {
    return e.Wrap(fmt.Errorf(format, args...))
}

func (e *Error) Error() string {
    message := strings.TrimRight(e.err.Error(), "\n ")
    if strings.Contains(message, "\n") {
        message = fmt.Sprintf("%s:\n  %s", e.class.name,
            strings.Replace(message, "\n", "\n  ", -1))
    } else {
        message = fmt.Sprintf("%s: %s", e.class.name, message)
    }
    if e.stack == nil {
        return message
    }
    return fmt.Sprintf("%s\n\n%s backtrace: %s", message, e.class.name, e.stack)
}

func (e *Error) WrappedErr() error {
    return e.err
}

func (e *Error) Class() *ErrorClass {
    return e.class
}

func (e *Error) Stack() []byte {
    return e.stack
}

func WrappedErr(err error) error {
    cast, ok := err.(*Error)
    if !ok {
        return err
    }
    return cast.WrappedErr()
}

func (e *Error) Is(ec *ErrorClass) bool {
    return e.class.Is(ec)
}

func (e *ErrorClass) Contains(err error) bool {
    cast, ok := err.(*Error)
    if !ok {
        return SystemError == e
    }
    return cast.Is(e)
}

func LogWithStack(message string) {
    buf := make([]byte, *stackLogSize)
    buf = buf[:runtime.Stack(buf, false)]
    log.Printf("%s\n%s", message, buf)
}

var (
    // useful error classes
    NotImplementedError = NewSpecified(nil, "Not Implemented Error", LogOnCreation|CaptureStack)
    ProgrammerError     = NewSpecified(nil, "Programmer Error", LogOnCreation|CaptureStack)
)
<|endoftext|>


<commit_before>package locker

import "fmt"

type LockNotFound struct {
	service string
}

func (e LockNotFound) Error() string {
	return fmt.Sprintf("Lock not found: %s", e.service)
}

type KeyNotFound struct {
	key string
}

func (e KeyNotFound) Error() string {
	return fmt.Sprintf("Key not found: %s", e.key)
}

type LockDenied struct {
	key string
}

func (e LockDenied) Error() string {
	return fmt.Sprintf("Lock attempt was denied: %s", e.key)
}
<commit_msg>Remove unused error<commit_after>package locker

import "fmt"

type LockNotFound struct {
	service string
}

func (e LockNotFound) Error() string {
	return fmt.Sprintf("Lock not found: %s", e.service)
}

type LockDenied struct {
	key string
}

func (e LockDenied) Error() string {
	return fmt.Sprintf("Lock attempt was denied: %s", e.key)
}
<|endoftext|>


<commit_before>package util

import (
	"log"
	"runtime"
)

func CheckErr(err error) {
	if err != nil {
		log.SetFlags(0)
		_, filename, lineno, ok := runtime.Caller(1)
		if ok {
			log.Fatalf("%v:%v: %v\n", filename, lineno, err)
		} else {
			log.Fatalln(err)
		}
	}
}

func WarnErr(err error) error {
	if err != nil {
		f := log.Flags()
		log.SetFlags(0)
		_, filename, lineno, ok := runtime.Caller(1)
		if ok {
			log.Printf("%v:%v: %v\n", filename, lineno, err)
		} else {
			log.Println(err)
		}
		log.SetFlags(f)
	}
	return err
}
<commit_msg>CheckErr(), WarnErr(): now with optional additional arguments to print in message.<commit_after>package util

import (
	"bytes"
	"fmt"
	"log"
	"runtime"
)

func makeErr(err error, msg ...interface{}) string {
	var b bytes.Buffer
	_, filename, lineno, ok := runtime.Caller(2)
	if ok {
		b.WriteString(fmt.Sprintf("%v:%v: %v", filename, lineno, err))
	} else {
		b.WriteString(err.Error())
	}
	if len(msg) > 0 {
		b.WriteString(",")
		for _, m := range msg {
			b.WriteString(fmt.Sprintf(" %v", m))
		}
	}
	return b.String()
}

func CheckErr(err error, msg ...interface{}) {
	if err != nil {
		log.SetFlags(0)
		log.Fatalln(makeErr(err, msg...))
	}
}

func WarnErr(err error, msg ...interface{}) error {
	if err != nil {
		f := log.Flags()
		log.SetFlags(0)
		log.Println(makeErr(err, msg...))
		log.SetFlags(f)
	}
	return err
}
<|endoftext|>


<commit_before>package merr

import (
	"fmt"
)

type MultiError struct {
	Errors []error
}

func New(errs ...error) error {
	if len(errs) == 0 {
		return nil
	}

	return &MultiError{errs}
}

func (e *MultiError) Error() string {
	errs := e.Errors
	tail := "..."

	switch len(errs) {
	case 0:
		return ""
	case 1:
		tail = ""
	}

	return fmt.Sprint("errors: ", len(errs), errs[0], tail)
}
<commit_msg>Errors インタフェース<commit_after>package merr

import (
	"fmt"
)

type Errors interface {
	Errors() []error
}

type multiError struct {
	errs []error
}

func New(errs ...error) error {
	if len(errs) == 0 {
		return nil
	}

	return &multiError{errs}
}

func (e *multiError) Error() string {
	errs := e.errs
	tail := "..."

	switch len(errs) {
	case 0:
		return ""
	case 1:
		tail = ""
	}

	return fmt.Sprint("errors: ", len(errs), errs[0], tail)
}

func (e *multiError) Errors() []error {
	return e.errs
}
<|endoftext|>


<commit_before>// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gocui

import (
	"errors"
	"strconv"
)

type escapeInterpreter struct {
	state                  escapeState
	curch                  rune
	csiParam               []string
	curFgColor, curBgColor Attribute
	mode                   OutputMode
}

type escapeState int

const (
	stateNone escapeState = iota
	stateEscape
	stateCSI
	stateParams
)

var (
	errNotCSI        = errors.New("Not a CSI escape sequence")
	errCSIParseError = errors.New("CSI escape sequence parsing error")
	errCSITooLong    = errors.New("CSI escape sequence is too long")
)

// runes in case of error will output the non-parsed runes as a string.
func (ei *escapeInterpreter) runes() []rune {
	switch ei.state {
	case stateNone:
		return []rune{0x1b}
	case stateEscape:
		return []rune{0x1b, ei.curch}
	case stateCSI:
		return []rune{0x1b, '[', ei.curch}
	case stateParams:
		ret := []rune{0x1b, '['}
		for _, s := range ei.csiParam {
			ret = append(ret, []rune(s)...)
			ret = append(ret, ';')
		}
		return append(ret, ei.curch)
	}
	return nil
}

// newEscapeInterpreter returns an escapeInterpreter that will be able to parse
// terminal escape sequences.
func newEscapeInterpreter(mode OutputMode) *escapeInterpreter {
	ei := &escapeInterpreter{
		state:      stateNone,
		curFgColor: ColorDefault,
		curBgColor: ColorDefault,
		mode:       mode,
	}
	return ei
}

// reset sets the escapeInterpreter in initial state.
func (ei *escapeInterpreter) reset() {
	ei.state = stateNone
	ei.curFgColor = ColorDefault
	ei.curBgColor = ColorDefault
	ei.csiParam = nil
}

// parseOne parses a rune. If isEscape is true, it means that the rune is part
// of an escape sequence, and as such should not be printed verbatim. Otherwise,
// it's not an escape sequence.
func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
	// Sanity checks
	if len(ei.csiParam) > 20 {
		return false, errCSITooLong
	}
	if len(ei.csiParam) > 0 && len(ei.csiParam[len(ei.csiParam)-1]) > 255 {
		return false, errCSITooLong
	}

	ei.curch = ch

	switch ei.state {
	case stateNone:
		if ch == 0x1b {
			ei.state = stateEscape
			return true, nil
		}
		return false, nil
	case stateEscape:
		if ch == '[' {
			ei.state = stateCSI
			return true, nil
		}
		return false, errNotCSI
	case stateCSI:
		switch {
		case ch >= '0' && ch <= '9':
			ei.csiParam = append(ei.csiParam, "")
		case ch == 'm':
			ei.csiParam = append(ei.csiParam, "0")
		default:
			return false, errCSIParseError
		}
		ei.state = stateParams
		fallthrough
	case stateParams:
		switch {
		case ch >= '0' && ch <= '9':
			ei.csiParam[len(ei.csiParam)-1] += string(ch)
			return true, nil
		case ch == ';':
			ei.csiParam = append(ei.csiParam, "")
			return true, nil
		case ch == 'm':
			var err error
			switch ei.mode {
			case OutputNormal:
				err = ei.outputNormal()
			case Output256:
				err = ei.output256()
			}
			if err != nil {
				return false, errCSIParseError
			}

			ei.state = stateNone
			ei.csiParam = nil
			return true, nil
		}
	}
	return false, nil
}

// outputNormal provides 8 different colors:
//   black, red, green, yellow, blue, magenta, cyan, white
func (ei *escapeInterpreter) outputNormal() error {
	for _, param := range ei.csiParam {
		p, err := strconv.Atoi(param)
		if err != nil {
			return errCSIParseError
		}

		switch {
		case p >= 30 && p <= 37:
			ei.curFgColor = Attribute(p - 30 + 1)
		case p == 39:
			ei.curFgColor = ColorDefault
		case p >= 40 && p <= 47:
			ei.curBgColor = Attribute(p - 40 + 1)
		case p == 49:
			ei.curBgColor = ColorDefault
		case p == 1:
			ei.curFgColor |= AttrBold
		case p == 4:
			ei.curFgColor |= AttrUnderline
		case p == 7:
			ei.curFgColor |= AttrReverse
		case p == 0:
			ei.curFgColor = ColorDefault
			ei.curBgColor = ColorDefault
		}
	}

	return nil
}

// output256 allows you to leverage the 256-colors terminal mode:
//   0x01 - 0x08: the 8 colors as in OutputNormal
//   0x09 - 0x10: Color* | AttrBold
//   0x11 - 0xe8: 216 different colors
//   0xe9 - 0x1ff: 24 different shades of grey
func (ei *escapeInterpreter) output256() error {
	if len(ei.csiParam) < 3 {
		return ei.outputNormal()
	}

	mode, err := strconv.Atoi(ei.csiParam[1])
	if err != nil {
		return errCSIParseError
	}
	if mode != 5 {
		return ei.outputNormal()
	}

	fgbg, err := strconv.Atoi(ei.csiParam[0])
	if err != nil {
		return errCSIParseError
	}
	color, err := strconv.Atoi(ei.csiParam[2])
	if err != nil {
		return errCSIParseError
	}

	switch fgbg {
	case 38:
		ei.curFgColor = Attribute(color + 1)

		for _, param := range ei.csiParam[3:] {
			p, err := strconv.Atoi(param)
			if err != nil {
				return errCSIParseError
			}

			switch {
			case p == 1:
				ei.curFgColor |= AttrBold
			case p == 4:
				ei.curFgColor |= AttrUnderline
			case p == 7:
				ei.curFgColor |= AttrReverse
			}
		}
	case 48:
		ei.curBgColor = Attribute(color + 1)
	default:
		return errCSIParseError
	}

	return nil
}
<commit_msg>Fix error handling in *escapeInterpreter.parseOne()<commit_after>// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gocui

import (
	"errors"
	"strconv"
)

type escapeInterpreter struct {
	state                  escapeState
	curch                  rune
	csiParam               []string
	curFgColor, curBgColor Attribute
	mode                   OutputMode
}

type escapeState int

const (
	stateNone escapeState = iota
	stateEscape
	stateCSI
	stateParams
)

var (
	errNotCSI        = errors.New("Not a CSI escape sequence")
	errCSIParseError = errors.New("CSI escape sequence parsing error")
	errCSITooLong    = errors.New("CSI escape sequence is too long")
)

// runes in case of error will output the non-parsed runes as a string.
func (ei *escapeInterpreter) runes() []rune {
	switch ei.state {
	case stateNone:
		return []rune{0x1b}
	case stateEscape:
		return []rune{0x1b, ei.curch}
	case stateCSI:
		return []rune{0x1b, '[', ei.curch}
	case stateParams:
		ret := []rune{0x1b, '['}
		for _, s := range ei.csiParam {
			ret = append(ret, []rune(s)...)
			ret = append(ret, ';')
		}
		return append(ret, ei.curch)
	}
	return nil
}

// newEscapeInterpreter returns an escapeInterpreter that will be able to parse
// terminal escape sequences.
func newEscapeInterpreter(mode OutputMode) *escapeInterpreter {
	ei := &escapeInterpreter{
		state:      stateNone,
		curFgColor: ColorDefault,
		curBgColor: ColorDefault,
		mode:       mode,
	}
	return ei
}

// reset sets the escapeInterpreter in initial state.
func (ei *escapeInterpreter) reset() {
	ei.state = stateNone
	ei.curFgColor = ColorDefault
	ei.curBgColor = ColorDefault
	ei.csiParam = nil
}

// parseOne parses a rune. If isEscape is true, it means that the rune is part
// of an escape sequence, and as such should not be printed verbatim. Otherwise,
// it's not an escape sequence.
func (ei *escapeInterpreter) parseOne(ch rune) (isEscape bool, err error) {
	// Sanity checks
	if len(ei.csiParam) > 20 {
		return false, errCSITooLong
	}
	if len(ei.csiParam) > 0 && len(ei.csiParam[len(ei.csiParam)-1]) > 255 {
		return false, errCSITooLong
	}

	ei.curch = ch

	switch ei.state {
	case stateNone:
		if ch == 0x1b {
			ei.state = stateEscape
			return true, nil
		}
		return false, nil
	case stateEscape:
		if ch == '[' {
			ei.state = stateCSI
			return true, nil
		}
		return false, errNotCSI
	case stateCSI:
		switch {
		case ch >= '0' && ch <= '9':
			ei.csiParam = append(ei.csiParam, "")
		case ch == 'm':
			ei.csiParam = append(ei.csiParam, "0")
		default:
			return false, errCSIParseError
		}
		ei.state = stateParams
		fallthrough
	case stateParams:
		switch {
		case ch >= '0' && ch <= '9':
			ei.csiParam[len(ei.csiParam)-1] += string(ch)
			return true, nil
		case ch == ';':
			ei.csiParam = append(ei.csiParam, "")
			return true, nil
		case ch == 'm':
			var err error
			switch ei.mode {
			case OutputNormal:
				err = ei.outputNormal()
			case Output256:
				err = ei.output256()
			}
			if err != nil {
				return false, errCSIParseError
			}

			ei.state = stateNone
			ei.csiParam = nil
			return true, nil
		default:
			return false, errCSIParseError
		}
	}
	return false, nil
}

// outputNormal provides 8 different colors:
//   black, red, green, yellow, blue, magenta, cyan, white
func (ei *escapeInterpreter) outputNormal() error {
	for _, param := range ei.csiParam {
		p, err := strconv.Atoi(param)
		if err != nil {
			return errCSIParseError
		}

		switch {
		case p >= 30 && p <= 37:
			ei.curFgColor = Attribute(p - 30 + 1)
		case p == 39:
			ei.curFgColor = ColorDefault
		case p >= 40 && p <= 47:
			ei.curBgColor = Attribute(p - 40 + 1)
		case p == 49:
			ei.curBgColor = ColorDefault
		case p == 1:
			ei.curFgColor |= AttrBold
		case p == 4:
			ei.curFgColor |= AttrUnderline
		case p == 7:
			ei.curFgColor |= AttrReverse
		case p == 0:
			ei.curFgColor = ColorDefault
			ei.curBgColor = ColorDefault
		}
	}

	return nil
}

// output256 allows you to leverage the 256-colors terminal mode:
//   0x01 - 0x08: the 8 colors as in OutputNormal
//   0x09 - 0x10: Color* | AttrBold
//   0x11 - 0xe8: 216 different colors
//   0xe9 - 0x1ff: 24 different shades of grey
func (ei *escapeInterpreter) output256() error {
	if len(ei.csiParam) < 3 {
		return ei.outputNormal()
	}

	mode, err := strconv.Atoi(ei.csiParam[1])
	if err != nil {
		return errCSIParseError
	}
	if mode != 5 {
		return ei.outputNormal()
	}

	fgbg, err := strconv.Atoi(ei.csiParam[0])
	if err != nil {
		return errCSIParseError
	}
	color, err := strconv.Atoi(ei.csiParam[2])
	if err != nil {
		return errCSIParseError
	}

	switch fgbg {
	case 38:
		ei.curFgColor = Attribute(color + 1)

		for _, param := range ei.csiParam[3:] {
			p, err := strconv.Atoi(param)
			if err != nil {
				return errCSIParseError
			}

			switch {
			case p == 1:
				ei.curFgColor |= AttrBold
			case p == 4:
				ei.curFgColor |= AttrUnderline
			case p == 7:
				ei.curFgColor |= AttrReverse
			}
		}
	case 48:
		ei.curBgColor = Attribute(color + 1)
	default:
		return errCSIParseError
	}

	return nil
}
<|endoftext|>


<commit_before>package birpc_test

import (
	"encoding/json"
	"errors"
	"io"
	"net"
	"testing"

	"github.com/tv42/birpc"
	"github.com/tv42/birpc/jsonmsg"
)

type WordLengthRequest struct {
	Word string
}

type WordLengthReply struct {
	Length int
}

type WordLength_LowLevelReply struct {
	Id     uint64          `json:"id,string"`
	Result WordLengthReply `json:"result"`
	Error  *birpc.Error    `json:"error"`
}

type WordLength struct{}

func (_ WordLength) Len(request *WordLengthRequest, reply *WordLengthReply) error {
	reply.Length = len(request.Word)
	return nil
}

// this is here only to trigger a bug where all methods are thought to
// be rpc methods
func (_ WordLength) redHerring() {
}

func makeRegistry() *birpc.Registry {
	r := birpc.NewRegistry()
	r.RegisterService(WordLength{})
	return r
}

const PALINDROME = `{"id": "42", "fn": "WordLength.Len", "args": {"Word": "saippuakauppias"}}` + "\n"

func TestServerSimple(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := makeRegistry()
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	io.WriteString(c, PALINDROME)

	var reply WordLength_LowLevelReply
	dec := json.NewDecoder(c)
	if err := dec.Decode(&reply); err != nil && err != io.EOF {
		t.Fatalf("decode failed: %s", err)
	}
	t.Logf("reply msg: %#v", reply)
	if reply.Error != nil {
		t.Fatalf("unexpected error response: %v", reply.Error)
	}
	if reply.Result.Length != 15 {
		t.Fatalf("got wrong answer: %v", reply.Result.Length)
	}

	c.Close()

	err := <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from ServeCodec: %v", err)
	}
}

func TestClient(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := makeRegistry()
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	client := birpc.NewEndpoint(jsonmsg.NewCodec(c), nil)
	client_err := make(chan error)
	go func() {
		client_err <- client.Serve()
	}()

	// Synchronous calls
	args := &WordLengthRequest{"xyzzy"}
	reply := &WordLengthReply{}
	err := client.Call("WordLength.Len", args, reply)
	if err != nil {
		t.Errorf("unexpected error from call: %v", err.Error())
	}
	if reply.Length != 5 {
		t.Fatalf("got wrong answer: %v", reply.Length)
	}

	c.Close()

	err = <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from peer ServeCodec: %v", err)
	}

	err = <-client_err
	if err != io.ErrClosedPipe {
		t.Fatalf("unexpected error from local ServeCodec: %v", err)
	}
}

func TestClientNilResult(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := makeRegistry()
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	client := birpc.NewEndpoint(jsonmsg.NewCodec(c), nil)
	client_err := make(chan error)
	go func() {
		client_err <- client.Serve()
	}()

	// Synchronous calls
	args := &WordLengthRequest{"xyzzy"}
	err := client.Call("WordLength.Len", args, nil)
	if err != nil {
		t.Errorf("unexpected error from call: %v", err.Error())
	}

	c.Close()

	err = <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from peer ServeCodec: %v", err)
	}

	err = <-client_err
	if err != io.ErrClosedPipe {
		t.Fatalf("unexpected error from local ServeCodec: %v", err)
	}
}

type EndpointPeer struct {
	seen *birpc.Endpoint
}

type nothing struct{}

func (e *EndpointPeer) Poke(request *nothing, reply *nothing, endpoint *birpc.Endpoint) error {
	if e.seen != nil {
		panic("poke called twice")
	}
	e.seen = endpoint
	return nil
}

type EndpointPeer_LowLevelReply struct {
	Id     uint64          `json:"id,string"`
	Result json.RawMessage `json:"result"`
	Error  *birpc.Error    `json:"error"`
}

func TestServerEndpointArg(t *testing.T) {
	peer := &EndpointPeer{}
	registry := birpc.NewRegistry()
	registry.RegisterService(peer)

	c, s := net.Pipe()
	defer c.Close()

	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	io.WriteString(c, `{"id":"42","fn":"EndpointPeer.Poke","args":{}}`)

	var reply EndpointPeer_LowLevelReply
	dec := json.NewDecoder(c)
	if err := dec.Decode(&reply); err != nil && err != io.EOF {
		t.Fatalf("decode failed: %s", err)
	}
	t.Logf("reply msg: %#v", reply)
	if reply.Error != nil {
		t.Fatalf("unexpected error response: %v", reply.Error)
	}
	c.Close()

	err := <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from ServeCodec: %v", err)
	}

	if peer.seen == nil {
		t.Fatalf("peer never saw a birpc.Endpoint")
	}
}

type Failing struct{}

func (_ Failing) Fail(request *nothing, reply *nothing) error {
	return errors.New("intentional")
}

type LowLevelFailingMsg struct {
	Id     uint64           `json:"id,string"`
	Result *json.RawMessage `json:"result"`
	Error  *birpc.Error     `json:"error"`
}

func TestServerError(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := birpc.NewRegistry()
	registry.RegisterService(Failing{})
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	const REQ = `{"id": "42", "fn": "Failing.Fail", "args": {}}` + "\n"
	io.WriteString(c, REQ)

	var reply LowLevelFailingMsg
	dec := json.NewDecoder(c)
	if err := dec.Decode(&reply); err != nil && err != io.EOF {
		t.Fatalf("decode failed: %s", err)
	}
	t.Logf("reply msg: %#v", reply)
	if reply.Error == nil {
		t.Fatalf("expected an error")
	}
	if g, e := reply.Error.Msg, "intentional"; g != e {
		t.Fatalf("unexpected error response: %q != %q", g, e)
	}
	if reply.Result != nil {
		t.Fatalf("got unexpected result: %v", reply.Result)
	}

	c.Close()

	err := <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from ServeCodec: %v", err)
	}
}
<commit_msg>Refactor to share test data structures<commit_after>package birpc_test

import (
	"encoding/json"
	"errors"
	"io"
	"net"
	"testing"

	"github.com/tv42/birpc"
	"github.com/tv42/birpc/jsonmsg"
)

// Generic reply parsing
type LowLevelReply struct {
	Id     uint64          `json:"id,string"`
	Result json.RawMessage `json:"result"`
	Error  *birpc.Error    `json:"error"`
}

type WordLengthRequest struct {
	Word string
}

type WordLengthReply struct {
	Length int
}

type WordLength_LowLevelReply struct {
	Id     uint64          `json:"id,string"`
	Result WordLengthReply `json:"result"`
	Error  *birpc.Error    `json:"error"`
}

type WordLength struct{}

func (_ WordLength) Len(request *WordLengthRequest, reply *WordLengthReply) error {
	reply.Length = len(request.Word)
	return nil
}

// this is here only to trigger a bug where all methods are thought to
// be rpc methods
func (_ WordLength) redHerring() {
}

func makeRegistry() *birpc.Registry {
	r := birpc.NewRegistry()
	r.RegisterService(WordLength{})
	return r
}

const PALINDROME = `{"id": "42", "fn": "WordLength.Len", "args": {"Word": "saippuakauppias"}}` + "\n"

func TestServerSimple(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := makeRegistry()
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	io.WriteString(c, PALINDROME)

	var reply WordLength_LowLevelReply
	dec := json.NewDecoder(c)
	if err := dec.Decode(&reply); err != nil && err != io.EOF {
		t.Fatalf("decode failed: %s", err)
	}
	t.Logf("reply msg: %#v", reply)
	if reply.Error != nil {
		t.Fatalf("unexpected error response: %v", reply.Error)
	}
	if reply.Result.Length != 15 {
		t.Fatalf("got wrong answer: %v", reply.Result.Length)
	}

	c.Close()

	err := <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from ServeCodec: %v", err)
	}
}

func TestClient(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := makeRegistry()
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	client := birpc.NewEndpoint(jsonmsg.NewCodec(c), nil)
	client_err := make(chan error)
	go func() {
		client_err <- client.Serve()
	}()

	// Synchronous calls
	args := &WordLengthRequest{"xyzzy"}
	reply := &WordLengthReply{}
	err := client.Call("WordLength.Len", args, reply)
	if err != nil {
		t.Errorf("unexpected error from call: %v", err.Error())
	}
	if reply.Length != 5 {
		t.Fatalf("got wrong answer: %v", reply.Length)
	}

	c.Close()

	err = <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from peer ServeCodec: %v", err)
	}

	err = <-client_err
	if err != io.ErrClosedPipe {
		t.Fatalf("unexpected error from local ServeCodec: %v", err)
	}
}

func TestClientNilResult(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := makeRegistry()
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	client := birpc.NewEndpoint(jsonmsg.NewCodec(c), nil)
	client_err := make(chan error)
	go func() {
		client_err <- client.Serve()
	}()

	// Synchronous calls
	args := &WordLengthRequest{"xyzzy"}
	err := client.Call("WordLength.Len", args, nil)
	if err != nil {
		t.Errorf("unexpected error from call: %v", err.Error())
	}

	c.Close()

	err = <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from peer ServeCodec: %v", err)
	}

	err = <-client_err
	if err != io.ErrClosedPipe {
		t.Fatalf("unexpected error from local ServeCodec: %v", err)
	}
}

type EndpointPeer struct {
	seen *birpc.Endpoint
}

type nothing struct{}

func (e *EndpointPeer) Poke(request *nothing, reply *nothing, endpoint *birpc.Endpoint) error {
	if e.seen != nil {
		panic("poke called twice")
	}
	e.seen = endpoint
	return nil
}

func TestServerEndpointArg(t *testing.T) {
	peer := &EndpointPeer{}
	registry := birpc.NewRegistry()
	registry.RegisterService(peer)

	c, s := net.Pipe()
	defer c.Close()

	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	io.WriteString(c, `{"id":"42","fn":"EndpointPeer.Poke","args":{}}`)

	var reply LowLevelReply
	dec := json.NewDecoder(c)
	if err := dec.Decode(&reply); err != nil && err != io.EOF {
		t.Fatalf("decode failed: %s", err)
	}
	t.Logf("reply msg: %#v", reply)
	if reply.Error != nil {
		t.Fatalf("unexpected error response: %v", reply.Error)
	}
	c.Close()

	err := <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from ServeCodec: %v", err)
	}

	if peer.seen == nil {
		t.Fatalf("peer never saw a birpc.Endpoint")
	}
}

type Failing struct{}

func (_ Failing) Fail(request *nothing, reply *nothing) error {
	return errors.New("intentional")
}

func TestServerError(t *testing.T) {
	c, s := net.Pipe()
	defer c.Close()
	registry := birpc.NewRegistry()
	registry.RegisterService(Failing{})
	server := birpc.NewEndpoint(jsonmsg.NewCodec(s), registry)
	server_err := make(chan error)
	go func() {
		server_err <- server.Serve()
	}()

	const REQ = `{"id": "42", "fn": "Failing.Fail", "args": {}}` + "\n"
	io.WriteString(c, REQ)

	var reply LowLevelReply
	dec := json.NewDecoder(c)
	if err := dec.Decode(&reply); err != nil && err != io.EOF {
		t.Fatalf("decode failed: %s", err)
	}
	t.Logf("reply msg: %#v", reply)
	if reply.Error == nil {
		t.Fatalf("expected an error")
	}
	if g, e := reply.Error.Msg, "intentional"; g != e {
		t.Fatalf("unexpected error response: %q != %q", g, e)
	}
	if reply.Result != nil {
		t.Fatalf("got unexpected result: %v", reply.Result)
	}

	c.Close()

	err := <-server_err
	if err != io.EOF {
		t.Fatalf("unexpected error from ServeCodec: %v", err)
	}
}
<|endoftext|>


<commit_before>package api

import (
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/neutrinoapp/neutrino/src/common/log"
	"github.com/neutrinoapp/neutrino/src/common/models"
	"github.com/neutrinoapp/neutrino/src/common/utils"
	"github.com/neutrinoapp/neutrino/src/common/db"
)

type ApplicationModel struct {
	Id   string `json:"id"`
	Name string `json:"name"`
}

type ApplicationController struct {
	*BaseController
}

func NewApplicationController() *ApplicationController {
	return &ApplicationController{NewBaseController()}
}

func (a *ApplicationController) CreateApplicationHandler(c *gin.Context) {
	body := &ApplicationModel{}

	if err := c.Bind(body); err != nil {
		log.Error(RestError(c, err))
		return
	}

	if body.Name == "" {
		log.Error(RestErrorInvalidBody(c))
		return
	}

	email := ApiUser(c).Email
	app := models.JSON{
		db.NAME_FIELD:       body.Name,
		db.OWNER_FIELD:      email,
		db.MASTER_KEY_FIELD: strings.ToUpper(utils.GetCleanUUID()),
	}

	appId, err := a.DbService.CreateApp(email, app)
	if err != nil {
		log.Error(RestError(c, err))
		return
	}

	RespondId(appId, c)
}

func (a *ApplicationController) GetApplicationsHandler(c *gin.Context) {
	email := ApiUser(c).Email
	apps, err := a.DbService.GetApps(email)
	if err != nil {
		log.Error(RestError(c, err))
		return
	}

	c.JSON(http.StatusOK, apps)
}

func (a *ApplicationController) GetApplicationHandler(c *gin.Context) {
	//user := ApiUser(c).Email
	appId := c.Param("appId")

	//TODO: permissions
	app, err := a.DbService.GetApp(appId)
	if err != nil {
		log.Error(RestError(c, err))
		return
	}

	c.JSON(http.StatusOK, app)
}

func (a *ApplicationController) DeleteApplicationHandler(c *gin.Context) {
	//user := ApiUser(c).Email
	//appId := c.Param("appId")
	//TODO:
	//d := db.NewUserDbService(user, appId)
	//err := d.DeleteApp()
	//
	//if err != nil {
	//	log.Error(RestError(c, err))
	//	return
	//}
	//
	//dataDb := db.NewDataDbService(appId, "")
	//err = dataDb.RemoveApp()
	//if err != nil {
	//	log.Error(RestError(c, err))
	//	return
	//}

	c.Status(http.StatusOK)
}

func (a *ApplicationController) UpdateApplicationHandler(c *gin.Context) {
	//TODO:
	//appId := c.Param("appId")
	//user := ApiUser(c).Email
	//
	//d := db.NewUserDbService(user, appId)
	//app := utils.WhitelistFields([]string{"name"}, webUtils.GetBody(c))
	//
	//err := d.UpdateApp(app)
	//if err != nil {
	//	log.Error(RestError(c, err))
	//	return
	//}

	c.Status(http.StatusOK)
}
<commit_msg>added ability to create app with specific id<commit_after>package api

import (
	"net/http"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/neutrinoapp/neutrino/src/common/db"
	"github.com/neutrinoapp/neutrino/src/common/log"
	"github.com/neutrinoapp/neutrino/src/common/models"
	"github.com/neutrinoapp/neutrino/src/common/utils"
)

type ApplicationModel struct {
	Id   string `json:"id"`
	Name string `json:"name"`
}

type ApplicationController struct {
	*BaseController
}

func NewApplicationController() *ApplicationController {
	return &ApplicationController{NewBaseController()}
}

func (a *ApplicationController) CreateApplicationHandler(c *gin.Context) {
	body := &ApplicationModel{}

	if err := c.Bind(body); err != nil {
		log.Error(RestError(c, err))
		return
	}

	if body.Name == "" {
		log.Error(RestErrorInvalidBody(c))
		return
	}

	email := ApiUser(c).Email
	app := models.JSON{
		db.ID_FIELD:         body.Id,
		db.NAME_FIELD:       body.Name,
		db.OWNER_FIELD:      email,
		db.MASTER_KEY_FIELD: strings.ToUpper(utils.GetCleanUUID()),
	}

	appId, err := a.DbService.CreateApp(email, app)
	if err != nil {
		log.Error(RestError(c, err))
		return
	}

	RespondId(appId, c)
}

func (a *ApplicationController) GetApplicationsHandler(c *gin.Context) {
	email := ApiUser(c).Email
	apps, err := a.DbService.GetApps(email)
	if err != nil {
		log.Error(RestError(c, err))
		return
	}

	c.JSON(http.StatusOK, apps)
}

func (a *ApplicationController) GetApplicationHandler(c *gin.Context) {
	//user := ApiUser(c).Email
	appId := c.Param("appId")

	//TODO: permissions
	app, err := a.DbService.GetApp(appId)
	if err != nil {
		log.Error(RestError(c, err))
		return
	}

	c.JSON(http.StatusOK, app)
}

func (a *ApplicationController) DeleteApplicationHandler(c *gin.Context) {
	//user := ApiUser(c).Email
	//appId := c.Param("appId")
	//TODO:
	//d := db.NewUserDbService(user, appId)
	//err := d.DeleteApp()
	//
	//if err != nil {
	//	log.Error(RestError(c, err))
	//	return
	//}
	//
	//dataDb := db.NewDataDbService(appId, "")
	//err = dataDb.RemoveApp()
	//if err != nil {
	//	log.Error(RestError(c, err))
	//	return
	//}

	c.Status(http.StatusOK)
}

func (a *ApplicationController) UpdateApplicationHandler(c *gin.Context) {
	//TODO:
	//appId := c.Param("appId")
	//user := ApiUser(c).Email
	//
	//d := db.NewUserDbService(user, appId)
	//app := utils.WhitelistFields([]string{"name"}, webUtils.GetBody(c))
	//
	//err := d.UpdateApp(app)
	//if err != nil {
	//	log.Error(RestError(c, err))
	//	return
	//}

	c.Status(http.StatusOK)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"
	"flag"
	"runtime"
)

var debugFlag bool
var verboseFlag bool
var delayFlag int
var iterationsFlag int
var queuesizeFlag int
var workersFlag int
var blockingFlag bool
var numcpusFlag int
var workers int

func msg(msg string) {
	if verboseFlag {
		fmt.Printf("%s", msg)
	}
}

func msgD(msg string) {
	if debugFlag {
		fmt.Printf("%s", msg)
	}
}

func worker(queue chan int, quit chan bool) {
	workers++
	var count = 0
	var delayDur = time.Duration(delayFlag)
	for {
		select {
			case <-quit:
				msg(fmt.Sprintf("\tworker exiting (%d jobs processed)\n", count))
				workers--
				return
			case _ = <-queue:
				msgD("-")
				count++
				time.Sleep(time.Microsecond*delayDur)
		}
	}
}

func init() {
	flag.IntVar(&delayFlag, "d", 0, "microsecond delay after worker processes job before getting another one")
	flag.IntVar(&iterationsFlag, "i", 100, "number of jobs to run")
	flag.IntVar(&queuesizeFlag, "q", 10, "number of jobs to hold in the queue")
	flag.IntVar(&workersFlag, "w", 10, "number of workers threads")
	flag.BoolVar(&blockingFlag, "b", false, "enable blocking queue behavior (unbuffered channel)")
	flag.IntVar(&numcpusFlag, "p", 1, "number of logical CPUs to use (0 means use ALL)")
	flag.BoolVar(&verboseFlag, "v", false, "detailed output")
	flag.BoolVar(&debugFlag, "D", false, "debug output")
}

func main() {
	flag.Parse()

	// If numcpus set to zero or larger than system logical cpus
	if numcpusFlag == 0 || numcpusFlag > runtime.NumCPU() {
		numcpusFlag = runtime.NumCPU()
	}

	// Set channel (queue) size appropriately
	if blockingFlag {
		queuesizeFlag = 1
	}

	// Create job queue channel
	queue := make(chan int, queuesizeFlag)

	// Set the number of available CPUs
	oldprocs := runtime.GOMAXPROCS(numcpusFlag)

	// Print parameters
	msg(fmt.Sprintf("# workers: %d\n", workersFlag))
	msg(fmt.Sprintf("Worker delay: %d microsecond(s)\n", delayFlag))
	msg(fmt.Sprintf("Queue size: %d\n", queuesizeFlag))
	msg(fmt.Sprintf("Blocking: %v\n", blockingFlag))
	msg(fmt.Sprintf("Iterations: %d\n", iterationsFlag))
	msg(fmt.Sprintf("# CPUs: %d (was %d)\n", numcpusFlag, oldprocs))
	msg("\n")

	// Create worker quit channel
	quit := make(chan bool)

	// Spawn worker threads
	msg(fmt.Sprintf("\tspawning %d workers\n", workersFlag))
	for i := 0; i < workersFlag; i++ {
		go worker(queue, quit)
	}

	// Send jobs
	msg(fmt.Sprintf("\tsending %d jobs to queue(s)\n", iterationsFlag))
	start := time.Now()
	for i := 0; i < iterationsFlag; i++ {
		msgD("+")
		queue <- i
	}

	// Wait for jobs to finish processing
	msg(fmt.Sprintf("\n\tWaiting for jobs to complete...\n"))
	for len(queue) > 0 {
		time.Sleep(time.Millisecond * 1)
	}
	end := time.Now()
	msg("\n")

	// Kill workers (closing the channel will instruct all workers to exit)
	close(quit)

	// Wait for workers to all be dead (we want their exit messages to display)
	for workers > 0 {
		time.Sleep(time.Microsecond * 100)
	}

	// Calculate elapsed time (just for job processing) and print out results
	elapsedSeconds := end.Sub(start).Seconds()
	iterPerSec := float64(iterationsFlag)/elapsedSeconds
	fmt.Printf("\nElapsed time: %.4f secs\n", elapsedSeconds)
	fmt.Printf("Jobs per second: %.4f\n", iterPerSec)
}
<commit_msg>Ran go fmt on code<commit_after>package main

import (
	"flag"
	"fmt"
	"runtime"
	"time"
)

var debugFlag bool
var verboseFlag bool
var delayFlag int
var iterationsFlag int
var queuesizeFlag int
var workersFlag int
var blockingFlag bool
var numcpusFlag int
var workers int

func msg(msg string) {
	if verboseFlag {
		fmt.Printf("%s", msg)
	}
}

func msgD(msg string) {
	if debugFlag {
		fmt.Printf("%s", msg)
	}
}

func worker(queue chan int, quit chan bool) {
	workers++
	var count = 0
	var delayDur = time.Duration(delayFlag)
	for {
		select {
		case <-quit:
			msg(fmt.Sprintf("\tworker exiting (%d jobs processed)\n", count))
			workers--
			return
		case _ = <-queue:
			msgD("-")
			count++
			time.Sleep(time.Microsecond * delayDur)
		}
	}
}

func init() {
	flag.IntVar(&delayFlag, "d", 0, "microsecond delay after worker processes job before getting another one")
	flag.IntVar(&iterationsFlag, "i", 100, "number of jobs to run")
	flag.IntVar(&queuesizeFlag, "q", 10, "number of jobs to hold in the queue")
	flag.IntVar(&workersFlag, "w", 10, "number of workers threads")
	flag.BoolVar(&blockingFlag, "b", false, "enable blocking queue behavior (unbuffered channel)")
	flag.IntVar(&numcpusFlag, "p", 1, "number of logical CPUs to use (0 means use ALL)")
	flag.BoolVar(&verboseFlag, "v", false, "detailed output")
	flag.BoolVar(&debugFlag, "D", false, "debug output")
}

func main() {
	flag.Parse()

	// If numcpus set to zero or larger than system logical cpus
	if numcpusFlag == 0 || numcpusFlag > runtime.NumCPU() {
		numcpusFlag = runtime.NumCPU()
	}

	// Set channel (queue) size appropriately
	if blockingFlag {
		queuesizeFlag = 1
	}

	// Create job queue channel
	queue := make(chan int, queuesizeFlag)

	// Set the number of available CPUs
	oldprocs := runtime.GOMAXPROCS(numcpusFlag)

	// Print parameters
	msg(fmt.Sprintf("# workers: %d\n", workersFlag))
	msg(fmt.Sprintf("Worker delay: %d microsecond(s)\n", delayFlag))
	msg(fmt.Sprintf("Queue size: %d\n", queuesizeFlag))
	msg(fmt.Sprintf("Blocking: %v\n", blockingFlag))
	msg(fmt.Sprintf("Iterations: %d\n", iterationsFlag))
	msg(fmt.Sprintf("# CPUs: %d (was %d)\n", numcpusFlag, oldprocs))
	msg("\n")

	// Create worker quit channel
	quit := make(chan bool)

	// Spawn worker threads
	msg(fmt.Sprintf("\tspawning %d workers\n", workersFlag))
	for i := 0; i < workersFlag; i++ {
		go worker(queue, quit)
	}

	// Send jobs
	msg(fmt.Sprintf("\tsending %d jobs to queue(s)\n", iterationsFlag))
	start := time.Now()
	for i := 0; i < iterationsFlag; i++ {
		msgD("+")
		queue <- i
	}

	// Wait for jobs to finish processing
	msg(fmt.Sprintf("\n\tWaiting for jobs to complete...\n"))
	for len(queue) > 0 {
		time.Sleep(time.Millisecond * 1)
	}
	end := time.Now()
	msg("\n")

	// Kill workers (closing the channel will instruct all workers to exit)
	close(quit)

	// Wait for workers to all be dead (we want their exit messages to display)
	for workers > 0 {
		time.Sleep(time.Microsecond * 100)
	}

	// Calculate elapsed time (just for job processing) and print out results
	elapsedSeconds := end.Sub(start).Seconds()
	iterPerSec := float64(iterationsFlag) / elapsedSeconds
	fmt.Printf("\nElapsed time: %.4f secs\n", elapsedSeconds)
	fmt.Printf("Jobs per second: %.4f\n", iterPerSec)
}
<|endoftext|>


<commit_before>package disgo

import (
	"fmt"
	"math"
)

type sendMessageBody struct {
	Content string `json:"content"`
	Embed   *Embed `json:"embed,omitempty"`
}

func (s *Session) SendMessage(channelID Snowflake, content string) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPost, EndPointMessages(channelID), &sendMessageBody{Content: content})
}

func (s *Session) SendEmbed(channelID Snowflake, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPost, EndPointMessages(channelID), &sendMessageBody{Content: "", Embed: &embed})
}

func (s *Session) SendEmbeddedMessage(channelID Snowflake, content string, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPost, EndPointMessages(channelID), &sendMessageBody{Content: content, Embed: &embed})
}

func (s *Session) EditMessage(channelID, messageID Snowflake, content string) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPatch, EndPointMessage(channelID, messageID), &sendMessageBody{Content: content})
}

func (s *Session) EditEmbed(channelID, messageID Snowflake, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPatch, EndPointMessage(channelID, messageID), &sendMessageBody{Embed: &embed})
}

func (s *Session) EditEmbeddedMessage(channelID, messageID Snowflake, content string, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPatch, EndPointMessage(channelID, messageID), &sendMessageBody{Content: content, Embed: &embed})
}

func (s *Session) sendMessageInternal(method func(endPoint EndPoint, body, target interface{}) error, endpoint EndPoint, body *sendMessageBody) (*Message, error) {
	message := &Message{}
	err := method(endpoint, body, message)
	if err != nil {
		return nil, err
	}
	message = objects.registerMessage(message)
	if message.session == nil {
		message.session = s
	}
	return message, nil
}

type GetMessageMode int

const (
	GetLastMessages GetMessageMode = iota
	GetMessagesAround
	GetMessagesBefore
	GetMessagesAfter
)

func (s *Session) GetLastMessages(channelID Snowflake, limit int) ([]*Message, error) {
	return s.GetMessages(channelID, GetLastMessages, 0, limit)
}

func (s *Session) GetMessages(channelID Snowflake, mode GetMessageMode, target Snowflake, limit int) ([]*Message, error) {
	endPoint := EndPointMessages(channelID)
	limit = int(math.Max(1, math.Min(float64(limit), 100)))

	switch mode {
	case GetLastMessages:
		break
	case GetMessagesAround:
		endPoint.Url += "?around=" + target.String()
	case GetMessagesBefore:
		endPoint.Url += "?before=" + target.String()
	case GetMessagesAfter:
		endPoint.Url += "?after=" + target.String()
	default:
		panic("Invalid mode parameter passed to Session#GetMessages")
	}

	endPoint.Url += fmt.Sprintf("&limit=%d", limit)
	messages := make([]*Message, 0, limit)

	err := s.doHttpGet(endPoint, &messages)
	if err != nil {
		return nil, err
	}

	return messages, nil
}

func (s *Message) Edit(content string) (err error) {
	_, err = s.session.EditMessage(s.internal.ChannelID, s.internal.ID, content)
	return
}

func (s *Message) EditEmbed(embed Embed) (err error) {
	_, err = s.session.EditEmbed(s.internal.ChannelID, s.internal.ID, embed)
	return
}

func (s *Message) EditEmbeddedMessage(content string, embed Embed) (err error) {
	_, err = s.session.EditEmbeddedMessage(s.internal.ChannelID, s.internal.ID, content, embed)
	return
}

func (s *Session) DeleteMessage(channelID, messageID Snowflake) error {
	endPoint := EndPointMessage(channelID, messageID)
	endPoint.bucket += "DELETE" // Deleting messages works with a separate ratelimit to allow better moderation
	return s.doHttpDelete(endPoint, nil)
}

func (s *Message) Delete() error {
	return s.session.DeleteMessage(s.internal.ChannelID, s.internal.ID)
}

func (s *Session) BulkDeleteMessages(channelID Snowflake, ids []Snowflake) error {
	return s.doHttpPost(EndPointMessageBulkDelete(channelID), ids, nil)
}

func (s *Session) MessageAddReaction(channelID, messageID Snowflake, emoji string) error {
	endPoint := EndPointOwnReaction(channelID, messageID)
	endPoint.Url = fmt.Sprintf(endPoint.Url, emoji)
	endPoint.resetTime = 300
	return s.doHttpPut(endPoint, nil)
}

func (s *Message) AddReaction(emoji string) error {
	return s.session.MessageAddReaction(s.internal.ChannelID, s.internal.ID, emoji)
}

func (s *Session) MessageDeleteOwnReaction(channelID, messageID Snowflake, emoji string) error {
	endPoint := EndPointOwnReaction(channelID, messageID)
	endPoint.Url = fmt.Sprintf(endPoint.Url, emoji)
	endPoint.resetTime = 250
	return s.doHttpDelete(endPoint, nil)
}

func (s *Session) MessageDeleteReaction(channelID, messageID, userID Snowflake, emoji string) error {
	endPoint := EndPointReaction(channelID, messageID, userID)
	endPoint.Url = fmt.Sprintf(endPoint.Url, emoji)
	endPoint.resetTime = 250
	return s.doHttpDelete(endPoint, nil)
}

func (s *Session) MessageDeleteAllReactions(channelID, messageID Snowflake) error {
	return s.doHttpDelete(EndPointReactions(channelID, messageID), nil)
}

func (s *Message) DeleteReaction(userID Snowflake, emoji string) error {
	return s.session.MessageDeleteReaction(s.internal.ChannelID, s.internal.ID, userID, emoji)
}

func (s *Message) DeleteOwnReaction(emoji string) error {
	return s.session.MessageDeleteOwnReaction(s.internal.ChannelID, s.internal.ID, emoji)
}

func (s *Message) DeleteAllReactions() error {
	return s.session.MessageDeleteAllReactions(s.internal.ChannelID, s.internal.ID)
}
<commit_msg>Fixed bulk delete function<commit_after>package disgo

import (
	"fmt"
	"math"
)

type sendMessageBody struct {
	Content string `json:"content"`
	Embed   *Embed `json:"embed,omitempty"`
}

func (s *Session) SendMessage(channelID Snowflake, content string) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPost, EndPointMessages(channelID), &sendMessageBody{Content: content})
}

func (s *Session) SendEmbed(channelID Snowflake, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPost, EndPointMessages(channelID), &sendMessageBody{Content: "", Embed: &embed})
}

func (s *Session) SendEmbeddedMessage(channelID Snowflake, content string, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPost, EndPointMessages(channelID), &sendMessageBody{Content: content, Embed: &embed})
}

func (s *Session) EditMessage(channelID, messageID Snowflake, content string) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPatch, EndPointMessage(channelID, messageID), &sendMessageBody{Content: content})
}

func (s *Session) EditEmbed(channelID, messageID Snowflake, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPatch, EndPointMessage(channelID, messageID), &sendMessageBody{Embed: &embed})
}

func (s *Session) EditEmbeddedMessage(channelID, messageID Snowflake, content string, embed Embed) (*Message, error) {
	return s.sendMessageInternal(s.doHttpPatch, EndPointMessage(channelID, messageID), &sendMessageBody{Content: content, Embed: &embed})
}

func (s *Session) sendMessageInternal(method func(endPoint EndPoint, body, target interface{}) error, endpoint EndPoint, body *sendMessageBody) (*Message, error) {
	message := &Message{}
	err := method(endpoint, body, message)
	if err != nil {
		return nil, err
	}
	message = objects.registerMessage(message)
	if message.session == nil {
		message.session = s
	}
	return message, nil
}

type GetMessageMode int

const (
	GetLastMessages GetMessageMode = iota
	GetMessagesAround
	GetMessagesBefore
	GetMessagesAfter
)

func (s *Session) GetLastMessages(channelID Snowflake, limit int) ([]*Message, error) {
	return s.GetMessages(channelID, GetLastMessages, 0, limit)
}

func (s *Session) GetMessages(channelID Snowflake, mode GetMessageMode, target Snowflake, limit int) ([]*Message, error) {
	endPoint := EndPointMessages(channelID)
	limit = int(math.Max(2, math.Min(float64(limit), 100)))

	switch mode {
	case GetLastMessages:
		endPoint.Url += "?"
	case GetMessagesAround:
		endPoint.Url += "?around=" + target.String()
	case GetMessagesBefore:
		endPoint.Url += "?before=" + target.String()
	case GetMessagesAfter:
		endPoint.Url += "?after=" + target.String()
	default:
		panic("Invalid mode parameter passed to Session#GetMessages")
	}

	endPoint.Url += fmt.Sprintf("&limit=%d", limit)
	messages := make([]*Message, 0, limit)

	err := s.doHttpGet(endPoint, &messages)
	if err != nil {
		return nil, err
	}

	return messages, nil
}

func (s *Message) Edit(content string) (err error) {
	_, err = s.session.EditMessage(s.internal.ChannelID, s.internal.ID, content)
	return
}

func (s *Message) EditEmbed(embed Embed) (err error) {
	_, err = s.session.EditEmbed(s.internal.ChannelID, s.internal.ID, embed)
	return
}

func (s *Message) EditEmbeddedMessage(content string, embed Embed) (err error) {
	_, err = s.session.EditEmbeddedMessage(s.internal.ChannelID, s.internal.ID, content, embed)
	return
}

func (s *Session) DeleteMessage(channelID, messageID Snowflake) error {
	endPoint := EndPointMessage(channelID, messageID)
	endPoint.bucket += "DELETE" // Deleting messages works with a separate ratelimit to allow better moderation
	return s.doHttpDelete(endPoint, nil)
}

func (s *Message) Delete() error {
	return s.session.DeleteMessage(s.internal.ChannelID, s.internal.ID)
}

func (s *Session) BulkDeleteMessages(channelID Snowflake, ids []Snowflake) error {
	return s.doHttpPost(EndPointMessageBulkDelete(channelID), struct {
		Messages []Snowflake `json:"messages"`
	}{ids}, nil)
}

func (s *Session) MessageAddReaction(channelID, messageID Snowflake, emoji string) error {
	endPoint := EndPointOwnReaction(channelID, messageID)
	endPoint.Url = fmt.Sprintf(endPoint.Url, emoji)
	endPoint.resetTime = 300
	return s.doHttpPut(endPoint, nil)
}

func (s *Message) AddReaction(emoji string) error {
	return s.session.MessageAddReaction(s.internal.ChannelID, s.internal.ID, emoji)
}

func (s *Session) MessageDeleteOwnReaction(channelID, messageID Snowflake, emoji string) error {
	endPoint := EndPointOwnReaction(channelID, messageID)
	endPoint.Url = fmt.Sprintf(endPoint.Url, emoji)
	endPoint.resetTime = 250
	return s.doHttpDelete(endPoint, nil)
}

func (s *Session) MessageDeleteReaction(channelID, messageID, userID Snowflake, emoji string) error {
	endPoint := EndPointReaction(channelID, messageID, userID)
	endPoint.Url = fmt.Sprintf(endPoint.Url, emoji)
	endPoint.resetTime = 250
	return s.doHttpDelete(endPoint, nil)
}

func (s *Session) MessageDeleteAllReactions(channelID, messageID Snowflake) error {
	return s.doHttpDelete(EndPointReactions(channelID, messageID), nil)
}

func (s *Message) DeleteReaction(userID Snowflake, emoji string) error {
	return s.session.MessageDeleteReaction(s.internal.ChannelID, s.internal.ID, userID, emoji)
}

func (s *Message) DeleteOwnReaction(emoji string) error {
	return s.session.MessageDeleteOwnReaction(s.internal.ChannelID, s.internal.ID, emoji)
}

func (s *Message) DeleteAllReactions() error {
	return s.session.MessageDeleteAllReactions(s.internal.ChannelID, s.internal.ID)
}
<|endoftext|>


<commit_before>package jsonrpc

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"sync"

	"github.com/cenkalti/rpc2"
)

type jsonCodec struct {
	dec *json.Decoder // for reading JSON values
	enc *json.Encoder // for writing JSON values
	c   io.Closer

	// temporary work space
	msg            message
	serverRequest  serverRequest
	clientRequest  clientRequest
	clientResponse clientResponse

	// JSON-RPC clients can use arbitrary json values as request IDs.
	// Package rpc expects uint64 request IDs.
	// We assign uint64 sequence numbers to incoming requests
	// but save the original request ID in the pending map.
	// When rpc responds, we use the sequence number in
	// the response to find the original request ID.
	mutext  sync.Mutex // protects seq, pending
	pending map[uint64]*json.RawMessage
	seq     uint64
}

func NewJSONCodec(conn io.ReadWriteCloser) rpc2.Codec {
	return &jsonCodec{
		dec:     json.NewDecoder(conn),
		enc:     json.NewEncoder(conn),
		c:       conn,
		pending: make(map[uint64]*json.RawMessage),
	}
}

type clientRequest struct {
	Method string         `json:"method"`
	Params [1]interface{} `json:"params"`
	Id     *uint64        `json:"id"`
}
type serverRequest struct {
	Method string           `json:"method"`
	Params *json.RawMessage `json:"params"`
	Id     *json.RawMessage `json:"id"`
}

type clientResponse struct {
	Id     uint64           `json:"id"`
	Result *json.RawMessage `json:"result"`
	Error  interface{}      `json:"error"`
}
type serverResponse struct {
	Id     *json.RawMessage `json:"id"`
	Result interface{}      `json:"result"`
	Error  interface{}      `json:"error"`
}

type message struct {
	Method string           `json:"method"`
	Params *json.RawMessage `json:"params"`
	Id     *json.RawMessage `json:"id"`
	Result *json.RawMessage `json:"result"`
	Error  interface{}      `json:"error"`
}

func (c *jsonCodec) ReadHeader(req *rpc2.Request, resp *rpc2.Response) error {
	c.msg = message{}
	if err := c.dec.Decode(&c.msg); err != nil {
		return err
	}

	if c.msg.Method != "" {
		// We are server and read a request from client.
		c.serverRequest.Id = c.msg.Id
		c.serverRequest.Method = c.msg.Method
		c.serverRequest.Params = c.msg.Params

		req.Method = c.serverRequest.Method

		// JSON request id can be any JSON value;
		// RPC package expects uint64.  Translate to
		// internal uint64 and save JSON on the side.
		if c.serverRequest.Id == nil {
			// Notification
		} else {
			c.mutext.Lock()
			c.seq++
			c.pending[c.seq] = c.serverRequest.Id
			c.serverRequest.Id = nil
			req.Seq = c.seq
			c.mutext.Unlock()
		}

		return nil

	} else if c.msg.Result != nil {
		// We are client and read a response from server.
		// c.clientResponse.Id = msg.Id // TODO fix
		err := json.Unmarshal([]byte(*c.msg.Id), &c.clientResponse.Id)
		if err != nil {
			return err
		}
		c.clientResponse.Result = c.msg.Result
		c.clientResponse.Error = c.msg.Error

		resp.Error = ""
		resp.Seq = c.clientResponse.Id
		if c.clientResponse.Error != nil || c.clientResponse.Result == nil {
			x, ok := c.clientResponse.Error.(string)
			if !ok {
				return fmt.Errorf("invalid error %v", c.clientResponse.Error)
			}
			if x == "" {
				x = "unspecified error"
			}
			resp.Error = x
		}
		return nil
	}
	return errors.New("cannot determine message type")
}

var errMissingParams = errors.New("jsonrpc: request body missing params")

func (c *jsonCodec) ReadRequestBody(x interface{}) error {
	if x == nil {
		return nil
	}
	if c.serverRequest.Params == nil {
		return errMissingParams
	}
	// JSON params is array value.
	// RPC params is struct.
	// Unmarshal into array containing struct for now.
	// Should think about making RPC more general.
	var params [1]interface{}
	params[0] = x
	return json.Unmarshal(*c.serverRequest.Params, &params)

}

func (c *jsonCodec) ReadResponseBody(x interface{}) error {
	if x == nil {
		return nil
	}
	return json.Unmarshal(*c.clientResponse.Result, x)
}

func (c *jsonCodec) WriteRequest(r *rpc2.Request, param interface{}) error {
	c.clientRequest.Method = r.Method
	c.clientRequest.Params[0] = param
	if r.Seq == 0 {
		// Notification
		c.clientRequest.Id = nil
	} else {
		seq := r.Seq
		c.clientRequest.Id = &seq
	}
	return c.enc.Encode(&c.clientRequest)
}

var null = json.RawMessage([]byte("null"))

func (c *jsonCodec) WriteResponse(r *rpc2.Response, x interface{}) error {
	var resp serverResponse
	c.mutext.Lock()
	b, ok := c.pending[r.Seq]
	if !ok {
		c.mutext.Unlock()
		return errors.New("invalid sequence number in response")
	}
	delete(c.pending, r.Seq)
	c.mutext.Unlock()

	if b == nil {
		// Invalid request so no id.  Use JSON null.
		b = &null
	}
	resp.Id = b
	resp.Result = x
	if r.Error == "" {
		resp.Error = nil
	} else {
		resp.Error = r.Error
	}
	return c.enc.Encode(resp)

}

func (c *jsonCodec) Close() error {
	return c.c.Close()
}
<commit_msg>remove old todo<commit_after>package jsonrpc

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"sync"

	"github.com/cenkalti/rpc2"
)

type jsonCodec struct {
	dec *json.Decoder // for reading JSON values
	enc *json.Encoder // for writing JSON values
	c   io.Closer

	// temporary work space
	msg            message
	serverRequest  serverRequest
	clientRequest  clientRequest
	clientResponse clientResponse

	// JSON-RPC clients can use arbitrary json values as request IDs.
	// Package rpc expects uint64 request IDs.
	// We assign uint64 sequence numbers to incoming requests
	// but save the original request ID in the pending map.
	// When rpc responds, we use the sequence number in
	// the response to find the original request ID.
	mutext  sync.Mutex // protects seq, pending
	pending map[uint64]*json.RawMessage
	seq     uint64
}

func NewJSONCodec(conn io.ReadWriteCloser) rpc2.Codec {
	return &jsonCodec{
		dec:     json.NewDecoder(conn),
		enc:     json.NewEncoder(conn),
		c:       conn,
		pending: make(map[uint64]*json.RawMessage),
	}
}

type clientRequest struct {
	Method string         `json:"method"`
	Params [1]interface{} `json:"params"`
	Id     *uint64        `json:"id"`
}
type serverRequest struct {
	Method string           `json:"method"`
	Params *json.RawMessage `json:"params"`
	Id     *json.RawMessage `json:"id"`
}

type clientResponse struct {
	Id     uint64           `json:"id"`
	Result *json.RawMessage `json:"result"`
	Error  interface{}      `json:"error"`
}
type serverResponse struct {
	Id     *json.RawMessage `json:"id"`
	Result interface{}      `json:"result"`
	Error  interface{}      `json:"error"`
}

type message struct {
	Method string           `json:"method"`
	Params *json.RawMessage `json:"params"`
	Id     *json.RawMessage `json:"id"`
	Result *json.RawMessage `json:"result"`
	Error  interface{}      `json:"error"`
}

func (c *jsonCodec) ReadHeader(req *rpc2.Request, resp *rpc2.Response) error {
	c.msg = message{}
	if err := c.dec.Decode(&c.msg); err != nil {
		return err
	}

	if c.msg.Method != "" {
		// We are server and read a request from client.
		c.serverRequest.Id = c.msg.Id
		c.serverRequest.Method = c.msg.Method
		c.serverRequest.Params = c.msg.Params

		req.Method = c.serverRequest.Method

		// JSON request id can be any JSON value;
		// RPC package expects uint64.  Translate to
		// internal uint64 and save JSON on the side.
		if c.serverRequest.Id == nil {
			// Notification
		} else {
			c.mutext.Lock()
			c.seq++
			c.pending[c.seq] = c.serverRequest.Id
			c.serverRequest.Id = nil
			req.Seq = c.seq
			c.mutext.Unlock()
		}

		return nil

	} else if c.msg.Result != nil {
		// We are client and read a response from server.
		err := json.Unmarshal(*c.msg.Id, &c.clientResponse.Id)
		if err != nil {
			return err
		}
		c.clientResponse.Result = c.msg.Result
		c.clientResponse.Error = c.msg.Error

		resp.Error = ""
		resp.Seq = c.clientResponse.Id
		if c.clientResponse.Error != nil || c.clientResponse.Result == nil {
			x, ok := c.clientResponse.Error.(string)
			if !ok {
				return fmt.Errorf("invalid error %v", c.clientResponse.Error)
			}
			if x == "" {
				x = "unspecified error"
			}
			resp.Error = x
		}
		return nil
	}
	return errors.New("cannot determine message type")
}

var errMissingParams = errors.New("jsonrpc: request body missing params")

func (c *jsonCodec) ReadRequestBody(x interface{}) error {
	if x == nil {
		return nil
	}
	if c.serverRequest.Params == nil {
		return errMissingParams
	}
	// JSON params is array value.
	// RPC params is struct.
	// Unmarshal into array containing struct for now.
	// Should think about making RPC more general.
	var params [1]interface{}
	params[0] = x
	return json.Unmarshal(*c.serverRequest.Params, &params)

}

func (c *jsonCodec) ReadResponseBody(x interface{}) error {
	if x == nil {
		return nil
	}
	return json.Unmarshal(*c.clientResponse.Result, x)
}

func (c *jsonCodec) WriteRequest(r *rpc2.Request, param interface{}) error {
	c.clientRequest.Method = r.Method
	c.clientRequest.Params[0] = param
	if r.Seq == 0 {
		// Notification
		c.clientRequest.Id = nil
	} else {
		seq := r.Seq
		c.clientRequest.Id = &seq
	}
	return c.enc.Encode(&c.clientRequest)
}

var null = json.RawMessage([]byte("null"))

func (c *jsonCodec) WriteResponse(r *rpc2.Response, x interface{}) error {
	var resp serverResponse
	c.mutext.Lock()
	b, ok := c.pending[r.Seq]
	if !ok {
		c.mutext.Unlock()
		return errors.New("invalid sequence number in response")
	}
	delete(c.pending, r.Seq)
	c.mutext.Unlock()

	if b == nil {
		// Invalid request so no id.  Use JSON null.
		b = &null
	}
	resp.Id = b
	resp.Result = x
	if r.Error == "" {
		resp.Error = nil
	} else {
		resp.Error = r.Error
	}
	return c.enc.Encode(resp)

}

func (c *jsonCodec) Close() error {
	return c.c.Close()
}
<|endoftext|>


<commit_before>package vivoupdater

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"github.com/Shopify/sarama"
	cluster "github.com/bsm/sarama-cluster"
	"io/ioutil"
	"log"
	"os"
)

//type Message struct {
//	URI  string `json:"uri"`
//	Type string `json:"type"`
//}

func NewTLSConfig(clientCertFile, clientKeyFile, caCertFile string) (*tls.Config, error) {
	tlsConfig := tls.Config{}
	// Load client cert
	cert, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile)
	if err != nil {
		return &tlsConfig, err
	}
	tlsConfig.Certificates = []tls.Certificate{cert}

	// Load CA cert
	caCert, err := ioutil.ReadFile(caCertFile)
	if err != nil {
		return &tlsConfig, err
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)
	tlsConfig.RootCAs = caCertPool

	tlsConfig.BuildNameToCertificate()
	return &tlsConfig, err
}

type KafkaSubscriber struct {
	Brokers []string
	Topics  []string
}

func (ks KafkaSubscriber) Subscribe(ctx Context) chan UpdateMessage {
	updates := make(chan UpdateMessage)

	sarama.Logger = log.New(os.Stdout, "[sarama] ", log.LstdFlags)
	brokers := ks.Brokers
	//brokers := []string{"kafka-dev-01.oit.duke.edu:9093",
	//		"kafka-dev-02.oit.duke.edu:9093", "kafka-dev-03.oit.duke.edu:9093"}
	//topics := []string{"scholars-resources-changed"}
	topics := ks.Topics

	tlsConfig, err := NewTLSConfig("scholars-load-dev.crt.pem",
		"scholars-load-dev.key.pem",
		"kafka-dev-ca.crt.pem")
	if err != nil {
		log.Fatal(err)
	}

	consumerConfig := cluster.NewConfig()
	consumerConfig.ClientID = "rn47" // should be config
	consumerConfig.Net.TLS.Enable = true
	consumerConfig.Net.TLS.Config = tlsConfig
	consumerConfig.Consumer.Return.Errors = true

	consumer, err := cluster.NewConsumer(
		brokers,
		"group-id",
		topics,
		consumerConfig)

	if err != nil {
		panic(err)
	}

	go func() {

	//ReceiveLoop:
		// The loop will iterate each time a message is written to the underlying channel
		for msg := range consumer.Messages() {
			// Now we can access the individual fields of the message and react
			// based on msg.Topic
			switch msg.Topic {
			case "scholars-resources-changed":
				// Do everything we need for this topic
				//n := bytes.IndexByte(msg.Value, 0)
				var m UpdateMessage
				json.Unmarshal(msg.Value, &m)
				updates <- m
				//s := string(msg.Value[:])
				log.Printf("%s", m)
				log.Printf("uri=%s;type=%s", m.Triple.Subject, m.Type)

				// Mark the message as processed. The sarama-cluster library will
				// automatically commit these.
				// You can manually commit the offsets using consumer.CommitOffsets()
				consumer.MarkOffset(msg, "required-metadata")
				break //ReceiveLoop
				// ...
			}
		}
	}()

	/*
		go func() {
			failedAttempts := 0
			for {
				ctx.Logger.Println("Connecting to Redis at " + us.RedisUrl)
				c, err := redis.Dial("tcp", us.RedisUrl)
					if err != nil {
						failedAttempts += 1
						if failedAttempts > us.MaxConnectAttempts {
							close(updates)
							ctx.handleError("Max redis connection attempts exceeded", err, true)
							break
						}
						ctx.handleError("Could not connect to Redis", err, false)
						time.Sleep(time.Duration(us.RetryInterval*failedAttempts) * time.Second)
						continue
					}
					failedAttempts = 0
					psc := redis.PubSubConn{c}
					psc.Subscribe(us.RedisChannel)
					ctx.Logger.Println("Subscribed to channel " + us.RedisChannel)

				ReceiveLoop:
					for {
						switch v := psc.Receive().(type) {
						case redis.Message:
							var m UpdateMessage
							json.Unmarshal(v.Data, &m)
							updates <- m
						case error:
							ctx.handleError("Lost connection to Redis", v, false)
							psc.Close()
							time.Sleep(time.Duration(us.RetryInterval) * time.Second)
							failedAttempts += 1
							break ReceiveLoop
						}
					}
				}
			}()
	*/

	return updates
}
<commit_msg>simplify for loop kafka checker<commit_after>package vivoupdater

import (
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"github.com/Shopify/sarama"
	cluster "github.com/bsm/sarama-cluster"
	"io/ioutil"
	"log"
	"os"
)

func NewTLSConfig(clientCertFile, clientKeyFile, caCertFile string) (*tls.Config, error) {
	tlsConfig := tls.Config{}
	// Load client cert
	cert, err := tls.LoadX509KeyPair(clientCertFile, clientKeyFile)
	if err != nil {
		return &tlsConfig, err
	}
	tlsConfig.Certificates = []tls.Certificate{cert}

	// Load CA cert
	caCert, err := ioutil.ReadFile(caCertFile)
	if err != nil {
		return &tlsConfig, err
	}
	caCertPool := x509.NewCertPool()
	caCertPool.AppendCertsFromPEM(caCert)
	tlsConfig.RootCAs = caCertPool

	tlsConfig.BuildNameToCertificate()
	return &tlsConfig, err
}

type KafkaSubscriber struct {
	Brokers []string
	Topics  []string
}

func (ks KafkaSubscriber) Subscribe(ctx Context) chan UpdateMessage {
	updates := make(chan UpdateMessage)

	sarama.Logger = log.New(os.Stdout, "[sarama] ", log.LstdFlags)
	brokers := ks.Brokers
	topics := ks.Topics

	tlsConfig, err := NewTLSConfig("scholars-load-dev.crt.pem",
		"scholars-load-dev.key.pem",
		"kafka-dev-ca.crt.pem")
	if err != nil {
		log.Fatal(err)
	}

	consumerConfig := cluster.NewConfig()
	consumerConfig.ClientID = "rn47" // should be config
	consumerConfig.Net.TLS.Enable = true
	consumerConfig.Net.TLS.Config = tlsConfig
	consumerConfig.Consumer.Return.Errors = true

	consumer, err := cluster.NewConsumer(
		brokers,
		"group-id",
		topics,
		consumerConfig)

	if err != nil {
		panic(err)
	}

	go func() {
		// The loop will iterate each time a message is written to the underlying channel
		for msg := range consumer.Messages() {
			var m UpdateMessage
			json.Unmarshal(msg.Value, &m)
			updates <- m
			log.Printf("REC:uri=%s", m.Triple.Subject)

			// Mark the message as processed. The sarama-cluster library will
			// automatically commit these.
			// You can manually commit the offsets using consumer.CommitOffsets()
			consumer.MarkOffset(msg, "required-metadata")
			//break
		}
	}()
	return updates
}
<|endoftext|>