<commit_before>package memalpha

import "testing"

func benchmarkSet(b *testing.B, c *Client) {
	key := "foo"
	value := []byte("bar")
	b.SetBytes(int64(len(key) + len(value)))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if err := c.Set(key, value); err != nil {
			b.Fatal(err)
		}
	}
	b.StopTimer()
}

func benchmarkSetGet(b *testing.B, c *Client) {
	key := "foo"
	value := []byte("bar")
	b.SetBytes(int64(len(key) + len(value)))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if err := c.Set(key, value); err != nil {
			b.Fatal(err)
		}
		if _, _, err := c.Get(key); err != nil {
			b.Fatal(err)
		}
	}
	b.StopTimer()
}

func BenchmarkSet(b *testing.B) {
	memd := newServer()
	err := memd.Start()
	if err != nil {
		b.Skipf("skipping test; couldn't start memcached: %s", err)
	}
	defer memd.Shutdown()

	benchmarkSet(b, memd.client)
}

func BenchmarkSetGet(b *testing.B) {
	memd := newServer()
	err := memd.Start()
	if err != nil {
		b.Skipf("skipping test; couldn't start memcached: %s", err)
	}
	defer memd.Shutdown()

	benchmarkSetGet(b, memd.client)
}
<commit_msg>Refactor benchmark<commit_after>package memalpha

import (
	"bytes"
	"testing"
)

func BenchmarkGetSmall(b *testing.B) { benchmarkGet(b, 5, 5) }
func BenchmarkGetLarge(b *testing.B) { benchmarkGet(b, 250, 500*1024) }
func BenchmarkSetSmall(b *testing.B) { benchmarkSet(b, 5, 5) }
func BenchmarkSetLarge(b *testing.B) { benchmarkSet(b, 250, 500*1024) }

func benchmarkGet(b *testing.B, keySize int, valueSize int) {
	key := string(bytes.Repeat([]byte("A"), keySize))
	value := bytes.Repeat([]byte("A"), valueSize)

	memd := newServer()
	if err := memd.Start(); err != nil {
		b.Skipf("skipping test; couldn't start memcached: %s", err)
	}
	defer memd.Shutdown()

	if err := memd.client.Set(key, value); err != nil {
		b.Skipf("skipping test; couldn't set(%s, %s) = %+v", key, value, err)
	}

	b.SetBytes(int64(keySize + valueSize))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if _, _, err := memd.client.Get(key); err != nil {
			b.Fatal(err)
		}
	}
	b.StopTimer()
}

func benchmarkSet(b *testing.B, keySize int, valueSize int) {
	key := string(bytes.Repeat([]byte("A"), keySize))
	value := bytes.Repeat([]byte("A"), valueSize)

	memd := newServer()
	if err := memd.Start(); err != nil {
		b.Skipf("skipping test; couldn't start memcached: %s", err)
	}
	defer memd.Shutdown()

	if err := memd.client.Set(key, value); err != nil {
		b.Skipf("skipping test; couldn't set(%s, %s) = %+v", key, value, err)
	}

	b.SetBytes(int64(keySize + valueSize))
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if err := memd.client.Set(key, value); err != nil {
			b.Fatal(err)
		}
	}
	b.StopTimer()
}
<|endoftext|>


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

// This implementation is loosely based on the algorithm described
// in: "On the linearization of graphs and writing symbol files",
// by R. Griesemer, Technical Report 156, ETH Zürich, 1991.

// package importer implements an exporter and importer for Go export data.
package importer

import (
	"encoding/binary"
	"fmt"
	"go/token"

	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
)

// ImportData imports a package from the serialized package data.
// If data is obviously malformed, an error is returned but in
// general it is not recommended to call ImportData on untrusted
// data.
func ImportData(imports map[string]*types.Package, data []byte) (*types.Package, error) {
	// check magic string
	if n := len(magic); len(data) < n || string(data[:n]) != magic {
		return nil, fmt.Errorf("incorrect magic string: got %q; want %q", data[:n], magic)
	}

	p := importer{
		data:     data[len(magic):],
		imports:  imports,
		consumed: len(magic), // for debugging only
	}

	// populate typList with predeclared types
	for _, t := range types.Typ[1:] {
		p.typList = append(p.typList, t)
	}
	p.typList = append(p.typList, types.Universe.Lookup("error").Type())

	if v := p.string(); v != version {
		return nil, fmt.Errorf("unknown version: got %d; want %d", v, version)
	}

	pkg := p.pkg()
	if debug && p.pkgList[0] != pkg {
		panic("imported packaged not found in pkgList[0]")
	}

	// read objects
	n := p.int()
	for i := 0; i < n; i++ {
		p.obj(pkg)
	}

	if len(p.data) > 0 {
		return nil, fmt.Errorf("not all input data consumed")
	}

	// package was imported completely and without errors
	pkg.MarkComplete()

	return pkg, nil
}

type importer struct {
	data    []byte
	imports map[string]*types.Package
	pkgList []*types.Package
	typList []types.Type

	// debugging support
	consumed int
}

func (p *importer) pkg() *types.Package {
	// if the package was seen before, i is its index (>= 0)
	i := p.int()
	if i >= 0 {
		return p.pkgList[i]
	}

	// otherwise, i is the package tag (< 0)
	if i != packageTag {
		panic(fmt.Sprintf("unexpected package tag %d", i))
	}

	// read package data
	name := p.string()
	path := p.string()

	// if the package was imported before, use that one; otherwise create a new one
	pkg := p.imports[path]
	if pkg == nil {
		pkg = types.NewPackage(path, name, types.NewScope(nil))
		p.imports[path] = pkg
	}
	p.pkgList = append(p.pkgList, pkg)

	return pkg
}

func (p *importer) obj(pkg *types.Package) {
	var obj types.Object
	switch tag := p.int(); tag {
	case constTag:
		obj = types.NewConst(token.NoPos, pkg, p.string(), p.typ(), p.value())
	case typeTag:
		// type object is added to scope via respective named type
		_ = p.typ().(*types.Named)
		return
	case varTag:
		obj = types.NewVar(token.NoPos, pkg, p.string(), p.typ())
	case funcTag:
		obj = types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature))
	default:
		panic(fmt.Sprintf("unexpected object tag %d", tag))
	}

	if alt := pkg.Scope().Insert(obj); alt != nil {
		panic(fmt.Sprintf("%s already declared", alt.Name()))
	}
}

func (p *importer) value() exact.Value {
	switch kind := exact.Kind(p.int()); kind {
	case falseTag:
		return exact.MakeBool(false)
	case trueTag:
		return exact.MakeBool(true)
	case stringTag:
		return exact.MakeString(p.string())
	case int64Tag:
		return exact.MakeInt64(p.int64())
	case floatTag:
		return p.float()
	case fractionTag:
		return p.fraction()
	case complexTag:
		re := p.fraction()
		im := p.fraction()
		return exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
	default:
		panic(fmt.Sprintf("unexpected value kind %d", kind))
	}
}

func (p *importer) float() exact.Value {
	sign := p.int()
	if sign == 0 {
		return exact.MakeInt64(0)
	}

	x := p.ufloat()
	if sign < 0 {
		x = exact.UnaryOp(token.SUB, x, 0)
	}
	return x
}

func (p *importer) fraction() exact.Value {
	sign := p.int()
	if sign == 0 {
		return exact.MakeInt64(0)
	}

	x := exact.BinaryOp(p.ufloat(), token.QUO, p.ufloat())
	if sign < 0 {
		x = exact.UnaryOp(token.SUB, x, 0)
	}
	return x
}

func (p *importer) ufloat() exact.Value {
	exp := p.int()
	x := exact.MakeFromBytes(p.bytes())
	switch {
	case exp < 0:
		d := exact.Shift(exact.MakeInt64(1), token.SHL, uint(-exp))
		x = exact.BinaryOp(x, token.QUO, d)
	case exp > 0:
		x = exact.Shift(x, token.SHL, uint(exp))
	}
	return x
}

func (p *importer) record(t types.Type) {
	p.typList = append(p.typList, t)
}

func (p *importer) typ() types.Type {
	// if the type was seen before, i is its index (>= 0)
	i := p.int()
	if i >= 0 {
		return p.typList[i]
	}

	// otherwise, i is the type tag (< 0)
	switch i {
	case basicTag:
		t := types.Universe.Lookup(p.string()).(*types.TypeName).Type().(*types.Basic)
		p.record(t)
		return t

	case arrayTag:
		t := new(types.Array)
		p.record(t)

		n := p.int64()
		*t = *types.NewArray(p.typ(), n)
		return t

	case sliceTag:
		t := new(types.Slice)
		p.record(t)

		*t = *types.NewSlice(p.typ())
		return t

	case structTag:
		t := new(types.Struct)
		p.record(t)

		n := p.int()
		fields := make([]*types.Var, n)
		tags := make([]string, n)
		for i := range fields {
			fields[i] = p.field()
			tags[i] = p.string()
		}
		*t = *types.NewStruct(fields, tags)
		return t

	case pointerTag:
		t := new(types.Pointer)
		p.record(t)

		*t = *types.NewPointer(p.typ())
		return t

	case signatureTag:
		t := new(types.Signature)
		p.record(t)

		*t = *p.signature()
		return t

	case interfaceTag:
		t := new(types.Interface)
		p.record(t)

		// read embedded interfaces
		embeddeds := make([]*types.Named, p.int())
		for i := range embeddeds {
			embeddeds[i] = p.typ().(*types.Named)
		}

		// read methods
		methods := make([]*types.Func, p.int())
		for i := range methods {
			pkg, name := p.qualifiedName()
			methods[i] = types.NewFunc(token.NoPos, pkg, name, p.typ().(*types.Signature))
		}

		*t = *types.NewInterface(methods, embeddeds)
		return t

	case mapTag:
		t := new(types.Map)
		p.record(t)

		*t = *types.NewMap(p.typ(), p.typ())
		return t

	case chanTag:
		t := new(types.Chan)
		p.record(t)

		*t = *types.NewChan(types.ChanDir(p.int()), p.typ())
		return t

	case namedTag:
		// read type object
		name := p.string()
		pkg := p.pkg()
		scope := pkg.Scope()
		obj := scope.Lookup(name)

		// if the object doesn't exist yet, create and insert it
		if obj == nil {
			obj = types.NewTypeName(token.NoPos, pkg, name, nil)
			scope.Insert(obj)
		}

		// associate new named type with obj if it doesn't exist yet
		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)

		// but record the existing type, if any
		t := obj.Type().(*types.Named)
		p.record(t)

		// read underlying type
		t0.SetUnderlying(p.typ())

		// read associated methods
		for i, n := 0, p.int(); i < n; i++ {
			t0.AddMethod(types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature)))
		}

		return t

	default:
		panic(fmt.Sprintf("unexpected type tag %d", i))
	}
}

func deref(typ types.Type) types.Type {
	if p, _ := typ.(*types.Pointer); p != nil {
		return p.Elem()
	}
	return typ
}

func (p *importer) field() *types.Var {
	pkg, name := p.qualifiedName()
	typ := p.typ()

	anonymous := false
	if name == "" {
		// anonymous field - typ must be T or *T and T must be a type name
		switch typ := deref(typ).(type) {
		case *types.Basic: // basic types are named types
			pkg = nil
			name = typ.Name()
		case *types.Named:
			obj := typ.Obj()
			name = obj.Name()
			// correct the field package for anonymous fields
			if exported(name) {
				pkg = p.pkgList[0]
			}
		default:
			panic("anonymous field expected")
		}
		anonymous = true
	}

	return types.NewField(token.NoPos, pkg, name, typ, anonymous)
}

func (p *importer) qualifiedName() (*types.Package, string) {
	name := p.string()
	pkg := p.pkgList[0] // exported names assume current package
	if !exported(name) {
		pkg = p.pkg()
	}
	return pkg, name
}

func (p *importer) signature() *types.Signature {
	var recv *types.Var
	if p.int() != 0 {
		recv = p.param()
	}
	return types.NewSignature(nil, recv, p.tuple(), p.tuple(), p.int() != 0)
}

func (p *importer) param() *types.Var {
	return types.NewVar(token.NoPos, nil, p.string(), p.typ())
}

func (p *importer) tuple() *types.Tuple {
	vars := make([]*types.Var, p.int())
	for i := range vars {
		vars[i] = p.param()
	}
	return types.NewTuple(vars...)
}

// ----------------------------------------------------------------------------
// decoders

func (p *importer) string() string {
	return string(p.bytes())
}

func (p *importer) int() int {
	return int(p.int64())
}

func (p *importer) int64() int64 {
	if debug {
		p.marker('i')
	}

	return p.rawInt64()
}

// Note: bytes() returns the respective byte slice w/o copy.
func (p *importer) bytes() []byte {
	if debug {
		p.marker('b')
	}

	var b []byte
	if n := int(p.rawInt64()); n > 0 {
		b = p.data[:n]
		p.data = p.data[n:]
		if debug {
			p.consumed += n
		}
	}
	return b
}

func (p *importer) marker(want byte) {
	if debug {
		if got := p.data[0]; got != want {
			panic(fmt.Sprintf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.consumed))
		}
		p.data = p.data[1:]
		p.consumed++

		pos := p.consumed
		if n := int(p.rawInt64()); n != pos {
			panic(fmt.Sprintf("incorrect position: got %d; want %d", n, pos))
		}
	}
}

// rawInt64 should only be used by low-level decoders
func (p *importer) rawInt64() int64 {
	i, n := binary.Varint(p.data)
	p.data = p.data[n:]
	if debug {
		p.consumed += n
	}
	return i
}
<commit_msg>go.tools/go/importer: fix format string<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This implementation is loosely based on the algorithm described
// in: "On the linearization of graphs and writing symbol files",
// by R. Griesemer, Technical Report 156, ETH Zürich, 1991.

// package importer implements an exporter and importer for Go export data.
package importer

import (
	"encoding/binary"
	"fmt"
	"go/token"

	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
)

// ImportData imports a package from the serialized package data.
// If data is obviously malformed, an error is returned but in
// general it is not recommended to call ImportData on untrusted
// data.
func ImportData(imports map[string]*types.Package, data []byte) (*types.Package, error) {
	// check magic string
	if n := len(magic); len(data) < n || string(data[:n]) != magic {
		return nil, fmt.Errorf("incorrect magic string: got %q; want %q", data[:n], magic)
	}

	p := importer{
		data:     data[len(magic):],
		imports:  imports,
		consumed: len(magic), // for debugging only
	}

	// populate typList with predeclared types
	for _, t := range types.Typ[1:] {
		p.typList = append(p.typList, t)
	}
	p.typList = append(p.typList, types.Universe.Lookup("error").Type())

	if v := p.string(); v != version {
		return nil, fmt.Errorf("unknown version: got %s; want %s", v, version)
	}

	pkg := p.pkg()
	if debug && p.pkgList[0] != pkg {
		panic("imported packaged not found in pkgList[0]")
	}

	// read objects
	n := p.int()
	for i := 0; i < n; i++ {
		p.obj(pkg)
	}

	if len(p.data) > 0 {
		return nil, fmt.Errorf("not all input data consumed")
	}

	// package was imported completely and without errors
	pkg.MarkComplete()

	return pkg, nil
}

type importer struct {
	data    []byte
	imports map[string]*types.Package
	pkgList []*types.Package
	typList []types.Type

	// debugging support
	consumed int
}

func (p *importer) pkg() *types.Package {
	// if the package was seen before, i is its index (>= 0)
	i := p.int()
	if i >= 0 {
		return p.pkgList[i]
	}

	// otherwise, i is the package tag (< 0)
	if i != packageTag {
		panic(fmt.Sprintf("unexpected package tag %d", i))
	}

	// read package data
	name := p.string()
	path := p.string()

	// if the package was imported before, use that one; otherwise create a new one
	pkg := p.imports[path]
	if pkg == nil {
		pkg = types.NewPackage(path, name, types.NewScope(nil))
		p.imports[path] = pkg
	}
	p.pkgList = append(p.pkgList, pkg)

	return pkg
}

func (p *importer) obj(pkg *types.Package) {
	var obj types.Object
	switch tag := p.int(); tag {
	case constTag:
		obj = types.NewConst(token.NoPos, pkg, p.string(), p.typ(), p.value())
	case typeTag:
		// type object is added to scope via respective named type
		_ = p.typ().(*types.Named)
		return
	case varTag:
		obj = types.NewVar(token.NoPos, pkg, p.string(), p.typ())
	case funcTag:
		obj = types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature))
	default:
		panic(fmt.Sprintf("unexpected object tag %d", tag))
	}

	if alt := pkg.Scope().Insert(obj); alt != nil {
		panic(fmt.Sprintf("%s already declared", alt.Name()))
	}
}

func (p *importer) value() exact.Value {
	switch kind := exact.Kind(p.int()); kind {
	case falseTag:
		return exact.MakeBool(false)
	case trueTag:
		return exact.MakeBool(true)
	case stringTag:
		return exact.MakeString(p.string())
	case int64Tag:
		return exact.MakeInt64(p.int64())
	case floatTag:
		return p.float()
	case fractionTag:
		return p.fraction()
	case complexTag:
		re := p.fraction()
		im := p.fraction()
		return exact.BinaryOp(re, token.ADD, exact.MakeImag(im))
	default:
		panic(fmt.Sprintf("unexpected value kind %d", kind))
	}
}

func (p *importer) float() exact.Value {
	sign := p.int()
	if sign == 0 {
		return exact.MakeInt64(0)
	}

	x := p.ufloat()
	if sign < 0 {
		x = exact.UnaryOp(token.SUB, x, 0)
	}
	return x
}

func (p *importer) fraction() exact.Value {
	sign := p.int()
	if sign == 0 {
		return exact.MakeInt64(0)
	}

	x := exact.BinaryOp(p.ufloat(), token.QUO, p.ufloat())
	if sign < 0 {
		x = exact.UnaryOp(token.SUB, x, 0)
	}
	return x
}

func (p *importer) ufloat() exact.Value {
	exp := p.int()
	x := exact.MakeFromBytes(p.bytes())
	switch {
	case exp < 0:
		d := exact.Shift(exact.MakeInt64(1), token.SHL, uint(-exp))
		x = exact.BinaryOp(x, token.QUO, d)
	case exp > 0:
		x = exact.Shift(x, token.SHL, uint(exp))
	}
	return x
}

func (p *importer) record(t types.Type) {
	p.typList = append(p.typList, t)
}

func (p *importer) typ() types.Type {
	// if the type was seen before, i is its index (>= 0)
	i := p.int()
	if i >= 0 {
		return p.typList[i]
	}

	// otherwise, i is the type tag (< 0)
	switch i {
	case basicTag:
		t := types.Universe.Lookup(p.string()).(*types.TypeName).Type().(*types.Basic)
		p.record(t)
		return t

	case arrayTag:
		t := new(types.Array)
		p.record(t)

		n := p.int64()
		*t = *types.NewArray(p.typ(), n)
		return t

	case sliceTag:
		t := new(types.Slice)
		p.record(t)

		*t = *types.NewSlice(p.typ())
		return t

	case structTag:
		t := new(types.Struct)
		p.record(t)

		n := p.int()
		fields := make([]*types.Var, n)
		tags := make([]string, n)
		for i := range fields {
			fields[i] = p.field()
			tags[i] = p.string()
		}
		*t = *types.NewStruct(fields, tags)
		return t

	case pointerTag:
		t := new(types.Pointer)
		p.record(t)

		*t = *types.NewPointer(p.typ())
		return t

	case signatureTag:
		t := new(types.Signature)
		p.record(t)

		*t = *p.signature()
		return t

	case interfaceTag:
		t := new(types.Interface)
		p.record(t)

		// read embedded interfaces
		embeddeds := make([]*types.Named, p.int())
		for i := range embeddeds {
			embeddeds[i] = p.typ().(*types.Named)
		}

		// read methods
		methods := make([]*types.Func, p.int())
		for i := range methods {
			pkg, name := p.qualifiedName()
			methods[i] = types.NewFunc(token.NoPos, pkg, name, p.typ().(*types.Signature))
		}

		*t = *types.NewInterface(methods, embeddeds)
		return t

	case mapTag:
		t := new(types.Map)
		p.record(t)

		*t = *types.NewMap(p.typ(), p.typ())
		return t

	case chanTag:
		t := new(types.Chan)
		p.record(t)

		*t = *types.NewChan(types.ChanDir(p.int()), p.typ())
		return t

	case namedTag:
		// read type object
		name := p.string()
		pkg := p.pkg()
		scope := pkg.Scope()
		obj := scope.Lookup(name)

		// if the object doesn't exist yet, create and insert it
		if obj == nil {
			obj = types.NewTypeName(token.NoPos, pkg, name, nil)
			scope.Insert(obj)
		}

		// associate new named type with obj if it doesn't exist yet
		t0 := types.NewNamed(obj.(*types.TypeName), nil, nil)

		// but record the existing type, if any
		t := obj.Type().(*types.Named)
		p.record(t)

		// read underlying type
		t0.SetUnderlying(p.typ())

		// read associated methods
		for i, n := 0, p.int(); i < n; i++ {
			t0.AddMethod(types.NewFunc(token.NoPos, pkg, p.string(), p.typ().(*types.Signature)))
		}

		return t

	default:
		panic(fmt.Sprintf("unexpected type tag %d", i))
	}
}

func deref(typ types.Type) types.Type {
	if p, _ := typ.(*types.Pointer); p != nil {
		return p.Elem()
	}
	return typ
}

func (p *importer) field() *types.Var {
	pkg, name := p.qualifiedName()
	typ := p.typ()

	anonymous := false
	if name == "" {
		// anonymous field - typ must be T or *T and T must be a type name
		switch typ := deref(typ).(type) {
		case *types.Basic: // basic types are named types
			pkg = nil
			name = typ.Name()
		case *types.Named:
			obj := typ.Obj()
			name = obj.Name()
			// correct the field package for anonymous fields
			if exported(name) {
				pkg = p.pkgList[0]
			}
		default:
			panic("anonymous field expected")
		}
		anonymous = true
	}

	return types.NewField(token.NoPos, pkg, name, typ, anonymous)
}

func (p *importer) qualifiedName() (*types.Package, string) {
	name := p.string()
	pkg := p.pkgList[0] // exported names assume current package
	if !exported(name) {
		pkg = p.pkg()
	}
	return pkg, name
}

func (p *importer) signature() *types.Signature {
	var recv *types.Var
	if p.int() != 0 {
		recv = p.param()
	}
	return types.NewSignature(nil, recv, p.tuple(), p.tuple(), p.int() != 0)
}

func (p *importer) param() *types.Var {
	return types.NewVar(token.NoPos, nil, p.string(), p.typ())
}

func (p *importer) tuple() *types.Tuple {
	vars := make([]*types.Var, p.int())
	for i := range vars {
		vars[i] = p.param()
	}
	return types.NewTuple(vars...)
}

// ----------------------------------------------------------------------------
// decoders

func (p *importer) string() string {
	return string(p.bytes())
}

func (p *importer) int() int {
	return int(p.int64())
}

func (p *importer) int64() int64 {
	if debug {
		p.marker('i')
	}

	return p.rawInt64()
}

// Note: bytes() returns the respective byte slice w/o copy.
func (p *importer) bytes() []byte {
	if debug {
		p.marker('b')
	}

	var b []byte
	if n := int(p.rawInt64()); n > 0 {
		b = p.data[:n]
		p.data = p.data[n:]
		if debug {
			p.consumed += n
		}
	}
	return b
}

func (p *importer) marker(want byte) {
	if debug {
		if got := p.data[0]; got != want {
			panic(fmt.Sprintf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.consumed))
		}
		p.data = p.data[1:]
		p.consumed++

		pos := p.consumed
		if n := int(p.rawInt64()); n != pos {
			panic(fmt.Sprintf("incorrect position: got %d; want %d", n, pos))
		}
	}
}

// rawInt64 should only be used by low-level decoders
func (p *importer) rawInt64() int64 {
	i, n := binary.Varint(p.data)
	p.data = p.data[n:]
	if debug {
		p.consumed += n
	}
	return i
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	_ "github.com/go-sql-driver/mysql"
	"html/template"
	"log"
	"math/rand"
	"net/http"
	"runtime"
	"sort"
	"strconv"
	"sync"
)

type MessageStruct struct {
	Message string
}

type World struct {
	Id           uint16 `json:"id"`
	RandomNumber uint16 `json:"randomNumber"`
}

type Fortune struct {
	Id      uint16 `json:"id"`
	Message string `json:"message"`
}

const (
	ConnectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world?charset=utf8"
	WorldSelect        = "SELECT id, randomNumber FROM World where id = ?"
	WorldUpdate				 = "UPDATE World SET randomNumber = ? where id = ?"
	FortuneSelect      = "SELECT id, message FROM Fortune;"
	WorldRowCount      = 10000
	MaxConnectionCount = 100
)

var (
	tmpl = template.Must(template.ParseFiles("templates/layout.html", "templates/fortune.html"))

	worldStatement    *sql.Stmt
	fortuneStatement *sql.Stmt
	updateStatement		*sql.Stmt
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	db, err := sql.Open("mysql", ConnectionString)
	if err != nil {
		log.Fatalf("Error opening database: %v", err)
	}
	db.SetMaxIdleConns(MaxConnectionCount)
	worldStatement, err = db.Prepare(WorldSelect)
	if err != nil {
		log.Fatal(err)
	}
	fortuneStatement, err = db.Prepare(FortuneSelect)
	if err != nil {
		log.Fatal(err)
	}
	updateStatement, err = db.Prepare(WorldUpdate)
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/db", worldHandler)
	http.HandleFunc("/json", jsonHandler)
	http.HandleFunc("/fortune", fortuneHandler)
	http.HandleFunc("/update", updateHandler)
	http.ListenAndServe(":8080", nil)
}

func jsonHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript")
	j, _ := json.Marshal(&MessageStruct{"Hello, world"})
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func worldHandler(w http.ResponseWriter, r *http.Request) {
	n := 1
	if nStr := r.URL.Query().Get("queries"); len(nStr) != 0 {
		n, _ = strconv.Atoi(nStr)
	}
	ww := make([]World, n)
	if n == 1 {
		worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[0].Id, &ww[0].RandomNumber)
	} else {
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func(i int) {
				err := worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
				if err != nil {
					log.Fatalf("Error scanning world row: %v", err)
				}
				wg.Done()
			}(i)
		}
		wg.Wait()
	}
	j, _ := json.Marshal(ww)
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func fortuneHandler(w http.ResponseWriter, r *http.Request) {
	fortunes := make([]*Fortune, 0, 16)

	//Execute the query
	rows, err := fortuneStatement.Query()
	if err != nil {
		log.Fatalf("Error preparing statement: %v", err)
	}

	i := 0
	var fortune *Fortune
	for rows.Next() { //Fetch rows
		fortune = new(Fortune)
		if err = rows.Scan(&fortune.Id, &fortune.Message); err != nil {
			log.Fatalf("Error scanning fortune row: %v", err)
		}
		fortunes = append(fortunes, fortune)
		i++
	}
	fortunes = append(fortunes, &Fortune{Message: "Additional fortune added at request time."})

	sort.Sort(ByMessage{fortunes})
	w.Header().Set("Content-Type", "text/html")
	if err := tmpl.Execute(w, map[string]interface{}{"fortunes": fortunes}); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func updateHandler(w http.ResponseWriter, r *http.Request) {
	n := 1
	if nStr := r.URL.Query().Get("queries"); len(nStr) != 0 {
		n, _ = strconv.Atoi(nStr)
	}
	ww := make([]World, n)
	if n == 1 {
		worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[0].Id, &ww[0].RandomNumber)
		ww[0].RandomNumber = rand.Intn(WorldRowCount) + 1
		updateStatement.Exec(ww[0].RandomNumber, ww[0].Id)
	} else {
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func(i int) {
				err := worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
				ww[i].RandomNumber = rand.Intn(WorldRowCount) + 1
				updateStatement.Exec(ww[i].RandomNumber, ww[i].Id)
				if err != nil {
					log.Fatalf("Error scanning world row: %v", err)
				}
				wg.Done()
			}(i)
		}
		wg.Wait()
	}
	j, _ := json.Marshal(ww)
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

type Fortunes []*Fortune

func (s Fortunes) Len() int      { return len(s) }
func (s Fortunes) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

type ByMessage struct{ Fortunes }

func (s ByMessage) Less(i, j int) bool { return s.Fortunes[i].Message < s.Fortunes[j].Message }
<commit_msg>convert int to uint16<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	_ "github.com/go-sql-driver/mysql"
	"html/template"
	"log"
	"math/rand"
	"net/http"
	"runtime"
	"sort"
	"strconv"
	"sync"
)

type MessageStruct struct {
	Message string
}

type World struct {
	Id           uint16 `json:"id"`
	RandomNumber uint16 `json:"randomNumber"`
}

type Fortune struct {
	Id      uint16 `json:"id"`
	Message string `json:"message"`
}

const (
	ConnectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world?charset=utf8"
	WorldSelect        = "SELECT id, randomNumber FROM World where id = ?"
	WorldUpdate				 = "UPDATE World SET randomNumber = ? where id = ?"
	FortuneSelect      = "SELECT id, message FROM Fortune;"
	WorldRowCount      = 10000
	MaxConnectionCount = 100
)

var (
	tmpl = template.Must(template.ParseFiles("templates/layout.html", "templates/fortune.html"))

	worldStatement    *sql.Stmt
	fortuneStatement *sql.Stmt
	updateStatement		*sql.Stmt
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	db, err := sql.Open("mysql", ConnectionString)
	if err != nil {
		log.Fatalf("Error opening database: %v", err)
	}
	db.SetMaxIdleConns(MaxConnectionCount)
	worldStatement, err = db.Prepare(WorldSelect)
	if err != nil {
		log.Fatal(err)
	}
	fortuneStatement, err = db.Prepare(FortuneSelect)
	if err != nil {
		log.Fatal(err)
	}
	updateStatement, err = db.Prepare(WorldUpdate)
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/db", worldHandler)
	http.HandleFunc("/json", jsonHandler)
	http.HandleFunc("/fortune", fortuneHandler)
	http.HandleFunc("/update", updateHandler)
	http.ListenAndServe(":8080", nil)
}

func jsonHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript")
	j, _ := json.Marshal(&MessageStruct{"Hello, world"})
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func worldHandler(w http.ResponseWriter, r *http.Request) {
	n := 1
	if nStr := r.URL.Query().Get("queries"); len(nStr) != 0 {
		n, _ = strconv.Atoi(nStr)
	}
	ww := make([]World, n)
	if n == 1 {
		worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[0].Id, &ww[0].RandomNumber)
	} else {
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func(i int) {
				err := worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
				if err != nil {
					log.Fatalf("Error scanning world row: %v", err)
				}
				wg.Done()
			}(i)
		}
		wg.Wait()
	}
	j, _ := json.Marshal(ww)
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func fortuneHandler(w http.ResponseWriter, r *http.Request) {
	fortunes := make([]*Fortune, 0, 16)

	//Execute the query
	rows, err := fortuneStatement.Query()
	if err != nil {
		log.Fatalf("Error preparing statement: %v", err)
	}

	i := 0
	var fortune *Fortune
	for rows.Next() { //Fetch rows
		fortune = new(Fortune)
		if err = rows.Scan(&fortune.Id, &fortune.Message); err != nil {
			log.Fatalf("Error scanning fortune row: %v", err)
		}
		fortunes = append(fortunes, fortune)
		i++
	}
	fortunes = append(fortunes, &Fortune{Message: "Additional fortune added at request time."})

	sort.Sort(ByMessage{fortunes})
	w.Header().Set("Content-Type", "text/html")
	if err := tmpl.Execute(w, map[string]interface{}{"fortunes": fortunes}); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

func updateHandler(w http.ResponseWriter, r *http.Request) {
	n := 1
	if nStr := r.URL.Query().Get("queries"); len(nStr) != 0 {
		n, _ = strconv.Atoi(nStr)
	}
	ww := make([]World, n)
	if n == 1 {
		worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[0].Id, &ww[0].RandomNumber)
		ww[0].RandomNumber = uint16(rand.Intn(WorldRowCount) + 1)
		updateStatement.Exec(ww[0].RandomNumber, ww[0].Id)
	} else {
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func(i int) {
				err := worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
				ww[i].RandomNumber = uint16(rand.Intn(WorldRowCount) + 1)
				updateStatement.Exec(ww[i].RandomNumber, ww[i].Id)
				if err != nil {
					log.Fatalf("Error scanning world row: %v", err)
				}
				wg.Done()
			}(i)
		}
		wg.Wait()
	}
	j, _ := json.Marshal(ww)
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

type Fortunes []*Fortune

func (s Fortunes) Len() int      { return len(s) }
func (s Fortunes) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

type ByMessage struct{ Fortunes }

func (s ByMessage) Less(i, j int) bool { return s.Fortunes[i].Message < s.Fortunes[j].Message }
<|endoftext|>


<commit_before>package main

import (
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/conformal/btcjson"
	"github.com/conformal/btcscript"
	"github.com/conformal/btcutil"
	"github.com/conformal/btcwallet/tx"
	"github.com/conformal/btcwallet/wallet"
	"github.com/conformal/btcwire"
	"testing"
)

func TestFakeTxs(t *testing.T) {
	// First we need a wallet.
	w, err := wallet.NewWallet("banana wallet", "", []byte("banana"))
	if err != nil {
		t.Errorf("Can not create encrypted wallet: %s", err)
		return
	}
	btcw := &BtcWallet{
		Wallet: w,
	}

	w.Unlock([]byte("banana"))

	// Create and add a fake Utxo so we have some funds to spend.
	//
	// This will pass validation because btcscript is unaware of invalid
	// tx inputs, however, this example would fail in btcd.
	utxo := &tx.Utxo{}
	addr, err := w.NextUnusedAddress()
	if err != nil {
		t.Errorf("Cannot get next address: %s", err)
		return
	}
	addr160, _, err := btcutil.DecodeAddress(addr)
	if err != nil {
		t.Errorf("Cannot decode address: %s", err)
		return
	}
	copy(utxo.Addr[:], addr160)
	ophash := (btcwire.ShaHash)([...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
		12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
		28, 29, 30, 31, 32})
	out := btcwire.NewOutPoint(&ophash, 0)
	utxo.Out = tx.OutPoint(*out)
	ss, err := btcscript.PayToPubKeyHashScript(addr160)
	if err != nil {
		t.Errorf("Could not create utxo PkScript: %s", err)
		return
	}
	utxo.Subscript = tx.PkScript(ss)
	utxo.Amt = 10000
	utxo.Height = 12345
	btcw.UtxoStore.s = append(btcw.UtxoStore.s, utxo)

	// Fake our current block height so btcd doesn't need to be queried.
	curHeight.h = 12346

	// Create the transaction.
	pairs := map[string]uint64{
		"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": 5000,
	}
	rawtx, err := btcw.txToPairs(pairs, 100, 0)
	if err != nil {
		t.Errorf("Tx creation failed: %s", err)
		return
	}

	msg := btcjson.Message{
		Jsonrpc: "1.0",
		Id:      "test",
		Method:  "sendrawtransaction",
		Params: []interface{}{
			hex.EncodeToString(rawtx),
		},
	}
	m, _ := json.Marshal(msg)
	_ = m
	_ = fmt.Println

	// Uncomment to print out json to send raw transaction
	// fmt.Println(string(m))
}
<commit_msg>unbreak tests<commit_after>package main

import (
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/conformal/btcjson"
	"github.com/conformal/btcscript"
	"github.com/conformal/btcutil"
	"github.com/conformal/btcwallet/tx"
	"github.com/conformal/btcwallet/wallet"
	"github.com/conformal/btcwire"
	"testing"
)

func TestFakeTxs(t *testing.T) {
	// First we need a wallet.
	w, err := wallet.NewWallet("banana wallet", "", []byte("banana"), btcwire.MainNet)
	if err != nil {
		t.Errorf("Can not create encrypted wallet: %s", err)
		return
	}
	btcw := &BtcWallet{
		Wallet: w,
	}

	w.Unlock([]byte("banana"))

	// Create and add a fake Utxo so we have some funds to spend.
	//
	// This will pass validation because btcscript is unaware of invalid
	// tx inputs, however, this example would fail in btcd.
	utxo := &tx.Utxo{}
	addr, err := w.NextUnusedAddress()
	if err != nil {
		t.Errorf("Cannot get next address: %s", err)
		return
	}
	addr160, _, err := btcutil.DecodeAddress(addr)
	if err != nil {
		t.Errorf("Cannot decode address: %s", err)
		return
	}
	copy(utxo.Addr[:], addr160)
	ophash := (btcwire.ShaHash)([...]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
		12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
		28, 29, 30, 31, 32})
	out := btcwire.NewOutPoint(&ophash, 0)
	utxo.Out = tx.OutPoint(*out)
	ss, err := btcscript.PayToPubKeyHashScript(addr160)
	if err != nil {
		t.Errorf("Could not create utxo PkScript: %s", err)
		return
	}
	utxo.Subscript = tx.PkScript(ss)
	utxo.Amt = 10000
	utxo.Height = 12345
	btcw.UtxoStore.s = append(btcw.UtxoStore.s, utxo)

	// Fake our current block height so btcd doesn't need to be queried.
	curHeight.h = 12346

	// Create the transaction.
	pairs := map[string]uint64{
		"17XhEvq9Nahdj7Xe1nv6oRe1tEmaHUuynH": 5000,
	}
	rawtx, err := btcw.txToPairs(pairs, 100, 0)
	if err != nil {
		t.Errorf("Tx creation failed: %s", err)
		return
	}

	msg := btcjson.Message{
		Jsonrpc: "1.0",
		Id:      "test",
		Method:  "sendrawtransaction",
		Params: []interface{}{
			hex.EncodeToString(rawtx),
		},
	}
	m, _ := json.Marshal(msg)
	_ = m
	_ = fmt.Println

	// Uncomment to print out json to send raw transaction
	// fmt.Println(string(m))
}
<|endoftext|>


<commit_before>package lifted

// Uniquify variable names to be of the form "?x#".
// This eliminates any issues with variable shadowing.

import (
	"fmt"
	"os"
)

func (d *Domain) AssignNums(s *Symtab) os.Error {
	for i, _ := range d.Types {
		s.types.Number(&d.Types[i].Name)
		for j, _ := range d.Types[i].Type {
			s.types.Number(&d.Types[i].Type[j])
		}
	}
	for i, _ := range d.Constants {
		s.consts.Number(&d.Constants[i].Name)
	}
	for i, _ := range d.Predicates {
		s.preds.Number(&d.Predicates[i].Name)
	}
	for _, a := range d.Actions {
		if err := a.AssignNums(s); err != nil {
			return err
		}
	}
	return nil
}

func (a *Action) AssignNums(s *Symtab) os.Error {
	var f *numFrame
	for i, _ := range a.Parameters {
		f = s.VarNum(f, &a.Parameters[i].Name)
	}
	if err := a.Precondition.AssignNums(s, f); err != nil {
		return err
	}
	return a.Effect.AssignNums(s, f)
}

func (p *Problem) AssignNums(s *Symtab) os.Error {
	for i, _ := range p.Objects {
		s.consts.Number(&p.Objects[i].Name)
	}
	return p.Goal.AssignNums(s, nil)
}

func (l *Literal) AssignNums(s *Symtab, f *numFrame) os.Error {
	for i, t := range l.Parameters {
		switch t.Kind {
		case TermVariable:
			if fnxt := s.VarNum(f, &l.Parameters[i].Name); fnxt == f {
				break
			}
			name := l.Parameters[i].Name.String
			return fmt.Errorf("%s: Unbound variable %s\n", t.Loc, name)
		case TermConstant:
			s.consts.Number(&l.Parameters[i].Name)
		}
	}
	s.preds.Number(&l.Name)
	return nil
}

func (e *ExprBinary) AssignNums(s *Symtab, f *numFrame) os.Error {
	if err := e.Left.AssignNums(s, f); err != nil {
		return err
	}
	return e.Right.AssignNums(s, f)
}

func (ExprTrue) AssignNums(*Symtab, *numFrame) os.Error { return nil }

func (ExprFalse) AssignNums(*Symtab, *numFrame) os.Error { return nil }

func (e *ExprAnd) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprBinary)(e).AssignNums(s, f)
}

func (e *ExprOr) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprBinary)(e).AssignNums(s, f)
}

func (e *ExprNot) AssignNums(s *Symtab, f *numFrame) os.Error {
	return e.Expr.AssignNums(s, f)
}

func (e *ExprQuant) AssignNums(s *Symtab, f *numFrame) os.Error {
	f = s.VarNum(f, &e.Variable.Name)
	return e.Expr.AssignNums(s, f)
}

func (e *ExprForall) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprQuant)(e).AssignNums(s, f)
}

func (e *ExprExists) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprQuant)(e).AssignNums(s, f)
}

func (e *ExprLiteral) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*Literal)(e).AssignNums(s, f)
}

func (e *EffectUnary) AssignNums(s *Symtab, f *numFrame) os.Error {
	return e.Effect.AssignNums(s, f)
}

func (EffectNone) AssignNums(*Symtab, *numFrame) os.Error { return nil }

func (e *EffectAnd) AssignNums(s *Symtab, f *numFrame) os.Error {
	if err := e.Left.AssignNums(s, f); err != nil {
		return err
	}
	return e.Right.AssignNums(s, f)
}

func (e *EffectForall) AssignNums(s *Symtab, f *numFrame) os.Error {
	f = s.VarNum(f, &e.Variable.Name)
	return e.Effect.AssignNums(s, f)
}

func (e *EffectWhen) AssignNums(s *Symtab, f *numFrame) os.Error {
	if err := e.Condition.AssignNums(s, f); err != nil {
		return err
	}
	return e.Effect.AssignNums(s, f)
}

func (e *EffectLiteral) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*Literal)(e).AssignNums(s, f)
}

func (e *EffectAssign) AssignNums(*Symtab, *numFrame) os.Error { return nil }

type Symtab struct {
	consts   Numberer
	preds    Numberer
	types    Numberer
	varNames []string
}

func NewSymtab() *Symtab {
	return &Symtab{
		consts: MakeNumberer(),
		preds:  MakeNumberer(),
		types:  MakeNumberer(),
	}
}

type Numberer struct {
	nums    map[string]int
	strings []string
}

func MakeNumberer() Numberer {
	return Numberer{nums: make(map[string]int)}
}

func (n *Numberer) Number(name *Name) {
	if num, ok := n.nums[name.String]; ok {
		name.Number = num
	}
	num := len(n.strings)
	n.nums[name.String] = num
	n.strings = append(n.strings, name.String)
	name.Number = num
}

func (s *Symtab) VarNum(f *numFrame, name *Name) *numFrame {
	if n, ok := f.lookup(name.String); ok {
		name.Number = n
		return f
	}
	n := len(s.varNames)
	s.varNames = append(s.varNames, name.String)
	name.Number = n
	return &numFrame{name: name.String, num: n, up: f}
}

type numFrame struct {
	name string
	num  int
	up   *numFrame
}

func (f *numFrame) lookup(name string) (int, bool) {
	if f == nil {
		return 0, false
	}
	if f.name == name {
		return f.num, true
	}
	return f.up.lookup(name)
}
<commit_msg>Rename Numberer to be CoatCheck.<commit_after>package lifted

// Uniquify variable names to be of the form "?x#".
// This eliminates any issues with variable shadowing.

import (
	"fmt"
	"os"
)

func (d *Domain) AssignNums(s *Symtab) os.Error {
	for i, _ := range d.Types {
		s.types.Number(&d.Types[i].Name)
		for j, _ := range d.Types[i].Type {
			s.types.Number(&d.Types[i].Type[j])
		}
	}
	for i, _ := range d.Constants {
		s.consts.Number(&d.Constants[i].Name)
	}
	for i, _ := range d.Predicates {
		s.preds.Number(&d.Predicates[i].Name)
	}
	for _, a := range d.Actions {
		if err := a.AssignNums(s); err != nil {
			return err
		}
	}
	return nil
}

func (a *Action) AssignNums(s *Symtab) os.Error {
	var f *numFrame
	for i, _ := range a.Parameters {
		f = s.VarNum(f, &a.Parameters[i].Name)
	}
	if err := a.Precondition.AssignNums(s, f); err != nil {
		return err
	}
	return a.Effect.AssignNums(s, f)
}

func (p *Problem) AssignNums(s *Symtab) os.Error {
	for i, _ := range p.Objects {
		s.consts.Number(&p.Objects[i].Name)
	}
	return p.Goal.AssignNums(s, nil)
}

func (l *Literal) AssignNums(s *Symtab, f *numFrame) os.Error {
	for i, t := range l.Parameters {
		switch t.Kind {
		case TermVariable:
			if fnxt := s.VarNum(f, &l.Parameters[i].Name); fnxt == f {
				break
			}
			name := l.Parameters[i].Name.String
			return fmt.Errorf("%s: Unbound variable %s\n", t.Loc, name)
		case TermConstant:
			s.consts.Number(&l.Parameters[i].Name)
		}
	}
	s.preds.Number(&l.Name)
	return nil
}

func (e *ExprBinary) AssignNums(s *Symtab, f *numFrame) os.Error {
	if err := e.Left.AssignNums(s, f); err != nil {
		return err
	}
	return e.Right.AssignNums(s, f)
}

func (ExprTrue) AssignNums(*Symtab, *numFrame) os.Error { return nil }

func (ExprFalse) AssignNums(*Symtab, *numFrame) os.Error { return nil }

func (e *ExprAnd) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprBinary)(e).AssignNums(s, f)
}

func (e *ExprOr) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprBinary)(e).AssignNums(s, f)
}

func (e *ExprNot) AssignNums(s *Symtab, f *numFrame) os.Error {
	return e.Expr.AssignNums(s, f)
}

func (e *ExprQuant) AssignNums(s *Symtab, f *numFrame) os.Error {
	f = s.VarNum(f, &e.Variable.Name)
	return e.Expr.AssignNums(s, f)
}

func (e *ExprForall) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprQuant)(e).AssignNums(s, f)
}

func (e *ExprExists) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*ExprQuant)(e).AssignNums(s, f)
}

func (e *ExprLiteral) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*Literal)(e).AssignNums(s, f)
}

func (e *EffectUnary) AssignNums(s *Symtab, f *numFrame) os.Error {
	return e.Effect.AssignNums(s, f)
}

func (EffectNone) AssignNums(*Symtab, *numFrame) os.Error { return nil }

func (e *EffectAnd) AssignNums(s *Symtab, f *numFrame) os.Error {
	if err := e.Left.AssignNums(s, f); err != nil {
		return err
	}
	return e.Right.AssignNums(s, f)
}

func (e *EffectForall) AssignNums(s *Symtab, f *numFrame) os.Error {
	f = s.VarNum(f, &e.Variable.Name)
	return e.Effect.AssignNums(s, f)
}

func (e *EffectWhen) AssignNums(s *Symtab, f *numFrame) os.Error {
	if err := e.Condition.AssignNums(s, f); err != nil {
		return err
	}
	return e.Effect.AssignNums(s, f)
}

func (e *EffectLiteral) AssignNums(s *Symtab, f *numFrame) os.Error {
	return (*Literal)(e).AssignNums(s, f)
}

func (e *EffectAssign) AssignNums(*Symtab, *numFrame) os.Error { return nil }

type Symtab struct {
	consts   CoatCheck
	preds    CoatCheck
	types    CoatCheck
	varNames []string
}

func NewSymtab() *Symtab {
	return &Symtab{
		consts: MakeCoatCheck(),
		preds:  MakeCoatCheck(),
		types:  MakeCoatCheck(),
	}
}

type CoatCheck struct {
	nums    map[string]int
	strings []string
}

func MakeCoatCheck() CoatCheck {
	return CoatCheck{nums: make(map[string]int)}
}

func (n *CoatCheck) Number(name *Name) {
	if num, ok := n.nums[name.String]; ok {
		name.Number = num
	}
	num := len(n.strings)
	n.nums[name.String] = num
	n.strings = append(n.strings, name.String)
	name.Number = num
}

func (s *Symtab) VarNum(f *numFrame, name *Name) *numFrame {
	if n, ok := f.lookup(name.String); ok {
		name.Number = n
		return f
	}
	n := len(s.varNames)
	s.varNames = append(s.varNames, name.String)
	name.Number = n
	return &numFrame{name: name.String, num: n, up: f}
}

type numFrame struct {
	name string
	num  int
	up   *numFrame
}

func (f *numFrame) lookup(name string) (int, bool) {
	if f == nil {
		return 0, false
	}
	if f.name == name {
		return f.num, true
	}
	return f.up.lookup(name)
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"errors"
	"strings"

	"github.com/yuin/gopher-lua"
	"github.com/zetamatta/nyagos/alias"
	"github.com/zetamatta/nyagos/shell"
)

type LuaBinaryChank struct {
	Chank *lua.LFunction
}

func (this *LuaBinaryChank) String() string {
	return "(lua-function)"
}

func (this *LuaBinaryChank) Call(ctx context.Context, cmd *shell.Cmd) (int, error) {
	luawrapper, ok := cmd.Tag().(*luaWrapper)
	if !ok {
		return 255, errors.New("LuaBinaryChank.Call: Lua instance not found")
	}
	L := luawrapper.Lua
	ctx = context.WithValue(ctx, luaKey, L)
	L.Push(this.Chank)
	callLua(ctx, &cmd.Shell, 0, 0)

	return 1, nil
}

func cmdSetAlias(L Lua) int {
	key := strings.ToLower(L.ToString(-2))
	switch L.Get(-1).Type() {
	case lua.LTString:
		alias.Table[key] = alias.New(L.ToString(-1))
	case lua.LTFunction:
		alias.Table[key] = &LuaBinaryChank{Chank: L.ToFunction(-1)}
	case lua.LTNil:
		delete(alias.Table, key)
	}
	L.Push(lua.LTrue)
	return 1
}

func cmdGetAlias(L Lua) int {
	value, ok := alias.Table[strings.ToLower(L.ToString(-1))]
	if !ok {
		L.Push(lua.LNil)
		return 1
	}
	switch v := value.(type) {
	case *LuaBinaryChank:
		L.Push(v.Chank)
	default:
		L.Push(lua.LString(v.String()))
	}
	return 1
}
<commit_msg>gopherSh: support alias's parameter<commit_after>package main

import (
	"context"
	"errors"
	"strings"

	"github.com/yuin/gopher-lua"
	"github.com/zetamatta/nyagos/alias"
	"github.com/zetamatta/nyagos/shell"
)

type LuaBinaryChank struct {
	Chank *lua.LFunction
}

func (this *LuaBinaryChank) String() string {
	return "(lua-function)"
}

func (this *LuaBinaryChank) Call(ctx context.Context, cmd *shell.Cmd) (int, error) {
	luawrapper, ok := cmd.Tag().(*luaWrapper)
	if !ok {
		return 255, errors.New("LuaBinaryChank.Call: Lua instance not found")
	}
	L := luawrapper.Lua
	ctx = context.WithValue(ctx, luaKey, L)
	L.Push(this.Chank)

	table := L.NewTable()
	for i, arg1 := range cmd.Args() {
		L.SetTable(table, lua.LNumber(i), lua.LString(arg1))
	}
	L.Push(table)

	callLua(ctx, &cmd.Shell, 1, 0)

	return 1, nil
}

func cmdSetAlias(L Lua) int {
	key := strings.ToLower(L.ToString(-2))
	switch L.Get(-1).Type() {
	case lua.LTString:
		alias.Table[key] = alias.New(L.ToString(-1))
	case lua.LTFunction:
		alias.Table[key] = &LuaBinaryChank{Chank: L.ToFunction(-1)}
	case lua.LTNil:
		delete(alias.Table, key)
	}
	L.Push(lua.LTrue)
	return 1
}

func cmdGetAlias(L Lua) int {
	value, ok := alias.Table[strings.ToLower(L.ToString(-1))]
	if !ok {
		L.Push(lua.LNil)
		return 1
	}
	switch v := value.(type) {
	case *LuaBinaryChank:
		L.Push(v.Chank)
	default:
		L.Push(lua.LString(v.String()))
	}
	return 1
}
<|endoftext|>


<commit_before>package linref

import (
	"encoding/csv"
	"fmt"
	"github.com/paulsmith/gogeos/geos"
	"io"
	"log"
	"os"
	"strconv"
)

type Referencer struct {
	Path *geos.Geometry
}

func NewReferencer(shapeId string) Referencer {
	ref := Referencer{}
	// Fixme
	file, err := os.Open("./muni_gtfs/shapes.txt")
	if err != nil {
		log.Fatal(err)
		return ref
	}
	defer file.Close()
	reader := csv.NewReader(file)
	reader.TrailingComma = true
	coords := []geos.Coord{}
	for {
		record, err := reader.Read()
		if err == io.EOF {
			break
		} else if err != nil {
			fmt.Println("Error:", err)
			return ref
		}
		if record[0] == shapeId {
			lon, _ := strconv.ParseFloat(record[1], 64)
			lat, _ := strconv.ParseFloat(record[2], 64)
			coords = append(coords, geos.NewCoord(lat, lon))
		}
	}
	path, _ := geos.NewLineString(coords...)
	ref.Path = path
	return ref
}

func (r Referencer) Reference(lat float64, lon float64) float64 {
	coord := geos.NewCoord(lat, lon)
	point, _ := geos.NewPoint(coord)
	return r.Path.ProjectNormalized(point)
}
<commit_msg>linref uses go.geo and go.gtfs.<commit_after>package linref

import (
	"github.com/bdon/go.gtfs"
	"github.com/paulmach/go.geo"
)

type Referencer struct {
	Path *geo.Path
}

func NewReferencer(shapeId string) Referencer {
	ref := Referencer{}

	// Fixme
	feed := gtfs.Load("muni_gtfs")
	route := feed.RouteByShortName("N")
	coords := route.Shapes()[0].Coords
	path := geo.NewPath()
	for _, c := range coords {
		path.Push(geo.NewPoint(c.Lon, c.Lat))
	}
	ref.Path = path
	return ref
}

func (r Referencer) Reference(lat float64, lon float64) float64 {
	point := geo.NewPoint(lon, lat)
	return r.Path.ProjectNormalized(point)
}
<|endoftext|>


<commit_before>// +build linux

package linux

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/containerd/containerd/api/services/shim"
	"github.com/containerd/containerd/api/types/mount"
	"github.com/containerd/containerd/api/types/task"
	"github.com/containerd/containerd/log"
	"github.com/containerd/containerd/plugin"
	runc "github.com/containerd/go-runc"

	"golang.org/x/sys/unix"
)

const (
	runtimeName    = "linux"
	configFilename = "config.json"
	defaultRuntime = "runc"
	defaultShim    = "containerd-shim"
)

func init() {
	plugin.Register(runtimeName, &plugin.Registration{
		Type: plugin.RuntimePlugin,
		Init: New,
		Config: &Config{
			Shim:    defaultShim,
			Runtime: defaultRuntime,
		},
	})
}

var _ = (plugin.Runtime)(&Runtime{})

type Config struct {
	// Shim is a path or name of binary implementing the Shim GRPC API
	Shim string `toml:"shim,omitempty"`
	// Runtime is a path or name of an OCI runtime used by the shim
	Runtime string `toml:"runtime,omitempty"`
	// NoShim calls runc directly from within the pkg
	NoShim bool `toml:"no_shim,omitempty"`
}

func New(ic *plugin.InitContext) (interface{}, error) {
	path := filepath.Join(ic.State, runtimeName)
	if err := os.MkdirAll(path, 0700); err != nil {
		return nil, err
	}
	cfg := ic.Config.(*Config)
	c, cancel := context.WithCancel(ic.Context)
	r := &Runtime{
		root:          path,
		remote:        !cfg.NoShim,
		shim:          cfg.Shim,
		runtime:       cfg.Runtime,
		events:        make(chan *plugin.Event, 2048),
		eventsContext: c,
		eventsCancel:  cancel,
		monitor:       ic.Monitor,
	}
	// set the events output for a monitor if it generates events
	ic.Monitor.Events(r.events)
	return r, nil
}

type Runtime struct {
	root    string
	shim    string
	runtime string
	remote  bool

	events        chan *plugin.Event
	eventsContext context.Context
	eventsCancel  func()
	monitor       plugin.TaskMonitor
}

func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Task, error) {
	path, err := r.newBundle(id, opts.Spec)
	if err != nil {
		return nil, err
	}
	s, err := newShim(r.shim, path, r.remote)
	if err != nil {
		os.RemoveAll(path)
		return nil, err
	}
	// Exit the shim on error
	defer func() {
		if err != nil {
			s.Exit(context.Background(), &shim.ExitRequest{})
		}
	}()
	if err = r.handleEvents(s); err != nil {
		os.RemoveAll(path)
		return nil, err
	}
	sopts := &shim.CreateRequest{
		ID:         id,
		Bundle:     path,
		Runtime:    r.runtime,
		Stdin:      opts.IO.Stdin,
		Stdout:     opts.IO.Stdout,
		Stderr:     opts.IO.Stderr,
		Terminal:   opts.IO.Terminal,
		Checkpoint: opts.Checkpoint,
	}
	for _, m := range opts.Rootfs {
		sopts.Rootfs = append(sopts.Rootfs, &mount.Mount{
			Type:    m.Type,
			Source:  m.Source,
			Options: m.Options,
		})
	}
	if _, err = s.Create(ctx, sopts); err != nil {
		os.RemoveAll(path)
		return nil, err
	}
	c := newTask(id, opts.Spec, s)
	// after the task is created, add it to the monitor
	if err = r.monitor.Monitor(c); err != nil {
		return nil, err
	}
	return c, nil
}

func (r *Runtime) Delete(ctx context.Context, c plugin.Task) (*plugin.Exit, error) {
	lc, ok := c.(*Task)
	if !ok {
		return nil, fmt.Errorf("container cannot be cast as *linux.Container")
	}
	// remove the container from the monitor
	if err := r.monitor.Stop(lc); err != nil {
		// TODO: log error here
		return nil, err
	}
	rsp, err := lc.shim.Delete(ctx, &shim.DeleteRequest{})
	if err != nil {
		return nil, err
	}
	lc.shim.Exit(ctx, &shim.ExitRequest{})
	return &plugin.Exit{
		Status:    rsp.ExitStatus,
		Timestamp: rsp.ExitedAt,
	}, r.deleteBundle(lc.containerID)
}

func (r *Runtime) Tasks(ctx context.Context) ([]plugin.Task, error) {
	dir, err := ioutil.ReadDir(r.root)
	if err != nil {
		return nil, err
	}
	var o []plugin.Task
	for _, fi := range dir {
		if !fi.IsDir() {
			continue
		}
		id := fi.Name()
		// TODO: optimize this if it is call frequently to list all containers
		// i.e. dont' reconnect to the the shim's ever time
		c, err := r.loadContainer(filepath.Join(r.root, id))
		if err != nil {
			log.G(ctx).WithError(err).Warnf("failed to load container %s", id)
			// if we fail to load the container, connect to the shim, make sure if the shim has
			// been killed and cleanup the resources still being held by the container
			r.killContainer(ctx, id)
			continue
		}
		o = append(o, c)
	}
	return o, nil
}

func (r *Runtime) Events(ctx context.Context) <-chan *plugin.Event {
	return r.events
}

func (r *Runtime) handleEvents(s shim.ShimClient) error {
	events, err := s.Events(r.eventsContext, &shim.EventsRequest{})
	if err != nil {
		return err
	}
	go r.forward(events)
	return nil
}

func (r *Runtime) forward(events shim.Shim_EventsClient) {
	for {
		e, err := events.Recv()
		if err != nil {
			if !strings.HasSuffix(err.Error(), "transport is closing") {
				log.G(r.eventsContext).WithError(err).Error("get event from shim")
			}
			return
		}
		var et plugin.EventType
		switch e.Type {
		case task.Event_CREATE:
			et = plugin.CreateEvent
		case task.Event_EXEC_ADDED:
			et = plugin.ExecAddEvent
		case task.Event_EXIT:
			et = plugin.ExitEvent
		case task.Event_OOM:
			et = plugin.OOMEvent
		case task.Event_START:
			et = plugin.StartEvent
		}
		r.events <- &plugin.Event{
			Timestamp:  time.Now(),
			Runtime:    runtimeName,
			Type:       et,
			Pid:        e.Pid,
			ID:         e.ID,
			ExitStatus: e.ExitStatus,
			ExitedAt:   e.ExitedAt,
		}
	}
}

func (r *Runtime) newBundle(id string, spec []byte) (string, error) {
	path := filepath.Join(r.root, id)
	if err := os.Mkdir(path, 0700); err != nil {
		return "", err
	}
	if err := os.Mkdir(filepath.Join(path, "rootfs"), 0700); err != nil {
		return "", err
	}
	f, err := os.Create(filepath.Join(path, configFilename))
	if err != nil {
		return "", err
	}
	defer f.Close()
	_, err = io.Copy(f, bytes.NewReader(spec))
	return path, err
}

func (r *Runtime) deleteBundle(id string) error {
	return os.RemoveAll(filepath.Join(r.root, id))
}

func (r *Runtime) loadContainer(path string) (*Task, error) {
	id := filepath.Base(path)
	s, err := loadShim(path, r.remote)
	if err != nil {
		return nil, err
	}

	data, err := ioutil.ReadFile(filepath.Join(path, configFilename))
	if err != nil {
		return nil, err
	}

	return &Task{
		containerID: id,
		shim:        s,
		spec:        data,
	}, nil
}

// killContainer is used whenever the runtime fails to connect to a shim (it died)
// and needs to cleanup the container resources in the underlying runtime (runc, etc...)
func (r *Runtime) killContainer(ctx context.Context, id string) {
	log.G(ctx).Debug("terminating container after failed load")
	runtime := &runc.Runc{
		// TODO: get Command provided for initial container creation
		//	Command:      r.Runtime,
		LogFormat:    runc.JSON,
		PdeathSignal: unix.SIGKILL,
	}
	if err := runtime.Kill(ctx, id, int(unix.SIGKILL), &runc.KillOpts{
		All: true,
	}); err != nil {
		log.G(ctx).WithError(err).Warnf("kill all processes for %s", id)
	}
	// it can take a while for the container to be killed so poll for the container's status
	// until it is in a stopped state
	status := "running"
	for status != "stopped" {
		c, err := runtime.State(ctx, id)
		if err != nil {
			break
		}
		status = c.Status
		time.Sleep(10 * time.Millisecond)
	}
	if err := runtime.Delete(ctx, id); err != nil {
		log.G(ctx).WithError(err).Warnf("delete container %s", id)
	}
	// try to unmount the rootfs is it was not held by an external shim
	unix.Unmount(filepath.Join(r.root, id, "rootfs"), 0)
	// remove container bundle
	if err := r.deleteBundle(id); err != nil {
		log.G(ctx).WithError(err).Warnf("delete container bundle %s", id)
	}
}
<commit_msg>Use conf value when killing loaded container<commit_after>// +build linux

package linux

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/containerd/containerd/api/services/shim"
	"github.com/containerd/containerd/api/types/mount"
	"github.com/containerd/containerd/api/types/task"
	"github.com/containerd/containerd/log"
	"github.com/containerd/containerd/plugin"
	runc "github.com/containerd/go-runc"

	"golang.org/x/sys/unix"
)

const (
	runtimeName    = "linux"
	configFilename = "config.json"
	defaultRuntime = "runc"
	defaultShim    = "containerd-shim"
)

func init() {
	plugin.Register(runtimeName, &plugin.Registration{
		Type: plugin.RuntimePlugin,
		Init: New,
		Config: &Config{
			Shim:    defaultShim,
			Runtime: defaultRuntime,
		},
	})
}

var _ = (plugin.Runtime)(&Runtime{})

type Config struct {
	// Shim is a path or name of binary implementing the Shim GRPC API
	Shim string `toml:"shim,omitempty"`
	// Runtime is a path or name of an OCI runtime used by the shim
	Runtime string `toml:"runtime,omitempty"`
	// NoShim calls runc directly from within the pkg
	NoShim bool `toml:"no_shim,omitempty"`
}

func New(ic *plugin.InitContext) (interface{}, error) {
	path := filepath.Join(ic.State, runtimeName)
	if err := os.MkdirAll(path, 0700); err != nil {
		return nil, err
	}
	cfg := ic.Config.(*Config)
	c, cancel := context.WithCancel(ic.Context)
	r := &Runtime{
		root:          path,
		remote:        !cfg.NoShim,
		shim:          cfg.Shim,
		runtime:       cfg.Runtime,
		events:        make(chan *plugin.Event, 2048),
		eventsContext: c,
		eventsCancel:  cancel,
		monitor:       ic.Monitor,
	}
	// set the events output for a monitor if it generates events
	ic.Monitor.Events(r.events)
	return r, nil
}

type Runtime struct {
	root    string
	shim    string
	runtime string
	remote  bool

	events        chan *plugin.Event
	eventsContext context.Context
	eventsCancel  func()
	monitor       plugin.TaskMonitor
}

func (r *Runtime) Create(ctx context.Context, id string, opts plugin.CreateOpts) (plugin.Task, error) {
	path, err := r.newBundle(id, opts.Spec)
	if err != nil {
		return nil, err
	}
	s, err := newShim(r.shim, path, r.remote)
	if err != nil {
		os.RemoveAll(path)
		return nil, err
	}
	// Exit the shim on error
	defer func() {
		if err != nil {
			s.Exit(context.Background(), &shim.ExitRequest{})
		}
	}()
	if err = r.handleEvents(s); err != nil {
		os.RemoveAll(path)
		return nil, err
	}
	sopts := &shim.CreateRequest{
		ID:         id,
		Bundle:     path,
		Runtime:    r.runtime,
		Stdin:      opts.IO.Stdin,
		Stdout:     opts.IO.Stdout,
		Stderr:     opts.IO.Stderr,
		Terminal:   opts.IO.Terminal,
		Checkpoint: opts.Checkpoint,
	}
	for _, m := range opts.Rootfs {
		sopts.Rootfs = append(sopts.Rootfs, &mount.Mount{
			Type:    m.Type,
			Source:  m.Source,
			Options: m.Options,
		})
	}
	if _, err = s.Create(ctx, sopts); err != nil {
		os.RemoveAll(path)
		return nil, err
	}
	c := newTask(id, opts.Spec, s)
	// after the task is created, add it to the monitor
	if err = r.monitor.Monitor(c); err != nil {
		return nil, err
	}
	return c, nil
}

func (r *Runtime) Delete(ctx context.Context, c plugin.Task) (*plugin.Exit, error) {
	lc, ok := c.(*Task)
	if !ok {
		return nil, fmt.Errorf("container cannot be cast as *linux.Container")
	}
	// remove the container from the monitor
	if err := r.monitor.Stop(lc); err != nil {
		// TODO: log error here
		return nil, err
	}
	rsp, err := lc.shim.Delete(ctx, &shim.DeleteRequest{})
	if err != nil {
		return nil, err
	}
	lc.shim.Exit(ctx, &shim.ExitRequest{})
	return &plugin.Exit{
		Status:    rsp.ExitStatus,
		Timestamp: rsp.ExitedAt,
	}, r.deleteBundle(lc.containerID)
}

func (r *Runtime) Tasks(ctx context.Context) ([]plugin.Task, error) {
	dir, err := ioutil.ReadDir(r.root)
	if err != nil {
		return nil, err
	}
	var o []plugin.Task
	for _, fi := range dir {
		if !fi.IsDir() {
			continue
		}
		id := fi.Name()
		// TODO: optimize this if it is call frequently to list all containers
		// i.e. dont' reconnect to the the shim's ever time
		c, err := r.loadContainer(filepath.Join(r.root, id))
		if err != nil {
			log.G(ctx).WithError(err).Warnf("failed to load container %s", id)
			// if we fail to load the container, connect to the shim, make sure if the shim has
			// been killed and cleanup the resources still being held by the container
			r.killContainer(ctx, id)
			continue
		}
		o = append(o, c)
	}
	return o, nil
}

func (r *Runtime) Events(ctx context.Context) <-chan *plugin.Event {
	return r.events
}

func (r *Runtime) handleEvents(s shim.ShimClient) error {
	events, err := s.Events(r.eventsContext, &shim.EventsRequest{})
	if err != nil {
		return err
	}
	go r.forward(events)
	return nil
}

func (r *Runtime) forward(events shim.Shim_EventsClient) {
	for {
		e, err := events.Recv()
		if err != nil {
			if !strings.HasSuffix(err.Error(), "transport is closing") {
				log.G(r.eventsContext).WithError(err).Error("get event from shim")
			}
			return
		}
		var et plugin.EventType
		switch e.Type {
		case task.Event_CREATE:
			et = plugin.CreateEvent
		case task.Event_EXEC_ADDED:
			et = plugin.ExecAddEvent
		case task.Event_EXIT:
			et = plugin.ExitEvent
		case task.Event_OOM:
			et = plugin.OOMEvent
		case task.Event_START:
			et = plugin.StartEvent
		}
		r.events <- &plugin.Event{
			Timestamp:  time.Now(),
			Runtime:    runtimeName,
			Type:       et,
			Pid:        e.Pid,
			ID:         e.ID,
			ExitStatus: e.ExitStatus,
			ExitedAt:   e.ExitedAt,
		}
	}
}

func (r *Runtime) newBundle(id string, spec []byte) (string, error) {
	path := filepath.Join(r.root, id)
	if err := os.Mkdir(path, 0700); err != nil {
		return "", err
	}
	if err := os.Mkdir(filepath.Join(path, "rootfs"), 0700); err != nil {
		return "", err
	}
	f, err := os.Create(filepath.Join(path, configFilename))
	if err != nil {
		return "", err
	}
	defer f.Close()
	_, err = io.Copy(f, bytes.NewReader(spec))
	return path, err
}

func (r *Runtime) deleteBundle(id string) error {
	return os.RemoveAll(filepath.Join(r.root, id))
}

func (r *Runtime) loadContainer(path string) (*Task, error) {
	id := filepath.Base(path)
	s, err := loadShim(path, r.remote)
	if err != nil {
		return nil, err
	}

	data, err := ioutil.ReadFile(filepath.Join(path, configFilename))
	if err != nil {
		return nil, err
	}

	return &Task{
		containerID: id,
		shim:        s,
		spec:        data,
	}, nil
}

// killContainer is used whenever the runtime fails to connect to a shim (it died)
// and needs to cleanup the container resources in the underlying runtime (runc, etc...)
func (r *Runtime) killContainer(ctx context.Context, id string) {
	log.G(ctx).Debug("terminating container after failed load")
	runtime := &runc.Runc{
		// TODO: should we get Command provided for initial container creation?
		Command:      r.runtime,
		LogFormat:    runc.JSON,
		PdeathSignal: unix.SIGKILL,
	}
	if err := runtime.Kill(ctx, id, int(unix.SIGKILL), &runc.KillOpts{
		All: true,
	}); err != nil {
		log.G(ctx).WithError(err).Warnf("kill all processes for %s", id)
	}
	// it can take a while for the container to be killed so poll for the container's status
	// until it is in a stopped state
	status := "running"
	for status != "stopped" {
		c, err := runtime.State(ctx, id)
		if err != nil {
			break
		}
		status = c.Status
		time.Sleep(10 * time.Millisecond)
	}
	if err := runtime.Delete(ctx, id); err != nil {
		log.G(ctx).WithError(err).Warnf("delete container %s", id)
	}
	// try to unmount the rootfs is it was not held by an external shim
	unix.Unmount(filepath.Join(r.root, id, "rootfs"), 0)
	// remove container bundle
	if err := r.deleteBundle(id); err != nil {
		log.G(ctx).WithError(err).Warnf("delete container bundle %s", id)
	}
}
<|endoftext|>


<commit_before>package goroup

import (
	"reflect"
	"testing"
)

func Test_NewSet(t *testing.T) {
	s := NewSet()
	if reflect.TypeOf(s) != reflect.TypeOf(Set{}) {
		t.Errorf("NewSet() should return Set type: %#v", s)
	}
}

func Test_Size(t *testing.T) {
	s := NewSet()
	if s.Size() != 0 {
		t.Errorf("NewSet() should return Set of size 0: %#v", s)
	}
}

func Test_IsEmpty(t *testing.T) {
	s := NewSet()
	if s.IsEmpty() != true {
		t.Errorf("IsEmpty() should return true: %#v", s)
	}
}

func Test_Insert(t *testing.T) {
	s := NewSet()
	s.Insert(1, 2, -.9, "A", 0, 2, 2, 2)
	if s.IsEmpty() != false {
		t.Errorf("IsEmpty() should return false: %#v", s)
	}
	if s.Size() != 5 {
		t.Errorf("Size() should return 5: %#v", s)
	}

	value, exist := s[2]
	if value != 4 {
		t.Errorf("s[2]'s value should be 4: %#v", value)
	}
	if exist != true {
		t.Errorf("s[2] should exist: %#v", value)
	}
}

func Test_InstantiateSet(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	if s.IsEmpty() != false {
		t.Errorf("IsEmpty() should return false: %#v", s)
	}
	if s.Size() != 5 {
		t.Errorf("Size() should return 5: %#v", s)
	}
	value, exist := s[2]
	if value != 1 {
		t.Errorf("value should be 1: %#v", s)
	}
	if exist != true {
		t.Errorf("s[2] should exist: %#v", s)
	}
}

func Test_GetElements(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0, 10, 20)
	sl := s.GetElements()
	if len(sl) != 7 {
		t.Errorf("len(sl) should be 7: %#v", s)
	}
}

func Test_Contains(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	result := s.Contains(-0.9)
	if result != true {
		t.Errorf("s.Contains(-0.9) should return true: %#v", s)
	}
}

func Test_Delete(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	result1 := s.Delete(-0.9)
	if result1 != true {
		t.Errorf("s.Delete(-0.9) should return true: %#v", s)
	}
	result2 := s.Delete("A")
	if result2 != true {
		t.Errorf("s.Delete('A') should return true: %#v", s)
	}
	if s.Size() != 3 {
		t.Errorf("s.Size() should return 3: %#v", s)
	}
	result3 := s.Delete(100)
	if result3 != false {
		t.Errorf("s.Delete(100) should return false: %#v", s)
	}
}

func Test_Intersection(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(1, 2)
	result := s.Intersection(a)
	if len(result) != 2 {
		t.Errorf("len(result) should return 2: %#v", s)
	}
	if result[0] != []interface{}{1, 2}[0] {
		t.Errorf("result[0] should return 1: %#v", s)
	}
	if result[1] != []interface{}{1, 2}[1] {
		t.Errorf("result[1] should return 2: %#v", s)
	}
}

func Test_Union(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(100, 200)
	result := s.Union(a)
	if len(result) != 7 {
		t.Errorf("len(result) should return 7: %#v", s)
	}
}

func Test_Subtract(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(1, 2)
	result := s.Subtract(a)
	if len(result) != 3 {
		t.Errorf("len(result) should return 3: %#v", s)
	}
}

func Test_IsEqual(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)

	a := InstantiateSet(1, 2)
	result1 := s.IsEqual(a)
	if result1 != false {
		t.Errorf("result1 should be false: %#v", s)
	}

	b := InstantiateSet(1, 2, -.9, "A", 0)
	result2 := s.IsEqual(b)
	if result2 != true {
		t.Errorf("result2 should be true: %#v", s)
	}
}

func Test_Subset(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(1, 2)
	result1 := s.Subset(a)
	if result1 != true {
		t.Errorf("result1 should be true: %#v", s)
	}

	b := InstantiateSet(1, 2, -.9, "A", 0, 100)
	result2 := s.Subset(b)
	if result2 != false {
		t.Errorf("result2 should be false: %#v", s)
	}
}

func Test_Clone(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := s.Clone()
	result := s.IsEqual(a)
	if result != true {
		t.Errorf("result should be true: %#v", s)
	}
}
<commit_msg>Update goroup testing. Set does not consider its order<commit_after>package goroup

import (
	"reflect"
	"testing"
)

func Test_NewSet(t *testing.T) {
	s := NewSet()
	if reflect.TypeOf(s) != reflect.TypeOf(Set{}) {
		t.Errorf("NewSet() should return Set type: %#v", s)
	}
}

func Test_Size(t *testing.T) {
	s := NewSet()
	if s.Size() != 0 {
		t.Errorf("NewSet() should return Set of size 0: %#v", s)
	}
}

func Test_IsEmpty(t *testing.T) {
	s := NewSet()
	if s.IsEmpty() != true {
		t.Errorf("IsEmpty() should return true: %#v", s)
	}
}

func Test_Insert(t *testing.T) {
	s := NewSet()
	s.Insert(1, 2, -.9, "A", 0, 2, 2, 2)
	if s.IsEmpty() != false {
		t.Errorf("IsEmpty() should return false: %#v", s)
	}
	if s.Size() != 5 {
		t.Errorf("Size() should return 5: %#v", s)
	}

	value, exist := s[2]
	if value != 4 {
		t.Errorf("s[2]'s value should be 4: %#v", value)
	}
	if exist != true {
		t.Errorf("s[2] should exist: %#v", value)
	}
}

func Test_InstantiateSet(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	if s.IsEmpty() != false {
		t.Errorf("IsEmpty() should return false: %#v", s)
	}
	if s.Size() != 5 {
		t.Errorf("Size() should return 5: %#v", s)
	}
	value, exist := s[2]
	if value != 1 {
		t.Errorf("value should be 1: %#v", s)
	}
	if exist != true {
		t.Errorf("s[2] should exist: %#v", s)
	}
}

func Test_GetElements(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0, 10, 20)
	sl := s.GetElements()
	if len(sl) != 7 {
		t.Errorf("len(sl) should be 7: %#v", s)
	}
}

func Test_Contains(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	result := s.Contains(-0.9)
	if result != true {
		t.Errorf("s.Contains(-0.9) should return true: %#v", s)
	}
}

func Test_Delete(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	result1 := s.Delete(-0.9)
	if result1 != true {
		t.Errorf("s.Delete(-0.9) should return true: %#v", s)
	}
	result2 := s.Delete("A")
	if result2 != true {
		t.Errorf("s.Delete('A') should return true: %#v", s)
	}
	if s.Size() != 3 {
		t.Errorf("s.Size() should return 3: %#v", s)
	}
	result3 := s.Delete(100)
	if result3 != false {
		t.Errorf("s.Delete(100) should return false: %#v", s)
	}
}

func Test_Intersection(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(1, 2)
	result := s.Intersection(a)
	if len(result) != 2 {
		t.Errorf("len(result) should return 2: %#v", s)
	}
	// if result[0] != []interface{}{1, 2}[0] {
	// t.Errorf("result[0] should return 1: %#v", s)
	// }
	// if result[1] != []interface{}{1, 2}[1] {
	// t.Errorf("result[1] should return 2: %#v", s)
	// }
}

func Test_Union(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(100, 200)
	result := s.Union(a)
	if len(result) != 7 {
		t.Errorf("len(result) should return 7: %#v", s)
	}
}

func Test_Subtract(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(1, 2)
	result := s.Subtract(a)
	if len(result) != 3 {
		t.Errorf("len(result) should return 3: %#v", s)
	}
}

func Test_IsEqual(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)

	a := InstantiateSet(1, 2)
	result1 := s.IsEqual(a)
	if result1 != false {
		t.Errorf("result1 should be false: %#v", s)
	}

	b := InstantiateSet(1, 2, -.9, "A", 0)
	result2 := s.IsEqual(b)
	if result2 != true {
		t.Errorf("result2 should be true: %#v", s)
	}
}

func Test_Subset(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := InstantiateSet(1, 2)
	result1 := s.Subset(a)
	if result1 != true {
		t.Errorf("result1 should be true: %#v", s)
	}

	b := InstantiateSet(1, 2, -.9, "A", 0, 100)
	result2 := s.Subset(b)
	if result2 != false {
		t.Errorf("result2 should be false: %#v", s)
	}
}

func Test_Clone(t *testing.T) {
	s := InstantiateSet(1, 2, -.9, "A", 0)
	a := s.Clone()
	result := s.IsEqual(a)
	if result != true {
		t.Errorf("result should be true: %#v", s)
	}
}
<|endoftext|>


<commit_before>package benchmark

import (
	"context"
	"testing"

	"github.com/morikuni/guard"
	"github.com/morikuni/guard/circuitbreaker"
	"github.com/morikuni/guard/panicguard"
	"github.com/morikuni/guard/retry"
	"github.com/morikuni/guard/semaphore"
)

func BenchmarkBase(b *testing.B) {
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		func(ctx context.Context) error {
			return nil
		}(context.Background())
	}
}

func BenchmarkRetry(b *testing.B) {
	g := retry.New(retry.Inf, guard.NewNoBackoff())

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		g.Run(context.Background(), func(ctx context.Context) error {
			return nil
		})
	}
}

func BenchmarkPanicguard(b *testing.B) {
	g := panicguard.New()

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		g.Run(context.Background(), func(ctx context.Context) error {
			return nil
		})
	}
}

func BenchmarkSemaphore(b *testing.B) {
	g := semaphore.New(3)

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		g.Run(context.Background(), func(ctx context.Context) error {
			return nil
		})
	}
}

func BenchmarkCircuitBreaker(b *testing.B) {
	window := circuitbreaker.NewCountBaseWindow(100)
	g := circuitbreaker.New(window, 0.2, guard.NewNoBackoff())

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		g.Run(context.Background(), func(ctx context.Context) error {
			return nil
		})
	}
}
<commit_msg>Update benchmark<commit_after>package benchmark

import (
	"context"
	"testing"

	"github.com/morikuni/guard"
	"github.com/morikuni/guard/circuitbreaker"
	"github.com/morikuni/guard/panicguard"
	"github.com/morikuni/guard/retry"
	"github.com/morikuni/guard/semaphore"
)

func BenchmarkBase(b *testing.B) {
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			func(ctx context.Context) error {
				return nil
			}(context.Background())
		}
	})
}

func BenchmarkRetry(b *testing.B) {
	g := retry.New(retry.Inf, guard.NewNoBackoff())

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			g.Run(context.Background(), func(ctx context.Context) error {
				return nil
			})
		}
	})
}

func BenchmarkPanicguard(b *testing.B) {
	g := panicguard.New()

	b.Run("without panic", func(b *testing.B) {
		b.RunParallel(func(pb *testing.PB) {
			for pb.Next() {
				g.Run(context.Background(), func(ctx context.Context) error {
					return nil
				})
			}
		})
	})

	b.Run("with panic", func(b *testing.B) {
		b.RunParallel(func(pb *testing.PB) {
			for pb.Next() {
				g.Run(context.Background(), func(ctx context.Context) error {
					panic("hello")
				})
			}
		})
	})
}

func BenchmarkSemaphore(b *testing.B) {
	g := semaphore.New(100)

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			g.Run(context.Background(), func(ctx context.Context) error {
				return nil
			})
		}
	})
}

func BenchmarkCircuitBreaker(b *testing.B) {
	window := circuitbreaker.NewCountBaseWindow(100)
	g := circuitbreaker.New(window, 0.2, guard.NewNoBackoff())

	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			g.Run(context.Background(), func(ctx context.Context) error {
				return nil
			})
		}
	})
}
}
<|endoftext|>


<commit_before>package loader

import (
	"fmt"
	"github.com/tsliwowicz/go-wrk/util"
	"io/ioutil"
	"net/http"
	"net/url"
	"sync/atomic"
	"time"
)

const (
	USER_AGENT = "go-wrk"
)

type LoadCfg struct {
	duration           int //seconds
	goroutines         int
	testUrl            string
	method             string
	statsAggregator    chan *RequesterStats
	timeoutms          int
	allowRedirects     bool
	disableCompression bool
	disableKeepAlive   bool
	interrupted int32
}

// RequesterStats used for colelcting aggregate statistics
type RequesterStats struct {
	TotRespSize    int64
	TotDuration    time.Duration
	MinRequestTime time.Duration
	MaxRequestTime time.Duration
	NumRequests    int
	NumErrs        int
}

func NewLoadCfg(duration int, //seconds
	goroutines int,
	testUrl string,
	method string,
	statsAggregator chan *RequesterStats,
	timeoutms int,
	allowRedirects bool,
	disableCompression bool,
	disableKeepAlive bool) (rt *LoadCfg) {
	rt = &LoadCfg{duration, goroutines, testUrl, method, statsAggregator, timeoutms,
		allowRedirects, disableCompression, disableKeepAlive, 0}
	return
}

//DoRequest single request implementation. Returns the size of the response and its duration
//On error - returns -1 on both
func DoRequest(httpClient *http.Client, method string, loadUrl string) (respSize int, duration time.Duration) {
	respSize = -1
	duration = -1
	req, err := http.NewRequest(method, loadUrl, nil)

	req.Header.Add("User-Agent", USER_AGENT)
	start := time.Now()
	resp, err := httpClient.Do(req)
	if err != nil {
		//this is a bit weird. When redirection is prevented, a url.Error is retuned. This creates an issue to distinguish
		//between an invalid URL that was provided and and redirection error.
		rr, ok := err.(*url.Error)
		if !ok {
			fmt.Println("An error occured doing request", err, rr)
			return
		}
	}
	if resp == nil {
		return
	}
	defer func() {
		if resp != nil && resp.Body != nil {
			resp.Body.Close()
		}
	}()
	if resp.StatusCode == http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			fmt.Println("An error occured reading body", err)
		} else {
			duration = time.Since(start)
			respSize = len(body) + int(util.EstimateHttpHeadersSize(resp.Header))
		}
	} else if resp.StatusCode == http.StatusMovedPermanently || resp.StatusCode == http.StatusTemporaryRedirect {
		duration = time.Since(start)
		respSize = int(resp.ContentLength) + int(util.EstimateHttpHeadersSize(resp.Header))
	}

	return
}

//Requester a go function for repeatedly making requests and aggregating statistics as long as required
//When it is done, it sends the results using the statsAggregator channel
func (cfg *LoadCfg) RunSingleLoadSession() {
	stats := &RequesterStats{MinRequestTime: time.Minute}
	start := time.Now()
	var httpClient *http.Client

	if cfg.allowRedirects {
		httpClient = &http.Client{}
	} else {
		//returning an error when trying to redirect. This prevents the redirection from happening.
		httpClient = &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return util.NewRedirectError("redirection not allowed")
		}}
	}

	//overriding the default parameters
	httpClient.Transport = &http.Transport{
		DisableCompression:    cfg.disableCompression,
		DisableKeepAlives:     cfg.disableKeepAlive,
		ResponseHeaderTimeout: time.Millisecond * time.Duration(cfg.timeoutms),
	}

	for time.Since(start).Seconds() <= float64(cfg.duration) && atomic.LoadInt32(&cfg.interrupted) == 0 {
		respSize, reqDur := DoRequest(httpClient, cfg.method, cfg.testUrl)
		if respSize > 0 {
			stats.TotRespSize += int64(respSize)
			stats.TotDuration += reqDur
			stats.MaxRequestTime = util.MaxDuration(reqDur, stats.MaxRequestTime)
			stats.MinRequestTime = util.MinDuration(reqDur, stats.MinRequestTime)
			stats.NumRequests++
		} else {
			stats.NumErrs++
		}
	}
	cfg.statsAggregator <- stats
}

func (cfg *LoadCfg) Stop() {
	atomic.StoreInt32(&cfg.interrupted, 1)
}
<commit_msg>Added url escaping<commit_after>package loader

import (
	"fmt"
	"github.com/tsliwowicz/go-wrk/util"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"sync/atomic"
	"time"
)

const (
	USER_AGENT = "go-wrk"
)

type LoadCfg struct {
	duration           int //seconds
	goroutines         int
	testUrl            string
	method             string
	statsAggregator    chan *RequesterStats
	timeoutms          int
	allowRedirects     bool
	disableCompression bool
	disableKeepAlive   bool
	interrupted        int32
}

// RequesterStats used for colelcting aggregate statistics
type RequesterStats struct {
	TotRespSize    int64
	TotDuration    time.Duration
	MinRequestTime time.Duration
	MaxRequestTime time.Duration
	NumRequests    int
	NumErrs        int
}

func NewLoadCfg(duration int, //seconds
	goroutines int,
	testUrl string,
	method string,
	statsAggregator chan *RequesterStats,
	timeoutms int,
	allowRedirects bool,
	disableCompression bool,
	disableKeepAlive bool) (rt *LoadCfg) {
	rt = &LoadCfg{duration, goroutines, testUrl, method, statsAggregator, timeoutms,
		allowRedirects, disableCompression, disableKeepAlive, 0}
	return
}

func escapeUrlStr(in string) string {
	qm := strings.Index(in, "?")
	if qm != -1 {
		qry := in[qm+1:]
		qrys := strings.Split(qry, "&")
		var query string = ""
		var qEscaped string = ""
		var first bool = true
		for _, q := range qrys {
			qSplit := strings.Split(q, "=")
			if len(qSplit) == 2 {
				qEscaped = qSplit[0] + "=" + url.QueryEscape(qSplit[1])
			} else {
				qEscaped = qSplit[0]
			}
			if first {
				first = false
			} else {
				query += "&"
			}
			query += qEscaped

		}
		return in[:qm] + "?" + query
	} else {
		return in
	}
}

//DoRequest single request implementation. Returns the size of the response and its duration
//On error - returns -1 on both
func DoRequest(httpClient *http.Client, method string, loadUrl string) (respSize int, duration time.Duration) {
	respSize = -1
	duration = -1

	loadUrl = escapeUrlStr(loadUrl)

	req, err := http.NewRequest(method, loadUrl, nil)
	if err != nil {
		fmt.Println("An error occured doing request", err)
		return
	}

	req.Header.Add("User-Agent", USER_AGENT)
	start := time.Now()
	resp, err := httpClient.Do(req)
	if err != nil {
		fmt.Println("redirect?")
		//this is a bit weird. When redirection is prevented, a url.Error is retuned. This creates an issue to distinguish
		//between an invalid URL that was provided and and redirection error.
		rr, ok := err.(*url.Error)
		if !ok {
			fmt.Println("An error occured doing request", err, rr)
			return
		}
	}
	if resp == nil {
		fmt.Println("empty response")
		return
	}
	defer func() {
		if resp != nil && resp.Body != nil {
			resp.Body.Close()
		}
	}()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("An error occured reading body", err)
	}
	if resp.StatusCode == http.StatusOK {
		duration = time.Since(start)
		respSize = len(body) + int(util.EstimateHttpHeadersSize(resp.Header))
	} else if resp.StatusCode == http.StatusMovedPermanently || resp.StatusCode == http.StatusTemporaryRedirect {
		duration = time.Since(start)
		respSize = int(resp.ContentLength) + int(util.EstimateHttpHeadersSize(resp.Header))
	} else {
		fmt.Println("received status code", resp.StatusCode, "from", resp.Header, "content", string(body), req)
	}

	return
}

//Requester a go function for repeatedly making requests and aggregating statistics as long as required
//When it is done, it sends the results using the statsAggregator channel
func (cfg *LoadCfg) RunSingleLoadSession() {
	stats := &RequesterStats{MinRequestTime: time.Minute}
	start := time.Now()
	var httpClient *http.Client

	if cfg.allowRedirects {
		httpClient = &http.Client{}
	} else {
		//returning an error when trying to redirect. This prevents the redirection from happening.
		httpClient = &http.Client{CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return util.NewRedirectError("redirection not allowed")
		}}
	}

	//overriding the default parameters
	httpClient.Transport = &http.Transport{
		DisableCompression:    cfg.disableCompression,
		DisableKeepAlives:     cfg.disableKeepAlive,
		ResponseHeaderTimeout: time.Millisecond * time.Duration(cfg.timeoutms),
	}

	for time.Since(start).Seconds() <= float64(cfg.duration) && atomic.LoadInt32(&cfg.interrupted) == 0 {
		respSize, reqDur := DoRequest(httpClient, cfg.method, cfg.testUrl)
		if respSize > 0 {
			stats.TotRespSize += int64(respSize)
			stats.TotDuration += reqDur
			stats.MaxRequestTime = util.MaxDuration(reqDur, stats.MaxRequestTime)
			stats.MinRequestTime = util.MinDuration(reqDur, stats.MinRequestTime)
			stats.NumRequests++
		} else {
			stats.NumErrs++
		}
	}
	cfg.statsAggregator <- stats
}

func (cfg *LoadCfg) Stop() {
	atomic.StoreInt32(&cfg.interrupted, 1)
}
<|endoftext|>


<commit_before>package apptail

import (
	"fmt"
	"github.com/ActiveState/log"
	"github.com/ActiveState/tail"
	"github.com/ActiveState/zmqpubsub"
	"logyard"
	"os"
	"time"
)

// Instance is the NATS message sent by dea_ng to notify of new instances.
type Instance struct {
	AppGUID  string
	AppName  string
	AppSpace string `json:"space"`
	Type     string
	Index    int
	DockerId string `json:"docker_id"`
	LogFiles map[string]string
}

func (instance *Instance) Identifier() string {
	return fmt.Sprintf("%v[%v:%v]", instance.AppName, instance.Index, instance.DockerId[:ID_LENGTH])
}

// Tail begins tailing the files for this instance.
func (instance *Instance) Tail() {
	log.Infof("Tailing %v logs for %v -- %+v",
		instance.Type, instance.Identifier(), instance)

	stopCh := make(chan bool)

	for name, filename := range instance.LogFiles {
		go instance.tailFile(name, filename, stopCh)
	}

	go func() {
		DockerListener.WaitForContainer(instance.DockerId)
		log.Infof("Container for %v exited", instance.Identifier())
		close(stopCh)
	}()
}

func (instance *Instance) tailFile(name, filename string, stopCh chan bool) {
	var err error

	pub := logyard.Broker.NewPublisherMust()
	defer pub.Stop()

	limit, err := instance.getReadLimit(pub, name, filename)
	if err != nil {
		log.Error(err)
		return
	}

	tail, err := tail.TailFile(filename, tail.Config{
		MaxLineSize: GetConfig().MaxRecordSize,
		MustExist:   true,
		Follow:      true,
		Location:    &tail.SeekInfo{-limit, os.SEEK_END},
		ReOpen:      false,
		Poll:        false,
		LimitRate:   GetConfig().RateLimit})
	if err != nil {
		log.Errorf("Cannot tail file (%s); %s", filename, err)
		return
	}

FORLOOP:
	for {
		select {
		case line, ok := <-tail.Lines:
			if !ok {
				err = tail.Wait()
				break FORLOOP
			}
			instance.publishLine(pub, name, line)
		case <-stopCh:
			err = tail.Stop()
			break FORLOOP
		}
	}

	if err != nil {
		log.Error(err)
	}

	log.Infof("Completed tailing %v log for %v", name, instance.Identifier())
}

func (instance *Instance) getReadLimit(
	pub *zmqpubsub.Publisher,
	logname string,
	filename string) (int64, error) {
	// convert MB to limit in bytes.
	filesizeLimit := GetConfig().FileSizeLimit * 1024 * 1024
	if !(filesizeLimit > 0) {
		panic("invalid value for `read_limit' in apptail config")
	}

	fi, err := os.Stat(filename)
	if err != nil {
		return -1, fmt.Errorf("Cannot stat file (%s); %s", filename, err)
	}
	size := fi.Size()
	limit := filesizeLimit
	if size > filesizeLimit {
		err := fmt.Errorf("Skipping much of a large log file (%s); size (%v bytes) > read_limit (%v bytes)",
			logname, size, filesizeLimit)
		// Publish special error message.
		instance.publishLine(pub, logname, &tail.Line{
			Text: err.Error(),
			Time: time.Now(),
			Err:  err})
	} else {
		limit = size
	}
	return limit, nil
}

// publishLine zmq-publishes a log line corresponding to this instance
func (instance *Instance) publishLine(
	pub *zmqpubsub.Publisher,
	logname string,
	line *tail.Line) {

	if line == nil {
		panic("line is nil")
	}

	msg := &Message{
		Text:          line.Text,
		LogFilename:   logname,
		UnixTime:      line.Time.Unix(),
		HumanTime:     ToHerokuTime(line.Time),
		Source:        instance.Type,
		InstanceIndex: instance.Index,
		AppGUID:       instance.AppGUID,
		AppName:       instance.AppName,
		AppSpace:      instance.AppSpace,
		NodeID:        LocalNodeId(),
	}

	if line.Err != nil {
		// Mark this as a special error record, as it is
		// coming from tail, not the app.
		msg.Source = "stackato.apptail"
		msg.LogFilename = ""
		log.Warnf("[%s] %s", instance.AppName, line.Text)
	}

	err := msg.Publish(pub, false)
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>apptail: warn on file/perm related errors on log file<commit_after>package apptail

import (
	"fmt"
	"github.com/ActiveState/log"
	"github.com/ActiveState/tail"
	"github.com/ActiveState/zmqpubsub"
	"logyard"
	"os"
	"time"
)

// Instance is the NATS message sent by dea_ng to notify of new instances.
type Instance struct {
	AppGUID  string
	AppName  string
	AppSpace string `json:"space"`
	Type     string
	Index    int
	DockerId string `json:"docker_id"`
	LogFiles map[string]string
}

func (instance *Instance) Identifier() string {
	return fmt.Sprintf("%v[%v:%v]", instance.AppName, instance.Index, instance.DockerId[:ID_LENGTH])
}

// Tail begins tailing the files for this instance.
func (instance *Instance) Tail() {
	log.Infof("Tailing %v logs for %v -- %+v",
		instance.Type, instance.Identifier(), instance)

	stopCh := make(chan bool)

	for name, filename := range instance.LogFiles {
		go instance.tailFile(name, filename, stopCh)
	}

	go func() {
		DockerListener.WaitForContainer(instance.DockerId)
		log.Infof("Container for %v exited", instance.Identifier())
		close(stopCh)
	}()
}

func (instance *Instance) tailFile(name, filename string, stopCh chan bool) {
	var err error

	pub := logyard.Broker.NewPublisherMust()
	defer pub.Stop()

	limit, err := instance.getReadLimit(pub, name, filename)
	if err != nil {
		log.Warn(err)
		return
	}

	tail, err := tail.TailFile(filename, tail.Config{
		MaxLineSize: GetConfig().MaxRecordSize,
		MustExist:   true,
		Follow:      true,
		Location:    &tail.SeekInfo{-limit, os.SEEK_END},
		ReOpen:      false,
		Poll:        false,
		LimitRate:   GetConfig().RateLimit})
	if err != nil {
		log.Warnf("Cannot tail file (%s); %s", filename, err)
		return
	}

FORLOOP:
	for {
		select {
		case line, ok := <-tail.Lines:
			if !ok {
				err = tail.Wait()
				break FORLOOP
			}
			instance.publishLine(pub, name, line)
		case <-stopCh:
			err = tail.Stop()
			break FORLOOP
		}
	}

	if err != nil {
		log.Warn(err)
	}

	log.Infof("Completed tailing %v log for %v", name, instance.Identifier())
}

func (instance *Instance) getReadLimit(
	pub *zmqpubsub.Publisher,
	logname string,
	filename string) (int64, error) {
	// convert MB to limit in bytes.
	filesizeLimit := GetConfig().FileSizeLimit * 1024 * 1024
	if !(filesizeLimit > 0) {
		panic("invalid value for `read_limit' in apptail config")
	}

	fi, err := os.Stat(filename)
	if err != nil {
		return -1, fmt.Errorf("Cannot stat file (%s); %s", filename, err)
	}
	size := fi.Size()
	limit := filesizeLimit
	if size > filesizeLimit {
		err := fmt.Errorf("Skipping much of a large log file (%s); size (%v bytes) > read_limit (%v bytes)",
			logname, size, filesizeLimit)
		// Publish special error message.
		instance.publishLine(pub, logname, &tail.Line{
			Text: err.Error(),
			Time: time.Now(),
			Err:  err})
	} else {
		limit = size
	}
	return limit, nil
}

// publishLine zmq-publishes a log line corresponding to this instance
func (instance *Instance) publishLine(
	pub *zmqpubsub.Publisher,
	logname string,
	line *tail.Line) {

	if line == nil {
		panic("line is nil")
	}

	msg := &Message{
		Text:          line.Text,
		LogFilename:   logname,
		UnixTime:      line.Time.Unix(),
		HumanTime:     ToHerokuTime(line.Time),
		Source:        instance.Type,
		InstanceIndex: instance.Index,
		AppGUID:       instance.AppGUID,
		AppName:       instance.AppName,
		AppSpace:      instance.AppSpace,
		NodeID:        LocalNodeId(),
	}

	if line.Err != nil {
		// Mark this as a special error record, as it is
		// coming from tail, not the app.
		msg.Source = "stackato.apptail"
		msg.LogFilename = ""
		log.Warnf("[%s] %s", instance.AppName, line.Text)
	}

	err := msg.Publish(pub, false)
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>