<commit_before>package ops

import (
	"bsearch/index"
	"container/heap"
)

type union []QueryOp

func NewUnion(n ...QueryOp) QueryContainer {
	var un union

	heap.Init(&un)

	un.Add(n...)
	return &un
}

func (un *union) Add(nodes ...QueryOp) {
	for _, n := range nodes {
		if n.CurrentDoc() != nil {
			heap.Push(un, n)
		}
	}
}

func (un *union) CurrentDoc() *index.IbDoc {
	h := un.peek()
	if h == nil {
		return nil
	}
	return h.CurrentDoc()
}

func (un *union) NextDoc(search *index.IbDoc) *index.IbDoc {
	d := un.CurrentDoc()
	// Chew up all documents bigger than search
	for d != nil && search.Cmp(d) < 0 {
		/*
		 * We could use a heap.UpdateHead here to avoid all those expensive
		 * Pop/Push. It is trivially implemented with heap.down(h, 0, h.Len()),
		 * but unfortunately that's not exposed to us. Another alternative is
		 * heap.Init, but that's too brutal too.
		 */
		n := heap.Pop(un).(QueryOp)

		/* Only put the element back into the heap if it's not empty. */
		if n.NextDoc(search) != nil {
			heap.Push(un, n)
		}
		d = un.CurrentDoc()
	}
	return d
}

// Len returns the number of elements in the union.
// Needed to implement heap.Interface.
func (un union) Len() int {
	return len(un)
}

// Compares two elements and returns which one is bigger than the other.
// Needed to implement heap.Interface.
// It's called Less because the heap is a min heap, but we want a max heap.
func (un union) Less(i, j int) bool {
	a := un[i].CurrentDoc()
	b := un[j].CurrentDoc()
	return a.Cmp(b) > 0 // we want a max-heap
}

// Swap to elements in the union.
// Needed to implement heap.Interface.
func (un union) Swap(i, j int) {
	un[i], un[j] = un[j], un[i]
}

// Add an element at the end of the union.
// Needed to implement heap.Interface.
func (un *union) Push(x interface{}) {
	*un = append(*un, x.(QueryOp))
}

// Remove one element from the end of the union.
// Needed to implement heap.Interface.
func (un *union) Pop() interface{} {
	l := len(*un)
	r := (*un)[l-1]
	*un = (*un)[:l-1]
	return r
}

// Peek at the head of the heap.
func (un union) peek() QueryOp {
	l := len(un)
	if l > 0 {
		return un[l-1]
	}
	return nil
}

func (un union) ProcessHeaders(hc HeaderCollector) {
	for _, n := range un {
		n.ProcessHeaders(hc)
	}
}
<commit_msg>Fix union.peek() so that we return the top element of the union, not the last one. OOps.<commit_after>package ops

import (
	"bsearch/index"
	"container/heap"
)

type union []QueryOp

func NewUnion(n ...QueryOp) QueryContainer {
	var un union

	heap.Init(&un)

	un.Add(n...)
	return &un
}

func (un *union) Add(nodes ...QueryOp) {
	for _, n := range nodes {
		if n.CurrentDoc() != nil {
			heap.Push(un, n)
		}
	}
}

func (un *union) CurrentDoc() *index.IbDoc {
	h := un.peek()
	if h == nil {
		return nil
	}
	return h.CurrentDoc()
}

func (un *union) NextDoc(search *index.IbDoc) *index.IbDoc {
	d := un.CurrentDoc()
	// Chew up all documents bigger than search
	for d != nil && search.Cmp(d) < 0 {
		/*
		 * We could use a heap.UpdateHead here to avoid all those expensive
		 * Pop/Push. It is trivially implemented with heap.down(h, 0, h.Len()),
		 * but unfortunately that's not exposed to us. Another alternative is
		 * heap.Init, but that's too brutal too.
		 */
		n := heap.Pop(un).(QueryOp)

		/* Only put the element back into the heap if it's not empty. */
		if n.NextDoc(search) != nil {
			heap.Push(un, n)
		}
		d = un.CurrentDoc()
	}
	return d
}

// Len returns the number of elements in the union.
// Needed to implement heap.Interface.
func (un union) Len() int {
	return len(un)
}

// Compares two elements and returns which one is bigger than the other.
// Needed to implement heap.Interface.
// It's called Less because the heap is a min heap, but we want a max heap.
func (un union) Less(i, j int) bool {
	a := un[i].CurrentDoc()
	b := un[j].CurrentDoc()
	return a.Cmp(b) > 0 // we want a max-heap
}

// Swap to elements in the union.
// Needed to implement heap.Interface.
func (un union) Swap(i, j int) {
	un[i], un[j] = un[j], un[i]
}

// Add an element at the end of the union.
// Needed to implement heap.Interface.
func (un *union) Push(x interface{}) {
	*un = append(*un, x.(QueryOp))
}

// Remove one element from the end of the union.
// Needed to implement heap.Interface.
func (un *union) Pop() interface{} {
	l := len(*un)
	r := (*un)[l-1]
	*un = (*un)[:l-1]
	return r
}

// Peek at the head of the heap.
func (un union) peek() QueryOp {
	l := len(un)
	if l > 0 {
		return un[0]
	}
	return nil
}

func (un union) ProcessHeaders(hc HeaderCollector) {
	for _, n := range un {
		n.ProcessHeaders(hc)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"dealer"
	"encoding/json"
	"fmt"
	"time"
)

func main() {
	test := dealer.Socket{}
	test.Connect("localhost", "8082")

	mess := map[string]string{"id": "5", "content": "This is a test"}
	messBytes, _ := json.Marshal(mess)

	// Warmup
	test.SendBytes(messBytes)
	_ = test.ReadBlock("5")

	// Benchmark
	fmt.Println("Starting benchmark")
	numberOfRuns := 500
	numberOfBenchs := 10

	var runtime = make([]float64, numberOfBenchs)

	for j := 0; j < numberOfBenchs; j++ {
		start := time.Now()
		for i := 0; i < numberOfRuns; i++ {
			test.SendBytes(messBytes)
			_ = test.ReadBlock("5")
		}

		elapsed := time.Since(start)
		runtime[j] = float64(numberOfRuns) / elapsed.Seconds()
		fmt.Printf("Processed %.2f requests per second\n", runtime[j])
	}

	fmt.Println("----------------\n")
	fmt.Println("Runs completed.\n")
	avg := 0.
	for _, val := range runtime {
		avg += val
	}

	avg /= float64(numberOfBenchs)
	fmt.Printf("Processed %.2f requests per second on average\n", avg)

	test.Close()
}
<commit_msg>minor style fix<commit_after>package main

import (
	"bufio"
	"dealer"
	"encoding/json"
	"fmt"
	"net"
	"strconv"
	"time"
)

func serveEcho(conn net.Conn, id int) {
	for {
		message, _ := bufio.NewReader(conn).ReadString('}')

		if len(message) > 0 {
			conn.Write([]byte(message))
		}
	}
}

func echo() {

	ln, _ := net.Listen("tcp", "localhost:8082")
	id := 0

	for {
		fmt.Println("Server ready, awaiting connection")
		conn, _ := ln.Accept() // Blocking call, awaiting client

		// Start the echo routine, and go back waiting for a new connection
		fmt.Println("Server got a new client : " + strconv.Itoa(id))
		go serveEcho(conn, id)
		id = id + 1
	}
}

func main() {
	// Start the Echo Server through a go routine
	go echo()
	time.Sleep(time.Second)

	// Connect our client
	test := dealer.Socket{}
	test.Connect("localhost", "8082")

	// Warmup
	mess := map[string]string{"id": "5", "content": "This is a test"}
	messBytes, _ := json.Marshal(mess)

	test.SendBytes(messBytes)
	_ = test.ReadBlock("5")

	// Benchmark
	fmt.Println("\nStarting benchmark")
	numberOfRuns := 500
	numberOfBenchs := 10

	var runtime = make([]float64, numberOfBenchs)

	for j := 0; j < numberOfBenchs; j++ {
		start := time.Now()
		for i := 0; i < numberOfRuns; i++ {
			test.SendBytes(messBytes)
			_ = test.ReadBlock("5")
		}

		elapsed := time.Since(start)
		runtime[j] = float64(numberOfRuns) / elapsed.Seconds()
		fmt.Printf("Processed %.2f requests per second\n", runtime[j])
	}

	fmt.Printf("\n----------------\n")
	fmt.Print("Runs completed.\n")
	avg := 0.
	for _, val := range runtime {
		avg += val
	}

	avg /= float64(numberOfBenchs)
	fmt.Printf("Processed %.2f requests per second on average\n", avg)

	delay := 1000. / avg
	fmt.Printf("corresponding to %.2f ms delay\n", delay)

	test.Close()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"database/sql"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

type Streams struct {
	// {{{
	Stream []struct {
		// Id   int64  `json:"_id"`
		Game    string `json:"game"`
		Viewers int    `json:"viewers"`
		// CreatedAt string `json:"created_at"`
		// Links     struct {
		// Self string `json:"self"`
		// } `json:"_links"`
		// Preview struct {
		// Small    string `json:"small"`
		// Medium   string `json:"medium"`
		// Large    string `json:"large"`
		// Template string `json:"template"`
		// } `json:"preview"`
		Channel struct {
			// Links struct {
			// Self          string `json:"self"`
			// Follows       string `json:"follows"`
			// Commercial    string `json:"commercial"`
			// StreamKey     string `json:"stream_key"`
			// Chat          string `json:"chat"`
			// Features      string `json:"features"`
			// Subscriptions string `json:"subscriptions"`
			// Editors       string `json:"editors"`
			// Videos        string `json:"videos"`
			// Teams         string `json:"teams"`
			// } `json:"_links"`
			// Background                   interface{} `json:"background"`
			// Banner                       interface{} `json:"banner"`
			// BroadcasterLanguage          string      `json:"broadcaster_language"`
			DisplayName string `json:"display_name"`
			// Game        string `json:"game"`
			Logo string `json:"logo"`
			// Mature                       bool        `json:"mature"`
			Status string `json:"status"`
			// Partner                      bool        `json:"partner"`
			Url string `json:"url"`
			// VideoBanner                  string      `json:"video_banner"`
			// Id                           int         `json:"_id"`
			// Name                         string      `json:"name"`
			// CreatedAt                    string      `json:"created_at"`
			// UpdatedAt                    string      `json:"updated_at"`
			// Delay                        int         `json:"delay"`
			// Followers                    int         `json:"followers"`
			// ProfileBanner                string      `json:"profile_banner"`
			// ProfileBannerBackgroundColor interface{} `json:"profile_banner_background_color"`
			// Views                        int         `json:"views"`
			// Language                     string      `json:"language"`
		} `json:"channel"`
	} `json:"streams"`
	// Total int `json:"_total"`
	// Links struct {
	// Self     string `json:"self"`
	// Next     string `json:"next"`
	// Featured string `json:"featured"`
	// Summary  string `json:"summary"`
	// Followed string `json:"followed"`
	// } `json:"_links"`
	// }}}
}

var LiveStreams [25]string
var PrevStreams [25]string

// It is OK if this returns nil. It will only prevent the DB from updating
func getTopStreams(first bool) *Streams {
	res, err := http.Get("https://api.twitch.tv/kraken/streams")
	if err != nil {
		log.Println("info: no response from api")
		return nil
	}

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Println("error: could not read api response")
		return nil
	}

	dat := new(Streams)
	if err := json.Unmarshal(body, dat); err != nil {
		log.Println("could not parse json")
		return nil
	}

	if !first {
		for i := 0; i < 25; i++ {
			PrevStreams[i] = LiveStreams[i]
		}
	}
	for i, _ := range dat.Stream {
		dat.Stream[i].Channel.DisplayName = strings.ToLower(dat.Stream[i].Channel.DisplayName)
		LiveStreams[i] = dat.Stream[i].Channel.DisplayName
	}
	return dat
}

func JSONMarshal(v interface{}, safeEncoding bool) ([]byte, error) {
	b, err := json.Marshal(v)

	if safeEncoding {
		b = bytes.Replace(b, []byte("\\u003c"), []byte("<"), -1)
		b = bytes.Replace(b, []byte("\\u003e"), []byte(">"), -1)
		b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)
	}
	return b, err
}

func returnJSON(db *sql.DB) string {
	d, err := queryDB(db)
	if err != nil {
		// TODO: do more
		return err.Error()
		// return "error"
	}
	wrapper := &Wrapper{Streams: d}
	out, err := JSONMarshal(&wrapper, true)
	if err != nil {
		// TODO: do more
		return "error"
	}
	return string(out)
}
<commit_msg>remove unsed api data<commit_after>package main

import (
	"bytes"
	"database/sql"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"strings"
)

type Streams struct {
	// {{{
	Stream []struct {
		// Id   int64  `json:"_id"`
		Game    string `json:"game"`
		Viewers int    `json:"viewers"`
		// CreatedAt string `json:"created_at"`
		// Links     struct {
		// Self string `json:"self"`
		// } `json:"_links"`
		// Preview struct {
		// Small    string `json:"small"`
		// Medium   string `json:"medium"`
		// Large    string `json:"large"`
		// Template string `json:"template"`
		// } `json:"preview"`
		Channel struct {
			// Links struct {
			// Self          string `json:"self"`
			// Follows       string `json:"follows"`
			// Commercial    string `json:"commercial"`
			// StreamKey     string `json:"stream_key"`
			// Chat          string `json:"chat"`
			// Features      string `json:"features"`
			// Subscriptions string `json:"subscriptions"`
			// Editors       string `json:"editors"`
			// Videos        string `json:"videos"`
			// Teams         string `json:"teams"`
			// } `json:"_links"`
			// Background                   interface{} `json:"background"`
			// Banner                       interface{} `json:"banner"`
			// BroadcasterLanguage          string      `json:"broadcaster_language"`
			DisplayName string `json:"display_name"`
			// Game        string `json:"game"`
			Logo string `json:"logo"`
			// Mature                       bool        `json:"mature"`
			// Status string `json:"status"`
			// Partner                      bool        `json:"partner"`
			// Url string `json:"url"`
			// VideoBanner                  string      `json:"video_banner"`
			// Id                           int         `json:"_id"`
			// Name                         string      `json:"name"`
			// CreatedAt                    string      `json:"created_at"`
			// UpdatedAt                    string      `json:"updated_at"`
			// Delay                        int         `json:"delay"`
			// Followers                    int         `json:"followers"`
			// ProfileBanner                string      `json:"profile_banner"`
			// ProfileBannerBackgroundColor interface{} `json:"profile_banner_background_color"`
			// Views                        int         `json:"views"`
			// Language                     string      `json:"language"`
		} `json:"channel"`
	} `json:"streams"`
	// Total int `json:"_total"`
	// Links struct {
	// Self     string `json:"self"`
	// Next     string `json:"next"`
	// Featured string `json:"featured"`
	// Summary  string `json:"summary"`
	// Followed string `json:"followed"`
	// } `json:"_links"`
	// }}}
}

var LiveStreams [25]string
var PrevStreams [25]string

// It is OK if this returns nil. It will only prevent the DB from updating
func getTopStreams(first bool) *Streams {
	res, err := http.Get("https://api.twitch.tv/kraken/streams")
	if err != nil {
		log.Println("info: no response from api")
		return nil
	}

	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Println("error: could not read api response")
		return nil
	}

	dat := new(Streams)
	if err := json.Unmarshal(body, dat); err != nil {
		log.Println("could not parse json")
		return nil
	}

	if !first {
		for i := 0; i < 25; i++ {
			PrevStreams[i] = LiveStreams[i]
		}
	}
	for i, _ := range dat.Stream {
		dat.Stream[i].Channel.DisplayName = strings.ToLower(dat.Stream[i].Channel.DisplayName)
		LiveStreams[i] = dat.Stream[i].Channel.DisplayName
	}
	return dat
}

func JSONMarshal(v interface{}, safeEncoding bool) ([]byte, error) {
	b, err := json.Marshal(v)

	if safeEncoding {
		b = bytes.Replace(b, []byte("\\u003c"), []byte("<"), -1)
		b = bytes.Replace(b, []byte("\\u003e"), []byte(">"), -1)
		b = bytes.Replace(b, []byte("\\u0026"), []byte("&"), -1)
	}
	return b, err
}

func returnJSON(db *sql.DB) string {
	d, err := queryDB(db)
	if err != nil {
		// TODO: do more
		return err.Error()
		// return "error"
	}
	wrapper := &Wrapper{Streams: d}
	out, err := JSONMarshal(&wrapper, true)
	if err != nil {
		// TODO: do more
		return "error"
	}
	return string(out)
}
<|endoftext|>


<commit_before>package testhelpers

import (
	"cf/app"
	"flag"
	"github.com/codegangsta/cli"
)

func NewContext(cmdName string, args []string) (*cli.Context) {
	targetCommand := findCommand(cmdName)

	flagSet := new(flag.FlagSet)
	for i, _ := range targetCommand.Flags {
		targetCommand.Flags[i].Apply(flagSet)
	}

	flagSet.Parse(args)

	globalSet := new(flag.FlagSet)

	return cli.NewContext(cli.NewApp(), flagSet, globalSet)
}

func findCommand(cmdName string) (cmd cli.Command) {
	myApp, _ := app.New()

	for _, cmd := range myApp.Commands {
		if cmd.Name == cmdName {
			return cmd
		}
	}

	return
}

<commit_msg>Tests can pass CLI flags at the end or the beginning<commit_after>package testhelpers

import (
	"cf/app"
	"flag"
	"github.com/codegangsta/cli"
	"strings"
)

func NewContext(cmdName string, args []string) (*cli.Context) {
	targetCommand := findCommand(cmdName)

	flagSet := new(flag.FlagSet)
	for i, _ := range targetCommand.Flags {
		targetCommand.Flags[i].Apply(flagSet)
	}

	// move all flag args to the beginning of the list, go requires them all upfront
	firstFlagIndex := -1
	for index, arg := range args {
		if strings.HasPrefix(arg, "-") {
			firstFlagIndex = index
			break
		}
	}
	if firstFlagIndex > 0 {
		args := args[0:firstFlagIndex]
		flags := args[firstFlagIndex:]
		flagSet.Parse(append(flags, args...))
	} else {
		flagSet.Parse(args[0:])
	}

	globalSet := new(flag.FlagSet)

	return cli.NewContext(cli.NewApp(), flagSet, globalSet)
}

func findCommand(cmdName string) (cmd cli.Command) {
	myApp, _ := app.New()

	for _, cmd := range myApp.Commands {
		if cmd.Name == cmdName {
			return cmd
		}
	}

	return
}

<|endoftext|>


<commit_before>package binding

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"reflect"

	"github.com/gocraft/web"
)

var ErrRequestBodyIncomplete = fmt.Errorf("Request body is empty")
func decodeBodyToJSON(ctx interface{}, fieldType reflect.Type, r *web.Request) error {
	t := reflect.ValueOf(ctx)
	if t.Type().Kind() != reflect.Ptr {
		panic("expected pointer to struct")
	}
	t = t.Elem()
	const contextFieldNameForRequest = "RequestJSON"
	saveToField := t.FieldByName(contextFieldNameForRequest)
	if !saveToField.IsValid() {
		panic(fmt.Sprintf("Expected to find field named %q name on the context",contextFieldNameForRequest))
	}

	if !saveToField.CanSet() {
		panic(fmt.Sprintf("Unable to set the value of field named %q on the context",contextFieldNameForRequest))
	}

	newObject := reflect.New(fieldType)
	err := json.NewDecoder(r.Body).Decode(newObject.Elem().Addr().Interface())
	if err != nil {
		if err == io.EOF {
			return ErrRequestBodyIncomplete
		}
		return err
	}

	saveToField.Set(newObject)

	return nil
}

func Request(field interface{}, errorHandlerCustom func(web.ResponseWriter, error)) func(
	interface{}, web.ResponseWriter, *web.Request, web.NextMiddlewareFunc) {

	errorHandler := ErrorHandler
	if errorHandlerCustom != nil {
		errorHandler = errorHandlerCustom
	}

	fieldType := reflect.TypeOf(field)

	return func(ctx interface{}, rw web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) {
		err := decodeBodyToJSON(ctx, fieldType, r)
		if err != nil {
			errorHandler(rw, err)
			return
		}
		next(rw, r)
	}
}

func ErrorHandler(rw web.ResponseWriter, err error) {
	if rw.Written() {
		panic(fmt.Sprintf("Data already started to be sent to the client and i had an error: %s", err))
	}
	rw.WriteHeader(http.StatusBadRequest)
	fmt.Fprintf(rw, "{\"Error\": \"%s\"", err)
}
<commit_msg>Error default handler json error<commit_after>package binding

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"reflect"

	"github.com/gocraft/web"
)

var ErrRequestBodyIncomplete = fmt.Errorf("Request body is empty")

func decodeBodyToJSON(ctx interface{}, fieldType reflect.Type, r *web.Request) error {
	t := reflect.ValueOf(ctx)
	if t.Type().Kind() != reflect.Ptr {
		panic("expected pointer to struct")
	}
	t = t.Elem()
	const contextFieldNameForRequest = "RequestJSON"
	saveToField := t.FieldByName(contextFieldNameForRequest)
	if !saveToField.IsValid() {
		panic(fmt.Sprintf("Expected to find field named %q name on the context", contextFieldNameForRequest))
	}

	if !saveToField.CanSet() {
		panic(fmt.Sprintf("Unable to set the value of field named %q on the context", contextFieldNameForRequest))
	}

	newObject := reflect.New(fieldType)
	err := json.NewDecoder(r.Body).Decode(newObject.Elem().Addr().Interface())
	if err != nil {
		if err == io.EOF {
			return ErrRequestBodyIncomplete
		}
		return err
	}

	saveToField.Set(newObject)

	return nil
}

func Request(field interface{}, errorHandlerCustom func(web.ResponseWriter, error)) func(
	interface{}, web.ResponseWriter, *web.Request, web.NextMiddlewareFunc) {

	errorHandler := ErrorHandler
	if errorHandlerCustom != nil {
		errorHandler = errorHandlerCustom
	}

	fieldType := reflect.TypeOf(field)

	return func(ctx interface{}, rw web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) {
		err := decodeBodyToJSON(ctx, fieldType, r)
		if err != nil {
			errorHandler(rw, err)
			return
		}
		next(rw, r)
	}
}

func ErrorHandler(rw web.ResponseWriter, err error) {
	if rw.Written() {
		panic(fmt.Sprintf("Data already started to be sent to the client and i had an error: %s", err))
	}
	rw.WriteHeader(http.StatusBadRequest)
	fmt.Fprintf(rw, "{\"Error\": \"%s\"}", err)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"
	"regexp"
	"strconv"
	"strings"
)

type Request struct {
	Filename    string
	Content     string
	Command     string
	Image       string
	Format      string
	MemoryLimit int64
	NamespaceId string
}

var FilenameRegexp = regexp.MustCompile(`\A([a-z\d\-\_]+)\.[a-z]{1,6}\z`)

func normalizeString(val string) string {
	return strings.ToLower(strings.TrimSpace(val))
}

func parseInt(val string) int64 {
	if val == "" {
		return 0
	}

	result, err := strconv.Atoi(val)
	if err != nil {
		return 0
	}

	if result < 0 {
		result = 0
	}

	return int64(result)
}

func ParseRequest(r *http.Request) (*Request, error) {
	req := Request{
		Filename:    normalizeString(r.FormValue("filename")),
		Command:     normalizeString(r.FormValue("command")),
		Content:     r.FormValue("content"),
		Image:       r.FormValue("image"),
		MemoryLimit: parseInt(r.FormValue("memory_limit")),
		NamespaceId: normalizeString(r.FormValue("namespace")),
	}

	if req.Filename == "" {
		return nil, fmt.Errorf("Filename is required")
	}

	if !FilenameRegexp.Match([]byte(req.Filename)) {
		return nil, fmt.Errorf("Invalid filename")
	}

	if req.Content == "" {
		return nil, fmt.Errorf("Content is required")
	}

	lang, err := GetLanguageConfig(req.Filename)
	if err != nil {
		return nil, err
	}

	req.Format = lang.Format

	if req.Image == "" {
		req.Image = lang.Image
	}

	if req.Command == "" {
		req.Command = fmt.Sprintf(lang.Command, req.Filename)
	}

	return &req, nil
}
<commit_msg>Allow longer file extensions<commit_after>package main

import (
	"fmt"
	"net/http"
	"regexp"
	"strconv"
	"strings"
)

type Request struct {
	Filename    string
	Content     string
	Command     string
	Image       string
	Format      string
	MemoryLimit int64
	NamespaceId string
}

var FilenameRegexp = regexp.MustCompile(`\A([a-z\d\-\_]+)\.[a-z]{1,12}\z`)

func normalizeString(val string) string {
	return strings.ToLower(strings.TrimSpace(val))
}

func parseInt(val string) int64 {
	if val == "" {
		return 0
	}

	result, err := strconv.Atoi(val)
	if err != nil {
		return 0
	}

	if result < 0 {
		result = 0
	}

	return int64(result)
}

func ParseRequest(r *http.Request) (*Request, error) {
	req := Request{
		Filename:    normalizeString(r.FormValue("filename")),
		Command:     normalizeString(r.FormValue("command")),
		Content:     r.FormValue("content"),
		Image:       r.FormValue("image"),
		MemoryLimit: parseInt(r.FormValue("memory_limit")),
		NamespaceId: normalizeString(r.FormValue("namespace")),
	}

	if req.Filename == "" {
		return nil, fmt.Errorf("Filename is required")
	}

	if !FilenameRegexp.Match([]byte(req.Filename)) {
		return nil, fmt.Errorf("Invalid filename")
	}

	if req.Content == "" {
		return nil, fmt.Errorf("Content is required")
	}

	lang, err := GetLanguageConfig(req.Filename)
	if err != nil {
		return nil, err
	}

	req.Format = lang.Format

	if req.Image == "" {
		req.Image = lang.Image
	}

	if req.Command == "" {
		req.Command = fmt.Sprintf(lang.Command, req.Filename)
	}

	return &req, nil
}
<|endoftext|>


<commit_before>package epazote

import (
	"bytes"
	"crypto/tls"
	"net"
	"net/http"
	"net/url"
	"regexp"
	"strings"
	"time"
)

const URL string = `^((ftp|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`

var rxURL = regexp.MustCompile(URL)

type ServiceHttpResponse struct {
	Err     error
	Service string
}

// AsyncGet used as a URL validation method
func AsyncGet(s *Services) <-chan ServiceHttpResponse {
	ch := make(chan ServiceHttpResponse, len(*s))

	for k, v := range *s {
		go func(name string, url string, verify bool, h map[string]string) {
			res, err := HTTPGet(url, true, verify, h)
			if err != nil {
				ch <- ServiceHttpResponse{err, name}
				return
			}
			res.Body.Close()
			ch <- ServiceHttpResponse{nil, name}
		}(k, v.URL, v.Insecure, v.Header)
	}

	return ch
}

// HTTPGet creates a new http request
func HTTPGet(url string, follow, insecure bool, h map[string]string, timeout ...int) (*http.Response, error) {
	// timeout in seconds defaults to 5
	var t int = 5

	if len(timeout) > 0 {
		t = timeout[0]
	}

	// if insecure = true, skip ssl verification
	tr := &http.Transport{
		Dial: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
		}).Dial,
		TLSHandshakeTimeout:   60 * time.Second,
		TLSClientConfig:       &tls.Config{InsecureSkipVerify: insecure},
		ResponseHeaderTimeout: time.Duration(t) * time.Second,
	}

	client := &http.Client{}
	client.Transport = tr

	// create a new request
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", "epazote")

	// set custom headers on request
	if h != nil {
		for k, v := range h {
			req.Header.Set(k, v)
		}
	}

	if follow {
		res, err := client.Do(req)
		if err != nil {
			return nil, err
		}
		return res, nil
	}

	// not follow redirects
	var DefaultTransport http.RoundTripper = tr

	res, err := DefaultTransport.RoundTrip(req)
	if err != nil {
		return nil, err
	}
	return res, nil
}

// HTTPPost post service json data
func HTTPPost(url string, data []byte, h map[string]string) (*http.Response, error) {
	// create a new request
	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(data))
	req.Header.Set("User-Agent", "epazote")
	req.Header.Set("Content-Type", "application/json")

	// set custom headers on request
	if h != nil {
		for k, v := range h {
			req.Header.Set(k, v)
		}
	}

	client := &http.Client{}

	res, err := client.Do(req)
	if err != nil {
		return nil, err
	}

	return res, nil
}

// IsURL https://github.com/asaskevich/govalidator/blob/master/validator.go#L44
func IsURL(str string) bool {
	if str == "" || len(str) >= 2083 || len(str) <= 3 || strings.HasPrefix(str, ".") {
		return false
	}
	u, err := url.Parse(str)
	if err != nil {
		return false
	}
	if strings.HasPrefix(u.Host, ".") {
		return false
	}
	if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
		return false
	}
	return rxURL.MatchString(str)
}
<commit_msg>prototype check certificate expiry<commit_after>package epazote

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"net"
	"net/http"
	"net/url"
	"regexp"
	"strings"
	"time"
)

const URL string = `^((ftp|https?):\/\/)?(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`

var rxURL = regexp.MustCompile(URL)

type ServiceHttpResponse struct {
	Err     error
	Service string
}

// AsyncGet used as a URL validation method
func AsyncGet(s *Services) <-chan ServiceHttpResponse {
	ch := make(chan ServiceHttpResponse, len(*s))

	for k, v := range *s {
		go func(name string, url string, verify bool, h map[string]string) {
			res, err := HTTPGet(url, true, verify, h)
			if err != nil {
				ch <- ServiceHttpResponse{err, name}
				return
			}
			res.Body.Close()
			ch <- ServiceHttpResponse{nil, name}
		}(k, v.URL, v.Insecure, v.Header)
	}

	return ch
}

// HTTPGet creates a new http request
func HTTPGet(url string, follow, insecure bool, h map[string]string, timeout ...int) (*http.Response, error) {
	// timeout in seconds defaults to 5
	var t int = 5

	if len(timeout) > 0 {
		t = timeout[0]
	}

	// if insecure = true, skip ssl verification
	tr := &http.Transport{
		Dial: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
		}).Dial,
		TLSHandshakeTimeout:   60 * time.Second,
		TLSClientConfig:       &tls.Config{InsecureSkipVerify: insecure},
		ResponseHeaderTimeout: time.Duration(t) * time.Second,
	}

	client := &http.Client{}
	client.Transport = tr

	// create a new request
	req, _ := http.NewRequest("GET", url, nil)
	req.Header.Set("User-Agent", "epazote")

	// set custom headers on request
	if h != nil {
		for k, v := range h {
			req.Header.Set(k, v)
		}
	}

	if follow {
		res, err := client.Do(req)
		if err != nil {
			return nil, err
		}
		return res, nil
	}

	// not follow redirects
	var DefaultTransport http.RoundTripper = tr

	res, err := DefaultTransport.RoundTrip(req)
	fmt.Printf("res.TLS = %+v\n", res.TLS)
	fmt.Printf("res.TLS.PeerCertificates = %+v\n", res.TLS.PeerCertificates)
	for _, v := range res.TLS.PeerCertificates {
		fmt.Printf("v.NotAfter = %+v\n", v.NotAfter)
		fmt.Printf("v.Subject = %+v\n", v.Subject.CommonName)
	}
	if err != nil {
		return nil, err
	}
	return res, nil
}

// HTTPPost post service json data
func HTTPPost(url string, data []byte, h map[string]string) (*http.Response, error) {
	// create a new request
	req, _ := http.NewRequest("POST", url, bytes.NewBuffer(data))
	req.Header.Set("User-Agent", "epazote")
	req.Header.Set("Content-Type", "application/json")

	// set custom headers on request
	if h != nil {
		for k, v := range h {
			req.Header.Set(k, v)
		}
	}

	client := &http.Client{}

	res, err := client.Do(req)
	if err != nil {
		return nil, err
	}

	return res, nil
}

// IsURL https://github.com/asaskevich/govalidator/blob/master/validator.go#L44
func IsURL(str string) bool {
	if str == "" || len(str) >= 2083 || len(str) <= 3 || strings.HasPrefix(str, ".") {
		return false
	}
	u, err := url.Parse(str)
	if err != nil {
		return false
	}
	if strings.HasPrefix(u.Host, ".") {
		return false
	}
	if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
		return false
	}
	return rxURL.MatchString(str)
}
<|endoftext|>


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

// Package gcp implements the user service upspin.User on the Google Cloud Platform (GCP).
package gcp

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

	"upspin.io/bind"
	gcpCloud "upspin.io/cloud/gcp"
	"upspin.io/log"
	"upspin.io/path"
	"upspin.io/upspin"
)

// Configuration options for this package.
const (
	// ConfigProjectID specifies which GCP project to use for talking to GCP.
	// If not specified, "upspin" is used.
	ConfigProjectID = "gcpProjectId"

	// ConfigBucketName specifies which GCS bucket to store data in.
	// If not specified, "g-upspin-store" is used.
	ConfigBucketName = "gcpBucketName"
)

// user is the implementation of the User Service on GCP.
type user struct {
	context     upspin.Context
	endpoint    upspin.Endpoint
	cloudClient gcpCloud.GCP
}

var _ upspin.User = (*user)(nil)

// userEntry stores all known information for a given user. The fields
// are exported because JSON parsing needs access to them.
type userEntry struct {
	User      upspin.UserName    // User's email address (e.g. bob@bar.com).
	Keys      []upspin.PublicKey // Known keys for the user.
	Endpoints []upspin.Endpoint  // Known endpoints for the user's directory entry.
}

const (
	minKeyLen = 12
)

var (
	errKeyTooShort     = errors.New("key length too short")
	errInvalidUserName = errors.New("invalid user name format")
)

var (
	mu       sync.Mutex // protects fields below
	refCount uint64
)

func isNotFound(err error) bool {
	if err == nil {
		return false
	}
	return strings.Contains(strings.ToLower(err.Error()), "not found")
}

func isKeyInSlice(key upspin.PublicKey, slice []upspin.PublicKey) bool {
	for _, k := range slice {
		if key == k {
			return true
		}
	}
	return false
}

// AddKey adds a new public key for a user.
// TODO: this is not used yet, but useful in the future and was supported by the HTTP RESTful user server, so keeping it
// around for re-using later.
func (u *user) AddKey(userName upspin.UserName, key upspin.PublicKey) error {
	// Validate user name
	_, err := path.Parse(upspin.PathName(userName) + "/")
	if err != nil {
		return errInvalidUserName
	}
	if len(key) < minKeyLen {
		return errKeyTooShort
	}

	// Appends to the current user entry, if any.
	ue, err := u.fetchUserEntry(userName)
	if err != nil {
		// If this is a Not Found error, then allocate a new userEntry and continue.
		if isNotFound(err) {
			log.Printf("User %q not found on GCP, adding new one", userName)
			ue = &userEntry{
				User: upspin.UserName(userName),
				Keys: make([]upspin.PublicKey, 0, 1),
			}
		} else {
			return err
		}
	}
	// Check that the key is not already there.
	if !isKeyInSlice(key, ue.Keys) {
		// Place key at head of slice to indicate higher priority.
		ue.Keys = append([]upspin.PublicKey{key}, ue.Keys...)
		err = u.putUserEntry(userName, ue)
		if err != nil {
			return err
		}
	}
	log.Printf("Added key %s for user %v\n", key, userName)
	return nil
}

// AddRoot adds a new root endpoint for a user.
// TODO: this is not used yet, but useful in the future and was supported by the HTTP RESTful user server, so keeping it
// around for re-using later.
func (u *user) AddRoot(userName upspin.UserName, endpoint upspin.Endpoint) error {
	// Validate user name
	_, err := path.Parse(upspin.PathName(userName) + "/")
	if err != nil {
		return errInvalidUserName
	}

	// Get the user entry from GCP.
	ue, err := u.fetchUserEntry(userName)
	if err != nil {
		// If this is a Not Found error, then allocate a new userEntry and continue.
		if isNotFound(err) {
			log.Printf("User %q not found on GCP, adding new one", userName)
			ue = &userEntry{
				User:      upspin.UserName(userName),
				Endpoints: make([]upspin.Endpoint, 0, 1),
			}
		} else {
			return err
		}
	}
	// Place the endpoint at the head of the slice to indicate higher priority.
	ue.Endpoints = append([]upspin.Endpoint{endpoint}, ue.Endpoints...)
	err = u.putUserEntry(userName, ue)
	if err != nil {
		return err
	}
	log.Printf("Added root %v for user %v", endpoint, userName)
	return nil
}

// Lookup implements upspin.User.
func (u *user) Lookup(userName upspin.UserName) ([]upspin.Endpoint, []upspin.PublicKey, error) {
	// Validate user name
	_, err := path.Parse(upspin.PathName(userName) + "/")
	if err != nil {
		return nil, nil, errInvalidUserName
	}
	// Get the user entry from GCP.
	ue, err := u.fetchUserEntry(userName)
	if err != nil {
		return nil, nil, err
	}
	return ue.Endpoints, ue.Keys, nil
}

// fetchUserEntry reads the user entry for a given user from permanent storage on GCP.
func (u *user) fetchUserEntry(userName upspin.UserName) (*userEntry, error) {
	// Get the user entry from GCP
	log.Printf("Going to get user entry on GCP for user %s", userName)
	buf, err := u.cloudClient.Download(string(userName))
	if err != nil {
		log.Printf("Error downloading user entry for %q: %q", userName, err)
		return nil, err
	}
	// Now convert it to a userEntry
	var ue userEntry
	err = json.Unmarshal(buf, &ue)
	if err != nil {
		return nil, err
	}
	log.Printf("Fetched user entry for %s", userName)
	return &ue, nil
}

// putUserEntry writes the user entry for a user to permanent storage on GCP.
func (u *user) putUserEntry(userName upspin.UserName, userEntry *userEntry) error {
	if userEntry == nil {
		return errors.New("nil userEntry")
	}
	jsonBuf, err := json.Marshal(userEntry)
	if err != nil {
		return fmt.Errorf("conversion to JSON failed: %v", err)
	}
	_, err = u.cloudClient.Put(string(userName), jsonBuf)
	return err
}

// Configure configures an instance of the user service.
// Required configuration options are listed at the package comments.
func (u *user) Configure(options ...string) error {
	// These are defaults that only make sense for those running upspin.io.
	bucketName := "g-upspin-store"
	projectID := "upspin"
	for _, option := range options {
		opts := strings.Split(option, "=")
		if len(opts) != 2 {
			return fmt.Errorf("invalid option format: %q", option)
		}
		switch opts[0] {
		case ConfigBucketName:
			bucketName = opts[1]
		case ConfigProjectID:
			projectID = opts[1]
		default:
			return fmt.Errorf("invalid configuration option: %q", opts[0])
		}
	}

	u.cloudClient = gcpCloud.New(projectID, bucketName, gcpCloud.BucketOwnerFullCtrl)
	log.Debug.Printf("Configured GCP user: %v", options)
	return nil
}

// isServiceConfigured reports whether the user service has been configured via a Configure call.
func (u *user) isServiceConfigured() bool {
	return u.cloudClient != nil && u.context.UserName != ""
}

// Dial implements upspin.Service.
func (u *user) Dial(context *upspin.Context, e upspin.Endpoint) (upspin.Service, error) {
	if e.Transport != upspin.GCP {
		return nil, errors.New("user gcp: unrecognized transport")
	}
	mu.Lock()
	defer mu.Unlock()

	refCount++
	if refCount == 0 {
		// This is virtually impossible to happen. One will run out of memory before this happens.
		// It means the ref count wrapped around and thus we can't handle another instance. Fail.
		refCount--
		return nil, errors.New("user gcp: internal error: refCount wrapped around")
	}

	this := *u              // Clone ourselves.
	this.context = *context // Make a copy of the context, to prevent changes.
	this.endpoint = e
	return &this, nil
}

// Ping implements upspin.Service.
func (u *user) Ping() bool {
	return true
}

// Close implements upspin.Service.
func (u *user) Close() {
	mu.Lock()
	defer mu.Unlock()

	// Clean up this instance
	u.context.UserName = "" // ensure we get an error in subsequent calls.

	refCount--
	if refCount == 0 {
		u.cloudClient = nil
		// Do any other global clean ups here.
	}
}

// Authenticate implements upspin.Service.
func (u *user) Authenticate(*upspin.Context) error {
	// Authentication is not dealt here. It happens at other layers.
	return nil
}

// Endpoint implements upspin.Service.
func (u *user) Endpoint() upspin.Endpoint {
	return u.endpoint
}

func init() {
	bind.RegisterUser(upspin.GCP, &user{})
}
<commit_msg>users/gcp: convert to new errors package<commit_after>// Copyright 2016 The Upspin Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package gcp implements the user service upspin.User on the Google Cloud Platform (GCP).
package gcp

import (
	"encoding/json"
	"strings"
	"sync"

	"upspin.io/bind"
	gcpCloud "upspin.io/cloud/gcp"
	"upspin.io/errors"
	"upspin.io/log"
	"upspin.io/path"
	"upspin.io/upspin"
)

// Configuration options for this package.
const (
	// ConfigProjectID specifies which GCP project to use for talking to GCP.
	// If not specified, "upspin" is used.
	ConfigProjectID = "gcpProjectId"

	// ConfigBucketName specifies which GCS bucket to store data in.
	// If not specified, "g-upspin-store" is used.
	ConfigBucketName = "gcpBucketName"
)

// user is the implementation of the User Service on GCP.
type user struct {
	context     upspin.Context
	endpoint    upspin.Endpoint
	cloudClient gcpCloud.GCP
}

var _ upspin.User = (*user)(nil)

// userEntry stores all known information for a given user. The fields
// are exported because JSON parsing needs access to them.
type userEntry struct {
	User      upspin.UserName    // User's email address (e.g. bob@bar.com).
	Keys      []upspin.PublicKey // Known keys for the user.
	Endpoints []upspin.Endpoint  // Known endpoints for the user's directory entry.
}

const (
	minKeyLen = 12
)

var (
	errKeyTooShort     = errors.E(errors.Invalid, errors.Str("key length too short"))
	errInvalidUserName = errors.E(errors.Invalid, errors.Str("invalid user name format"))
)

var (
	mu       sync.Mutex // protects fields below
	refCount uint64
)

func isNotFound(err error) bool {
	if err == nil {
		return false
	}
	return strings.Contains(strings.ToLower(err.Error()), "not found")
}

func isKeyInSlice(key upspin.PublicKey, slice []upspin.PublicKey) bool {
	for _, k := range slice {
		if key == k {
			return true
		}
	}
	return false
}

// AddKey adds a new public key for a user.
// TODO: this is not used yet, but useful in the future and was supported by the HTTP RESTful user server, so keeping it
// around for re-using later.
func (u *user) AddKey(userName upspin.UserName, key upspin.PublicKey) error {
	const AddKey = "AddKey"
	// Validate user name
	_, err := path.Parse(upspin.PathName(userName) + "/")
	if err != nil {
		return errors.E(AddKey, userName, errInvalidUserName)
	}
	if len(key) < minKeyLen {
		return errors.E(AddKey, userName, errKeyTooShort)
	}

	// Appends to the current user entry, if any.
	ue, err := u.fetchUserEntry(AddKey, userName)
	if err != nil {
		// If this is a Not Found error, then allocate a new userEntry and continue.
		if isNotFound(err) {
			log.Printf("User %q not found on GCP, adding new one", userName)
			ue = &userEntry{
				User: upspin.UserName(userName),
				Keys: make([]upspin.PublicKey, 0, 1),
			}
		} else {
			return err
		}
	}
	// Check that the key is not already there.
	if !isKeyInSlice(key, ue.Keys) {
		// Place key at head of slice to indicate higher priority.
		ue.Keys = append([]upspin.PublicKey{key}, ue.Keys...)
		err = u.putUserEntry(AddKey, userName, ue)
		if err != nil {
			return err
		}
	}
	log.Printf("Added key %s for user %v\n", key, userName)
	return nil
}

// AddRoot adds a new root endpoint for a user.
// TODO: this is not used yet, but useful in the future and was supported by the HTTP RESTful user server, so keeping it
// around for re-using later.
func (u *user) AddRoot(userName upspin.UserName, endpoint upspin.Endpoint) error {
	const AddRoot = "AddRoot"
	// Validate user name
	_, err := path.Parse(upspin.PathName(userName) + "/")
	if err != nil {
		return errors.E(AddRoot, userName, errInvalidUserName)
	}

	// Get the user entry from GCP.
	ue, err := u.fetchUserEntry(AddRoot, userName)
	if err != nil {
		// If this is a Not Found error, then allocate a new userEntry and continue.
		if isNotFound(err) {
			log.Printf("User %q not found on GCP, adding new one", userName)
			ue = &userEntry{
				User:      upspin.UserName(userName),
				Endpoints: make([]upspin.Endpoint, 0, 1),
			}
		} else {
			return err
		}
	}
	// Place the endpoint at the head of the slice to indicate higher priority.
	ue.Endpoints = append([]upspin.Endpoint{endpoint}, ue.Endpoints...)
	err = u.putUserEntry(AddRoot, userName, ue)
	if err != nil {
		return err
	}
	log.Printf("Added root %v for user %v", endpoint, userName)
	return nil
}

// Lookup implements upspin.User.
func (u *user) Lookup(userName upspin.UserName) ([]upspin.Endpoint, []upspin.PublicKey, error) {
	const Lookup = "Lookup"
	// Validate user name
	_, err := path.Parse(upspin.PathName(userName) + "/")
	if err != nil {
		return nil, nil, errors.E(Lookup, userName, errInvalidUserName)
	}
	// Get the user entry from GCP.
	ue, err := u.fetchUserEntry(Lookup, userName)
	if err != nil {
		return nil, nil, err
	}
	return ue.Endpoints, ue.Keys, nil
}

// fetchUserEntry reads the user entry for a given user from permanent storage on GCP.
func (u *user) fetchUserEntry(op string, userName upspin.UserName) (*userEntry, error) {
	// Get the user entry from GCP
	log.Printf("Going to get user entry on GCP for user %s", userName)
	buf, err := u.cloudClient.Download(string(userName))
	if err != nil {
		log.Printf("Error downloading user entry for %q: %q", userName, err)
		return nil, errors.E(op, userName, errors.NotExist, err)
	}
	// Now convert it to a userEntry
	var ue userEntry
	err = json.Unmarshal(buf, &ue)
	if err != nil {
		return nil, errors.E(op, userName, errors.IO, err)
	}
	log.Printf("Fetched user entry for %s", userName)
	return &ue, nil
}

// putUserEntry writes the user entry for a user to permanent storage on GCP.
func (u *user) putUserEntry(op string, userName upspin.UserName, userEntry *userEntry) error {
	if userEntry == nil {
		return errors.E(op, errors.Invalid, userName, errors.Str("nil userEntry"))
	}
	jsonBuf, err := json.Marshal(userEntry)
	if err != nil {
		return errors.E(op, errors.Invalid, userName, errors.Errorf("conversion to JSON failed: %v", err))
	}
	_, err = u.cloudClient.Put(string(userName), jsonBuf)
	if err != nil {
		return errors.E(op, userName, err)
	}
	return nil
}

// Configure configures an instance of the user service.
// Required configuration options are listed at the package comments.
func (u *user) Configure(options ...string) error {
	const Configure = "Configure"
	// These are defaults that only make sense for those running upspin.io.
	bucketName := "g-upspin-store"
	projectID := "upspin"
	for _, option := range options {
		opts := strings.Split(option, "=")
		if len(opts) != 2 {
			return errors.E(Configure, errors.Invalid, errors.Errorf("invalid option format: %q", option))
		}
		switch opts[0] {
		case ConfigBucketName:
			bucketName = opts[1]
		case ConfigProjectID:
			projectID = opts[1]
		default:
			return errors.E(Configure, errors.Invalid, errors.Errorf("invalid configuration option: %q", opts[0]))
		}
	}

	u.cloudClient = gcpCloud.New(projectID, bucketName, gcpCloud.BucketOwnerFullCtrl)
	log.Debug.Printf("Configured GCP user: %v", options)
	return nil
}

// isServiceConfigured reports whether the user service has been configured via a Configure call.
func (u *user) isServiceConfigured() bool {
	return u.cloudClient != nil && u.context.UserName != ""
}

// Dial implements upspin.Service.
func (u *user) Dial(context *upspin.Context, e upspin.Endpoint) (upspin.Service, error) {
	if e.Transport != upspin.GCP {
		return nil, errors.E("Dial", errors.Invalid, errors.Str("unrecognized transport"))
	}
	mu.Lock()
	defer mu.Unlock()

	refCount++
	if refCount == 0 {
		// This is virtually impossible to happen. One will run out of memory before this happens.
		// It means the ref count wrapped around and thus we can't handle another instance. Fail.
		refCount--
		return nil, errors.E("Dial", errors.Str("user gcp: internal error: refCount wrapped around"))
	}

	this := *u              // Clone ourselves.
	this.context = *context // Make a copy of the context, to prevent changes.
	this.endpoint = e
	return &this, nil
}

// Ping implements upspin.Service.
func (u *user) Ping() bool {
	return true
}

// Close implements upspin.Service.
func (u *user) Close() {
	mu.Lock()
	defer mu.Unlock()

	// Clean up this instance
	u.context.UserName = "" // ensure we get an error in subsequent calls.

	refCount--
	if refCount == 0 {
		u.cloudClient = nil
		// Do any other global clean ups here.
	}
}

// Authenticate implements upspin.Service.
func (u *user) Authenticate(*upspin.Context) error {
	// Authentication is not dealt here. It happens at other layers.
	return nil
}

// Endpoint implements upspin.Service.
func (u *user) Endpoint() upspin.Endpoint {
	return u.endpoint
}

func init() {
	bind.RegisterUser(upspin.GCP, &user{})
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io"
	"log"
	"math"
	"os"

	"text/template"

	"github.com/dustin/go-nmea"
)

const kmlHeader = `<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"
          xmlns:gx="http://www.google.com/kml/ext/2.2">

<Folder>`
const kmlPoint = `<!-- {{ .D }} -->
<Placemark>
  <TimeStamp>{{.TS}}</TimeStamp>
  <Point><coordinates>{{.Lon}},{{.Lat}}</coordinates></Point>
  <gx:flyToMode>smooth</gx:flyToMode>
</Placemark>
`
const kmlFooter = `</Folder></kml>`

const tsFormat = "2006-01-02T15:04:05Z"

var (
	minDist = flag.Int("minDist", 1000, "minimum distance (meters) between points")

	tmpl = template.Must(template.New("").Parse(kmlPoint))
)

type errRememberer struct {
	w   io.WriteCloser
	err error
}

func (e errRememberer) Write(b []byte) (int, error) {
	if e.err != nil {
		return 0, e.err
	}

	var n int
	n, e.err = e.w.Write(b)

	return n, e.err
}

func (e errRememberer) Close() error {
	if e.err != nil {
		return e.err
	}
	return e.w.Close()
}

type kmlWriter struct {
	w          errRememberer
	plat, plon float64
}

func (k *kmlWriter) HandleRMC(m nmea.RMC) {
	Δλ := distance(m.Longitude, m.Latitude, k.plon, k.plat)
	if Δλ > float64(*minDist) {
		tmpl.Execute(k.w, struct {
			Lon, Lat float64
			TS       string
			D        float64
		}{m.Longitude, m.Latitude, m.Timestamp.Format(tsFormat), Δλ})
		k.plat = m.Latitude
		k.plon = m.Longitude
	} else {
		log.Printf("%v,%v is too close to %v,%v (%v)", m.Longitude, m.Latitude, k.plon, k.plat, Δλ)
	}
}

func (k kmlWriter) Init() error {
	k.w.Write([]byte(kmlHeader))
	return k.w.err
}

func (k kmlWriter) Close() error {
	k.w.Write([]byte(kmlFooter))
	return k.w.Close()
}

func d2r(d float64) float64 {
	return d * math.Pi / 180.0
}

func distance(lon1, lat1, lon2, lat2 float64) float64 {
	φ1 := d2r(lat1)
	φ2 := d2r(lat2)
	Δφ := d2r(lat2 - lat1)
	Δλ := d2r(lon2 - lon1)

	a := math.Sin(Δφ/2)*math.Sin(Δφ/2) +
		math.Cos(φ1)*math.Cos(φ2)*
			math.Sin(Δλ/2)*math.Sin(Δλ/2)
	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))

	rv := 6371000 * c
	log.Printf("Distance from %v,%v to %v,%v is %v", lon1, lat1, lon2, lat2, rv)
	return rv
}

func main() {
	flag.Parse()
	h := &kmlWriter{w: errRememberer{w: os.Stdout}}
	h.Init()
	err := nmea.Process(os.Stdin, h, func(s string, err error) error {
		if s != "" && err != nil {
			log.Printf("On %q: %v", s, err)
		}
		return nil
	})

	if err != nil {
		log.Fatalf("Error processing stuff: %v", err)
	}
	h.Close()
}
<commit_msg>Don't log all the dumped things.<commit_after>package main

import (
	"flag"
	"io"
	"log"
	"math"
	"os"

	"text/template"

	"github.com/dustin/go-nmea"
)

const kmlHeader = `<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2"
          xmlns:gx="http://www.google.com/kml/ext/2.2">

<Folder>`
const kmlPoint = `<!-- {{ .D }} -->
<Placemark>
  <TimeStamp>{{.TS}}</TimeStamp>
  <Point><coordinates>{{.Lon}},{{.Lat}}</coordinates></Point>
  <gx:flyToMode>smooth</gx:flyToMode>
</Placemark>
`
const kmlFooter = `</Folder></kml>`

const tsFormat = "2006-01-02T15:04:05Z"

var (
	minDist = flag.Int("minDist", 1000, "minimum distance (meters) between points")

	tmpl = template.Must(template.New("").Parse(kmlPoint))
)

type errRememberer struct {
	w   io.WriteCloser
	err error
}

func (e errRememberer) Write(b []byte) (int, error) {
	if e.err != nil {
		return 0, e.err
	}

	var n int
	n, e.err = e.w.Write(b)

	return n, e.err
}

func (e errRememberer) Close() error {
	if e.err != nil {
		return e.err
	}
	return e.w.Close()
}

type kmlWriter struct {
	w          errRememberer
	plat, plon float64
}

func (k *kmlWriter) HandleRMC(m nmea.RMC) {
	Δλ := distance(m.Longitude, m.Latitude, k.plon, k.plat)
	if Δλ > float64(*minDist) {
		tmpl.Execute(k.w, struct {
			Lon, Lat float64
			TS       string
			D        float64
		}{m.Longitude, m.Latitude, m.Timestamp.Format(tsFormat), Δλ})
		k.plat = m.Latitude
		k.plon = m.Longitude
	}
}

func (k kmlWriter) Init() error {
	k.w.Write([]byte(kmlHeader))
	return k.w.err
}

func (k kmlWriter) Close() error {
	k.w.Write([]byte(kmlFooter))
	return k.w.Close()
}

func d2r(d float64) float64 {
	return d * math.Pi / 180.0
}

func distance(lon1, lat1, lon2, lat2 float64) float64 {
	φ1 := d2r(lat1)
	φ2 := d2r(lat2)
	Δφ := d2r(lat2 - lat1)
	Δλ := d2r(lon2 - lon1)

	a := math.Sin(Δφ/2)*math.Sin(Δφ/2) +
		math.Cos(φ1)*math.Cos(φ2)*
			math.Sin(Δλ/2)*math.Sin(Δλ/2)
	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))

	rv := 6371000 * c
	log.Printf("Distance from %v,%v to %v,%v is %v", lon1, lat1, lon2, lat2, rv)
	return rv
}

func main() {
	flag.Parse()
	h := &kmlWriter{w: errRememberer{w: os.Stdout}}
	h.Init()
	err := nmea.Process(os.Stdin, h, func(s string, err error) error {
		if s != "" && err != nil {
			log.Printf("On %q: %v", s, err)
		}
		return nil
	})

	if err != nil {
		log.Fatalf("Error processing stuff: %v", err)
	}
	h.Close()
}
<|endoftext|>


<commit_before>// Copyright 2015 The Cockroach Authors.
//
// 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. See the AUTHORS file
// for names of contributors.
//
// Author: Vivek Menezes (vivek.menezes@gmail.com)

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"math/rand"
	"sync/atomic"
	"time"

	"github.com/cockroachdb/cockroach/client"
	"github.com/cockroachdb/cockroach/security"
	"github.com/cockroachdb/cockroach/security/securitytest"
	"github.com/cockroachdb/cockroach/server"
	"github.com/cockroachdb/cockroach/util/log"
)

var dbName = flag.String("db-name", "", "Name/URL of the distributed database backend.")
var useTransaction = flag.Bool("use-transaction", true, "Turn off to disable transaction.")

// These two flags configure a range of accounts over which the program functions.
var firstAccount = flag.Int("first-account", 0, "First account in the account range.")
var numAccounts = flag.Int("num-accounts", 1000, "Number of accounts in the account range.")

var numParallelTransfers = flag.Int("num-parallel-transfers", 100, "Number of parallel transfers.")

// Bank stores all the bank related state.
type Bank struct {
	db *client.DB
	// First account in the account range.
	firstAccount int
	// Total number of accounts.
	numAccounts  int
	numTransfers int32
}

// Account holds all the customers account information
type Account struct {
	Balance int64
}

func (a Account) encode() ([]byte, error) {
	return json.Marshal(a)
}

func (a *Account) decode(b []byte) error {
	return json.Unmarshal(b, a)
}

// Makes an id string from an id int.
func (bank *Bank) makeAccountID(id int) []byte {
	return []byte(fmt.Sprintf("%09d", bank.firstAccount+id))
}

// Read the balances in all the accounts and return them.
func (bank *Bank) sumAllAccounts() int64 {
	var result int64
	err := bank.db.Tx(func(tx *client.Tx) error {
		scan, err := tx.Scan(bank.makeAccountID(0), bank.makeAccountID(bank.numAccounts), int64(bank.numAccounts))
		if err != nil {
			return err
		}
		if len(scan.Rows) != bank.numAccounts {
			return fmt.Errorf("Could only read %d of %d rows of the database.\n", len(scan.Rows), bank.numAccounts)
		}
		// Sum up the balances.
		for i := 0; i < bank.numAccounts; i++ {
			account := &Account{}
			err := account.decode(scan.Rows[i].ValueBytes())
			if err != nil {
				return err
			}
			// fmt.Printf("Account %d contains %d$\n", bank.firstAccount+i, account.Balance)
			result += account.Balance
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
	return result
}

// continuouslyTransferMoney() keeps moving random amounts between
// random accounts.
func (bank *Bank) continuousMoneyTransfer(cash int64) {
	for {
		from := bank.makeAccountID(rand.Intn(bank.numAccounts))
		to := bank.makeAccountID(rand.Intn(bank.numAccounts))
		// Continue when from == to
		if bytes.Equal(from, to) {
			continue
		}
		exchangeAmount := rand.Int63n(cash)
		// transferMoney transfers exchangeAmount between the two accounts
		transferMoney := func(runner client.Runner) error {
			batchRead := &client.Batch{}
			batchRead.Get(from, to)
			if err := runner.Run(batchRead); err != nil {
				return err
			}
			// Read from value.
			fromAccount := &Account{}
			err := fromAccount.decode(batchRead.Results[0].Rows[0].ValueBytes())
			if err != nil {
				return err
			}
			// Ensure there is enough cash.
			if fromAccount.Balance < exchangeAmount {
				return nil
			}
			// Read to value.
			toAccount := &Account{}
			errRead := toAccount.decode(batchRead.Results[0].Rows[1].ValueBytes())
			if errRead != nil {
				return errRead
			}
			// Update both accounts.
			batchWrite := &client.Batch{}
			fromAccount.Balance -= exchangeAmount
			toAccount.Balance += exchangeAmount
			if fromValue, err := fromAccount.encode(); err != nil {
				return err
			} else if toValue, err := toAccount.encode(); err != nil {
				return err
			} else {
				batchWrite.Put(from, fromValue).Put(to, toValue)
			}
			return runner.Run(batchWrite)
		}
		var err error
		if *useTransaction {
			err = bank.db.Tx(func(tx *client.Tx) error { return transferMoney(tx) })
		} else {
			err = transferMoney(bank.db)
		}
		if err != nil {
			log.Fatal(err)
		}
		atomic.AddInt32(&bank.numTransfers, 1)
	}
}

// Initialize all the bank accounts with cash.
// When multiple instances of the bank app are running,
// only one gets to initialize the bank.
func (bank *Bank) initBankAccounts(cash int64) {
	if err := bank.db.Tx(func(tx *client.Tx) error {
		// Check if the accounts have been initialized by another instance
		if scan, err := tx.Scan(bank.makeAccountID(0), bank.makeAccountID(bank.numAccounts), int64(bank.numAccounts)); err != nil {
			return err
		} else if len(scan.Rows) == bank.numAccounts {
			log.Warning("accounts have already been initialized")
			return nil
		} else if len(scan.Rows) > 0 {
			// TODO(vivek): recover from this error
			return fmt.Errorf("%d of %d accounts of the database are initialized", len(scan.Rows), bank.numAccounts)
		}
		// Let's initialize all the accounts
		batch := &client.Batch{}
		account := Account{Balance: cash}
		value, err := account.encode()
		if err != nil {
			return err
		}
		for i := 0; i < bank.numAccounts; i++ {
			batch.Put(bank.makeAccountID(i), value)
		}
		return tx.Run(batch)
	}); err != nil {
		log.Fatal(err)
	}
	log.Info("done initializing all accounts")
}

func (bank *Bank) periodicallyCheckBalances(initCash int64) {
	for {
		// Sleep for a bit to allow money transfers to happen in the background.
		time.Sleep(time.Second)
		fmt.Printf("%d transfers were executed.\n\n", bank.numTransfers)
		// Check that all the money is accounted for.
		totalAmount := bank.sumAllAccounts()
		if totalAmount != int64(bank.numAccounts)*initCash {
			log.Fatalf("\nTotal cash in the bank = %d.\n", totalAmount)
		}
		fmt.Printf("\nThe bank is in good order\n\n")
	}
}

func main() {
	fmt.Printf("A simple program that keeps moving money between bank accounts.\n\n")
	flag.Parse()
	if !*useTransaction {
		fmt.Printf("Use of a transaction has been disabled.\n")
	}
	// Initialize the bank.
	var bank Bank
	bank.firstAccount = *firstAccount
	bank.numAccounts = *numAccounts
	if *dbName == "" {
		// Run a test cockroach instance to represent the bank.
		security.SetReadFileFn(securitytest.Asset)
		serv := server.StartTestServer(nil)
		defer serv.Stop()
		*dbName = "https://root@" + serv.ServingAddr() + "?certs=test_certs"
	}
	// Create a database handle
	db, err := client.Open(*dbName)
	if err != nil {
		log.Fatal(err)
	}
	bank.db = db
	// Initialize all the bank accounts.
	const initCash = 1000
	bank.initBankAccounts(initCash)

	// Start all the money transfer routines.
	for i := 0; i < *numParallelTransfers; i++ {
		// Keep transferring upto 10% of initCash between accounts.
		go bank.continuousMoneyTransfer(initCash / 10)
	}

	bank.periodicallyCheckBalances(initCash)
}
<commit_msg>Some changes and addition of performance metrics output to bank example<commit_after>// Copyright 2015 The Cockroach Authors.
//
// 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. See the AUTHORS file
// for names of contributors.
//
// Author: Vivek Menezes (vivek.menezes@gmail.com)

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"math/rand"
	"os"
	"sync/atomic"
	"time"

	"github.com/cockroachdb/cockroach/client"
	"github.com/cockroachdb/cockroach/security"
	"github.com/cockroachdb/cockroach/security/securitytest"
	"github.com/cockroachdb/cockroach/server"
	"github.com/cockroachdb/cockroach/util/log"
)

var dbName = flag.String("db-name", "", "Name/URL of the distributed database backend.")
var useTransaction = flag.Bool("use-transaction", true, "Turn off to disable transaction.")

// These two flags configure a range of accounts over which the program functions.
var firstAccount = flag.Int("first-account", 0, "First account in the account range.")
var numAccounts = flag.Int("num-accounts", 1000, "Number of accounts in the account range.")

var numParallelTransfers = flag.Int("num-parallel-transfers", 100, "Number of parallel transfers.")

// Bank stores all the bank related state.
type Bank struct {
	db *client.DB
	// First account in the account range.
	firstAccount int
	// Total number of accounts.
	numAccounts  int
	numTransfers int32
}

// Account holds all the customers account information
type Account struct {
	Balance int64
}

func (a Account) encode() ([]byte, error) {
	return json.Marshal(a)
}

func (a *Account) decode(b []byte) error {
	return json.Unmarshal(b, a)
}

// Makes an id string from an id int.
func (bank *Bank) makeAccountID(id int) []byte {
	return []byte(fmt.Sprintf("%09d", bank.firstAccount+id))
}

// Read the balances in all the accounts and return them.
func (bank *Bank) sumAllAccounts() int64 {
	var result int64
	err := bank.db.Tx(func(tx *client.Tx) error {
		scan, err := tx.Scan(bank.makeAccountID(0), bank.makeAccountID(bank.numAccounts), int64(bank.numAccounts))
		if err != nil {
			return err
		}
		if len(scan.Rows) != bank.numAccounts {
			return fmt.Errorf("Could only read %d of %d rows of the database.\n", len(scan.Rows), bank.numAccounts)
		}
		// Sum up the balances.
		for i := 0; i < bank.numAccounts; i++ {
			account := &Account{}
			err := account.decode(scan.Rows[i].ValueBytes())
			if err != nil {
				return err
			}
			// fmt.Printf("Account %d contains %d$\n", bank.firstAccount+i, account.Balance)
			result += account.Balance
		}
		return nil
	})
	if err != nil {
		log.Fatal(err)
	}
	return result
}

// continuouslyTransferMoney() keeps moving random amounts between
// random accounts.
func (bank *Bank) continuouslyTransferMoney(cash int64) {
	for {
		from := bank.makeAccountID(rand.Intn(bank.numAccounts))
		to := bank.makeAccountID(rand.Intn(bank.numAccounts))
		// Continue when from == to.
		if bytes.Equal(from, to) {
			continue
		}
		exchangeAmount := rand.Int63n(cash)
		// transferMoney transfers exchangeAmount between the two accounts
		transferMoney := func(runner client.Runner) error {
			batchRead := &client.Batch{}
			batchRead.Get(from, to)
			if err := runner.Run(batchRead); err != nil {
				return err
			}
			// Read from value.
			fromAccount := &Account{}
			err := fromAccount.decode(batchRead.Results[0].Rows[0].ValueBytes())
			if err != nil {
				return err
			}
			// Ensure there is enough cash.
			if fromAccount.Balance < exchangeAmount {
				return nil
			}
			// Read to value.
			toAccount := &Account{}
			errRead := toAccount.decode(batchRead.Results[0].Rows[1].ValueBytes())
			if errRead != nil {
				return errRead
			}
			// Update both accounts.
			batchWrite := &client.Batch{}
			fromAccount.Balance -= exchangeAmount
			toAccount.Balance += exchangeAmount
			if fromValue, err := fromAccount.encode(); err != nil {
				return err
			} else if toValue, err := toAccount.encode(); err != nil {
				return err
			} else {
				batchWrite.Put(from, fromValue).Put(to, toValue)
			}
			return runner.Run(batchWrite)
		}
		var err error
		if *useTransaction {
			err = bank.db.Tx(func(tx *client.Tx) error { return transferMoney(tx) })
		} else {
			err = transferMoney(bank.db)
		}
		if err != nil {
			log.Fatal(err)
		}
		atomic.AddInt32(&bank.numTransfers, 1)
	}
}

// Initialize all the bank accounts with cash.  When multiple
// instances of the bank app are running, only one gets to initialize
// the bank.
func (bank *Bank) initBankAccounts(cash int64) {
	if err := bank.db.Tx(func(tx *client.Tx) error {
		// Check if the accounts have been initialized by another instance.
		scan, err := tx.Scan(bank.makeAccountID(0), bank.makeAccountID(bank.numAccounts), int64(bank.numAccounts))
		if err != nil {
			return err
		}
		// Determine existing accounts.
		accts := map[string]struct{}{}
		for i := range scan.Rows {
			accts[string(scan.Rows[i].Key)] = struct{}{}
		}
		// Let's initialize all the accounts.
		batch := &client.Batch{}
		account := Account{Balance: cash}
		value, err := account.encode()
		if err != nil {
			return err
		}
		for i := 0; i < bank.numAccounts; i++ {
			id := bank.makeAccountID(i)
			if _, ok := accts[string(id)]; !ok {
				batch.Put(id, value)
			}
		}
		return tx.Run(batch)
	}); err != nil {
		log.Fatal(err)
	}
	log.Info("done initializing all accounts")
}

func (bank *Bank) periodicallyCheckBalances(initCash int64) {
	var lastNumTransfers int32
	for {
		// Sleep for a bit to allow money transfers to happen in the background.
		time.Sleep(time.Second)
		numTransfers := atomic.LoadInt32(&bank.numTransfers)
		fmt.Printf("%d transfers were executed at %d/second.\n", bank.numTransfers, numTransfers-lastNumTransfers)
		lastNumTransfers = numTransfers
		// Check that all the money is accounted for.
		totalAmount := bank.sumAllAccounts()
		if totalAmount != int64(bank.numAccounts)*initCash {
			log.Fatalf("\nTotal cash in the bank = %d.\n", totalAmount)
		}
		fmt.Printf("The bank is in good order.\n")
	}
}

func main() {
	fmt.Printf("A simple program that keeps moving money between bank accounts.\n\n")
	flag.Parse()
	if *numAccounts < 2 {
		fmt.Fprintf(os.Stderr, "At least two accounts are required to transfer money.\n")
		os.Exit(1)
	}
	if *numParallelTransfers < 1 {
		fmt.Fprintf(os.Stderr, "At least one transfer routine must be active.\n")
		os.Exit(1)
	}
	if !*useTransaction {
		fmt.Printf("Use of transactions has been disabled.\n")
	}
	// Initialize the bank.
	var bank Bank
	bank.firstAccount = *firstAccount
	bank.numAccounts = *numAccounts
	if *dbName == "" {
		// Run a test cockroach instance to represent the bank.
		security.SetReadFileFn(securitytest.Asset)
		serv := server.StartTestServer(nil)
		defer serv.Stop()
		*dbName = "https://root@" + serv.ServingAddr() + "?certs=test_certs"
	}
	// Create a database handle.
	db, err := client.Open(*dbName)
	if err != nil {
		log.Fatal(err)
	}
	bank.db = db
	// Initialize all the bank accounts.
	const initCash = 1000
	bank.initBankAccounts(initCash)

	// Start all the money transfer routines.
	for i := 0; i < *numParallelTransfers; i++ {
		// Keep transferring upto 10% of initCash between accounts.
		go bank.continuouslyTransferMoney(initCash / 10)
	}

	bank.periodicallyCheckBalances(initCash)
}
<|endoftext|>


<commit_before>package wavelet

import (
	"testing"
	"strings"
)

func TestBasic(t *testing.T) {
	var str string = "Sing, Goddess, of the wrath of Achilles"

	ab := alphabet(str)
	chars := strings.Split(str, "")

	wt := NewWaveletTree(ab, chars)

	var newstr string

	for x := range wt.Iter() {
		newstr += x
	}

	if str != newstr {
		t.Error("Couldn't rebuild input!", str, newstr)
	}
}

func BenchmarkNewWaveletTree(b *testing.B) {
	var str string = "As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed in his bed into a monstrous vermin."

	ab := alphabet(str)
	chars := strings.Split(str, "")

	for i := 0; i < b.N; i++ {
		NewWaveletTree(ab, chars)
	}
}

func BenchmarkIter(b *testing.B) {
	var str string = "Call me Ishmael."

	ab := alphabet(str)
	chars := strings.Split(str, "")

	wt := NewWaveletTree(ab, chars)

	for i := 0; i < b.N; i++ {
		var newstr string
		for x := range wt.Iter() {
			newstr += x
		}
	}
}
<commit_msg>adding test for missing alphabet chars<commit_after>package wavelet

import (
	"testing"
	"strings"
)

func TestBasic(t *testing.T) {
	var str string = "Sing, Goddess, of the wrath of Achilles"

	ab := alphabet(str)
	chars := strings.Split(str, "")

	wt := NewWaveletTree(ab, chars)

	var newstr string

	for x := range wt.Iter() {
		newstr += x
	}

	if str != newstr {
		t.Error("Couldn't rebuild input!", str, newstr)
	}
}

func TestMissingAlphaChars(t *testing.T) {
	var str string = "It was a pleasure to burn."

	ab := []string{"p", "l", "e", "a", "s", "u", "r", "e"}
	chars := strings.Split(str, "")

	wt := NewWaveletTree(ab, chars)

	var newstr string

	for x := range wt.Iter() {
		newstr += x
	}

	if "asapleasureur" != newstr {
		t.Error("Couldn't rebuild input!", str)
	}
}

func BenchmarkNewWaveletTree(b *testing.B) {
	var str string = "As Gregor Samsa awoke one morning from uneasy dreams he found himself transformed in his bed into a monstrous vermin."

	ab := alphabet(str)
	chars := strings.Split(str, "")

	for i := 0; i < b.N; i++ {
		NewWaveletTree(ab, chars)
	}
}

func BenchmarkIter(b *testing.B) {
	var str string = "Call me Ishmael."

	ab := alphabet(str)
	chars := strings.Split(str, "")

	wt := NewWaveletTree(ab, chars)

	for i := 0; i < b.N; i++ {
		var newstr string
		for x := range wt.Iter() {
			newstr += x
		}
	}
}
<|endoftext|>


<commit_before>package waiter

import (
	"time"

	"github.com/aws/aws-sdk-go/service/kinesisanalytics"
	"github.com/hashicorp/aws-sdk-go-base/tfawserr"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	iamwaiter "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/waiter"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

// ApplicationDeleted waits for an Application to return Deleted
func ApplicationDeleted(conn *kinesisanalytics.KinesisAnalytics, name string, timeout time.Duration) (*kinesisanalytics.ApplicationSummary, error) {
	stateConf := &resource.StateChangeConf{
		Pending: []string{kinesisanalytics.ApplicationStatusRunning, kinesisanalytics.ApplicationStatusDeleting},
		Target:  []string{},
		Refresh: ApplicationStatus(conn, name),
		Timeout: timeout,
	}

	outputRaw, err := stateConf.WaitForState()

	if v, ok := outputRaw.(*kinesisanalytics.ApplicationSummary); ok {
		return v, err
	}

	return nil, err
}

// IAMPropagation retries the specified function if the returned error indicates an IAM eventual consistency issue.
// If the retries time out the specified function is called one last time.
func IAMPropagation(f func() (interface{}, error)) (interface{}, error) {
	var output interface{}

	err := resource.Retry(iamwaiter.PropagationTimeout, func() *resource.RetryError {
		var err error

		output, err = f()

		// Kinesis Stream: https://github.com/terraform-providers/terraform-provider-aws/issues/7032
		if tfawserr.ErrMessageContains(err, kinesisanalytics.ErrCodeInvalidArgumentException, "Kinesis Analytics service doesn't have sufficient privileges") {
			return resource.RetryableError(err)
		}

		// Kinesis Firehose: https://github.com/terraform-providers/terraform-provider-aws/issues/7394
		if tfawserr.ErrMessageContains(err, kinesisanalytics.ErrCodeInvalidArgumentException, "Kinesis Analytics doesn't have sufficient privileges") {
			return resource.RetryableError(err)
		}

		// InvalidArgumentException: Given IAM role arn : arn:aws:iam::123456789012:role/xxx does not provide Invoke permissions on the Lambda resource : arn:aws:lambda:us-west-2:123456789012:function:yyy
		if tfawserr.ErrMessageContains(err, kinesisanalytics.ErrCodeInvalidArgumentException, "does not provide Invoke permissions on the Lambda resource") {
			return resource.RetryableError(err)
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return nil
	})

	if tfresource.TimedOut(err) {
		output, err = f()
	}

	if err != nil {
		return nil, err
	}

	return output, nil
}
<commit_msg>r/aws_kinesis_analytics_application: Update GH organization (#15859).<commit_after>package waiter

import (
	"time"

	"github.com/aws/aws-sdk-go/service/kinesisanalytics"
	"github.com/hashicorp/aws-sdk-go-base/tfawserr"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
	iamwaiter "github.com/terraform-providers/terraform-provider-aws/aws/internal/service/iam/waiter"
	"github.com/terraform-providers/terraform-provider-aws/aws/internal/tfresource"
)

// ApplicationDeleted waits for an Application to return Deleted
func ApplicationDeleted(conn *kinesisanalytics.KinesisAnalytics, name string, timeout time.Duration) (*kinesisanalytics.ApplicationSummary, error) {
	stateConf := &resource.StateChangeConf{
		Pending: []string{kinesisanalytics.ApplicationStatusRunning, kinesisanalytics.ApplicationStatusDeleting},
		Target:  []string{},
		Refresh: ApplicationStatus(conn, name),
		Timeout: timeout,
	}

	outputRaw, err := stateConf.WaitForState()

	if v, ok := outputRaw.(*kinesisanalytics.ApplicationSummary); ok {
		return v, err
	}

	return nil, err
}

// IAMPropagation retries the specified function if the returned error indicates an IAM eventual consistency issue.
// If the retries time out the specified function is called one last time.
func IAMPropagation(f func() (interface{}, error)) (interface{}, error) {
	var output interface{}

	err := resource.Retry(iamwaiter.PropagationTimeout, func() *resource.RetryError {
		var err error

		output, err = f()

		// Kinesis Stream: https://github.com/hashicorp/terraform-provider-aws/issues/7032
		if tfawserr.ErrMessageContains(err, kinesisanalytics.ErrCodeInvalidArgumentException, "Kinesis Analytics service doesn't have sufficient privileges") {
			return resource.RetryableError(err)
		}

		// Kinesis Firehose: https://github.com/hashicorp/terraform-provider-aws/issues/7394
		if tfawserr.ErrMessageContains(err, kinesisanalytics.ErrCodeInvalidArgumentException, "Kinesis Analytics doesn't have sufficient privileges") {
			return resource.RetryableError(err)
		}

		// InvalidArgumentException: Given IAM role arn : arn:aws:iam::123456789012:role/xxx does not provide Invoke permissions on the Lambda resource : arn:aws:lambda:us-west-2:123456789012:function:yyy
		if tfawserr.ErrMessageContains(err, kinesisanalytics.ErrCodeInvalidArgumentException, "does not provide Invoke permissions on the Lambda resource") {
			return resource.RetryableError(err)
		}

		if err != nil {
			return resource.NonRetryableError(err)
		}

		return nil
	})

	if tfresource.TimedOut(err) {
		output, err = f()
	}

	if err != nil {
		return nil, err
	}

	return output, nil
}
<|endoftext|>