<commit_before>// Copyright 2014 Richard Lehane. All rights reserved.
//
// 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 msoleps implements a reader for Microsoft OLE Property Set Data structures,
// (http://msdn.microsoft.com/en-au/library/dd942421.aspx) a generic persistence format
// for simple typed metadata

// Example:
//   file, _ := os.Open("test/test.doc")
//   defer file.Close()
//   doc, err := mscfb.NewReader(file)
//   if err != nil {
//    log.Fatal(err)
//   }
//   props := msoleps.New()
//   for entry, err := doc.Next(); err == nil; entry, err = doc.Next() {
//     if msoleps.IsMSOLEPS(entry.Initial) {
//       if oerr := props.Reset(doc); oerr != nil {
//         log.Fatal(oerr)
//       }
//       for prop := range props.Property {
//         fmt.Printf("Name: %s; Type: %s; Value: %v", prop.Name, prop.Type(), prop)
//       }
//     }
//   }
package msoleps

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"

	"github.com/richardlehane/msoleps/types"
)

var (
	ErrFormat = errors.New("msoleps: not a valid msoleps stream")
	ErrRead   = errors.New("msoleps: error reading msoleps stream")
	ErrSeek   = errors.New("msoleps: can't seek backwards")
)

// IsMSOLEPS checks the first uint16 character of an mscfb name to test if it is a MSOLEPS stream
func IsMSOLEPS(i uint16) bool {
	if i == 0x0005 {
		return true
	}
	return false
}

// Reader is a reader for MS OLE Property Set Data structures
type Reader struct {
	Property []*Property

	b   *bytes.Buffer
	buf []byte
	*propertySetStream
	pSets [2]*propertySet
}

func New() *Reader {
	r := &Reader{}
	r.b = &bytes.Buffer{}
	return r
}

func (r *Reader) Reset(rdr io.Reader) error {
	r.b.Reset()
	return r.start(rdr)
}

func NewFrom(rdr io.Reader) (*Reader, error) {
	r := &Reader{}
	r.b = &bytes.Buffer{}
	return r, r.start(rdr)
}

func (r *Reader) start(rdr io.Reader) error {
	if _, err := r.b.ReadFrom(rdr); err != nil {
		return ErrRead
	}
	r.buf = r.b.Bytes()
	// read the header (property stream details)
	pss, err := makePropertySetStream(r.buf)
	if err != nil {
		return err
	}
	// sanity checks to find obvious errors
	switch {
	case pss.byteOrder != 0xFFFE, pss.version > 0x0001, pss.numPropertySets > 0x00000002:
		return ErrFormat
	}
	r.propertySetStream = pss
	// identify the property identifiers and offsets
	ps, err := r.getPropertySet(pss.offsetA)
	if err != nil {
		return err
	}
	plen := len(ps.idsOffs)
	r.pSets[0] = ps
	var psb *propertySet
	if pss.numPropertySets == 2 {
		psb, err = r.getPropertySet(pss.offsetB)
		if err != nil {
			return err
		}
		r.pSets[1] = psb
		plen += len(psb.idsOffs)
	}
	r.Property = make([]*Property, plen)
	dict, ok := propertySets[pss.fmtidA]
	if !ok {
		dict = ps.dict
		if dict == nil {
			dict = make(map[uint32]string)
		}
	}
	for i, v := range ps.idsOffs {
		r.Property[i] = &Property{}
		r.Property[i].Name = dict[v.id]
		t, _ := types.Evaluate(r.buf[int(v.offset+pss.offsetA):])
		if t.Type() == "CodeString" {
			cs := t.(*types.CodeString)
			cs.SetId(ps.code)
			t = types.Type(cs)
		}
		r.Property[i].T = t
	}
	if pss.numPropertySets != 2 {
		return nil
	}
	dict, ok = propertySets[pss.fmtidB]
	if !ok {
		dict = psb.dict
		if dict == nil {
			dict = make(map[uint32]string)
		}
	}
	for i, v := range psb.idsOffs {
		i += len(ps.idsOffs)
		r.Property[i] = &Property{}
		r.Property[i].Name = dict[v.id]
		t, _ := types.Evaluate(r.buf[int(v.offset+pss.offsetB):])
		if t.Type() == "CodeString" {
			cs := t.(*types.CodeString)
			cs.SetId(psb.code)
			t = types.Type(cs)
		}
		r.Property[i].T = t
	}
	return nil
}

func (r *Reader) getPropertySet(o uint32) (*propertySet, error) {
	pSet := &propertySet{}
	pSet.size = binary.LittleEndian.Uint32(r.buf[int(o) : int(o)+4])
	pSet.numProperties = binary.LittleEndian.Uint32(r.buf[int(o)+4 : int(o)+8])
	pSet.idsOffs = make([]propertyIDandOffset, int(pSet.numProperties))
	var dictOff uint32
	for i := range pSet.idsOffs {
		this := i*8 + 8 + int(o)
		pSet.idsOffs[i].id = binary.LittleEndian.Uint32(r.buf[this : this+4])
		pSet.idsOffs[i].offset = binary.LittleEndian.Uint32(r.buf[this+4 : this+8])
		switch pSet.idsOffs[i].id {
		case 0x00000000:
			dictOff = pSet.idsOffs[i].offset
		case 0x00000001:
			off := int(pSet.idsOffs[i].offset + o)
			pSet.code = types.CodePageID(binary.LittleEndian.Uint16(r.buf[off+4 : off+6]))
		}
	}
	if dictOff > 0 {
		var err error
		pSet.dict, err = r.getDictionary(dictOff+o, pSet.code)
		if err != nil {
			return nil, err
		}
	}
	return pSet, nil
}

func (r *Reader) getDictionary(o uint32, code types.CodePageID) (map[uint32]string, error) {
	b := r.buf[int(o):]
	e := 4
	if len(b) < e {
		return nil, ErrFormat
	}
	num := int(binary.LittleEndian.Uint32(b[:e]))
	if num == 0 {
		return nil, nil
	}
	dict := make(map[uint32]string)
	for i := 0; i < num; i++ {
		if len(b[e:]) < 8 {
			return nil, ErrFormat
		}
		id, l := binary.LittleEndian.Uint32(b[e:e+4]), binary.LittleEndian.Uint32(b[e+4:e+8])
		var s types.Type
		var err error
		if code == 0x04B0 {
			var pad int
			if l%2 != 0 {
				pad = 2
			}
			s, err = types.MakeUnicode(b[e+4:])
			if err != nil {
				return nil, ErrFormat
			}
			e = e + 8 + pad + int(l)*2
		} else {
			s, err = types.MakeCodeString(b[e+4:])
			if err != nil {
				return nil, ErrFormat
			}
			cs := s.(*types.CodeString)
			cs.SetId((code))
			s = cs
			e = e + 8 + int(l)
		}
		dict[id] = s.String()
	}
	return dict, nil
}
<commit_msg>whitespace<commit_after>// Copyright 2014 Richard Lehane. All rights reserved.
//
// 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 msoleps implements a reader for Microsoft OLE Property Set Data structures,
// (http://msdn.microsoft.com/en-au/library/dd942421.aspx) a generic persistence format
// for simple typed metadata

// Example:
//   file, _ := os.Open("test/test.doc")
//   defer file.Close()
//   doc, err := mscfb.NewReader(file)
//   if err != nil {
//    log.Fatal(err)
//   }
//   props := msoleps.New()
//   for entry, err := doc.Next(); err == nil; entry, err = doc.Next() {
//     if msoleps.IsMSOLEPS(entry.Initial) {
//       if oerr := props.Reset(doc); oerr != nil {
//         log.Fatal(oerr)
//       }
//       for prop := range props.Property {
//         fmt.Printf("Name: %s; Type: %s; Value: %v", prop.Name, prop.Type(), prop)
//       }
//     }
//   }
package msoleps

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"

	"github.com/richardlehane/msoleps/types"
)

var (
	ErrFormat = errors.New("msoleps: not a valid msoleps stream")
	ErrRead   = errors.New("msoleps: error reading msoleps stream")
	ErrSeek   = errors.New("msoleps: can't seek backwards")
)

// IsMSOLEPS checks the first uint16 character of an mscfb name to test if it is a MSOLEPS stream
func IsMSOLEPS(i uint16) bool {
	if i == 0x0005 {
		return true
	}
	return false
}

// Reader is a reader for MS OLE Property Set Data structures
type Reader struct {
	Property []*Property
	b        *bytes.Buffer
	buf      []byte
	*propertySetStream
	pSets [2]*propertySet
}

func New() *Reader {
	r := &Reader{}
	r.b = &bytes.Buffer{}
	return r
}

func (r *Reader) Reset(rdr io.Reader) error {
	r.b.Reset()
	return r.start(rdr)
}

func NewFrom(rdr io.Reader) (*Reader, error) {
	r := &Reader{}
	r.b = &bytes.Buffer{}
	return r, r.start(rdr)
}

func (r *Reader) start(rdr io.Reader) error {
	if _, err := r.b.ReadFrom(rdr); err != nil {
		return ErrRead
	}
	r.buf = r.b.Bytes()
	// read the header (property stream details)
	pss, err := makePropertySetStream(r.buf)
	if err != nil {
		return err
	}
	// sanity checks to find obvious errors
	switch {
	case pss.byteOrder != 0xFFFE, pss.version > 0x0001, pss.numPropertySets > 0x00000002:
		return ErrFormat
	}
	r.propertySetStream = pss
	// identify the property identifiers and offsets
	ps, err := r.getPropertySet(pss.offsetA)
	if err != nil {
		return err
	}
	plen := len(ps.idsOffs)
	r.pSets[0] = ps
	var psb *propertySet
	if pss.numPropertySets == 2 {
		psb, err = r.getPropertySet(pss.offsetB)
		if err != nil {
			return err
		}
		r.pSets[1] = psb
		plen += len(psb.idsOffs)
	}
	r.Property = make([]*Property, plen)
	dict, ok := propertySets[pss.fmtidA]
	if !ok {
		dict = ps.dict
		if dict == nil {
			dict = make(map[uint32]string)
		}
	}
	for i, v := range ps.idsOffs {
		r.Property[i] = &Property{}
		r.Property[i].Name = dict[v.id]
		t, _ := types.Evaluate(r.buf[int(v.offset+pss.offsetA):])
		if t.Type() == "CodeString" {
			cs := t.(*types.CodeString)
			cs.SetId(ps.code)
			t = types.Type(cs)
		}
		r.Property[i].T = t
	}
	if pss.numPropertySets != 2 {
		return nil
	}
	dict, ok = propertySets[pss.fmtidB]
	if !ok {
		dict = psb.dict
		if dict == nil {
			dict = make(map[uint32]string)
		}
	}
	for i, v := range psb.idsOffs {
		i += len(ps.idsOffs)
		r.Property[i] = &Property{}
		r.Property[i].Name = dict[v.id]
		t, _ := types.Evaluate(r.buf[int(v.offset+pss.offsetB):])
		if t.Type() == "CodeString" {
			cs := t.(*types.CodeString)
			cs.SetId(psb.code)
			t = types.Type(cs)
		}
		r.Property[i].T = t
	}
	return nil
}

func (r *Reader) getPropertySet(o uint32) (*propertySet, error) {
	pSet := &propertySet{}
	pSet.size = binary.LittleEndian.Uint32(r.buf[int(o) : int(o)+4])
	pSet.numProperties = binary.LittleEndian.Uint32(r.buf[int(o)+4 : int(o)+8])
	pSet.idsOffs = make([]propertyIDandOffset, int(pSet.numProperties))
	var dictOff uint32
	for i := range pSet.idsOffs {
		this := i*8 + 8 + int(o)
		pSet.idsOffs[i].id = binary.LittleEndian.Uint32(r.buf[this : this+4])
		pSet.idsOffs[i].offset = binary.LittleEndian.Uint32(r.buf[this+4 : this+8])
		switch pSet.idsOffs[i].id {
		case 0x00000000:
			dictOff = pSet.idsOffs[i].offset
		case 0x00000001:
			off := int(pSet.idsOffs[i].offset + o)
			pSet.code = types.CodePageID(binary.LittleEndian.Uint16(r.buf[off+4 : off+6]))
		}
	}
	if dictOff > 0 {
		var err error
		pSet.dict, err = r.getDictionary(dictOff+o, pSet.code)
		if err != nil {
			return nil, err
		}
	}
	return pSet, nil
}

func (r *Reader) getDictionary(o uint32, code types.CodePageID) (map[uint32]string, error) {
	b := r.buf[int(o):]
	e := 4
	if len(b) < e {
		return nil, ErrFormat
	}
	num := int(binary.LittleEndian.Uint32(b[:e]))
	if num == 0 {
		return nil, nil
	}
	dict := make(map[uint32]string)
	for i := 0; i < num; i++ {
		if len(b[e:]) < 8 {
			return nil, ErrFormat
		}
		id, l := binary.LittleEndian.Uint32(b[e:e+4]), binary.LittleEndian.Uint32(b[e+4:e+8])
		var s types.Type
		var err error
		if code == 0x04B0 {
			var pad int
			if l%2 != 0 {
				pad = 2
			}
			s, err = types.MakeUnicode(b[e+4:])
			if err != nil {
				return nil, ErrFormat
			}
			e = e + 8 + pad + int(l)*2
		} else {
			s, err = types.MakeCodeString(b[e+4:])
			if err != nil {
				return nil, ErrFormat
			}
			cs := s.(*types.CodeString)
			cs.SetId((code))
			s = cs
			e = e + 8 + int(l)
		}
		dict[id] = s.String()
	}
	return dict, nil
}
<|endoftext|>


<commit_before>package vanity

import (
	stdlog "log"
	"net/http"
	"os"
)

func ExampleRedirect() {
	http.Handle("/", Redirect("git", "kkn.fi", "github.com/kare"))
}

func ExampleSetLogger() {
	// stdlog is Go Standard Library's log package
	errorLog := stdlog.New(os.Stderr, "vanity: ", stdlog.Ldate|stdlog.Ltime|stdlog.LUTC)
	SetLogger(errorLog)
}
<commit_msg>Fix Examples<commit_after>package vanity_test

import (
	"log"
	"net/http"
	"os"

	"kkn.fi/vanity"
)

func ExampleRedirect() {
	http.Handle("/", vanity.Redirect("git", "kkn.fi", "github.com/kare"))
	// Output:
}

func ExampleSetLogger() {
	errorLog := log.New(os.Stderr, "vanity: ", log.Ldate|log.Ltime|log.LUTC)
	vanity.SetLogger(errorLog)
	// Output:
}
<|endoftext|>


<commit_before>package netconfig_test

import (
	"fmt"
	"log"

	"v.io/core/veyron/lib/netconfig"
)

func ExampleNetConfigWatcher() {
	w, err := netconfig.NewNetConfigWatcher()
	if err != nil {
		log.Fatalf("oops: %s", err)
	}
	fmt.Println("Do something to your network. You should see one or more dings.")
	for {
		<-w.Channel()
		fmt.Println("ding")
	}
}
<commit_msg>TBR renaming v.io/core/veyron to v.io/x/ref<commit_after>package netconfig_test

import (
	"fmt"
	"log"

	"v.io/x/ref/lib/netconfig"
)

func ExampleNetConfigWatcher() {
	w, err := netconfig.NewNetConfigWatcher()
	if err != nil {
		log.Fatalf("oops: %s", err)
	}
	fmt.Println("Do something to your network. You should see one or more dings.")
	for {
		<-w.Channel()
		fmt.Println("ding")
	}
}
<|endoftext|>


<commit_before>package shredis_test

import (
	"fmt"

	"github.com/alicebob/shredis"
)

func main() {
	shr := shredis.New(map[string]string{
		"shard0": "127.0.0.1:6389",
		"shard1": "127.0.0.1:6390",
		"shard2": "127.0.0.1:6391",
		"shard3": "127.0.0.1:6392",
	})
	cs := []*shredis.Cmd{
		shredis.Build("Key", "GET", "Key"),
		shredis.Build("Key2", "GET", "Key2"),
	}
	shr.Exec(cs[0], cs[1])
	for _, c := range cs {
		res, err := c.Get()
		if err != nil {
			fmt.Printf("Command err: %s\n", err)
			continue
		}
		fmt.Printf("Result: %s\n", res)
	}
}
<commit_msg>more exampling<commit_after>package shredis_test

import (
	"fmt"

	"github.com/alicebob/shredis"
)

func main() {
	shr := shredis.New(map[string]string{
		"shard0": "127.0.0.1:6389",
		"shard1": "127.0.0.1:6390",
		"shard2": "127.0.0.1:6391",
		"shard3": "127.0.0.1:6392",
	})
	defer shr.Close()

	// Build the commands.
	cs := []*shredis.Cmd{
		shredis.Build("Key", "GET", "Key"),
		shredis.Build("Key2", "GET", "Key2"),
	}
	// Send to all redises. This blocks.
	shr.Exec(cs...)
	// Check the results.
	for _, c := range cs {
		res, err := c.Get()
		if err != nil {
			fmt.Printf("Command err: %s\n", err)
			continue
		}
		fmt.Printf("Result: %v\n", res)
	}

	// Or keep the commands around:
	set := shredis.BuildSet("Key2", "Value")
	get := shredis.BuildGet("Key2")
	shr.Exec(set, get)
	if _, err := set.Get(); err != nil {
		fmt.Printf("set error: %s", err)
	}

	v, err := get.Get()
	if err != nil {
		fmt.Printf("get error: %s", err)
	}
	fmt.Printf("got: %q", string(v.([]byte)))

	// Or use a Get* helper to deal with the interface{}:
	var vs string
	if vs, err = get.GetString(); err != nil {
		fmt.Printf("get error: %s", err)
	}
	fmt.Printf("got: %q", vs)

}
<|endoftext|>


<commit_before>package reflections_test

import (
	"fmt"
	"github.com/oleiade/reflections"
	"log"
)

type MyStruct struct {
	FirstField  string `matched:"first tag"`
	SecondField int    `matched:"second tag"`
	ThirdField  string `unmatched:"third tag"`
}

func ExampleGetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	fieldsToExtract := []string{"FirstField", "ThirdField"}

	for _, fieldName := range fieldsToExtract {
		value, err := reflections.GetField(s, fieldName)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(value)
	}
}

func ExampleGetFieldKind() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var firstFieldKind reflect.String
	var secondFieldKind reflect.Int
	var err error

	firstFieldKind, err = GetFieldKind(s, "FirstField")
	if err != nil {
		log.Fatal(err)
	}

	secondFieldKind, err = GetFieldKind(s, "SecondField")
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleHasField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// has == true
	has, _ := reflections.HasField(s, "FirstField")
	fmt.Println(has)

	// has == false
	has, _ = reflections.HasField(s, "FourthField")
	fmt.Println(has)
}

func ExampleFields() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var fields []string

	// Fields will list every structure exportable fields.
	// Here, it's content would be equal to:
	// []string{"FirstField", "SecondField", "ThirdField"}
	fields, _ = reflections.Fields(s)
	fmt.Println(fields)
}

func ExampleItems() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structItems map[string]interface{}

	// Items will return a field name to
	// field value map
	structItems, _ = reflections.Items(s)
	fmt.Println(structItems)
}

func ExampleTags() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structTags map[string]string

	// Tags will return a field name to tag content
	// map. Nota that only field with the tag name
	// you've provided which will be matched.
	// Here structTags will contain:
	// {
	//     "FirstField": "first tag",
	//     "SecondField": "second tag",
	// }
	structTags, _ = reflections.Tags(s, "matched")
	fmt.Println(structTags)
}

func ExampleSetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// In order to be able to set the structure's values,
	// a pointer to it has to be passed to it.
	err := reflections.SetField(&s, "FirstField", "new value")
	if err != nil {
		log.Fatal(err)
	}

	// If you try to set a field's value using the wrong type,
	// an error will be returned
	err = reflections.SetField(&s, "FirstField", 123) // err != nil
	if err != nil {
		log.Fatal(err)
	}
}
<commit_msg>Fix: examples<commit_after>package reflections_test

import (
	"fmt"
	"github.com/oleiade/reflections"
	"log"
	"reflect"
)

type MyStruct struct {
	FirstField  string `matched:"first tag"`
	SecondField int    `matched:"second tag"`
	ThirdField  string `unmatched:"third tag"`
}

func ExampleGetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	fieldsToExtract := []string{"FirstField", "ThirdField"}

	for _, fieldName := range fieldsToExtract {
		value, err := reflections.GetField(s, fieldName)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Println(value)
	}
}

func ExampleGetFieldKind() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var firstFieldKind reflect.Kind
	var secondFieldKind reflect.Kind
	var err error

	// GetFieldKind will return reflect.String
	firstFieldKind, err = reflections.GetFieldKind(s, "FirstField")
	if err != nil {
		log.Fatal(err)
	}

	// GetFieldKind will return reflect.Int
	secondFieldKind, err = reflections.GetFieldKind(s, "SecondField")
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleHasField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// has == true
	has, _ := reflections.HasField(s, "FirstField")
	fmt.Println(has)

	// has == false
	has, _ = reflections.HasField(s, "FourthField")
	fmt.Println(has)
}

func ExampleFields() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var fields []string

	// Fields will list every structure exportable fields.
	// Here, it's content would be equal to:
	// []string{"FirstField", "SecondField", "ThirdField"}
	fields, _ = reflections.Fields(s)
	fmt.Println(fields)
}

func ExampleItems() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structItems map[string]interface{}

	// Items will return a field name to
	// field value map
	structItems, _ = reflections.Items(s)
	fmt.Println(structItems)
}

func ExampleTags() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	var structTags map[string]string

	// Tags will return a field name to tag content
	// map. Nota that only field with the tag name
	// you've provided which will be matched.
	// Here structTags will contain:
	// {
	//     "FirstField": "first tag",
	//     "SecondField": "second tag",
	// }
	structTags, _ = reflections.Tags(s, "matched")
	fmt.Println(structTags)
}

func ExampleSetField() {
	s := MyStruct{
		FirstField:  "first value",
		SecondField: 2,
		ThirdField:  "third value",
	}

	// In order to be able to set the structure's values,
	// a pointer to it has to be passed to it.
	err := reflections.SetField(&s, "FirstField", "new value")
	if err != nil {
		log.Fatal(err)
	}

	// If you try to set a field's value using the wrong type,
	// an error will be returned
	err = reflections.SetField(&s, "FirstField", 123) // err != nil
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package circuit

import (
	"fmt"

	"github.com/peterbourgon/g2s"

	"io/ioutil"
	"log"
	"time"
)

func ExampleThresholdBreaker() {
	// This example sets up a ThresholdBreaker that will trip if remoteCall returns
	// an error 10 times in a row. The error returned by Call() will be the error
	// returned by remoteCall, unless the breaker has been tripped, in which case
	// it will return ErrBreakerOpen.
	breaker := NewThresholdBreaker(10)
	err := breaker.Call(remoteCall, 0)
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleThresholdBreaker_manual() {
	// This example demonstrates the manual use of a ThresholdBreaker. The breaker
	// will trip when Fail is called 10 times in a row.
	breaker := NewThresholdBreaker(10)
	if breaker.Ready() {
		err := remoteCall
		if err != nil {
			breaker.Fail()
			log.Fatal(err)
		} else {
			breaker.Success()
		}
	}
}

func ExampleTimeoutBreaker() {
	// This example sets up a TimeoutBreaker that will trip if remoteCall returns
	// an error OR takes longer than one second 10 times in a row. The error returned
	// by Call() will be the error returned by remoteCall with two exceptions: if
	// remoteCall takes longer than one second the return value will be ErrBreakerTimeout,
	// if the breaker has been tripped the return value will be ErrBreakerOpen.
	breaker := NewThresholdBreaker(10)
	err := breaker.Call(remoteCall, time.Second)
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleConsecutiveBreaker() {
	// This example sets up a FrequencyBreaker that will trip if remoteCall returns
	// an error 10 times in a row within a period of 2 minutes.
	breaker := NewConsecutiveBreaker(10)
	err := breaker.Call(remoteCall, 0)
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleHTTPClient() {
	// This example sets up an HTTP client wrapped in a TimeoutBreaker. The breaker
	// will trip with the same behavior as TimeoutBreaker.
	client := NewHTTPClient(time.Second*5, 10, nil)

	resp, err := client.Get("http://example.com/resource.json")
	if err != nil {
		log.Fatal(err)
	}
	resource, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", resource)
}

func ExampleBreaker_events() {
	// This example demonstrates the BreakerTripped and BreakerReset callbacks. These are
	// available on all breaker types.
	breaker := NewThresholdBreaker(1)
	events := breaker.Subscribe()

	go func() {
		for {
			e := <-events
			switch e {
			case BreakerTripped:
				log.Println("breaker tripped")
			case BreakerReset:
				log.Println("breaker reset")
			case BreakerFail:
				log.Println("breaker fail")
			case BreakerReady:
				log.Println("breaker ready")
			}
		}
	}()

	breaker.Fail()
	breaker.Reset()
}

func ExamplePanel() {
	// This example demonstrates using a Panel to aggregate and manage circuit breakers.
	breaker1 := NewThresholdBreaker(10)
	breaker2 := NewRateBreaker(0.95, 100)

	panel := NewPanel()
	panel.Add("breaker1", breaker1)
	panel.Add("breaker2", breaker2)

	// Elsewhere in the code ...
	b1, _ := panel.Get("breaker1")
	b1.Call(func() error {
		// Do some work
		return nil
	}, 0)

	b2, _ := panel.Get("breaker2")
	b2.Call(func() error {
		// Do some work
		return nil
	}, 0)
}

func ExamplePanel_stats() {
	// This example demonstrates how to push circuit breaker stats to statsd via a Panel.
	// This example uses g2s. Anything conforming to the Statter interface can be used.
	s, err := g2s.Dial("udp", "statsd-server:8125")
	if err != nil {
		log.Fatal(err)
	}

	breaker := NewThresholdBreaker(10)
	panel := NewPanel()
	panel.Statter = s
	panel.StatsPrefixf = "sys.production"
	panel.Add("x", breaker)

	breaker.Trip()  // sys.production.circuit.x.tripped
	breaker.Reset() // sys.production.circuit.x.reset, sys.production.circuit.x.trip-time
	breaker.Fail()  // sys.production.circuit.x.fail
	breaker.Ready() // sys.production.circuit.x.ready (if it's tripped and ready to retry)
}

func remoteCall() error {
	// Expensive remote call
	return nil
}
<commit_msg>Fix bug in statsd bucket name documentation<commit_after>package circuit

import (
	"fmt"

	"github.com/peterbourgon/g2s"

	"io/ioutil"
	"log"
	"time"
)

func ExampleThresholdBreaker() {
	// This example sets up a ThresholdBreaker that will trip if remoteCall returns
	// an error 10 times in a row. The error returned by Call() will be the error
	// returned by remoteCall, unless the breaker has been tripped, in which case
	// it will return ErrBreakerOpen.
	breaker := NewThresholdBreaker(10)
	err := breaker.Call(remoteCall, 0)
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleThresholdBreaker_manual() {
	// This example demonstrates the manual use of a ThresholdBreaker. The breaker
	// will trip when Fail is called 10 times in a row.
	breaker := NewThresholdBreaker(10)
	if breaker.Ready() {
		err := remoteCall
		if err != nil {
			breaker.Fail()
			log.Fatal(err)
		} else {
			breaker.Success()
		}
	}
}

func ExampleTimeoutBreaker() {
	// This example sets up a TimeoutBreaker that will trip if remoteCall returns
	// an error OR takes longer than one second 10 times in a row. The error returned
	// by Call() will be the error returned by remoteCall with two exceptions: if
	// remoteCall takes longer than one second the return value will be ErrBreakerTimeout,
	// if the breaker has been tripped the return value will be ErrBreakerOpen.
	breaker := NewThresholdBreaker(10)
	err := breaker.Call(remoteCall, time.Second)
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleConsecutiveBreaker() {
	// This example sets up a FrequencyBreaker that will trip if remoteCall returns
	// an error 10 times in a row within a period of 2 minutes.
	breaker := NewConsecutiveBreaker(10)
	err := breaker.Call(remoteCall, 0)
	if err != nil {
		log.Fatal(err)
	}
}

func ExampleHTTPClient() {
	// This example sets up an HTTP client wrapped in a TimeoutBreaker. The breaker
	// will trip with the same behavior as TimeoutBreaker.
	client := NewHTTPClient(time.Second*5, 10, nil)

	resp, err := client.Get("http://example.com/resource.json")
	if err != nil {
		log.Fatal(err)
	}
	resource, err := ioutil.ReadAll(resp.Body)
	resp.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("%s", resource)
}

func ExampleBreaker_events() {
	// This example demonstrates the BreakerTripped and BreakerReset callbacks. These are
	// available on all breaker types.
	breaker := NewThresholdBreaker(1)
	events := breaker.Subscribe()

	go func() {
		for {
			e := <-events
			switch e {
			case BreakerTripped:
				log.Println("breaker tripped")
			case BreakerReset:
				log.Println("breaker reset")
			case BreakerFail:
				log.Println("breaker fail")
			case BreakerReady:
				log.Println("breaker ready")
			}
		}
	}()

	breaker.Fail()
	breaker.Reset()
}

func ExamplePanel() {
	// This example demonstrates using a Panel to aggregate and manage circuit breakers.
	breaker1 := NewThresholdBreaker(10)
	breaker2 := NewRateBreaker(0.95, 100)

	panel := NewPanel()
	panel.Add("breaker1", breaker1)
	panel.Add("breaker2", breaker2)

	// Elsewhere in the code ...
	b1, _ := panel.Get("breaker1")
	b1.Call(func() error {
		// Do some work
		return nil
	}, 0)

	b2, _ := panel.Get("breaker2")
	b2.Call(func() error {
		// Do some work
		return nil
	}, 0)
}

func ExamplePanel_stats() {
	// This example demonstrates how to push circuit breaker stats to statsd via a Panel.
	// This example uses g2s. Anything conforming to the Statter interface can be used.
	s, err := g2s.Dial("udp", "statsd-server:8125")
	if err != nil {
		log.Fatal(err)
	}

	breaker := NewThresholdBreaker(10)
	panel := NewPanel()
	panel.Statter = s
	panel.StatsPrefixf = "sys.production.%s"
	panel.Add("x", breaker)

	breaker.Trip()  // sys.production.circuit.x.tripped
	breaker.Reset() // sys.production.circuit.x.reset, sys.production.circuit.x.trip-time
	breaker.Fail()  // sys.production.circuit.x.fail
	breaker.Ready() // sys.production.circuit.x.ready (if it's tripped and ready to retry)
}

func remoteCall() error {
	// Expensive remote call
	return nil
}
<|endoftext|>


<commit_before>package tcp

import (
	"github.com/davyxu/cellnet"
	"github.com/davyxu/cellnet/peer"
	"github.com/davyxu/cellnet/util"
	"net"
	"sync"
	"sync/atomic"
	"time"
)

// Socket会话
type tcpSession struct {
	peer.CoreContextSet
	peer.CoreSessionIdentify
	*peer.CoreProcBundle

	pInterface cellnet.Peer

	// Socket原始连接
	conn net.Conn

	// 退出同步器
	exitSync sync.WaitGroup

	// 发送队列
	sendQueue *cellnet.Pipe

	cleanupGuard sync.Mutex

	endNotify func()

	closing int64
}

func (self *tcpSession) Peer() cellnet.Peer {
	return self.pInterface
}

// 取原始连接
func (self *tcpSession) Raw() interface{} {
	return self.conn
}

func (self *tcpSession) Close() {

	closing := atomic.SwapInt64(&self.closing, 1)
	if closing == 1 {
		return
	}

	if self.conn != nil {
		// 关闭读
		con := self.conn.(*net.TCPConn)
		// 关闭读
		con.CloseRead()
		// 手动读超时
		con.SetReadDeadline(time.Now())
	}
}

// 发送封包
func (self *tcpSession) Send(msg interface{}) {

	// 只能通过Close关闭连接
	if msg == nil {
		return
	}

	// 已经关闭，不再发送
	if atomic.LoadInt64(&self.closing) == 1 {
		return
	}

	self.sendQueue.Add(msg)
}

// 接收循环
func (self *tcpSession) recvLoop() {

	for self.conn != nil {

		msg, err := self.ReadMessage(self)

		if err != nil {
			if !util.IsEOFOrNetReadError(err) {
				log.Errorf("session closed, sesid: %d, err: %s", self.ID(), err)
			}

			self.sendQueue.Add(nil)

			manualClosed := atomic.LoadInt64(&self.closing)

			// 标记为手动关闭原因
			closedMsg := &cellnet.SessionClosed{}
			if manualClosed != 0 {
				closedMsg.Reason = cellnet.CloseReason_Manual
			}

			self.PostEvent(&cellnet.RecvMsgEvent{self, closedMsg})
			break
		}

		self.PostEvent(&cellnet.RecvMsgEvent{self, msg})
	}

	// 通知完成
	self.exitSync.Done()
}

// 发送循环
func (self *tcpSession) sendLoop() {

	var writeList []interface{}

	for {
		writeList = writeList[0:0]
		exit := self.sendQueue.Pick(&writeList)

		// 遍历要发送的数据
		for _, msg := range writeList {

			self.SendMessage(&cellnet.SendMsgEvent{self, msg})
		}

		if exit {
			break
		}
	}

	// 完整关闭
	self.conn.Close()

	// 通知完成
	self.exitSync.Done()
}

// 启动会话的各种资源
func (self *tcpSession) Start() {

	atomic.StoreInt64(&self.closing, 0)

	// connector复用session时，上一次发送队列未释放可能造成问题
	self.sendQueue.Reset()

	// 需要接收和发送线程同时完成时才算真正的完成
	self.exitSync.Add(2)

	go func() {

		// 等待2个任务结束
		self.exitSync.Wait()

		// 将会话从管理器移除
		self.Peer().(peer.SessionManager).Remove(self)

		if self.endNotify != nil {
			self.endNotify()
		}

	}()

	// 启动并发接收goroutine
	go self.recvLoop()

	// 启动并发发送goroutine
	go self.sendLoop()

	// 将会话添加到管理器
	self.Peer().(peer.SessionManager).Add(self)
}

func newSession(conn net.Conn, p cellnet.Peer, endNotify func()) *tcpSession {
	self := &tcpSession{
		conn:       conn,
		endNotify:  endNotify,
		sendQueue:  cellnet.NewPipe(),
		pInterface: p,
		CoreProcBundle: p.(interface {
			GetBundle() *peer.CoreProcBundle
		}).GetBundle(),
	}

	return self
}
<commit_msg>mod 精简代码<commit_after>package tcp

import (
	"github.com/davyxu/cellnet"
	"github.com/davyxu/cellnet/peer"
	"github.com/davyxu/cellnet/util"
	"net"
	"sync"
	"sync/atomic"
	"time"
)

// Socket会话
type tcpSession struct {
	peer.CoreContextSet
	peer.CoreSessionIdentify
	*peer.CoreProcBundle

	pInterface cellnet.Peer

	// Socket原始连接
	conn net.Conn

	// 退出同步器
	exitSync sync.WaitGroup

	// 发送队列
	sendQueue *cellnet.Pipe

	cleanupGuard sync.Mutex

	endNotify func()

	closing int64
}

func (self *tcpSession) Peer() cellnet.Peer {
	return self.pInterface
}

// 取原始连接
func (self *tcpSession) Raw() interface{} {
	return self.conn
}

func (self *tcpSession) Close() {

	closing := atomic.SwapInt64(&self.closing, 1)
	if closing != 0 {
		return
	}

	if self.conn != nil {
		// 关闭读
		con := self.conn.(*net.TCPConn)
		// 关闭读
		con.CloseRead()
		// 手动读超时
		con.SetReadDeadline(time.Now())
	}
}

// 发送封包
func (self *tcpSession) Send(msg interface{}) {

	// 只能通过Close关闭连接
	if msg == nil {
		return
	}

	// 已经关闭，不再发送
	if self.IsManualClosed() {
		return
	}

	self.sendQueue.Add(msg)
}

func (self *tcpSession) IsManualClosed() bool {
	return atomic.LoadInt64(&self.closing) != 0
}

// 接收循环
func (self *tcpSession) recvLoop() {

	for self.conn != nil {

		msg, err := self.ReadMessage(self)

		if err != nil {
			if !util.IsEOFOrNetReadError(err) {
				log.Errorf("session closed, sesid: %d, err: %s", self.ID(), err)
			}

			self.sendQueue.Add(nil)

			// 标记为手动关闭原因
			closedMsg := &cellnet.SessionClosed{}
			if self.IsManualClosed() {
				closedMsg.Reason = cellnet.CloseReason_Manual
			}

			self.PostEvent(&cellnet.RecvMsgEvent{self, closedMsg})
			break
		}

		self.PostEvent(&cellnet.RecvMsgEvent{self, msg})
	}

	// 通知完成
	self.exitSync.Done()
}

// 发送循环
func (self *tcpSession) sendLoop() {

	var writeList []interface{}

	for {
		writeList = writeList[0:0]
		exit := self.sendQueue.Pick(&writeList)

		// 遍历要发送的数据
		for _, msg := range writeList {

			self.SendMessage(&cellnet.SendMsgEvent{self, msg})
		}

		if exit {
			break
		}
	}

	// 完整关闭
	self.conn.Close()

	// 通知完成
	self.exitSync.Done()
}

// 启动会话的各种资源
func (self *tcpSession) Start() {

	atomic.StoreInt64(&self.closing, 0)

	// connector复用session时，上一次发送队列未释放可能造成问题
	self.sendQueue.Reset()

	// 需要接收和发送线程同时完成时才算真正的完成
	self.exitSync.Add(2)

	go func() {

		// 等待2个任务结束
		self.exitSync.Wait()

		// 将会话从管理器移除
		self.Peer().(peer.SessionManager).Remove(self)

		if self.endNotify != nil {
			self.endNotify()
		}

	}()

	// 启动并发接收goroutine
	go self.recvLoop()

	// 启动并发发送goroutine
	go self.sendLoop()

	// 将会话添加到管理器
	self.Peer().(peer.SessionManager).Add(self)
}

func newSession(conn net.Conn, p cellnet.Peer, endNotify func()) *tcpSession {
	self := &tcpSession{
		conn:       conn,
		endNotify:  endNotify,
		sendQueue:  cellnet.NewPipe(),
		pInterface: p,
		CoreProcBundle: p.(interface {
			GetBundle() *peer.CoreProcBundle
		}).GetBundle(),
	}

	return self
}
<|endoftext|>


<commit_before>package vm

import (
	"fmt"

	"github.com/goby-lang/goby/vm/classes"
	"github.com/goby-lang/goby/vm/errors"
	"github.com/st0012/metago"
)

// GoObject ...
type GoObject struct {
	*BaseObj
	data interface{}
}

// Class methods --------------------------------------------------------
var builtinGoObjectClassMethods = []*BuiltinMethodObject{}

// Instance methods -----------------------------------------------------
var builtinGoObjectInstanceMethods = []*BuiltinMethodObject{
	{
		// An experimental method for loading plugins (written in Golang) dynamically.
		// Needs improvements.
		//
		/// ```ruby
		/// require "plugin"
		//
		//	p = Plugin.use "../test_fixtures/import_test/plugin/plugin.go"
		//	p.go_func("Foo", "!")
		//	p.go_func("Baz")
		// ```
		//
		// @param name [String]
		// @return [Object]
		Name: "go_func",
		Fn: func(receiver Object, sourceLine int, t *Thread, args []Object, blockFrame *normalCallFrame) Object {
			s, ok := args[0].(*StringObject)

			if !ok {
				return t.vm.InitErrorObject(errors.TypeError, sourceLine, errors.WrongArgumentTypeFormat, classes.StringClass, args[0].Class().Name)
			}

			funcName := s.value
			r := receiver.(*GoObject)

			funcArgs, err := ConvertToGoFuncArgs(args[1:])

			if err != nil {
				t.vm.InitErrorObject(errors.TypeError, sourceLine, err.Error())
			}

			result := metago.CallFunc(r.data, funcName, funcArgs...)
			return t.vm.InitObjectFromGoType(result)

		},
	},
}

// Internal functions ===================================================

// Functions for initialization -----------------------------------------

func (vm *VM) initGoObject(d interface{}) *GoObject {
	return &GoObject{data: d, BaseObj: NewBaseObject(vm.TopLevelClass(classes.GoObjectClass))}
}

func (vm *VM) initGoClass() *RClass {
	sc := vm.initializeClass(classes.GoObjectClass)
	sc.setBuiltinMethods(builtinGoObjectClassMethods, true)
	sc.setBuiltinMethods(builtinGoObjectInstanceMethods, false)
	vm.objectClass.setClassConstant(sc)
	return sc
}

// Polymorphic helper functions -----------------------------------------

// Value returns the object
func (s *GoObject) Value() interface{} {
	return s.data
}

// ToString returns the object's name as the string format
func (s *GoObject) ToString() string {
	return fmt.Sprintf("<GoObject: %p>", s)
}

// Inspect delegates to ToString
func (s *GoObject) Inspect() string {
	return s.ToString()
}

// ToJSON just delegates to ToString
func (s *GoObject) ToJSON(t *Thread) string {
	return s.ToString()
}

// Other helper functions -----------------------------------------------

func ConvertToGoFuncArgs(args []Object) ([]interface{}, error) {
	funcArgs := []interface{}{}

	for _, arg := range args {
		switch v := arg.(type) {
		case *IntegerObject:
			switch v.flag {
			case f64:
				funcArgs = append(funcArgs, float64(v.value))
				continue
			case f32:
				funcArgs = append(funcArgs, float32(v.value))
				continue
			case ui64:
				funcArgs = append(funcArgs, uint64(v.value))
				continue
			case ui32:
				funcArgs = append(funcArgs, uint32(v.value))
				continue
			case ui16:
				funcArgs = append(funcArgs, uint16(v.value))
				continue
			case ui8:
				funcArgs = append(funcArgs, uint8(v.value))
				continue
			case i64:
				funcArgs = append(funcArgs, int64(v.value))
				continue
			case i32:
				funcArgs = append(funcArgs, int32(v.value))
				continue
			case i16:
				funcArgs = append(funcArgs, int16(v.value))
				continue
			case i8:
				funcArgs = append(funcArgs, int8(v.value))
				continue
			}
		}

		funcArgs = append(funcArgs, arg.Value())
	}

	return funcArgs, nil
}
<commit_msg>Add comments to comply with golint<commit_after>package vm

import (
	"fmt"

	"github.com/goby-lang/goby/vm/classes"
	"github.com/goby-lang/goby/vm/errors"
	"github.com/st0012/metago"
)

// GoObject ...
type GoObject struct {
	*BaseObj
	data interface{}
}

// Class methods --------------------------------------------------------
var builtinGoObjectClassMethods = []*BuiltinMethodObject{}

// Instance methods -----------------------------------------------------
var builtinGoObjectInstanceMethods = []*BuiltinMethodObject{
	{
		// An experimental method for loading plugins (written in Golang) dynamically.
		// Needs improvements.
		//
		/// ```ruby
		/// require "plugin"
		//
		//	p = Plugin.use "../test_fixtures/import_test/plugin/plugin.go"
		//	p.go_func("Foo", "!")
		//	p.go_func("Baz")
		// ```
		//
		// @param name [String]
		// @return [Object]
		Name: "go_func",
		Fn: func(receiver Object, sourceLine int, t *Thread, args []Object, blockFrame *normalCallFrame) Object {
			s, ok := args[0].(*StringObject)

			if !ok {
				return t.vm.InitErrorObject(errors.TypeError, sourceLine, errors.WrongArgumentTypeFormat, classes.StringClass, args[0].Class().Name)
			}

			funcName := s.value
			r := receiver.(*GoObject)

			funcArgs, err := ConvertToGoFuncArgs(args[1:])

			if err != nil {
				t.vm.InitErrorObject(errors.TypeError, sourceLine, err.Error())
			}

			result := metago.CallFunc(r.data, funcName, funcArgs...)
			return t.vm.InitObjectFromGoType(result)

		},
	},
}

// Internal functions ===================================================

// Functions for initialization -----------------------------------------

func (vm *VM) initGoObject(d interface{}) *GoObject {
	return &GoObject{data: d, BaseObj: NewBaseObject(vm.TopLevelClass(classes.GoObjectClass))}
}

func (vm *VM) initGoClass() *RClass {
	sc := vm.initializeClass(classes.GoObjectClass)
	sc.setBuiltinMethods(builtinGoObjectClassMethods, true)
	sc.setBuiltinMethods(builtinGoObjectInstanceMethods, false)
	vm.objectClass.setClassConstant(sc)
	return sc
}

// Polymorphic helper functions -----------------------------------------

// Value returns the object
func (s *GoObject) Value() interface{} {
	return s.data
}

// ToString returns the object's name as the string format
func (s *GoObject) ToString() string {
	return fmt.Sprintf("<GoObject: %p>", s)
}

// Inspect delegates to ToString
func (s *GoObject) Inspect() string {
	return s.ToString()
}

// ToJSON just delegates to ToString
func (s *GoObject) ToJSON(t *Thread) string {
	return s.ToString()
}

// Other helper functions -----------------------------------------------

// ConvertToGoFuncArgs converts Goby's args to Go func's args
func ConvertToGoFuncArgs(args []Object) ([]interface{}, error) {
	funcArgs := []interface{}{}

	for _, arg := range args {
		switch v := arg.(type) {
		case *IntegerObject:
			switch v.flag {
			case f64:
				funcArgs = append(funcArgs, float64(v.value))
				continue
			case f32:
				funcArgs = append(funcArgs, float32(v.value))
				continue
			case ui64:
				funcArgs = append(funcArgs, uint64(v.value))
				continue
			case ui32:
				funcArgs = append(funcArgs, uint32(v.value))
				continue
			case ui16:
				funcArgs = append(funcArgs, uint16(v.value))
				continue
			case ui8:
				funcArgs = append(funcArgs, uint8(v.value))
				continue
			case i64:
				funcArgs = append(funcArgs, int64(v.value))
				continue
			case i32:
				funcArgs = append(funcArgs, int32(v.value))
				continue
			case i16:
				funcArgs = append(funcArgs, int16(v.value))
				continue
			case i8:
				funcArgs = append(funcArgs, int8(v.value))
				continue
			}
		}

		funcArgs = append(funcArgs, arg.Value())
	}

	return funcArgs, nil
}
<|endoftext|>


<commit_before>package main

import (
	"dns"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func q(w dns.RequestWriter, m *dns.Msg) {
	w.Send(m)
	r, err := w.Receive()
	if err != nil {
		fmt.Printf("%s\n", err.Error())
	}
	w.Write(r)
}

func main() {
	dnssec := flag.Bool("dnssec", false, "request DNSSEC records")
	query := flag.Bool("question", false, "show question")
	short := flag.Bool("short", false, "abbreviate long DNSKEY and RRSIG RRs")
	check := flag.Bool("check", false, "check internal DNSSEC consistency")
	port := flag.Int("port", 53, "port number to use")
	aa := flag.Bool("aa", false, "set AA flag in query")
	ad := flag.Bool("ad", false, "set AD flag in query")
	cd := flag.Bool("cd", false, "set CD flag in query")
	rd := flag.Bool("rd", true, "unset RD flag in query")
	tcp := flag.Bool("tcp", false, "TCP mode")
	nsid := flag.Bool("nsid", false, "ask for NSID")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		if k, ok := dns.Str_rr[strings.ToUpper(flag.Arg(i))]; ok {
			qtype = k
			continue Flags
		}
		// If it looks like a class, it is a class
		if k, ok := dns.Str_class[strings.ToUpper(flag.Arg(i))]; ok {
			qclass = k
			continue Flags
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)

	// ipv6 todo
	// We use the async query handling, just to show how
	// it is to be used.
	dns.HandleQueryFunc(".", q)
	dns.ListenAndQuery(nil, nil)
	c := dns.NewClient()
	if *tcp {
		c.Net = "tcp"
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec || *nsid {
		o := new(dns.RR_OPT)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		if *dnssec {
			o.SetDo()
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *nsid {
			o.SetNsid("")
		}
		m.Extra = append(m.Extra, o)
	}

	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s\n", m.String())
		}
		c.Do(m, nameserver)
	}

	i := 0
forever:
	for {
		select {
		case r := <-dns.DefaultReplyChan:
			if r.Reply != nil {
				if r.Reply.Rcode == dns.RcodeSuccess {
					if r.Request.Id != r.Reply.Id {
						fmt.Printf("Id mismatch\n")
					}
				}
				if *check {
					sigCheck(r.Reply, nameserver, *tcp)
					nsecCheck(r.Reply)
				}
				if *short {
					r.Reply = shortMsg(r.Reply)
				}

				fmt.Printf("%v", r.Reply)
			}
			i++
			if i == len(qname) {
				break forever
			}
		}
	}
}

func sectionCheck(set []dns.RR, server string, tcp bool) {
	for _, rr := range set {
		if rr.Header().Rrtype == dns.TypeRRSIG {
			rrset := getRRset(set, rr.Header().Name, rr.(*dns.RR_RRSIG).TypeCovered)
			key := getKey(rr.(*dns.RR_RRSIG).SignerName, rr.(*dns.RR_RRSIG).KeyTag, server, tcp)
			if key == nil {
				fmt.Printf(";? DNSKEY %s/%d not found\n", rr.(*dns.RR_RRSIG).SignerName, rr.(*dns.RR_RRSIG).KeyTag)
                                continue
			}
			if err := rr.(*dns.RR_RRSIG).Verify(key, rrset); err != nil {
				fmt.Printf(";- Bogus signature,  %s does not validate (DNSKEY %s/%d)\n", shortSig(rr.(*dns.RR_RRSIG)), key.Header().Name, key.KeyTag())
			} else {
				fmt.Printf(";+ Secure signature, %s validates (DNSKEY %s/%d)\n", shortSig(rr.(*dns.RR_RRSIG)), key.Header().Name, key.KeyTag())
			}
		}
	}
}

// Check if we have nsec3 records and if so, check them
func nsecCheck(in *dns.Msg) {
        for _, r := range in.Answer {
                if r.Header().Rrtype == dns.TypeNSEC3 {
                        goto Check
                }
        }
        for _, r := range in.Ns {
                if r.Header().Rrtype == dns.TypeNSEC3 {
                        goto Check
                }
        }
        for _, r := range in.Extra {
                if r.Header().Rrtype == dns.TypeNSEC3 {
                        goto Check
                }
        }
        return
Check:
        w, err := in.Nsec3Verify(in.Question[0])
        switch w {
        case dns.NSEC3_NXDOMAIN:
                fmt.Printf(";+ Correct denial of existence (NSEC3/NXDOMAIN)\n")
        case dns.NSEC3_NODATA:
                fmt.Printf(";+ Correct denial of existence (NSEC3/NODATA)\n")
        default:
                // w == 0
                if err != nil {
	                fmt.Printf(";- Incorrect denial of existence (NSEC3): %s\n",err.Error())
                }
        }
}

// Check the sigs in the msg, get the signer's key (additional query), get the
// rrset from the message, check the signature(s)
func sigCheck(in *dns.Msg, server string, tcp bool) {
        sectionCheck(in.Answer, server, tcp)
        sectionCheck(in.Ns, server, tcp)
        sectionCheck(in.Extra, server, tcp)
}

// Return the RRset belonging to the signature with name and type t
func getRRset(l []dns.RR, name string, t uint16) []dns.RR {
	l1 := make([]dns.RR, 0)
	for _, rr := range l {
		if rr.Header().Name == name && rr.Header().Rrtype == t {
			l1 = append(l1, rr)
		}
	}
	return l1
}

// Get the key from the DNS (uses the local resolver) and return them.
// If nothing is found we return nil
func getKey(name string, keytag uint16, server string, tcp bool) *dns.RR_DNSKEY {
	c := dns.NewClient()
        if tcp {
                c.Net = "tcp"
        }
	m := new(dns.Msg)
	m.SetQuestion(name, dns.TypeDNSKEY)
	r, err := c.Exchange(m, server)
	if err != nil {
		return nil
	}
	for _, k := range r.Answer {
		if k1, ok := k.(*dns.RR_DNSKEY); ok {
			if k1.KeyTag() == keytag {
				return k1
			}
		}
	}
	return nil
}

// shorten RRSIG to "miek.nl RRSIG(NS)"
func shortSig(sig *dns.RR_RRSIG) string {
	return sig.Header().Name + " RRSIG(" + dns.Rr_str[sig.TypeCovered] + ")"
}

// Walk trough message and short Key data and Sig data
func shortMsg(in *dns.Msg) *dns.Msg {
	for i := 0; i < len(in.Answer); i++ {
		in.Answer[i] = shortRR(in.Answer[i])
	}
	for i := 0; i < len(in.Ns); i++ {
		in.Ns[i] = shortRR(in.Ns[i])
	}
	for i := 0; i < len(in.Extra); i++ {
		in.Extra[i] = shortRR(in.Extra[i])
	}
	return in
}

func shortRR(r dns.RR) dns.RR {
	switch t := r.(type) {
	case *dns.RR_DS:
		t.Digest = "..."
	case *dns.RR_DNSKEY:
		t.PublicKey = "..."
	case *dns.RR_RRSIG:
		t.Signature = "..."
	case *dns.RR_NSEC3:
		t.Salt = "-" // Nobody cares
		if len(t.TypeBitMap) > 5 {
			t.TypeBitMap = t.TypeBitMap[1:5]
		}
	}
	return r
}
<commit_msg>make the  help nicer<commit_after>package main

import (
	"dns"
	"flag"
	"fmt"
	"os"
	"strconv"
	"strings"
)

func q(w dns.RequestWriter, m *dns.Msg) {
	w.Send(m)
	r, err := w.Receive()
	if err != nil {
		fmt.Printf("%s\n", err.Error())
	}
	w.Write(r)
}

func main() {
	dnssec := flag.Bool("dnssec", false, "request DNSSEC records")
	query := flag.Bool("question", false, "show question")
	short := flag.Bool("short", false, "abbreviate long DNSSEC records")
	check := flag.Bool("check", false, "check internal DNSSEC consistency")
	port := flag.Int("port", 53, "port number to use")
	aa := flag.Bool("aa", false, "set AA flag in query")
	ad := flag.Bool("ad", false, "set AD flag in query")
	cd := flag.Bool("cd", false, "set CD flag in query")
	rd := flag.Bool("rd", true, "unset RD flag in query")
	tcp := flag.Bool("tcp", false, "TCP mode")
	nsid := flag.Bool("nsid", false, "ask for NSID")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: %s [@server] [qtype] [qclass] [name ...]\n", os.Args[0])
		flag.PrintDefaults()
	}

	conf, _ := dns.ClientConfigFromFile("/etc/resolv.conf")
	nameserver := "@" + conf.Servers[0]
	qtype := uint16(0)
	qclass := uint16(dns.ClassINET) // Default qclass
	var qname []string

	flag.Parse()

Flags:
	for i := 0; i < flag.NArg(); i++ {
		// If it starts with @ it is a nameserver
		if flag.Arg(i)[0] == '@' {
			nameserver = flag.Arg(i)
			continue Flags
		}
		// First class, then type, to make ANY queries possible
		// And if it looks like type, it is a type
		if k, ok := dns.Str_rr[strings.ToUpper(flag.Arg(i))]; ok {
			qtype = k
			continue Flags
		}
		// If it looks like a class, it is a class
		if k, ok := dns.Str_class[strings.ToUpper(flag.Arg(i))]; ok {
			qclass = k
			continue Flags
		}
		// If it starts with TYPExxx it is unknown rr
		if strings.HasPrefix(flag.Arg(i), "TYPE") {
			i, e := strconv.Atoi(string([]byte(flag.Arg(i))[4:]))
			if e == nil {
				qtype = uint16(i)
				continue Flags
			}
		}

		// Anything else is a qname
		qname = append(qname, flag.Arg(i))
	}
	if len(qname) == 0 {
		qname = make([]string, 1)
		qname[0] = "."
		qtype = dns.TypeNS
	}
	if qtype == 0 {
		qtype = dns.TypeA
	}

	nameserver = string([]byte(nameserver)[1:]) // chop off @
	nameserver += ":" + strconv.Itoa(*port)

	// ipv6 todo
	// We use the async query handling, just to show how
	// it is to be used.
	dns.HandleQueryFunc(".", q)
	dns.ListenAndQuery(nil, nil)
	c := dns.NewClient()
	if *tcp {
		c.Net = "tcp"
	}

	m := new(dns.Msg)
	m.MsgHdr.Authoritative = *aa
	m.MsgHdr.AuthenticatedData = *ad
	m.MsgHdr.CheckingDisabled = *cd
	m.MsgHdr.RecursionDesired = *rd
	m.Question = make([]dns.Question, 1)
	if *dnssec || *nsid {
		o := new(dns.RR_OPT)
		o.Hdr.Name = "."
		o.Hdr.Rrtype = dns.TypeOPT
		if *dnssec {
			o.SetDo()
			o.SetUDPSize(dns.DefaultMsgSize)
		}
		if *nsid {
			o.SetNsid("")
		}
		m.Extra = append(m.Extra, o)
	}

	for _, v := range qname {
		m.Question[0] = dns.Question{v, qtype, qclass}
		m.Id = dns.Id()
		if *query {
			fmt.Printf("%s\n", m.String())
		}
		c.Do(m, nameserver)
	}

	i := 0
forever:
	for {
		select {
		case r := <-dns.DefaultReplyChan:
			if r.Reply != nil {
				if r.Reply.Rcode == dns.RcodeSuccess {
					if r.Request.Id != r.Reply.Id {
						fmt.Printf("Id mismatch\n")
					}
				}
				if *check {
					sigCheck(r.Reply, nameserver, *tcp)
					nsecCheck(r.Reply)
				}
				if *short {
					r.Reply = shortMsg(r.Reply)
				}

				fmt.Printf("%v", r.Reply)
			}
			i++
			if i == len(qname) {
				break forever
			}
		}
	}
}

func sectionCheck(set []dns.RR, server string, tcp bool) {
	for _, rr := range set {
		if rr.Header().Rrtype == dns.TypeRRSIG {
			rrset := getRRset(set, rr.Header().Name, rr.(*dns.RR_RRSIG).TypeCovered)
			key := getKey(rr.(*dns.RR_RRSIG).SignerName, rr.(*dns.RR_RRSIG).KeyTag, server, tcp)
			if key == nil {
				fmt.Printf(";? DNSKEY %s/%d not found\n", rr.(*dns.RR_RRSIG).SignerName, rr.(*dns.RR_RRSIG).KeyTag)
                                continue
			}
			if err := rr.(*dns.RR_RRSIG).Verify(key, rrset); err != nil {
				fmt.Printf(";- Bogus signature,  %s does not validate (DNSKEY %s/%d)\n", shortSig(rr.(*dns.RR_RRSIG)), key.Header().Name, key.KeyTag())
			} else {
				fmt.Printf(";+ Secure signature, %s validates (DNSKEY %s/%d)\n", shortSig(rr.(*dns.RR_RRSIG)), key.Header().Name, key.KeyTag())
			}
		}
	}
}

// Check if we have nsec3 records and if so, check them
func nsecCheck(in *dns.Msg) {
        for _, r := range in.Answer {
                if r.Header().Rrtype == dns.TypeNSEC3 {
                        goto Check
                }
        }
        for _, r := range in.Ns {
                if r.Header().Rrtype == dns.TypeNSEC3 {
                        goto Check
                }
        }
        for _, r := range in.Extra {
                if r.Header().Rrtype == dns.TypeNSEC3 {
                        goto Check
                }
        }
        return
Check:
        w, err := in.Nsec3Verify(in.Question[0])
        switch w {
        case dns.NSEC3_NXDOMAIN:
                fmt.Printf(";+ Correct denial of existence (NSEC3/NXDOMAIN)\n")
        case dns.NSEC3_NODATA:
                fmt.Printf(";+ Correct denial of existence (NSEC3/NODATA)\n")
        default:
                // w == 0
                if err != nil {
	                fmt.Printf(";- Incorrect denial of existence (NSEC3): %s\n",err.Error())
                }
        }
}

// Check the sigs in the msg, get the signer's key (additional query), get the
// rrset from the message, check the signature(s)
func sigCheck(in *dns.Msg, server string, tcp bool) {
        sectionCheck(in.Answer, server, tcp)
        sectionCheck(in.Ns, server, tcp)
        sectionCheck(in.Extra, server, tcp)
}

// Return the RRset belonging to the signature with name and type t
func getRRset(l []dns.RR, name string, t uint16) []dns.RR {
	l1 := make([]dns.RR, 0)
	for _, rr := range l {
		if rr.Header().Name == name && rr.Header().Rrtype == t {
			l1 = append(l1, rr)
		}
	}
	return l1
}

// Get the key from the DNS (uses the local resolver) and return them.
// If nothing is found we return nil
func getKey(name string, keytag uint16, server string, tcp bool) *dns.RR_DNSKEY {
	c := dns.NewClient()
        if tcp {
                c.Net = "tcp"
        }
	m := new(dns.Msg)
	m.SetQuestion(name, dns.TypeDNSKEY)
	r, err := c.Exchange(m, server)
	if err != nil {
		return nil
	}
	for _, k := range r.Answer {
		if k1, ok := k.(*dns.RR_DNSKEY); ok {
			if k1.KeyTag() == keytag {
				return k1
			}
		}
	}
	return nil
}

// shorten RRSIG to "miek.nl RRSIG(NS)"
func shortSig(sig *dns.RR_RRSIG) string {
	return sig.Header().Name + " RRSIG(" + dns.Rr_str[sig.TypeCovered] + ")"
}

// Walk trough message and short Key data and Sig data
func shortMsg(in *dns.Msg) *dns.Msg {
	for i := 0; i < len(in.Answer); i++ {
		in.Answer[i] = shortRR(in.Answer[i])
	}
	for i := 0; i < len(in.Ns); i++ {
		in.Ns[i] = shortRR(in.Ns[i])
	}
	for i := 0; i < len(in.Extra); i++ {
		in.Extra[i] = shortRR(in.Extra[i])
	}
	return in
}

func shortRR(r dns.RR) dns.RR {
	switch t := r.(type) {
	case *dns.RR_DS:
		t.Digest = "..."
	case *dns.RR_DNSKEY:
		t.PublicKey = "..."
	case *dns.RR_RRSIG:
		t.Signature = "..."
	case *dns.RR_NSEC3:
		t.Salt = "-" // Nobody cares
		if len(t.TypeBitMap) > 5 {
			t.TypeBitMap = t.TypeBitMap[1:5]
		}
	}
	return r
}
<|endoftext|>


<commit_before>package irc

import (
	"crypto/tls"
	"fmt"
	"log"
	"regexp"

	"github.com/thoj/go-ircevent"

	"hg.mornie.org/perpetua/config"
	"hg.mornie.org/perpetua/db"
)

const version = "perpetua quote bot v0.1a"

var connection *irc.Connection
var options *config.Options
var store *db.Store

func connect() {
	connection = irc.IRC(options.IRC.Nickname, options.IRC.User)
	connection.Version = version
	connection.UseTLS = options.Server.UseTLS
	if options.Server.SkipVerify == true {
		connection.TLSConfig = &tls.Config{InsecureSkipVerify: true}
	}

	err := connection.Connect(fmt.Sprintf("%s:%d",
		options.Server.Hostname,
		options.Server.Port))

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

func handleEvents() {
	connection.AddCallback("001", doWelcome)
	connection.AddCallback("JOIN", doJoin)
	connection.AddCallback("PRIVMSG", doPrivmsg)
}

func doWelcome(event *irc.Event) {
	connection.Join(options.IRC.Channel)
	connection.Log.Println("Joined to " + options.IRC.Channel)
}

func doJoin(event *irc.Event) {

	if event.Nick == options.IRC.Nickname {
		connection.Privmsg(event.Arguments[0], "Hello! I'm "+version)
	} else {

		connection.Privmsg(event.Arguments[0],
			fmt.Sprintf("Hello %s! I'm %s. Do you want a quote?",
				event.Nick,
				version))
	}
}

func doPrivmsg(event *irc.Event) {
	channel := event.Arguments[0]

	// Don't speak in private!
	if channel == options.IRC.Nickname {
		return
	}
	command, person := parseMessage(event.Message())

	if command != "" && person != "" {
		connection.Privmsg(event.Arguments[0], store.GetQuote(person))
	}
}

func parseMessage(message string) (command, person string) {

	re := regexp.MustCompile(options.IRC.Nickname +
		`:?` +
		`\s*` +
		`(?P<command>cita|cosa dice|quote|what does it say)` +
		`\s*(?P<person>[\w\s-'\p{Latin}]+)`)

	res := re.FindStringSubmatch(message)

	names := re.SubexpNames()
	md := map[string]string{}
	for i, n := range res {
		md[names[i]] = n
	}

	return md["command"], md["person"]
}

func Client(opt *config.Options, db *db.Store) {
	options = opt
	store = db
	connect()
	handleEvents()
	connection.Loop()
}
<commit_msg>Handle a message with or without an argument<commit_after>package irc

import (
	"crypto/tls"
	"fmt"
	"log"
	"regexp"

	"github.com/thoj/go-ircevent"

	"hg.mornie.org/perpetua/config"
	"hg.mornie.org/perpetua/db"
)

const version = "perpetua quote bot v0.1a"

var connection *irc.Connection
var options *config.Options
var store *db.Store

func connect() {
	connection = irc.IRC(options.IRC.Nickname, options.IRC.User)
	connection.Version = version
	connection.UseTLS = options.Server.UseTLS
	if options.Server.SkipVerify == true {
		connection.TLSConfig = &tls.Config{InsecureSkipVerify: true}
	}

	err := connection.Connect(fmt.Sprintf("%s:%d",
		options.Server.Hostname,
		options.Server.Port))

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

func handleEvents() {
	connection.AddCallback("001", doWelcome)
	connection.AddCallback("JOIN", doJoin)
	connection.AddCallback("PRIVMSG", doPrivmsg)
}

func doWelcome(event *irc.Event) {
	connection.Join(options.IRC.Channel)
	connection.Log.Println("Joined to " + options.IRC.Channel)
}

func doJoin(event *irc.Event) {

	if event.Nick == options.IRC.Nickname {
		connection.Privmsg(event.Arguments[0], "Hello! I'm "+version)
	} else {

		connection.Privmsg(event.Arguments[0],
			fmt.Sprintf("Hello %s! I'm %s. Do you want a quote?",
				event.Nick,
				version))
	}
}

func doPrivmsg(event *irc.Event) {
	channel := event.Arguments[0]

	// Don't speak in private!
	if channel == options.IRC.Nickname {
		return
	}
	command, person, extra, argument := parseMessage(event.Message())

	if command != "" && person != "" {

		if extra != "" && argument != "" {
			fmt.Println("argument")
			connection.Privmsg(event.Arguments[0],
				store.GetQuoteAbout(person, argument))
			return
		}
		connection.Privmsg(event.Arguments[0], store.GetQuote(person))
	}
}

func parseMessage(message string) (command, person, extra, argument string) {
	var names []string

	reArgument := regexp.MustCompile(options.IRC.Nickname +
		`:?` +
		`\s+` +
		`(?P<command>cita|cosa dice|quote|what does it say)` +
		`\s+` +
		`(?P<person>[\w\s-'\p{Latin}]+)` +
		`(?:\s+)` +
		`(?P<extra>su|about)` +
		`(?:\s+)` +
		`(?P<argument>[\w\s-'\p{Latin}]+)`)

	re := regexp.MustCompile(options.IRC.Nickname +
		`:?` +
		`\s+` +
		`(?P<command>cita|cosa dice|quote|what does it say)` +
		`\s+` +
		`(?P<person>[\w\s-'\p{Latin}]+)`)

	res := reArgument.FindStringSubmatch(message)

	if res == nil {
		res = re.FindStringSubmatch(message)
		names = re.SubexpNames()
	} else {
		names = reArgument.SubexpNames()
	}

	md := map[string]string{}
	for i, n := range res {
		md[names[i]] = n
	}

	return md["command"], md["person"], md["extra"], md["argument"]
}

func Client(opt *config.Options, db *db.Store) {
	options = opt
	store = db
	connect()
	handleEvents()
	connection.Loop()
}
<|endoftext|>


<commit_before>// Package bitcoind is a package
package rpc

/*
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
import (
	"bytes"
	"github.com/gorilla/rpc/v2/json2"
	"net/http"
	"time"
)

type RPCClient struct {
	url      string
	username string
	password string
	client   *http.Client
}

func NewRPCClient(url, user string, password string) *RPCClient {
	return &RPCClient{
		url,
		user,
		password,
		&http.Client{Timeout: 10 * time.Second},
	}
}

func (r *RPCClient) Post(method, args interface{}) (*http.Response, error) {
	encoded, err := json2.EncodeClientRequest("getpeerinfo", args)

	if err != nil {
		return nil, err
	}

	request, err := http.NewRequest("POST", r.url, bytes.NewBuffer(encoded))

	if err != nil {
		return nil, err
	}

	request.SetBasicAuth(r.username, r.password)
	response, err := r.client.Do(request)

	if err != nil {
		return nil, err
	}

	return response, nil
}
<commit_msg>Ooops, RPC method name was hardcoded<commit_after>// Package rpc is a package
package rpc

/*
 * The MIT License (MIT)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
import (
	"bytes"
	"github.com/gorilla/rpc/v2/json2"
	"net/http"
	"time"
)

type RPCClient struct {
	url      string
	username string
	password string
	client   *http.Client
}

func NewRPCClient(url, user string, password string) *RPCClient {
	return &RPCClient{
		url,
		user,
		password,
		&http.Client{Timeout: 10 * time.Second},
	}
}

func (r *RPCClient) Post(method string, args interface{}) (*http.Response, error) {
	encoded, err := json2.EncodeClientRequest(method, args)

	if err != nil {
		return nil, err
	}

	request, err := http.NewRequest("POST", r.url, bytes.NewBuffer(encoded))

	if err != nil {
		return nil, err
	}

	request.SetBasicAuth(r.username, r.password)
	response, err := r.client.Do(request)

	if err != nil {
		return nil, err
	}

	return response, nil
}
<|endoftext|>


<commit_before>package queue

import (
	"reflect"
	"testing"
)

var John = Item{"john", "done some coding"}
var Jimmy = Item{"jimmy", "fix some bugs"}
var Mick = Item{"mick", "refactoring"}
var Colin = Item{"colin", "adding bugs"}

func TestCreateQueue(t *testing.T) {
	q := Queue{}
	if len(q) != 0 {
		t.Errorf("Expected empty queue, but has length %d", len(q))
	}

	defer func() {
		if recover() == nil {
			t.Errorf("Expected no active user but one was found")
		}
	}()
	q.Active()
}

func TestCreateQueueWithEntries(t *testing.T) {
	q := Queue{Mick, John}
	if len(q) != 2 {
		t.Errorf("Expected 2 entries in queue, but found %d", len(q))
	}
}

func TestAddImmutable(t *testing.T) {
	q := Queue{}
	q.Add(Mick)
	if len(q) != 0 {
		t.Errorf("Expected empty queue, but has length %d", len(q))
	}
}

func TestAdd(t *testing.T) {
	q := Queue{}
	q = q.Add(Mick)
	if len(q) != 1 {
		t.Errorf("Expected 1 entry in queue, but found %d", len(q))
	}

	active := q.Active()
	if active != Mick {
		t.Errorf("Expected active user to be 'mick' but was '%s'", active)
	}
}

func TestAddDuplicate(t *testing.T) {
	q := Queue{Mick}
	q = q.Add(Mick)
	if len(q) != 1 {
		t.Errorf("Expecte 1 entry in queue, but found %d", len(q))
	}
}

func TestAddWithDifferentReason(t *testing.T) {
	q := Queue{Mick}
	q = q.Add(Item{"mick", "wrote tests"})
	if len(q) != 2 {
		t.Errorf("Expecte 2 entry in queue, but found %d", len(q))
	}
}

func TestWaitingWhenEmpty(t *testing.T) {
	q := Queue{}
	w := q.Waiting()
	if len(w) > 0 {
		t.Errorf("Expected 0 waiting, but found %d", len(w))
	}
}

func TestWaitingWhenOnlyOne(t *testing.T) {
	q := Queue{Mick}
	w := q.Waiting()
	if len(w) > 0 {
		t.Errorf("Expected 0 waiting, but found %d", len(w))
	}
}

func TestWaitingWhenMoreThanOne(t *testing.T) {
	q := Queue{Mick, John, Jimmy}
	expected := []Item{John, Jimmy}
	if !reflect.DeepEqual(q.Waiting(), expected) {
		t.Errorf("Expected %v waiting, but found %v", expected, q.Waiting())
	}
}

func TestRemoveImmutable(t *testing.T) {
	q := Queue{Mick}
	q.Remove(Mick)
	if len(q) != 1 {
		t.Errorf("Expected 1 entry in queue, but found %d", len(q))
	}
}

func TestRemoveActive(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Remove(Mick)
	if len(q) != 1 {
		t.Errorf("Expected 1 entry in queue, but found %d", len(q))
	}

	if q.Active() != John {
		t.Errorf("Expected 'john' to be active but was '%s'", q.Active())
	}
}

func TestRemoveMiddle(t *testing.T) {
	q := Queue{Mick, Jimmy, John}
	q = q.Remove(Jimmy)
	if len(q) != 2 {
		t.Errorf("Expected 2 entry in queue, but found %d", len(q))
	}
	if q.Contains(Jimmy) {
		t.Errorf("Expected 'jimmy' to be removed but was found")
	}
}

func TestRemoveLast(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Remove(John)
	if len(q) != 1 {
		t.Errorf("Expected 1 entry in queue, but found %d", len(q))
	}
	if q.Contains(John) {
		t.Errorf("Expected 'john' to be removed but was found")
	}
}

func TestRemoveNotPresent(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Remove(Jimmy)
	if len(q) != 2 {
		t.Errorf("Expected 2 entry in queue, but found %d", len(q))
	}
}

func TestYield(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Yield()
	if q.Active() != John {
		t.Errorf("Expected 'john' to be active but was '%s'", q.Active())
	}
}

func TestYieldAlone(t *testing.T) {
	q := Queue{Mick}
	q = q.Yield()
	if q.Active() != Mick {
		t.Errorf("Expected 'mick' to be active but was '%s'", q.Active())
	}
}

func TestBargeWhenEmpty(t *testing.T) {
	q := Queue{}
	q = q.Barge(Mick)
	if q.Active() != Mick {
		t.Errorf("Expected 'mick' to be active but was '%s'", q.Active())
	}
}

func TestBargeWhenActive(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Barge(Mick)
	if q.Active() != Mick {
		t.Errorf("Expected 'mick' to be active but was '%s'", q.Active())
	}
}

func TestBargeWhenOnlyOne(t *testing.T) {
	q := Queue{John}
	q = q.Barge(Mick)
	expected := []Item{Mick}
	if !reflect.DeepEqual(q.Waiting(), expected) {
		t.Errorf("Expected waiting to be %v but was %v", expected, q.Waiting())
	}
}

func TestBargeWhenOnlyTwoAndAlreadySecond(t *testing.T) {
	q := Queue{John, Mick}
	q = q.Barge(Mick)
	expected := []Item{Mick}
	if !reflect.DeepEqual(q.Waiting(), expected) {
		t.Errorf("Expected waiting to be %v but was %v", expected, q.Waiting())
	}
}

func TestBargeWhenOnlyTwo(t *testing.T) {
	q := Queue{John, Jimmy}
	q = q.Barge(Mick)
	expected := []Item{Mick, Jimmy}
	if !reflect.DeepEqual(q.Waiting(), expected) {
		t.Errorf("Expected waiting to be %v but was %v", expected, q.Waiting())
	}
}

func TestBargeWhenAlreadySecond(t *testing.T) {
	q := Queue{John, Mick}
	q = q.Barge(Mick)
	expected := []Item{Mick}
	if !reflect.DeepEqual(q.Waiting(), expected) {
		t.Errorf("Expected waiting to be %v but was %v", expected, q.Waiting())
	}
}

func TestBargeWhenNotPresent(t *testing.T) {
	q := Queue{John, Colin, Jimmy}
	q = q.Barge(Mick)
	expected := []Item{Mick, Colin, Jimmy}
	if !reflect.DeepEqual(q.Waiting(), expected) {
		t.Errorf("Expected waiting to be %v but was %v", expected, q.Waiting())
	}
}

func TestBargeWhenPresent(t *testing.T) {
	q := Queue{John, Colin, Mick, Jimmy}
	q = q.Barge(Mick)
	expected := []Item{Mick, Colin, Jimmy}
	if !reflect.DeepEqual(q.Waiting(), expected) {
		t.Errorf("Expected waiting to be %v but was %v", expected, q.Waiting())
	}
}
<commit_msg>Use testify<commit_after>package queue

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

var John = Item{"john", "done some coding"}
var Jimmy = Item{"jimmy", "fix some bugs"}
var Mick = Item{"mick", "refactoring"}
var Colin = Item{"colin", "adding bugs"}

func TestCreateQueue(t *testing.T) {
	q := Queue{}
	assert.Equal(t, 0, len(q))

	defer func() {
		assert.NotNil(t, recover(), "Expected no active user but found one")
	}()
	q.Active()
}

func TestCreateQueueWithEntries(t *testing.T) {
	q := Queue{Mick, John}
	assert.Equal(t, 2, len(q))
}

func TestAddImmutable(t *testing.T) {
	q := Queue{}
	q.Add(Mick)
	assert.Equal(t, 0, len(q))
}

func TestAdd(t *testing.T) {
	q := Queue{}
	q = q.Add(Mick)
	assert.Equal(t, 1, len(q))

	active := q.Active()
	assert.Equal(t, Mick, active)
}

func TestAddDuplicate(t *testing.T) {
	q := Queue{Mick}
	q = q.Add(Mick)
	assert.Equal(t, 1, len(q))
}

func TestAddWithDifferentReason(t *testing.T) {
	q := Queue{Mick}
	q = q.Add(Item{"mick", "wrote tests"})
	assert.Equal(t, 2, len(q))
}

func TestWaitingWhenEmpty(t *testing.T) {
	q := Queue{}
	w := q.Waiting()
	assert.Equal(t, 0, len(w))
}

func TestWaitingWhenOnlyOne(t *testing.T) {
	q := Queue{Mick}
	w := q.Waiting()
	assert.Equal(t, 0, len(w))
}

func TestWaitingWhenMoreThanOne(t *testing.T) {
	q := Queue{Mick, John, Jimmy}
	expected := []Item{John, Jimmy}
	assert.Equal(t, expected, q.Waiting())
}

func TestRemoveImmutable(t *testing.T) {
	q := Queue{Mick}
	q.Remove(Mick)
	assert.Equal(t, 1, len(q))
}

func TestRemoveActive(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Remove(Mick)
	assert.Equal(t, 1, len(q))
	assert.Equal(t, John, q.Active())
}

func TestRemoveMiddle(t *testing.T) {
	q := Queue{Mick, Jimmy, John}
	q = q.Remove(Jimmy)
	assert.Equal(t, 2, len(q))
	assert.NotContains(t, q, Jimmy)
}

func TestRemoveLast(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Remove(John)
	assert.Equal(t, 1, len(q))
	assert.NotContains(t, q, John)
}

func TestRemoveNotPresent(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Remove(Jimmy)
	assert.Equal(t, 2, len(q))
}

func TestYield(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Yield()
	assert.Equal(t, John, q.Active())
}

func TestYieldAlone(t *testing.T) {
	q := Queue{Mick}
	q = q.Yield()
	assert.Equal(t, Mick, q.Active())
}

func TestBargeWhenEmpty(t *testing.T) {
	q := Queue{}
	q = q.Barge(Mick)
	assert.Equal(t, Mick, q.Active())
}

func TestBargeWhenActive(t *testing.T) {
	q := Queue{Mick, John}
	q = q.Barge(Mick)
	assert.Equal(t, Mick, q.Active())
}

func TestBargeWhenOnlyOne(t *testing.T) {
	q := Queue{John}
	q = q.Barge(Mick)
	expected := []Item{Mick}
	assert.Equal(t, expected, q.Waiting())
}

func TestBargeWhenOnlyTwoAndAlreadySecond(t *testing.T) {
	q := Queue{John, Mick}
	q = q.Barge(Mick)
	expected := []Item{Mick}
	assert.Equal(t, expected, q.Waiting())
}

func TestBargeWhenOnlyTwo(t *testing.T) {
	q := Queue{John, Jimmy}
	q = q.Barge(Mick)
	expected := []Item{Mick, Jimmy}
	assert.Equal(t, expected, q.Waiting())
}

func TestBargeWhenAlreadySecond(t *testing.T) {
	q := Queue{John, Mick}
	q = q.Barge(Mick)
	expected := []Item{Mick}
	assert.Equal(t, expected, q.Waiting())
}

func TestBargeWhenNotPresent(t *testing.T) {
	q := Queue{John, Colin, Jimmy}
	q = q.Barge(Mick)
	expected := []Item{Mick, Colin, Jimmy}
	assert.Equal(t, expected, q.Waiting())
}

func TestBargeWhenPresent(t *testing.T) {
	q := Queue{John, Colin, Mick, Jimmy}
	q = q.Barge(Mick)
	expected := []Item{Mick, Colin, Jimmy}
	assert.Equal(t, expected, q.Waiting())
}
<|endoftext|>


<commit_before>// Package vtrace extends the veyron2/context to allow you to attach
// various types of debugging information.  This debugging information
// accumulates along the various parts of the context tree and can be
// inspected to help you understand the performance and behavior of
// your system even across servers and processes.
//
// A new root context, as created by veyron2.Runtime.NewContext()
// represents a new operation unconnected to any other.  Vtrace
// represents all the debugging information collected about this
// operation, even across servers and processes, as a single Trace.
// The Trace will be divided into a hierarchy of timespans (Spans).
// For example, imagine our high level operation is making a new
// blog post.  We may have to first authentiate with an auth server,
// then write the new post to a database, and finally notify subscribers
// of the new content.  The trace might look like this:
//
//    Trace:
//    <---------------- Make a new blog post ----------->
//    |                  |                   |
//    <- Authenticate -> |                   |
//                       |                   |
//                       <-- Write to DB --> |
//                                           <- Notify ->
//    0s                      1.5s                      3s
//
// Here we have a single trace with four Spans.  Note that some Spans
// are children of other Spans.  This structure falls directly out of
// our building off of the context.T tree.  When you derive a new
// context using SetNewSpan(), you create a Span thats a child of
// the currently active span in the context.  Note that spans that
// share a parent may overlap in time.
//
// In this case the tree would have been created with code like this:
//
//    function MakeBlogPost(ctx *context.T) {
//        authCtx, _ := vtrace.SetNewSpan(ctx, "Authenticate")
//        Authenticate(authCtx)
//        writeCtx, _ := vtrace.SetNewSpan(ctx, "Write To DB")
//        Write(writeCtx)
//        notifyCtx, _ := vtrace.SetNewSpan(ctx, "Notify")
//        Notify(notifyCtx)
//    }
//
// Just as we have Spans to represent timesspans we have Annotations
// to attach debugging information to the current span that is relevant
// to the current moment.  Currently we only support string annotations.
// You can add an annotation to the current span by calling the Spans
// Annotate method:
//
//    span := vtrace.FromContext(ctx)
//    span.Annotate("Just got an error")
//
// When you make an annotation we record the annotation and the time
// when it was attached.
// TODO(mattr): Allow other types of annotations, for example server
// information, start and stop events.
//
// Traces can be composed of large numbers of spans containing
// data collected from large numbers of different processes.  Because
// this data is large we don't collect it for every context.  By
// default we collect trace data on only a small random sample of
// the contexts that are created.  If a particular operation is of
// special importants you can force it to be collected by calling the
// Trace's ForceCollect method.  All the spans and annotations that
// are added after ForceCollect is called will be collected.
//
// If your trace has collected information you can retrieve the data
// collected so far by calling the Trace.Record() method, which gives
// you a dump in the form of a TraceRecord.
package vtrace

import (
	"v.io/core/veyron2/context"
	"v.io/core/veyron2/uniqueid"
)

// Spans represent a named time period.  You can create new spans
// to represent new parts of your computation.
// Spans are safe to use from multiple goroutines simultaneously.
type Span interface {
	// Name returns the name of the span.
	Name() string

	// ID returns the uniqueid.ID of the span.
	ID() uniqueid.Id

	// Parent returns the uniqueid.ID of this spans parent span.
	Parent() uniqueid.Id

	// Annotate adds a string annotation to the trace.  Where Spans
	// represent time periods Annotations represent data thats relevant
	// at a specific moment.
	Annotate(s string)

	// Annotatef adds an annotation to the trace.  Where Spans represent
	// time periods Annotations represent data thats relevant at a
	// specific moment.
	// format and a are interpreted as with fmt.Printf.
	Annotatef(format string, a ...interface{})

	// Finish ends the span, marking the end time.  The span should
	// not be used after Finish is called.
	Finish()

	// Trace returns the id of the trace this Span is a member of.
	Trace() uniqueid.Id
}

// Store selectively collects information about traces in the system.
type Store interface {
	// TraceRecords returns TraceRecords for all traces saved in the store.
	TraceRecords() []TraceRecord

	// TraceRecord returns a TraceRecord for a given ID.  Returns
	// nil if the given id is not present.
	TraceRecord(traceid uniqueid.Id) *TraceRecord

	// ForceCollect forces the store to collect all information about a given trace.
	ForceCollect(traceid uniqueid.Id)
}

type Manager interface {
	// SetNewTrace creates a new vtrace context that is not the child of any
	// other span.  This is useful when starting operations that are
	// disconnected from the activity ctx is performing.  For example
	// this might be used to start background tasks.
	SetNewTrace(ctx *context.T) (*context.T, Span)

	// SetNewSpan derives a context with a new Span that can be used to
	// trace and annotate operations across process boundaries.
	SetNewSpan(ctx *context.T, name string) (*context.T, Span)

	// Span finds the currently active span.
	GetSpan(ctx *context.T) Span

	// Store returns the current Store.
	GetStore(ctx *context.T) Store
}

// managerKey is used to store a Manger in the context.
type managerKey struct{}

// WithManager returns a new context with a Vtrace manager attached.
func WithManager(ctx *context.T, manager Manager) *context.T {
	return context.WithValue(ctx, managerKey{}, manager)
}

func manager(ctx *context.T) Manager {
	manager, _ := ctx.Value(managerKey{}).(Manager)
	if manager == nil {
		panic(`Vtrace is uninitialized.
You are calling a Vtrace function but vtrace has not been initialized.
This is normally handled by the runtime initialization.  You should call
veyron2.Init() in your main or test before performing this function.`)
	}
	return manager
}

// SetNewTrace creates a new vtrace context that is not the child of any
// other span.  This is useful when starting operations that are
// disconnected from the activity ctx is performing.  For example
// this might be used to start background tasks.
func SetNewTrace(ctx *context.T) (*context.T, Span) {
	return manager(ctx).SetNewTrace(ctx)
}

// SetNewSpan derives a context with a new Span that can be used to
// trace and annotate operations across process boundaries.
func SetNewSpan(ctx *context.T, name string) (*context.T, Span) {
	return manager(ctx).SetNewSpan(ctx, name)
}

// Span finds the currently active span.
func GetSpan(ctx *context.T) Span {
	return manager(ctx).GetSpan(ctx)
}

// VtraceStore returns the current Store.
func GetStore(ctx *context.T) Store {
	return manager(ctx).GetStore(ctx)
}

// ForceCollect forces the store to collect all information about the
// current trace.
func ForceCollect(ctx *context.T) {
	m := manager(ctx)
	m.GetStore(ctx).ForceCollect(m.GetSpan(ctx).Trace())
}
<commit_msg>core: Implement vtrace (part 1 of many)<commit_after>// Package vtrace extends the veyron2/context to allow you to attach
// various types of debugging information.  This debugging information
// accumulates along the various parts of the context tree and can be
// inspected to help you understand the performance and behavior of
// your system even across servers and processes.
//
// A new root context, as created by veyron2.Runtime.NewContext()
// represents a new operation unconnected to any other.  Vtrace
// represents all the debugging information collected about this
// operation, even across servers and processes, as a single Trace.
// The Trace will be divided into a hierarchy of timespans (Spans).
// For example, imagine our high level operation is making a new
// blog post.  We may have to first authentiate with an auth server,
// then write the new post to a database, and finally notify subscribers
// of the new content.  The trace might look like this:
//
//    Trace:
//    <---------------- Make a new blog post ----------->
//    |                  |                   |
//    <- Authenticate -> |                   |
//                       |                   |
//                       <-- Write to DB --> |
//                                           <- Notify ->
//    0s                      1.5s                      3s
//
// Here we have a single trace with four Spans.  Note that some Spans
// are children of other Spans.  This structure falls directly out of
// our building off of the context.T tree.  When you derive a new
// context using SetNewSpan(), you create a Span thats a child of
// the currently active span in the context.  Note that spans that
// share a parent may overlap in time.
//
// In this case the tree would have been created with code like this:
//
//    function MakeBlogPost(ctx *context.T) {
//        authCtx, _ := vtrace.SetNewSpan(ctx, "Authenticate")
//        Authenticate(authCtx)
//        writeCtx, _ := vtrace.SetNewSpan(ctx, "Write To DB")
//        Write(writeCtx)
//        notifyCtx, _ := vtrace.SetNewSpan(ctx, "Notify")
//        Notify(notifyCtx)
//    }
//
// Just as we have Spans to represent timesspans we have Annotations
// to attach debugging information to the current span that is relevant
// to the current moment.  Currently we only support string annotations.
// You can add an annotation to the current span by calling the Spans
// Annotate method:
//
//    span := vtrace.FromContext(ctx)
//    span.Annotate("Just got an error")
//
// When you make an annotation we record the annotation and the time
// when it was attached.
// TODO(mattr): Allow other types of annotations, for example server
// information, start and stop events.
//
// Traces can be composed of large numbers of spans containing
// data collected from large numbers of different processes.  Because
// this data is large we don't collect it for every context.  By
// default we collect trace data on only a small random sample of
// the contexts that are created.  If a particular operation is of
// special importants you can force it to be collected by calling the
// Trace's ForceCollect method.  All the spans and annotations that
// are added after ForceCollect is called will be collected.
//
// If your trace has collected information you can retrieve the data
// collected so far by calling the Trace.Record() method, which gives
// you a dump in the form of a TraceRecord.
package vtrace

import (
	"v.io/core/veyron2/context"
	"v.io/core/veyron2/uniqueid"
)

// Spans represent a named time period.  You can create new spans
// to represent new parts of your computation.
// Spans are safe to use from multiple goroutines simultaneously.
type Span interface {
	// Name returns the name of the span.
	Name() string

	// ID returns the uniqueid.ID of the span.
	ID() uniqueid.Id

	// Parent returns the uniqueid.ID of this spans parent span.
	Parent() uniqueid.Id

	// Annotate adds a string annotation to the trace.  Where Spans
	// represent time periods Annotations represent data thats relevant
	// at a specific moment.
	Annotate(s string)

	// Annotatef adds an annotation to the trace.  Where Spans represent
	// time periods Annotations represent data thats relevant at a
	// specific moment.
	// format and a are interpreted as with fmt.Printf.
	Annotatef(format string, a ...interface{})

	// Finish ends the span, marking the end time.  The span should
	// not be used after Finish is called.
	Finish()

	// Trace returns the id of the trace this Span is a member of.
	Trace() uniqueid.Id
}

// Store selectively collects information about traces in the system.
type Store interface {
	// TraceRecords returns TraceRecords for all traces saved in the store.
	TraceRecords() []TraceRecord

	// TraceRecord returns a TraceRecord for a given ID.  Returns
	// nil if the given id is not present.
	TraceRecord(traceid uniqueid.Id) *TraceRecord

	// ForceCollect forces the store to collect all information about a given trace.
	ForceCollect(traceid uniqueid.Id)
}

type Manager interface {
	// SetNewTrace creates a new vtrace context that is not the child of any
	// other span.  This is useful when starting operations that are
	// disconnected from the activity ctx is performing.  For example
	// this might be used to start background tasks.
	SetNewTrace(ctx *context.T) (*context.T, Span)

	// SetContinuedTrace creates a span that represents a continuation of
	// a trace from a remote server.  name is the name of the new span and
	// req contains the parameters needed to connect this span with it's
	// trace.
	SetContinuedTrace(ctx *context.T, name string, req Request) (*context.T, Span)

	// SetNewSpan derives a context with a new Span that can be used to
	// trace and annotate operations across process boundaries.
	SetNewSpan(ctx *context.T, name string) (*context.T, Span)

	// Span finds the currently active span.
	GetSpan(ctx *context.T) Span

	// Store returns the current Store.
	GetStore(ctx *context.T) Store
}

// managerKey is used to store a Manger in the context.
type managerKey struct{}

// WithManager returns a new context with a Vtrace manager attached.
func WithManager(ctx *context.T, manager Manager) *context.T {
	return context.WithValue(ctx, managerKey{}, manager)
}

func manager(ctx *context.T) Manager {
	manager, _ := ctx.Value(managerKey{}).(Manager)
	if manager == nil {
		panic(`Vtrace is uninitialized.
You are calling a Vtrace function but vtrace has not been initialized.
This is normally handled by the runtime initialization.  You should call
veyron2.Init() in your main or test before performing this function.`)
	}
	return manager
}

// SetNewTrace creates a new vtrace context that is not the child of any
// other span.  This is useful when starting operations that are
// disconnected from the activity ctx is performing.  For example
// this might be used to start background tasks.
func SetNewTrace(ctx *context.T) (*context.T, Span) {
	return manager(ctx).SetNewTrace(ctx)
}

// SetContinuedTrace creates a span that represents a continuation of
// a trace from a remote server.  name is the name of the new span and
// req contains the parameters needed to connect this span with it's
// trace.
func SetContinuedTrace(ctx *context.T, name string, req Request) (*context.T, Span) {
	return manager(ctx).SetContinuedTrace(ctx, name, req)
}

// SetNewSpan derives a context with a new Span that can be used to
// trace and annotate operations across process boundaries.
func SetNewSpan(ctx *context.T, name string) (*context.T, Span) {
	return manager(ctx).SetNewSpan(ctx, name)
}

// Span finds the currently active span.
func GetSpan(ctx *context.T) Span {
	return manager(ctx).GetSpan(ctx)
}

// VtraceStore returns the current Store.
func GetStore(ctx *context.T) Store {
	return manager(ctx).GetStore(ctx)
}

// ForceCollect forces the store to collect all information about the
// current trace.
func ForceCollect(ctx *context.T) {
	m := manager(ctx)
	m.GetStore(ctx).ForceCollect(m.GetSpan(ctx).Trace())
}
<|endoftext|>


<commit_before>// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
// 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 cmd

import (
	"fmt"

	"github.com/spf13/cobra"
)

// exploreCmd represents the explore command
var exploreCmd = &cobra.Command{
	Use:   "explore",
	Short: "A brief description of your command",
	Long: `A longer description that spans multiple lines and likely contains examples
and usage of using your command. For example:

Cobra is a CLI library for Go that empowers applications.
This application is a tool to generate the needed files
to quickly create a Cobra application.`,
	Run: func(cmd *cobra.Command, args []string) {
		fmt.Println("explore called")
	},
}

func init() {
	RootCmd.AddCommand(exploreCmd)

	// Here you will define your flags and configuration settings.

	// Cobra supports Persistent Flags which will work for this command
	// and all subcommands, e.g.:
	// exploreCmd.PersistentFlags().String("foo", "", "A help for foo")

	// Cobra supports local flags which will only run when this command
	// is called directly, e.g.:
	// exploreCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
<commit_msg>implements explore CLI cmd<commit_after>// Copyright © 2017 NAME HERE <EMAIL ADDRESS>
// 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 cmd

import (
	"fmt"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/mhausenblas/reshifter/pkg/discovery"
	"github.com/mhausenblas/reshifter/pkg/types"
	"github.com/spf13/cobra"
)

// exploreCmd represents the explore command
var exploreCmd = &cobra.Command{
	Use:   "explore",
	Short: "Probes an etcd endpoint",
	Long:  `Probes an etc endpoint at path /version to figure which version of etcd it is and in which mode (secure or insecure) it is used`,
	Run: func(cmd *cobra.Command, args []string) {
		ep := cmd.Flag("endpoint").Value.String()
		fmt.Printf("Exploring etcd endpoint %s\n", ep)
		doexplore(ep)
	},
}

func init() {
	RootCmd.AddCommand(exploreCmd)
	exploreCmd.Flags().StringP("endpoint", "e", "http://127.0.0.1:2379", "The URL of the etcd to probe.")
}

func doexplore(endpoint string) {
	if endpoint == "" || strings.Index(endpoint, "http") != 0 {
		merr := "The endpoint is malformed"
		log.Error(merr)
		return
	}
	version, issecure, err := discovery.ProbeEtcd(endpoint)
	if err != nil {
		log.Errorf(fmt.Sprintf("%s", err))
		return
	}
	distrotype, err := discovery.ProbeKubernetesDistro(endpoint)
	if err != nil {
		log.Errorf(fmt.Sprintf("Can't determine Kubernetes distro: %s", err))
		return
	}
	secure := "insecure etcd, no SSL/TLS configured"
	if issecure {
		secure = "secure etcd, SSL/TLS configure"
	}
	var distro string
	switch distrotype {
	case types.Vanilla:
		distro = "Vanilla Kubernetes"
	case types.OpenShift:
		distro = "OpenShift"
	default:
		distro = "no Kubernetes distro found"
	}
	fmt.Printf("Version: %s\nSecure: %s\nDistro: %s\n\n", version, secure, distro)
}
<|endoftext|>