<commit_before>/*
** Copyright [2013-2015] [Megam Systems]
**
** 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 docker

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

	"github.com/fsouza/go-dockerclient"
	"github.com/megamsys/libgo/log"
	"github.com/megamsys/libgo/db"
	"github.com/megamsys/megamd/global"
	"github.com/megamsys/megamd/provisioner"
	"github.com/megamsys/megamd/swarmc"
	"github.com/megamsys/seru/cmd"
	"github.com/megamsys/seru/cmd/seru"
	"github.com/tsuru/config"
)

type dockerProvisioner struct {
	cluster        *swarmc.Cluster
	storage        swarmc.Storage
	isDryMode      bool
}

var mainDockerProvisioner *dockerProvisioner

// Registers docker as provisioner in provisioner interface.
func Init() {
	mainDockerProvisioner = &dockerProvisioner{}
	provisioner.Register("docker", mainDockerProvisioner)
}

func (p *dockerProvisioner) initDockerCluster() error {
	var err error
	if p.storage == nil {
		p.storage, err = buildClusterStorage()
		if err != nil {
			return err
		}
	}

	var nodes []cluster.Node
	totalMemoryMetadata, _ := config.GetString("docker:scheduler:total-memory-metadata")
	maxUsedMemory, _ := config.GetFloat("docker:scheduler:max-used-memory")
	p.scheduler = &segregatedScheduler{
		maxMemoryRatio:      float32(maxUsedMemory),
		totalMemoryMetadata: totalMemoryMetadata,
		provisioner:         p,
	}
	p.cluster, err = cluster.New(p.scheduler, p.storage, nodes...)
	if err != nil {
		return err
	}
	return nil
}

func (p *dockerProvisioner) stopDryMode() {
	if p.isDryMode {
		p.cluster.StopDryMode()
	}
}

func (p *dockerProvisioner) dryMode(ignoredContainers []container) (*dockerProvisioner, error) {
	var err error
	overridenProvisioner := &dockerProvisioner{
		collectionName: "containers_dry_" + randomString(),
		isDryMode:      true,
	}
	containerIds := make([]string, len(ignoredContainers))
	for i := range ignoredContainers {
		containerIds[i] = ignoredContainers[i].ID
	}
	overridenProvisioner.scheduler = &segregatedScheduler{
		maxMemoryRatio:      p.scheduler.maxMemoryRatio,
		totalMemoryMetadata: p.scheduler.totalMemoryMetadata,
		provisioner:         overridenProvisioner,
		ignoredContainers:   containerIds,
	}
	overridenProvisioner.cluster, err = cluster.New(overridenProvisioner.scheduler, p.storage)
	if err != nil {
		return nil, err
	}
	overridenProvisioner.cluster.DryMode()
	containersToCopy, err := p.listAllContainers()
	if err != nil {
		return nil, err
	}
	coll := overridenProvisioner.collection()
	defer coll.Close()
	toInsert := make([]interface{}, len(containersToCopy))
	for i := range containersToCopy {
		toInsert[i] = containersToCopy[i]
	}
	if len(toInsert) > 0 {
		err = coll.Insert(toInsert...)
		if err != nil {
			return nil, err
		}
	}
	return overridenProvisioner, nil
}

func (p *dockerProvisioner) getCluster() *cluster.Cluster {
	if p.cluster == nil {
		panic("nil cluster")
	}
	return p.cluster
}

func (p *dockerProvisioner) Initialize() error {
	return p.initDockerCluster()
}

func (p *dockerProvisioner) StartupMessage() (string, error) {
	nodeList, err := p.getCluster().UnfilteredNodes()
	if err != nil {
		return "", err
	}
	out := """
	*-------------------------------------------------*
	| Megamswarm           /-+-fishing nodes for you. |
	*-------------------------------------------------*\n"""

	for _, node := range nodeList {
		out += fmt.Sprintf("    Docker node: %s\n", node.Address)
	}
	return out, nil
}

/*
* Create provisioner is called to launch docker containers by
* talking to swarm cluster. Common provisioner for both
* Baremetal and VM-docker launch. Specify endpoint
* Swarm Host IP is added into the conf file.
*
*/

func (i *dockerProvisioner) Create(assembly *global.AssemblyWithComponents, id string, instance bool, act_id string) (string, error) {
	log.Info("%q", assembly)
	pair_endpoint, perrscm := global.ParseKeyValuePair(assembly.Inputs, "endpoint")
	if perrscm != nil {
		log.Error("Failed to get the endpoint value : %s", perrscm)
		return "", perrscm
	}

	var endpoint string
	if pair_endpoint.Value == BAREMETAL {

		/*
		 * swarm host is obtained from conf file. Swarm host is considered
		 * only when the 'endpoint' is baremetal in the Component JSON
		 */
		api_host, _ := config.GetString("docker:swarm_host")
		endpoint = api_host

		containerID, containerName, cerr := create(assembly, endpoint)
		if cerr != nil {
			log.Error("container creation was failed : %s", cerr)
			return "", cerr
		}

		serr := StartContainer(containerID, endpoint)
		if serr != nil {
			log.Error("container starting error : %s", serr)
			return "", serr
		}

		ipaddress, iperr := setContainerNAL(containerID, containerName, endpoint)
		if iperr != nil {
			log.Error("set container network was failed : %s", iperr)
			return "", iperr
		}

		herr := setHostName(containerName, ipaddress)
		if herr != nil {
		  log.Error("set host name error : %s", herr)
		}

		updateContainerJSON(assembly, ipaddress, containerID, endpoint)
	} else {
		endpoint = pair_endpoint.Value
		create(assembly, endpoint)
	}

	return "", nil
}

/*
* Delete command kills the container by talking to swarm cluster and giving
* the container ID.
*
 */
func (i *dockerProvisioner) Delete(assembly *global.AssemblyWithComponents, id string) (string, error) {

	pair_endpoint, perrscm := global.ParseKeyValuePair(assembly.Inputs, "endpoint")
	if perrscm != nil {
		log.Error("Failed to get the endpoint value : %s", perrscm)
	}

	pair_id, iderr := global.ParseKeyValuePair(assembly.Components[0].Outputs, "id")
	if iderr != nil {
		log.Error("Failed to get the endpoint value : %s", iderr)
	}

	var endpoint string
	if pair_endpoint.Value == BAREMETAL {

		api_host, _ := config.GetString("docker:swarm_host")
		endpoint = api_host

	} else {
		endpoint = pair_endpoint.Value
	}

	client, _ := docker.NewClient(endpoint)
	kerr := client.KillContainer(docker.KillContainerOptions{ID: pair_id.Value})
	if kerr != nil {
		log.Error("Failed to kill the container : %s", kerr)
		return "", kerr
	}
	log.Info("Container is killed")
	return "", nil
}

/*
* Docker API client to connect to swarm/docker VM.
* Swarm supports all docker API endpoints
*/
func create(assembly *global.AssemblyWithComponents, endpoint string) (string, string, error) {

	pair_img, perrscm := global.ParseKeyValuePair(assembly.Components[0].Inputs, "source")
	if perrscm != nil {
		log.Error("Failed to get the image value : %s", perrscm)
		return "", "", perrscm
	}

	pair_domain, perrdomain := global.ParseKeyValuePair(assembly.Components[0].Inputs, "domain")
	if perrdomain != nil {
		log.Error("Failed to get the image value : %s", perrdomain)
		return "", "", perrdomain
	}

	client, _ := docker.NewClient(endpoint)

	opts := docker.PullImageOptions{
		Repository: pair_img.Value,
	}
	pullerr := client.PullImage(opts, docker.AuthConfiguration{})
	if pullerr != nil {
		log.Error("Image pulled failed : %s", pullerr)
		return "", "", pullerr
	}

	dconfig := docker.Config{Image: pair_img.Value, NetworkDisabled: true}
	copts := docker.CreateContainerOptions{Name: fmt.Sprint(assembly.Components[0].Name, ".", pair_domain.Value), Config: &dconfig}

	/*
	 * Creation of the container with copts.
	 */

	container, conerr := client.CreateContainer(copts)
	if conerr != nil {
		log.Error("Container creation failed : %s", conerr)
		return "", "", conerr
	}

	cont := &docker.Container{}
	mapP, _ := json.Marshal(container)
	json.Unmarshal([]byte(string(mapP)), cont)

	return cont.ID, cont.Name, nil
}

/*
* start the container using docker endpoint
*/
func (p *dockerProvisioner) StartContainer(containerID string, endpoint string) error {

	client, _ := docker.NewClient(endpoint)

	/*
	 * hostConfig{} struct for portbindings - to expose visible ports
	 *  Also for specfying the container configurations (memory, cpuquota etc)
	 */

	hostConfig := docker.HostConfig{}

	/*
	 *   Starting container once the container is created - container ID &
	 *   hostConfig is proivided to start the container.
	 *
	 */
	serr := client.StartContainer(containerID, &hostConfig)
	if serr != nil {
		log.Error("Start container was failed : %s", serr)
		return serr
	}
 return nil
}

/*
* stop the container using docker endpoint
*/
func StopContainer(containerID string, endpoint string) error {

	client, _ := docker.NewClient(endpoint)
	serr := client.StopContainer(containerID, 10)
	if serr != nil {
		log.Error("container was not stopped - Error : %s", serr)
		return serr
	}
	return nil
}

/*
* restart the container using docker endpoint
*/
func RestartContainer(containerID string, endpoint string) error {
	client, _ := docker.NewClient(endpoint)
	rerr := client.RestartContainer(containerID, 10)
	if rerr != nil {
		log.Error("container was not restarted - Error : %s", rerr)
		return rerr
	}
	return nil
}
<commit_msg>a minor update to provisioner<commit_after>/*
** Copyright [2013-2015] [Megam Systems]
**
** 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 docker

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

	"github.com/fsouza/go-dockerclient"
	"github.com/megamsys/libgo/log"
	"github.com/megamsys/libgo/db"
	"github.com/megamsys/megamd/global"
	"github.com/megamsys/megamd/provisioner"
	"github.com/megamsys/megamd/swarmc"
	"github.com/megamsys/seru/cmd"
	"github.com/megamsys/seru/cmd/seru"
	"github.com/tsuru/config"
)

type dockerProvisioner struct {
	cluster        *swarmc.Cluster
	storage        swarmc.Storage
	isDryMode      bool
}

var mainDockerProvisioner *dockerProvisioner

// Registers docker as provisioner in provisioner interface.
func Init() {
	mainDockerProvisioner = &dockerProvisioner{}
	provisioner.Register("docker", mainDockerProvisioner)
}

func (p *dockerProvisioner) initDockerCluster() error {
	var err error
	if p.storage == nil {
		p.storage, err = buildClusterStorage()
		if err != nil {
			return err
		}
	}

	var nodes []cluster.Node
	totalMemoryMetadata, _ := config.GetString("docker:scheduler:total-memory-metadata")
	maxUsedMemory, _ := config.GetFloat("docker:scheduler:max-used-memory")
	p.scheduler = &segregatedScheduler{
		maxMemoryRatio:      float32(maxUsedMemory),
		totalMemoryMetadata: totalMemoryMetadata,
		provisioner:         p,
	}
	p.cluster, err = cluster.New(p.scheduler, p.storage, nodes...)
	if err != nil {
		return err
	}
	return nil
}

func (p *dockerProvisioner) stopDryMode() {
	if p.isDryMode {
		p.cluster.StopDryMode()
	}
}

func (p *dockerProvisioner) dryMode(ignoredContainers []container) (*dockerProvisioner, error) {
	var err error
	overridenProvisioner := &dockerProvisioner{
		collectionName: "containers_dry_" + randomString(),
		isDryMode:      true,
	}
	containerIds := make([]string, len(ignoredContainers))
	for i := range ignoredContainers {
		containerIds[i] = ignoredContainers[i].ID
	}
	overridenProvisioner.scheduler = &segregatedScheduler{
		maxMemoryRatio:      p.scheduler.maxMemoryRatio,
		totalMemoryMetadata: p.scheduler.totalMemoryMetadata,
		provisioner:         overridenProvisioner,
		ignoredContainers:   containerIds,
	}
	overridenProvisioner.cluster, err = cluster.New(overridenProvisioner.scheduler, p.storage)
	if err != nil {
		return nil, err
	}
	overridenProvisioner.cluster.DryMode()
	containersToCopy, err := p.listAllContainers()
	if err != nil {
		return nil, err
	}
	coll := overridenProvisioner.collection()
	defer coll.Close()
	toInsert := make([]interface{}, len(containersToCopy))
	for i := range containersToCopy {
		toInsert[i] = containersToCopy[i]
	}
	if len(toInsert) > 0 {
		err = coll.Insert(toInsert...)
		if err != nil {
			return nil, err
		}
	}
	return overridenProvisioner, nil
}

func (p *dockerProvisioner) getCluster() *cluster.Cluster {
	if p.cluster == nil {
		panic("nil cluster")
	}
	return p.cluster
}

func (p *dockerProvisioner) Initialize() error {
	return p.initDockerCluster()
}

func (p *dockerProvisioner) StartupMessage() (string, error) {
	nodeList, err := p.getCluster().UnfilteredNodes()
	if err != nil {
		return "", err
	}
	out := """
	*-------------------------------------------------*
	| megamswarm     ----->    fishing nodes for you. |
	*-------------------------------------------------*\n"""

	for _, node := range nodeList {
		out += fmt.Sprintf("    Docker node: %s\n", node.Address)
	}
	return out, nil
}

/*
* Create provisioner is called to launch docker containers by
* talking to swarm cluster. Common provisioner for both
* Baremetal and VM-docker launch. Specify endpoint
* Swarm Host IP is added into the conf file.
*
*/
func (i *dockerProvisioner) Create(assembly *global.AssemblyWithComponents, id string, instance bool, act_id string) (string, error) {
	log.Info("%q", assembly)
	pair_endpoint, perrscm := global.ParseKeyValuePair(assembly.Inputs, "endpoint")
	if perrscm != nil {
		log.Error("Failed to get the endpoint value : %s", perrscm)
		return "", perrscm
	}

	var endpoint string
	if pair_endpoint.Value == BAREMETAL {

		/*
		 * swarm host is obtained from conf file. Swarm host is considered
		 * only when the 'endpoint' is baremetal in the Component JSON
		 */
		api_host, _ := config.GetString("docker:swarm_host")
		endpoint = api_host

		containerID, containerName, cerr := create(assembly, endpoint)
		if cerr != nil {
			log.Error("container creation was failed : %s", cerr)
			return "", cerr
		}

		serr := StartContainer(containerID, endpoint)
		if serr != nil {
			log.Error("container starting error : %s", serr)
			return "", serr
		}

		ipaddress, iperr := setContainerNAL(containerID, containerName, endpoint)
		if iperr != nil {
			log.Error("set container network was failed : %s", iperr)
			return "", iperr
		}

		herr := setHostName(containerName, ipaddress)
		if herr != nil {
		  log.Error("set host name error : %s", herr)
		}

		updateContainerJSON(assembly, ipaddress, containerID, endpoint)
	} else {
		endpoint = pair_endpoint.Value
		create(assembly, endpoint)
	}

	return "", nil
}

/*
* Delete command kills the container by talking to swarm cluster and giving
* the container ID.
*
 */
func (i *dockerProvisioner) Delete(assembly *global.AssemblyWithComponents, id string) (string, error) {

	pair_endpoint, perrscm := global.ParseKeyValuePair(assembly.Inputs, "endpoint")
	if perrscm != nil {
		log.Error("Failed to get the endpoint value : %s", perrscm)
	}

	pair_id, iderr := global.ParseKeyValuePair(assembly.Components[0].Outputs, "id")
	if iderr != nil {
		log.Error("Failed to get the endpoint value : %s", iderr)
	}

	var endpoint string
	if pair_endpoint.Value == BAREMETAL {

		api_host, _ := config.GetString("docker:swarm_host")
		endpoint = api_host

	} else {
		endpoint = pair_endpoint.Value
	}

	client, _ := docker.NewClient(endpoint)
	kerr := client.KillContainer(docker.KillContainerOptions{ID: pair_id.Value})
	if kerr != nil {
		log.Error("Failed to kill the container : %s", kerr)
		return "", kerr
	}
	log.Info("Container is killed")
	return "", nil
}

/*
* Docker API client to connect to swarm/docker VM.
* Swarm supports all docker API endpoints
*/
func create(assembly *global.AssemblyWithComponents, endpoint string) (string, string, error) {
	pair_img, perrscm := global.ParseKeyValuePair(assembly.Components[0].Inputs, "source")
	if perrscm != nil {
		log.Error("Failed to get the image value : %s", perrscm)
		return "", "", perrscm
	}

	pair_domain, perrdomain := global.ParseKeyValuePair(assembly.Components[0].Inputs, "domain")
	if perrdomain != nil {
		log.Error("Failed to get the image value : %s", perrdomain)
		return "", "", perrdomain
	}

	client, _ := docker.NewClient(endpoint)

	opts := docker.PullImageOptions{
		Repository: pair_img.Value,
	}
	pullerr := client.PullImage(opts, docker.AuthConfiguration{})
	if pullerr != nil {
		log.Error("Image pulled failed : %s", pullerr)
		return "", "", pullerr
	}

	dconfig := docker.Config{Image: pair_img.Value, NetworkDisabled: true}
	copts := docker.CreateContainerOptions{Name: fmt.Sprint(assembly.Components[0].Name, ".", pair_domain.Value), Config: &dconfig}

	/*
	 * Creation of the container with copts.
	 */

	container, conerr := client.CreateContainer(copts)
	if conerr != nil {
		log.Error("Container creation failed : %s", conerr)
		return "", "", conerr
	}

	cont := &docker.Container{}
	mapP, _ := json.Marshal(container)
	json.Unmarshal([]byte(string(mapP)), cont)

	return cont.ID, cont.Name, nil
}

/*
* start the container using docker endpoint
*/
func (p *dockerProvisioner) StartContainer(containerID string, endpoint string) error {

	client, _ := docker.NewClient(endpoint)

	/*
	 * hostConfig{} struct for portbindings - to expose visible ports
	 *  Also for specfying the container configurations (memory, cpuquota etc)
	 */

	hostConfig := docker.HostConfig{}

	/*
	 *   Starting container once the container is created - container ID &
	 *   hostConfig is proivided to start the container.
	 *
	 */
	serr := client.StartContainer(containerID, &hostConfig)
	if serr != nil {
		log.Error("Start container was failed : %s", serr)
		return serr
	}
 return nil
}

/*
* stop the container using docker endpoint
*/
func StopContainer(containerID string, endpoint string) error {

	client, _ := docker.NewClient(endpoint)
	serr := client.StopContainer(containerID, 10)
	if serr != nil {
		log.Error("container was not stopped - Error : %s", serr)
		return serr
	}
	return nil
}

/*
* restart the container using docker endpoint
*/
func RestartContainer(containerID string, endpoint string) error {
	client, _ := docker.NewClient(endpoint)
	rerr := client.RestartContainer(containerID, 10)
	if rerr != nil {
		log.Error("container was not restarted - Error : %s", rerr)
		return rerr
	}
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/big"
	"testing"
)

// bigIntSlice takes a slice of int64 and returns a slice of them all converted
// to *big.Ints
func bigIntSlice(nums []int64) []*big.Int {
	b := make([]*big.Int, len(nums))
	for i, n := range nums {
		b[i] = big.NewInt(n)
	}
	return b
}

func TestCRTs(t *testing.T) {
	var tests = []struct {
		a, n   []int64
		answer int64
	}{
		{[]int64{0, 3, 4}, []int64{3, 4, 5}, 39},
		{[]int64{2, 4, 5}, []int64{3, 5, 7}, 89},
		{[]int64{19, 6, 7, 11}, []int64{31, 32, 99, 23}, 138310},
		{[]int64{2292, 3010, 500, 399}, []int64{77003, 61223, 60161, 25873}, 4412381708627286819},

		{[]int64{0, 3, 4}, []int64{3, 4, 9}, -1},
	}

	for _, tt := range tests {
		ttname := fmt.Sprintf("a=%v, n=%v", tt.a, tt.n)
		t.Run(ttname, func(t *testing.T) {

			// Only run crtSearch on the smallest examples.
			if tt.n[0] < 1000 {
				r1 := crtSearch(tt.a, tt.n)
				if r1 != tt.answer {
					t.Errorf("crtSearch=%v, want=%v", r1, tt.answer)
				}
			}

			r2 := crtSieve(tt.a, tt.n)
			if r2 != tt.answer {
				t.Errorf("crtSieve=%v, want=%v", r2, tt.answer)
			}

			r3big := crtSieveBig(bigIntSlice(tt.a), bigIntSlice(tt.n))
			if r3big.Cmp(big.NewInt(tt.answer)) != 0 {
				t.Errorf("crtSieveBig=%v, want %v", r3big, tt.answer)
			}

			r4big := crtConstructBig(bigIntSlice(tt.a), bigIntSlice(tt.n))
			if r4big.Cmp(big.NewInt(tt.answer)) != 0 {
				t.Errorf("crtConstructBig=%v, want %v", r4big, tt.answer)
			}
		})
	}
}

func TestCRTHuge(t *testing.T) {
	// Check that both methods return the same result.
	a := []int64{990101, 2019304, 80000, 102, 201, 3010, 500, 399}
	n := []int64{3333383, 2666141, 902761, 668821, 77003, 61223, 60161, 25873}

	r1 := crtSieveBig(bigIntSlice(a), bigIntSlice(n))
	r2 := crtConstructBig(bigIntSlice(a), bigIntSlice(n))

	if r1.Cmp(r2) != 0 {
		t.Errorf("want equal results; got r1=%v, r2=%v", r1, r2)
	}
}
<commit_msg>Added benchmarks<commit_after>package main

import (
	"fmt"
	"math/big"
	"testing"
)

// bigIntSlice takes a slice of int64 and returns a slice of them all converted
// to *big.Ints
func bigIntSlice(nums []int64) []*big.Int {
	b := make([]*big.Int, len(nums))
	for i, n := range nums {
		b[i] = big.NewInt(n)
	}
	return b
}

func TestCRTs(t *testing.T) {
	var tests = []struct {
		a, n   []int64
		answer int64
	}{
		{[]int64{0, 3, 4}, []int64{3, 4, 5}, 39},
		{[]int64{2, 4, 5}, []int64{3, 5, 7}, 89},
		{[]int64{19, 6, 7, 11}, []int64{31, 32, 99, 23}, 138310},
		{[]int64{2292, 3010, 500, 399}, []int64{77003, 61223, 60161, 25873}, 4412381708627286819},

		{[]int64{0, 3, 4}, []int64{3, 4, 9}, -1},
	}

	for _, tt := range tests {
		ttname := fmt.Sprintf("a=%v, n=%v", tt.a, tt.n)
		t.Run(ttname, func(t *testing.T) {

			// Only run crtSearch on the smallest examples.
			if tt.n[0] < 1000 {
				r1 := crtSearch(tt.a, tt.n)
				if r1 != tt.answer {
					t.Errorf("crtSearch=%v, want=%v", r1, tt.answer)
				}
			}

			r2 := crtSieve(tt.a, tt.n)
			if r2 != tt.answer {
				t.Errorf("crtSieve=%v, want=%v", r2, tt.answer)
			}

			r3big := crtSieveBig(bigIntSlice(tt.a), bigIntSlice(tt.n))
			if r3big.Cmp(big.NewInt(tt.answer)) != 0 {
				t.Errorf("crtSieveBig=%v, want %v", r3big, tt.answer)
			}

			r4big := crtConstructBig(bigIntSlice(tt.a), bigIntSlice(tt.n))
			if r4big.Cmp(big.NewInt(tt.answer)) != 0 {
				t.Errorf("crtConstructBig=%v, want %v", r4big, tt.answer)
			}
		})
	}
}

func TestCrtHuge(t *testing.T) {
	// Check that both methods return the same result.
	a := []int64{990101, 2019304, 80000, 102, 201, 3010, 500, 399}
	n := []int64{3333383, 2666141, 902761, 668821, 77003, 61223, 60161, 25873}

	r1 := crtSieveBig(bigIntSlice(a), bigIntSlice(n))
	r2 := crtConstructBig(bigIntSlice(a), bigIntSlice(n))

	if r1.Cmp(r2) != 0 {
		t.Errorf("want equal results; got r1=%v, r2=%v", r1, r2)
	}
}

func BenchmarkCrtSearchSmall(b *testing.B) {
	for i := 0; i < b.N; i++ {
		crtSearch([]int64{19, 6, 7, 11}, []int64{31, 32, 99, 23})
	}
}

func BenchmarkCrtSieveSmall(b *testing.B) {
	for i := 0; i < b.N; i++ {
		crtSieve([]int64{19, 6, 7, 11}, []int64{31, 32, 99, 23})
	}
}

func BenchmarkCrtSieveSortedSmall(b *testing.B) {
	for i := 0; i < b.N; i++ {
		crtSieve([]int64{7, 6, 19, 11}, []int64{99, 32, 31, 23})
	}
}

func BenchmarkCrtSieveSortedLarge(b *testing.B) {
	as := bigIntSlice([]int64{990101, 2019304, 80000, 102, 201, 3010, 500, 399})
	ns := bigIntSlice([]int64{3333383, 2666141, 902761, 668821, 77003, 61223, 60161, 25873})
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		crtSieveBig(as, ns)
	}
}

func BenchmarkCrtConstructLarge(b *testing.B) {
	as := bigIntSlice([]int64{990101, 2019304, 80000, 102, 201, 3010, 500, 399})
	ns := bigIntSlice([]int64{3333383, 2666141, 902761, 668821, 77003, 61223, 60161, 25873})
	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		crtConstructBig(as, ns)
	}
}
<|endoftext|>


<commit_before>package system

import (
	"fmt"

	"github.com/docker/cli/cli"
	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/command/prune"
	"github.com/docker/cli/opts"
	units "github.com/docker/go-units"
	"github.com/spf13/cobra"
)

type pruneOptions struct {
	force  bool
	all    bool
	filter opts.FilterOpt
}

// NewPruneCommand creates a new cobra.Command for `docker prune`
func NewPruneCommand(dockerCli command.Cli) *cobra.Command {
	options := pruneOptions{filter: opts.NewFilterOpt()}

	cmd := &cobra.Command{
		Use:   "prune [OPTIONS]",
		Short: "Remove unused data",
		Args:  cli.NoArgs,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runPrune(dockerCli, options)
		},
		Tags: map[string]string{"version": "1.25"},
	}

	flags := cmd.Flags()
	flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
	flags.BoolVarP(&options.all, "all", "a", false, "Remove all unused images not just dangling ones")
	flags.Var(&options.filter, "filter", "Provide filter values (e.g. 'label=<key>=<value>')")
	// "filter" flag is available in 1.28 (docker 17.04) and up
	flags.SetAnnotation("filter", "version", []string{"1.28"})

	return cmd
}

const (
	warning = `WARNING! This will remove:
	- all stopped containers
	- all volumes not used by at least one container
	- all networks not used by at least one container
	%s
Are you sure you want to continue?`

	danglingImageDesc = "- all dangling images"
	allImageDesc      = `- all images without at least one container associated to them`
)

func runPrune(dockerCli command.Cli, options pruneOptions) error {
	var message string

	if options.all {
		message = fmt.Sprintf(warning, allImageDesc)
	} else {
		message = fmt.Sprintf(warning, danglingImageDesc)
	}

	if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), message) {
		return nil
	}

	var spaceReclaimed uint64

	for _, pruneFn := range []func(dockerCli command.Cli, filter opts.FilterOpt) (uint64, string, error){
		prune.RunContainerPrune,
		prune.RunVolumePrune,
		prune.RunNetworkPrune,
	} {
		spc, output, err := pruneFn(dockerCli, options.filter)
		if err != nil {
			return err
		}
		spaceReclaimed += spc
		if output != "" {
			fmt.Fprintln(dockerCli.Out(), output)
		}
	}

	spc, output, err := prune.RunImagePrune(dockerCli, options.all, options.filter)
	if err != nil {
		return err
	}
	if spc > 0 {
		spaceReclaimed += spc
		fmt.Fprintln(dockerCli.Out(), output)
	}

	fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))

	return nil
}
<commit_msg>Don't prune volumes on `docker system prune`<commit_after>package system

import (
	"fmt"

	"github.com/docker/cli/cli"
	"github.com/docker/cli/cli/command"
	"github.com/docker/cli/cli/command/prune"
	"github.com/docker/cli/opts"
	units "github.com/docker/go-units"
	"github.com/spf13/cobra"
)

type pruneOptions struct {
	force        bool
	all          bool
	pruneVolumes bool
	filter       opts.FilterOpt
}

// NewPruneCommand creates a new cobra.Command for `docker prune`
func NewPruneCommand(dockerCli command.Cli) *cobra.Command {
	options := pruneOptions{filter: opts.NewFilterOpt()}

	cmd := &cobra.Command{
		Use:   "prune [OPTIONS]",
		Short: "Remove unused data",
		Args:  cli.NoArgs,
		RunE: func(cmd *cobra.Command, args []string) error {
			return runPrune(dockerCli, options)
		},
		Tags: map[string]string{"version": "1.25"},
	}

	flags := cmd.Flags()
	flags.BoolVarP(&options.force, "force", "f", false, "Do not prompt for confirmation")
	flags.BoolVarP(&options.all, "all", "a", false, "Remove all unused images not just dangling ones")
	flags.BoolVar(&options.pruneVolumes, "volumes", false, "Prune volumes")
	flags.Var(&options.filter, "filter", "Provide filter values (e.g. 'label=<key>=<value>')")
	// "filter" flag is available in 1.28 (docker 17.04) and up
	flags.SetAnnotation("filter", "version", []string{"1.28"})

	return cmd
}

const (
	warning = `WARNING! This will remove:
	- all stopped containers
	- all volumes not used by at least one container
	- all networks not used by at least one container
	%s
Are you sure you want to continue?`

	danglingImageDesc = "- all dangling images"
	allImageDesc      = `- all images without at least one container associated to them`
)

func runPrune(dockerCli command.Cli, options pruneOptions) error {
	var message string

	if options.all {
		message = fmt.Sprintf(warning, allImageDesc)
	} else {
		message = fmt.Sprintf(warning, danglingImageDesc)
	}

	if !options.force && !command.PromptForConfirmation(dockerCli.In(), dockerCli.Out(), message) {
		return nil
	}

	var spaceReclaimed uint64
	pruneFuncs := []func(dockerCli command.Cli, filter opts.FilterOpt) (uint64, string, error){
		prune.RunContainerPrune,
		prune.RunNetworkPrune,
	}
	if options.pruneVolumes {
		pruneFuncs = append(pruneFuncs, prune.RunVolumePrune)
	}

	for _, pruneFn := range pruneFuncs {
		spc, output, err := pruneFn(dockerCli, options.filter)
		if err != nil {
			return err
		}
		spaceReclaimed += spc
		if output != "" {
			fmt.Fprintln(dockerCli.Out(), output)
		}
	}

	spc, output, err := prune.RunImagePrune(dockerCli, options.all, options.filter)
	if err != nil {
		return err
	}
	if spc > 0 {
		spaceReclaimed += spc
		fmt.Fprintln(dockerCli.Out(), output)
	}

	fmt.Fprintln(dockerCli.Out(), "Total reclaimed space:", units.HumanSize(float64(spaceReclaimed)))

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"
)

func runWebServer() error {
	srv := &webServer{
		motor:  NewMotor("134.158.125.223:502"),
		params: make([]Param, len(params)),
	}
	copy(srv.params, params)

	http.Handle("/lsst-fcs-motors", srv)
	log.Printf("listening on http://localhost:7070/lsst-fcs-motors ...\n")
	err := http.ListenAndServe(":7070", nil)
	return err
}

type webServer struct {
	motor  Motor
	params []Param
}

func (srv *webServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(
		w,
		`<title>LSST FCS Motors</title>
Motor: %s

 Parameters

`,
		srv.motor.Address,
	)

	fmt.Fprintf(w, "
\n")
	fmt.Fprintf(w, "\t
Parameter	Title	Value
\n")
	for _, p := range srv.params {
		fmt.Fprintf(w, "\t
\n")
		fmt.Fprintf(
			w,
			"\t\t%02d.%03d	%s	 ",
			p.menu, p.index, p.title,
		)
		o, err := srv.motor.read(NewParameter(p.mbreg()))
		if err != nil {
			fmt.Fprintf(w, "err=%v	\n", err)
			fmt.Fprintf(w, "\t
\n")
			continue
		}
		fmt.Fprintf(
			w,
			"
%s ==> %6d
	\n",
			displayBytes(o), codec.Uint16(o),
		)
		fmt.Fprintf(w, "\t
\n")
	}
	fmt.Fprintf(w, "
\n")
}
<commit_msg>web: modify css + display infos for all motors<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"
)

func runWebServer() error {
	srv := &webServer{
		motor:  NewMotor("134.158.125.223:502"),
		params: make([]Param, len(params)),
	}
	copy(srv.params, params)

	http.Handle("/lsst-fcs-motors", srv)
	log.Printf("listening on http://localhost:7070/lsst-fcs-motors ...\n")
	err := http.ListenAndServe(":7070", nil)
	return err
}

type webServer struct {
	motor  Motor
	params []Param
}

func (srv *webServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(
		w,
		`%s
<title>LSST FCS Motors</title>
`,
		css,
	)

	fmt.Fprintf(w, "\n\n")
	for i, motor := range []Motor{
		NewMotor("134.158.125.223:502"),
		NewMotor("134.158.125.224:502"),
	} {
		fmt.Fprintf(w, "
\n", i+1)
		fmt.Fprintf(w, "

Motor-%d (%s)

\n", i+1, motor.Address)
		fmt.Fprintf(w, "
\n")
		fmt.Fprintf(w, "\t
Parameter	Title	Value
\n")
		for _, p := range srv.params {
			fmt.Fprintf(w, "\t
\n")
			fmt.Fprintf(
				w,
				"\t\t%02d.%03d	%s	 ",
				p.menu, p.index, p.title,
			)
			o, err := motor.read(NewParameter(p.mbreg()))
			if err != nil {
				fmt.Fprintf(w, "err=%v	\n", err)
				fmt.Fprintf(w, "\t
\n")
				continue
			}
			fmt.Fprintf(
				w,
				"
%s ==> %6d
	\n",
				displayBytes(o), codec.Uint16(o),
			)
			fmt.Fprintf(w, "\t
\n")
		}
		fmt.Fprintf(w, "
\n
\n\n")
	}
	fmt.Fprintf(w, "\n")
}

const css = `
`
<|endoftext|>


<commit_before>package main

import (
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"os"

	"github.com/go-martini/martini"
	"github.com/joshuarubin/goscribe/telapi"
	"github.com/kr/pretty"
	"github.com/martini-contrib/auth"
	"github.com/martini-contrib/binding"
	"github.com/martini-contrib/gzip"
	"github.com/martini-contrib/render"
	"github.com/martini-contrib/strict"
	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
)

// TODO(jrubin):
// * mgo (http://labix.org/mgo)
// * sessions (https://github.com/martini-contrib/sessions)
// * oauth2 (https://github.com/martini-contrib/oauth2)
// * accessflags (https://github.com/martini-contrib/accessflags)
// * remove auth, replace with api key validator (github.com/martini-contrib/auth)
// * CORS support would be nice (https://github.com/martini-contrib/cors)
// * CSRF (https://github.com/martini-contrib/csrf)
// * secure (https://github.com/martini-contrib/secure)

var (
	m         *martini.ClassicMartini
	s3Bucket  *s3.Bucket
	s3BaseURL string
	baseURL   string
	authUser  string
	authPass  string
)

type callbackData struct {
	CallbackURL string `form:"callback_url" binding:"required"`
}

type transcribeData struct {
	callbackData
	AudioURL string `form:"audio_url" binding:"required"`
}

type transcribeUploadData struct {
	callbackData
	AudioData *multipart.FileHeader `form:"audio_data" binding:"required"`
}

func init() {
	// BASE_URL, AUTH_USER and AUTH_PASS, AWS_S3_BASE_URL are not required or else wercker tests would fail
	baseURL = os.Getenv("BASE_URL")
	authUser = os.Getenv("AUTH_USER")
	authPass = os.Getenv("AUTH_PASS")
	s3BaseURL = os.Getenv("AWS_S3_BASE_URL")

	if awsAuth, err := aws.EnvAuth(); err != nil {
		// not required or else wercker tests would fail
		log.Println(err)
	} else {
		// TODO(jrubin) allow region to be chosen by env variable
		s3Data := s3.New(awsAuth, aws.USWest2)
		s3Bucket = s3Data.Bucket(os.Getenv("AWS_S3_BUCKET_NAME"))
	}

	m = martini.Classic()

	m.Use(gzip.All())
	m.Use(render.Renderer())

	m.Get("/", func() string {
		return "hello, world"
	})

	m.Post(
		"/v1/transcribe",
		auth.Basic(authUser, authPass),
		strict.Accept("application/json"),
		strict.ContentType("application/x-www-form-urlencoded"),
		binding.Bind(transcribeData{}),
		binding.ErrorHandler,
		handleTranscribe,
	)

	m.Post(
		"/v1/transcribe/process",
		strict.ContentType("application/x-www-form-urlencoded"),
		binding.Bind(telapi.TranscribeCallbackData{}),
		binding.ErrorHandler,
		handleTranscribeProcess,
	)

	m.Post(
		"/v1/transcribe/upload",
		auth.Basic(authUser, authPass),
		strict.Accept("application/json"),
		binding.MultipartForm(transcribeUploadData{}),
		binding.ErrorHandler,
		handleTranscribeUpload,
	)

	m.Router.NotFound(strict.MethodNotAllowed, strict.NotFound)
}

func main() {
	m.Run()
}

func success(r render.Render, data ...interface{}) {
	ret := map[string]interface{}{
		"status": http.StatusOK,
	}

	l := len(data)
	if l == 1 {
		ret["data"] = data[0]
	} else if l > 1 {
		ret["data"] = data
	}

	r.JSON(http.StatusOK, ret)
}

func jsonError(r render.Render, status int, err error) {
	r.JSON(status, map[string]interface{}{
		"status": status,
		"error":  err.Error(),
	})
}

func telapiError(r render.Render, err error) {
	if telapiError, ok := err.(telapi.Error); ok {
		r.JSON(telapiError.JSON())
		return
	}

	jsonError(r, http.StatusInternalServerError, err)
}

func transcribe(r render.Render, url, callback string) {
	resp, err := telapi.TranscribeURL(url, callback)
	if err != nil {
		telapiError(r, err)
		return
	}

	success(r, resp.TranscribeClientResponse.Translate())
}

func s3Upload(basePath string, data *multipart.FileHeader) (string, error) {
	if s3Bucket == nil {
		return "", fmt.Errorf("upload unavailable")
	}

	fileName := data.Filename
	fileType := data.Header.Get("Content-Type")

	file, err := data.Open()
	defer file.Close()

	if err != nil {
		return "", err
	}

	fileData, err := ioutil.ReadAll(file)
	if err != nil {
		return "", err
	}

	h := sha1.New()
	if _, err := h.Write(fileData); err != nil {
		return "", err
	}

	filePath := fmt.Sprintf("/%s/%x_%s", basePath, h.Sum(nil), fileName)

	if err := s3Bucket.Put(filePath, fileData, fileType, s3.PublicRead); err != nil {
		return "", err
	}

	return s3BaseURL + filePath, nil
}

func handleTranscribe(data transcribeData, r render.Render) {
	transcribe(r, data.AudioURL, data.CallbackURL)
}

func handleTranscribeProcess(data telapi.TranscribeCallbackData, r render.Render) {
	pretty.Println(data)
	b, _ := json.Marshal(data.TranscribeCallbackClientData)
	pretty.Println(string(b))
	success(r)
}

func handleTranscribeUpload(data transcribeUploadData, r render.Render) {
	fileURL, err := s3Upload("audio", data.AudioData)
	if err != nil {
		jsonError(r, http.StatusInternalServerError, err)
		return
	}

	transcribe(r, fileURL, data.CallbackURL)
}
<commit_msg>dont even use filename in s3 upload<commit_after>package main

import (
	"crypto/sha1"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"mime/multipart"
	"net/http"
	"os"

	"github.com/go-martini/martini"
	"github.com/joshuarubin/goscribe/telapi"
	"github.com/kr/pretty"
	"github.com/martini-contrib/auth"
	"github.com/martini-contrib/binding"
	"github.com/martini-contrib/gzip"
	"github.com/martini-contrib/render"
	"github.com/martini-contrib/strict"
	"github.com/mitchellh/goamz/aws"
	"github.com/mitchellh/goamz/s3"
)

// TODO(jrubin):
// * mgo (http://labix.org/mgo)
// * sessions (https://github.com/martini-contrib/sessions)
// * oauth2 (https://github.com/martini-contrib/oauth2)
// * accessflags (https://github.com/martini-contrib/accessflags)
// * remove auth, replace with api key validator (github.com/martini-contrib/auth)
// * CORS support would be nice (https://github.com/martini-contrib/cors)
// * CSRF (https://github.com/martini-contrib/csrf)
// * secure (https://github.com/martini-contrib/secure)

var (
	m         *martini.ClassicMartini
	s3Bucket  *s3.Bucket
	s3BaseURL string
	baseURL   string
	authUser  string
	authPass  string
)

type callbackData struct {
	CallbackURL string `form:"callback_url" binding:"required"`
}

type transcribeData struct {
	callbackData
	AudioURL string `form:"audio_url" binding:"required"`
}

type transcribeUploadData struct {
	callbackData
	AudioData *multipart.FileHeader `form:"audio_data" binding:"required"`
}

func init() {
	// BASE_URL, AUTH_USER and AUTH_PASS, AWS_S3_BASE_URL are not required or else wercker tests would fail
	baseURL = os.Getenv("BASE_URL")
	authUser = os.Getenv("AUTH_USER")
	authPass = os.Getenv("AUTH_PASS")
	s3BaseURL = os.Getenv("AWS_S3_BASE_URL")

	if awsAuth, err := aws.EnvAuth(); err != nil {
		// not required or else wercker tests would fail
		log.Println(err)
	} else {
		// TODO(jrubin) allow region to be chosen by env variable
		s3Data := s3.New(awsAuth, aws.USWest2)
		s3Bucket = s3Data.Bucket(os.Getenv("AWS_S3_BUCKET_NAME"))
	}

	m = martini.Classic()

	m.Use(gzip.All())
	m.Use(render.Renderer())

	m.Get("/", func() string {
		return "hello, world"
	})

	m.Post(
		"/v1/transcribe",
		auth.Basic(authUser, authPass),
		strict.Accept("application/json"),
		strict.ContentType("application/x-www-form-urlencoded"),
		binding.Bind(transcribeData{}),
		binding.ErrorHandler,
		handleTranscribe,
	)

	m.Post(
		"/v1/transcribe/process",
		strict.ContentType("application/x-www-form-urlencoded"),
		binding.Bind(telapi.TranscribeCallbackData{}),
		binding.ErrorHandler,
		handleTranscribeProcess,
	)

	m.Post(
		"/v1/transcribe/upload",
		auth.Basic(authUser, authPass),
		strict.Accept("application/json"),
		binding.MultipartForm(transcribeUploadData{}),
		binding.ErrorHandler,
		handleTranscribeUpload,
	)

	m.Router.NotFound(strict.MethodNotAllowed, strict.NotFound)
}

func main() {
	m.Run()
}

func success(r render.Render, data ...interface{}) {
	ret := map[string]interface{}{
		"status": http.StatusOK,
	}

	l := len(data)
	if l == 1 {
		ret["data"] = data[0]
	} else if l > 1 {
		ret["data"] = data
	}

	r.JSON(http.StatusOK, ret)
}

func jsonError(r render.Render, status int, err error) {
	r.JSON(status, map[string]interface{}{
		"status": status,
		"error":  err.Error(),
	})
}

func telapiError(r render.Render, err error) {
	if telapiError, ok := err.(telapi.Error); ok {
		r.JSON(telapiError.JSON())
		return
	}

	jsonError(r, http.StatusInternalServerError, err)
}

func transcribe(r render.Render, url, callback string) {
	resp, err := telapi.TranscribeURL(url, callback)
	if err != nil {
		telapiError(r, err)
		return
	}

	success(r, resp.TranscribeClientResponse.Translate())
}

func s3Upload(basePath string, data *multipart.FileHeader) (string, error) {
	if s3Bucket == nil {
		return "", fmt.Errorf("upload unavailable")
	}

	fileType := data.Header.Get("Content-Type")

	file, err := data.Open()
	defer file.Close()

	if err != nil {
		return "", err
	}

	fileData, err := ioutil.ReadAll(file)
	if err != nil {
		return "", err
	}

	h := sha1.New()
	if _, err := h.Write(fileData); err != nil {
		return "", err
	}

	filePath := fmt.Sprintf("/%s/%x", basePath, h.Sum(nil))

	if err := s3Bucket.Put(filePath, fileData, fileType, s3.PublicRead); err != nil {
		return "", err
	}

	return s3BaseURL + filePath, nil
}

func handleTranscribe(data transcribeData, r render.Render) {
	transcribe(r, data.AudioURL, data.CallbackURL)
}

func handleTranscribeProcess(data telapi.TranscribeCallbackData, r render.Render) {
	pretty.Println(data)
	b, _ := json.Marshal(data.TranscribeCallbackClientData)
	pretty.Println(string(b))
	success(r)
}

func handleTranscribeUpload(data transcribeUploadData, r render.Render) {
	fileURL, err := s3Upload("audio", data.AudioData)
	if err != nil {
		jsonError(r, http.StatusInternalServerError, err)
		return
	}

	transcribe(r, fileURL, data.CallbackURL)
}
<|endoftext|>


<commit_before>package web

import (
    "bytes"
    "container/vector"
    "fmt"
    "http"
    "log"
    "os"
    "path"
    "rand"
    "reflect"
    "regexp"
    "time"
)

type Conn interface {
    StartResponse(status int)
    SetHeader(hdr string, val string, unique bool)
    Write(data []byte) (n int, err os.Error)
    WriteString(content string)
    Close()
}

type Context struct {
    *Request
    Session *session
    Conn
    responseStarted bool
}

func (ctx *Context) Abort(status int, body string) {
    ctx.Conn.StartResponse(status)
    ctx.Conn.WriteString(body)
    ctx.responseStarted = true
}

func (ctx *Context) Redirect(status int, url string) {
    //note := "" + statusText[code] + ".\n"

    ctx.Conn.SetHeader("Location", url, true)
    ctx.Conn.StartResponse(status)
    ctx.Conn.WriteString("")
    ctx.responseStarted = true
}
//Sets a cookie -- duration is the amount of time in seconds. 0 = forever
func (ctx *Context) SetCookie(name string, value string, duration int64) {
    if duration == 0 {
        //do some really long time
    }

    utctime := time.UTC()
    utc1 := time.SecondsToUTC(utctime.Seconds() + 60*30)
    expires := utc1.RFC1123()
    expires = expires[0:len(expires)-3] + "GMT"
    cookie := fmt.Sprintf("%s=%s; expires=%s", name, value, expires)
    ctx.Conn.SetHeader("Set-Cookie", cookie, false)
}

var sessionMap = make(map[string]*session)

func randomString(length int) string {
    pop := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    var res bytes.Buffer

    for i := 0; i < length; i++ {
        rnd := rand.Intn(len(pop))
        res.WriteByte(pop[rnd])
    }

    return res.String()
}

type session struct {
    Data map[string]interface{}
    Id   string
}

func newSession() *session {
    s := session{
        Data: make(map[string]interface{}),
        Id: randomString(10),
    }

    return &s
}

func (s *session) save() { sessionMap[s.Id] = s }

var contextType reflect.Type
var staticDir string

const sessionKey = "wgosession"

func init() {
    contextType = reflect.Typeof(Context{})
    SetStaticDir("static")
}

type route struct {
    r       string
    cr      *regexp.Regexp
    method  string
    handler *reflect.FuncValue
}

var routes = make(map[*regexp.Regexp]route)

func addRoute(r string, method string, handler interface{}) {
    cr, err := regexp.Compile(r)
    if err != nil {
        log.Stderrf("Error in route regex %q\n", r)
        return
    }
    fv := reflect.NewValue(handler).(*reflect.FuncValue)
    routes[cr] = route{r, cr, method, fv}
}

type httpConn struct {
    conn *http.Conn
}

func (c *httpConn) StartResponse(status int) { c.conn.WriteHeader(status) }

func (c *httpConn) SetHeader(hdr string, val string, unique bool) {
    //right now unique can't be implemented through the http package.
    //see issue 488
    c.conn.SetHeader(hdr, val)
}

func (c *httpConn) WriteString(content string) {
    buf := bytes.NewBufferString(content)
    c.conn.Write(buf.Bytes())
}

func (c *httpConn) Write(content []byte) (n int, err os.Error) {
    return c.conn.Write(content)
}

func (c *httpConn) Close() {
    rwc, buf, _ := c.conn.Hijack()
    if buf != nil {
        buf.Flush()
    }

    if rwc != nil {
        rwc.Close()
    }
}

func httpHandler(c *http.Conn, req *http.Request) {
    conn := httpConn{c}

    wreq := newRequest(req)

    routeHandler(wreq, &conn)
}

func routeHandler(req *Request, conn Conn) {
    requestPath := req.URL.Path

    //log the request
    if len(req.URL.RawQuery) == 0 {
        log.Stdout(requestPath)
    } else {
        log.Stdout(requestPath + "?" + req.URL.RawQuery)
    }

    //parse the form data (if it exists)
    perr := req.ParseParams()
    if perr != nil {
        log.Stderrf("Failed to parse form data %q", perr.String())
    }

    //check the cookies for a session id
    perr = req.ParseCookies()
    if perr != nil {
        log.Stderrf("Failed to parse cookies %q", perr.String())
    }

    s := newSession()

    for k, v := range (req.Cookies) {
        if k == sessionKey {
            if sess, ok := sessionMap[v]; ok {
                s = sess
            }
        }
    }

    ctx := Context{req, s, conn, false}

    //try to serve a static file
    staticFile := path.Join(staticDir, requestPath)
    if fileExists(staticFile) {
        serveFile(&ctx, staticFile)
        return
    }

    //set default encoding
    conn.SetHeader("Content-Type", "text/html; charset=utf-8", true)
    conn.SetHeader("Server", "web.go", true)

    for cr, route := range routes {
        if req.Method != route.method {
            continue
        }

        if !cr.MatchString(requestPath) {
            continue
        }
        match := cr.MatchStrings(requestPath)

        if len(match[0]) != len(requestPath) {
            continue
        }

        var args vector.Vector

        handlerType := route.handler.Type().(*reflect.FuncType)

        //check if the first arg in the handler is a context type
        if handlerType.NumIn() > 0 {
            if a0, ok := handlerType.In(0).(*reflect.PtrType); ok {
                typ := a0.Elem()
                if typ == contextType {
                    args.Push(reflect.NewValue(&ctx))
                }
            }
        }

        for _, arg := range match[1:] {
            args.Push(reflect.NewValue(arg))
        }

        if len(args) != handlerType.NumIn() {
            log.Stderrf("Incorrect number of arguments for %s\n", requestPath)
            ctx.Abort(500, "Server Error")
            return
        }

        valArgs := make([]reflect.Value, len(args))
        for i, j := range (args) {
            valArgs[i] = j.(reflect.Value)
        }
        ret := route.handler.Call(valArgs)[0].(*reflect.StringValue).Get()

        if !ctx.responseStarted {
            //check if session data is stored
            if len(s.Data) > 0 {
                s.save()
                //set the session for half an hour
                ctx.SetCookie(sessionKey, s.Id, 1800)
            }

            conn.StartResponse(200)
            ctx.responseStarted = true
            conn.WriteString(ret)
        }

        return
    }

    ctx.Abort(404, "Page not found")
}

//runs the web application and serves http requests
func Run(addr string) {
    http.Handle("/", http.HandlerFunc(httpHandler))

    log.Stdoutf("web.go serving %s", addr)
    err := http.ListenAndServe(addr, nil)
    if err != nil {
        log.Exit("ListenAndServe:", err)
    }
}

//runs the web application and serves scgi requests
func RunScgi(addr string) {
    log.Stdoutf("web.go serving scgi %s", addr)
    listenAndServeScgi(addr)
}

//runs the web application by serving fastcgi requests
func RunFcgi(addr string) {
    log.Stdoutf("web.go serving fcgi %s", addr)
    listenAndServeFcgi(addr)
}

//Adds a handler for the 'GET' http method.
func Get(route string, handler interface{}) { addRoute(route, "GET", handler) }

//Adds a handler for the 'POST' http method.
func Post(route string, handler interface{}) { addRoute(route, "POST", handler) }

//Adds a handler for the 'PUT' http method.
func Put(route string, handler interface{}) { addRoute(route, "PUT", handler) }

//Adds a handler for the 'DELETE' http method.
func Delete(route string, handler interface{}) {
    addRoute(route, "DELETE", handler)
}

func dirExists(dir string) bool {
    d, e := os.Stat(dir)
    switch {
    case e != nil:
        return false
    case !d.IsDirectory():
        return false
    }

    return true
}

func fileExists(dir string) bool {
    d, e := os.Stat(dir)
    switch {
    case e != nil:
        return false
    case !d.IsRegular():
        return false
    }

    return true
}

type dirError string

func (path dirError) String() string { return "Failed to set directory " + string(path) }

func getCwd() string { return os.Getenv("PWD") }

//changes the location of the static directory. by default, it's under the 'static' folder
//of the directory containing the web application
func SetStaticDir(dir string) os.Error {
    cwd := getCwd()
    sd := path.Join(cwd, dir)
    if !dirExists(sd) {
        return dirError(sd)

    }
    staticDir = sd

    return nil
}

//copied from go's http package, because it's not public
var statusText = map[int]string{
    http.StatusContinue: "Continue",
    http.StatusSwitchingProtocols: "Switching Protocols",

    http.StatusOK: "OK",
    http.StatusCreated: "Created",
    http.StatusAccepted: "Accepted",
    http.StatusNonAuthoritativeInfo: "Non-Authoritative Information",
    http.StatusNoContent: "No Content",
    http.StatusResetContent: "Reset Content",
    http.StatusPartialContent: "Partial Content",

    http.StatusMultipleChoices: "Multiple Choices",
    http.StatusMovedPermanently: "Moved Permanently",
    http.StatusFound: "Found",
    http.StatusSeeOther: "See Other",
    http.StatusNotModified: "Not Modified",
    http.StatusUseProxy: "Use Proxy",
    http.StatusTemporaryRedirect: "Temporary Redirect",

    http.StatusBadRequest: "Bad Request",
    http.StatusUnauthorized: "Unauthorized",
    http.StatusPaymentRequired: "Payment Required",
    http.StatusForbidden: "Forbidden",
    http.StatusNotFound: "Not Found",
    http.StatusMethodNotAllowed: "Method Not Allowed",
    http.StatusNotAcceptable: "Not Acceptable",
    http.StatusProxyAuthRequired: "Proxy Authentication Required",
    http.StatusRequestTimeout: "Request Timeout",
    http.StatusConflict: "Conflict",
    http.StatusGone: "Gone",
    http.StatusLengthRequired: "Length Required",
    http.StatusPreconditionFailed: "Precondition Failed",
    http.StatusRequestEntityTooLarge: "Request Entity Too Large",
    http.StatusRequestURITooLong: "Request URI Too Long",
    http.StatusUnsupportedMediaType: "Unsupported Media Type",
    http.StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
    http.StatusExpectationFailed: "Expectation Failed",

    http.StatusInternalServerError: "Internal Server Error",
    http.StatusNotImplemented: "Not Implemented",
    http.StatusBadGateway: "Bad Gateway",
    http.StatusServiceUnavailable: "Service Unavailable",
    http.StatusGatewayTimeout: "Gateway Timeout",
    http.StatusHTTPVersionNotSupported: "HTTP Version Not Supported",
}
<commit_msg>web.go was just using the unseeded rand.Intn(), which generates the same random numbers each time. Now it creates its own generator with the current time as a seed.<commit_after>package web

import (
    "bytes"
    "container/vector"
    "fmt"
    "http"
    "log"
    "os"
    "path"
    "rand"
    "reflect"
    "regexp"
    "time"
)

var rgen = rand.New( rand.NewSource( time.Nanoseconds() ) )

type Conn interface {
    StartResponse(status int)
    SetHeader(hdr string, val string, unique bool)
    Write(data []byte) (n int, err os.Error)
    WriteString(content string)
    Close()
}

type Context struct {
    *Request
    Session *session
    Conn
    responseStarted bool
}

func (ctx *Context) Abort(status int, body string) {
    ctx.Conn.StartResponse(status)
    ctx.Conn.WriteString(body)
    ctx.responseStarted = true
}

func (ctx *Context) Redirect(status int, url string) {
    //note := "" + statusText[code] + ".\n"

    ctx.Conn.SetHeader("Location", url, true)
    ctx.Conn.StartResponse(status)
    ctx.Conn.WriteString("")
    ctx.responseStarted = true
}
//Sets a cookie -- duration is the amount of time in seconds. 0 = forever
func (ctx *Context) SetCookie(name string, value string, duration int64) {
    if duration == 0 {
        //do some really long time
    }

    utctime := time.UTC()
    utc1 := time.SecondsToUTC(utctime.Seconds() + 60*30)
    expires := utc1.RFC1123()
    expires = expires[0:len(expires)-3] + "GMT"
    cookie := fmt.Sprintf("%s=%s; expires=%s", name, value, expires)
    ctx.Conn.SetHeader("Set-Cookie", cookie, false)
}

var sessionMap = make(map[string]*session)

func randomString(length int) string {
    pop := "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
    var res bytes.Buffer

    for i := 0; i < length; i++ {
        rnd := rgen.Intn(len(pop))
        res.WriteByte(pop[rnd])
    }

    return res.String()
}

type session struct {
    Data map[string]interface{}
    Id   string
}

func newSession() *session {
    s := session{
        Data: make(map[string]interface{}),
        Id: randomString(10),
    }

    return &s
}

func (s *session) save() { sessionMap[s.Id] = s }

var contextType reflect.Type
var staticDir string

const sessionKey = "wgosession"

func init() {
    contextType = reflect.Typeof(Context{})
    SetStaticDir("static")
}

type route struct {
    r       string
    cr      *regexp.Regexp
    method  string
    handler *reflect.FuncValue
}

var routes = make(map[*regexp.Regexp]route)

func addRoute(r string, method string, handler interface{}) {
    cr, err := regexp.Compile(r)
    if err != nil {
        log.Stderrf("Error in route regex %q\n", r)
        return
    }
    fv := reflect.NewValue(handler).(*reflect.FuncValue)
    routes[cr] = route{r, cr, method, fv}
}

type httpConn struct {
    conn *http.Conn
}

func (c *httpConn) StartResponse(status int) { c.conn.WriteHeader(status) }

func (c *httpConn) SetHeader(hdr string, val string, unique bool) {
    //right now unique can't be implemented through the http package.
    //see issue 488
    c.conn.SetHeader(hdr, val)
}

func (c *httpConn) WriteString(content string) {
    buf := bytes.NewBufferString(content)
    c.conn.Write(buf.Bytes())
}

func (c *httpConn) Write(content []byte) (n int, err os.Error) {
    return c.conn.Write(content)
}

func (c *httpConn) Close() {
    rwc, buf, _ := c.conn.Hijack()
    if buf != nil {
        buf.Flush()
    }

    if rwc != nil {
        rwc.Close()
    }
}

func httpHandler(c *http.Conn, req *http.Request) {
    conn := httpConn{c}

    wreq := newRequest(req)

    routeHandler(wreq, &conn)
}

func routeHandler(req *Request, conn Conn) {
    requestPath := req.URL.Path

    //log the request
    if len(req.URL.RawQuery) == 0 {
        log.Stdout(requestPath)
    } else {
        log.Stdout(requestPath + "?" + req.URL.RawQuery)
    }

    //parse the form data (if it exists)
    perr := req.ParseParams()
    if perr != nil {
        log.Stderrf("Failed to parse form data %q", perr.String())
    }

    //check the cookies for a session id
    perr = req.ParseCookies()
    if perr != nil {
        log.Stderrf("Failed to parse cookies %q", perr.String())
    }

    s := newSession()

    for k, v := range (req.Cookies) {
        if k == sessionKey {
            if sess, ok := sessionMap[v]; ok {
                s = sess
            }
        }
    }

    ctx := Context{req, s, conn, false}

    //try to serve a static file
    staticFile := path.Join(staticDir, requestPath)
    if fileExists(staticFile) {
        serveFile(&ctx, staticFile)
        return
    }

    //set default encoding
    conn.SetHeader("Content-Type", "text/html; charset=utf-8", true)
    conn.SetHeader("Server", "web.go", true)

    for cr, route := range routes {
        if req.Method != route.method {
            continue
        }

        if !cr.MatchString(requestPath) {
            continue
        }
        match := cr.MatchStrings(requestPath)

        if len(match[0]) != len(requestPath) {
            continue
        }

        var args vector.Vector

        handlerType := route.handler.Type().(*reflect.FuncType)

        //check if the first arg in the handler is a context type
        if handlerType.NumIn() > 0 {
            if a0, ok := handlerType.In(0).(*reflect.PtrType); ok {
                typ := a0.Elem()
                if typ == contextType {
                    args.Push(reflect.NewValue(&ctx))
                }
            }
        }

        for _, arg := range match[1:] {
            args.Push(reflect.NewValue(arg))
        }

        if len(args) != handlerType.NumIn() {
            log.Stderrf("Incorrect number of arguments for %s\n", requestPath)
            ctx.Abort(500, "Server Error")
            return
        }

        valArgs := make([]reflect.Value, len(args))
        for i, j := range (args) {
            valArgs[i] = j.(reflect.Value)
        }
        ret := route.handler.Call(valArgs)[0].(*reflect.StringValue).Get()

        if !ctx.responseStarted {
            //check if session data is stored
            if len(s.Data) > 0 {
                s.save()
                //set the session for half an hour
                ctx.SetCookie(sessionKey, s.Id, 1800)
            }

            conn.StartResponse(200)
            ctx.responseStarted = true
            conn.WriteString(ret)
        }

        return
    }

    ctx.Abort(404, "Page not found")
}

//runs the web application and serves http requests
func Run(addr string) {
    http.Handle("/", http.HandlerFunc(httpHandler))

    log.Stdoutf("web.go serving %s", addr)
    err := http.ListenAndServe(addr, nil)
    if err != nil {
        log.Exit("ListenAndServe:", err)
    }
}

//runs the web application and serves scgi requests
func RunScgi(addr string) {
    log.Stdoutf("web.go serving scgi %s", addr)
    listenAndServeScgi(addr)
}

//runs the web application by serving fastcgi requests
func RunFcgi(addr string) {
    log.Stdoutf("web.go serving fcgi %s", addr)
    listenAndServeFcgi(addr)
}

//Adds a handler for the 'GET' http method.
func Get(route string, handler interface{}) { addRoute(route, "GET", handler) }

//Adds a handler for the 'POST' http method.
func Post(route string, handler interface{}) { addRoute(route, "POST", handler) }

//Adds a handler for the 'PUT' http method.
func Put(route string, handler interface{}) { addRoute(route, "PUT", handler) }

//Adds a handler for the 'DELETE' http method.
func Delete(route string, handler interface{}) {
    addRoute(route, "DELETE", handler)
}

func dirExists(dir string) bool {
    d, e := os.Stat(dir)
    switch {
    case e != nil:
        return false
    case !d.IsDirectory():
        return false
    }

    return true
}

func fileExists(dir string) bool {
    d, e := os.Stat(dir)
    switch {
    case e != nil:
        return false
    case !d.IsRegular():
        return false
    }

    return true
}

type dirError string

func (path dirError) String() string { return "Failed to set directory " + string(path) }

func getCwd() string { return os.Getenv("PWD") }

//changes the location of the static directory. by default, it's under the 'static' folder
//of the directory containing the web application
func SetStaticDir(dir string) os.Error {
    cwd := getCwd()
    sd := path.Join(cwd, dir)
    if !dirExists(sd) {
        return dirError(sd)

    }
    staticDir = sd

    return nil
}

//copied from go's http package, because it's not public
var statusText = map[int]string{
    http.StatusContinue: "Continue",
    http.StatusSwitchingProtocols: "Switching Protocols",

    http.StatusOK: "OK",
    http.StatusCreated: "Created",
    http.StatusAccepted: "Accepted",
    http.StatusNonAuthoritativeInfo: "Non-Authoritative Information",
    http.StatusNoContent: "No Content",
    http.StatusResetContent: "Reset Content",
    http.StatusPartialContent: "Partial Content",

    http.StatusMultipleChoices: "Multiple Choices",
    http.StatusMovedPermanently: "Moved Permanently",
    http.StatusFound: "Found",
    http.StatusSeeOther: "See Other",
    http.StatusNotModified: "Not Modified",
    http.StatusUseProxy: "Use Proxy",
    http.StatusTemporaryRedirect: "Temporary Redirect",

    http.StatusBadRequest: "Bad Request",
    http.StatusUnauthorized: "Unauthorized",
    http.StatusPaymentRequired: "Payment Required",
    http.StatusForbidden: "Forbidden",
    http.StatusNotFound: "Not Found",
    http.StatusMethodNotAllowed: "Method Not Allowed",
    http.StatusNotAcceptable: "Not Acceptable",
    http.StatusProxyAuthRequired: "Proxy Authentication Required",
    http.StatusRequestTimeout: "Request Timeout",
    http.StatusConflict: "Conflict",
    http.StatusGone: "Gone",
    http.StatusLengthRequired: "Length Required",
    http.StatusPreconditionFailed: "Precondition Failed",
    http.StatusRequestEntityTooLarge: "Request Entity Too Large",
    http.StatusRequestURITooLong: "Request URI Too Long",
    http.StatusUnsupportedMediaType: "Unsupported Media Type",
    http.StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable",
    http.StatusExpectationFailed: "Expectation Failed",

    http.StatusInternalServerError: "Internal Server Error",
    http.StatusNotImplemented: "Not Implemented",
    http.StatusBadGateway: "Bad Gateway",
    http.StatusServiceUnavailable: "Service Unavailable",
    http.StatusGatewayTimeout: "Gateway Timeout",
    http.StatusHTTPVersionNotSupported: "HTTP Version Not Supported",
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"github.com/ricardolonga/openv2/domain"
	"os"
)

type Response struct {
	UserMessage string       `json:"userMessage"`
	User        *domain.User `json:"user"`
}

func main() {
	userRepository := &domain.UserRepository{}

	router := gin.Default()

	router.Use(HeadersRequired())

	router.GET("/", func(c *gin.Context) {
		c.String(200, fmt.Sprintf("Olá!"))
	})

	router.POST("/login", func(c *gin.Context) {
		user := &domain.User{Name: c.Request.Header.Get("name"), Email: c.Request.Header.Get("email")}
		userRepository.Save(user)
		c.JSON(http.StatusOK, &Response{UserMessage: "Login successful!", User: user})
	})

	err := http.ListenAndServe(":8080", router)
	if err != nil {
		panic(err)
	}
}

func HeadersRequired() gin.HandlerFunc {
	return func(c *gin.Context) {
		if _, contain := c.Request.Header["Name"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Name is not defined into headers."})
			c.Abort()
		}

		if _, contain := c.Request.Header["Email"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Email is not defined into headers."})
			c.Abort()
		}
	}
}
<commit_msg>Corrigido imports.<commit_after>package main

import (
	"github.com/gin-gonic/gin"
	"net/http"
	"github.com/ricardolonga/openv2/domain"
)

type Response struct {
	UserMessage string       `json:"userMessage"`
	User        *domain.User `json:"user"`
}

func main() {
	userRepository := &domain.UserRepository{}

	router := gin.Default()

	router.Use(HeadersRequired())

	router.GET("/", func(c *gin.Context) {
		c.String(200, fmt.Sprintf("Olá!"))
	})

	router.POST("/login", func(c *gin.Context) {
		user := &domain.User{Name: c.Request.Header.Get("name"), Email: c.Request.Header.Get("email")}
		userRepository.Save(user)
		c.JSON(http.StatusOK, &Response{UserMessage: "Login successful!", User: user})
	})

	err := http.ListenAndServe(":8080", router)
	if err != nil {
		panic(err)
	}
}

func HeadersRequired() gin.HandlerFunc {
	return func(c *gin.Context) {
		if _, contain := c.Request.Header["Name"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Name is not defined into headers."})
			c.Abort()
		}

		if _, contain := c.Request.Header["Email"]; !contain {
			c.JSON(http.StatusBadRequest, &Response{UserMessage: "Email is not defined into headers."})
			c.Abort()
		}
	}
}
<|endoftext|>


<commit_before>package keychain

import "testing"

var app = "github.com/lunixbochs/go-keychain/test"

func TestFlow(t *testing.T) {
	err := Add(app, "testuser", "password")
	if err != nil {
		t.Fatal(err)
	}
	pass, err := Find(app, "testuser")
	if err != nil {
		t.Fatal(err)
	}
	if pass != "password" {
		t.Fatalf("password did not match: %s", pass)
	}
	err = Remove(app, "testuser")
	if err != nil {
		t.Fatal(err)
	}
	pass, err = Find(app, "testuser")
	if err == nil || err.Error() != "The specified item could not be found in the keychain." || pass != "" {
		t.Fatal("password remove failed")
	}
}
<commit_msg>don't check for specific error message<commit_after>package keychain

import "testing"

var app = "github.com/lunixbochs/go-keychain/test"

func TestFlow(t *testing.T) {
	err := Add(app, "testuser", "password")
	if err != nil {
		t.Fatal(err)
	}
	pass, err := Find(app, "testuser")
	if err != nil {
		t.Fatal(err)
	}
	if pass != "password" {
		t.Fatalf("password did not match: %s", pass)
	}
	err = Remove(app, "testuser")
	if err != nil {
		t.Fatal(err)
	}
	pass, err = Find(app, "testuser")
	if err == nil || pass != "" {
		t.Fatal("password remove failed")
	}
	strErr := err.Error()
	if strErr == "" || strErr == "Unknown error" {
		t.Fatal("problem exporting error message")
	}
}
<|endoftext|>


<commit_before>package decor

import (
	"fmt"
	"time"
	"unicode/utf8"
)

const (
	// DidentRight bit specifies identation direction.
	// |foo   |b     | With DidentRight
	// |   foo|     b| Without DidentRight
	DidentRight = 1 << iota

	// DextraSpace bit adds extra space, makes sense with DSyncWidth only.
	// When DidentRight bit set, the space will be added to the right,
	// otherwise to the left.
	DextraSpace

	// DSyncWidth bit enables same column width synchronization.
	// Effective with multiple bars only.
	DSyncWidth

	// DSyncWidthR is shortcut for DSyncWidth|DidentRight
	DSyncWidthR = DSyncWidth | DidentRight

	// DSyncSpace is shortcut for DSyncWidth|DextraSpace
	DSyncSpace = DSyncWidth | DextraSpace

	// DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight
	DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight
)

const (
	ET_STYLE_GO = iota
	ET_STYLE_HHMMSS
	ET_STYLE_HHMM
	ET_STYLE_MMSS
)

// Statistics is a struct, which gets passed to a Decorator.
type Statistics struct {
	ID        int
	Completed bool
	Total     int64
	Current   int64
}

// Decorator is an interface with one method:
//
//	Decor(st *Statistics, widthAccumulator chan<- int, widthDistributor <-chan int) string
//
// All decorators in this package implement this interface.
type Decorator interface {
	Decor(*Statistics, chan<- int, <-chan int) string
}

// OnCompleteMessenger is an interface with one method:
//
//	OnCompleteMessage(message string, wc ...WC)
//
// Decorators implementing this interface suppose to return provided string on complete event.
type OnCompleteMessenger interface {
	OnCompleteMessage(string, ...WC)
}

type AmountReceiver interface {
	NextAmount(int, ...time.Duration)
}

type ShutdownListener interface {
	Shutdown()
}

// DecoratorFunc is an adapter for Decorator interface
type DecoratorFunc func(*Statistics, chan<- int, <-chan int) string

func (f DecoratorFunc) Decor(s *Statistics, widthAccumulator chan<- int, widthDistributor <-chan int) string {
	return f(s, widthAccumulator, widthDistributor)
}

// Global convenience shortcuts
var (
	WCSyncWidth  = WC{C: DSyncWidth}
	WCSyncWidthR = WC{C: DSyncWidthR}
	WCSyncSpace  = WC{C: DSyncSpace}
	WCSyncSpaceR = WC{C: DSyncSpaceR}
)

// WC is a struct with two public fields W and C, both of int type.
// W represents width and C represents bit set of width related config.
type WC struct {
	W      int
	C      int
	format string
}

// FormatMsg formats final message according to WC.W and WC.C.
// Should be called by any Decorator implementation.
func (wc WC) FormatMsg(msg string, widthAccumulator chan<- int, widthDistributor <-chan int) string {
	if (wc.C & DSyncWidth) != 0 {
		widthAccumulator <- utf8.RuneCountInString(msg)
		max := <-widthDistributor
		if max == 0 {
			max = wc.W
		}
		if (wc.C & DextraSpace) != 0 {
			max++
		}
		return fmt.Sprintf(fmt.Sprintf(wc.format, max), msg)
	}
	return fmt.Sprintf(fmt.Sprintf(wc.format, wc.W), msg)
}

// BuildFormat builds initial format according to WC.C
func (wc *WC) BuildFormat() {
	wc.format = "%%"
	if (wc.C & DidentRight) != 0 {
		wc.format += "-"
	}
	wc.format += "%ds"
}

// OnComplete returns decorator, which wraps provided decorator, with sole
// purpose to display provided message on complete event.
//
//	`decorator` Decorator to wrap
//
//	`message` message to display on complete event
//
//	`wcc` optional WC config
func OnComplete(decorator Decorator, message string, wcc ...WC) Decorator {
	if cm, ok := decorator.(OnCompleteMessenger); ok {
		cm.OnCompleteMessage(message, wcc...)
		return decorator
	}
	msgDecorator := Name(message, wcc...)
	return DecoratorFunc(func(s *Statistics, widthAccumulator chan<- int, widthDistributor <-chan int) string {
		if s.Completed {
			return msgDecorator.Decor(s, widthAccumulator, widthDistributor)
		}
		return decorator.Decor(s, widthAccumulator, widthDistributor)
	})
}
<commit_msg>parenthesis are not necessary<commit_after>package decor

import (
	"fmt"
	"time"
	"unicode/utf8"
)

const (
	// DidentRight bit specifies identation direction.
	// |foo   |b     | With DidentRight
	// |   foo|     b| Without DidentRight
	DidentRight = 1 << iota

	// DextraSpace bit adds extra space, makes sense with DSyncWidth only.
	// When DidentRight bit set, the space will be added to the right,
	// otherwise to the left.
	DextraSpace

	// DSyncWidth bit enables same column width synchronization.
	// Effective with multiple bars only.
	DSyncWidth

	// DSyncWidthR is shortcut for DSyncWidth|DidentRight
	DSyncWidthR = DSyncWidth | DidentRight

	// DSyncSpace is shortcut for DSyncWidth|DextraSpace
	DSyncSpace = DSyncWidth | DextraSpace

	// DSyncSpaceR is shortcut for DSyncWidth|DextraSpace|DidentRight
	DSyncSpaceR = DSyncWidth | DextraSpace | DidentRight
)

const (
	ET_STYLE_GO = iota
	ET_STYLE_HHMMSS
	ET_STYLE_HHMM
	ET_STYLE_MMSS
)

// Statistics is a struct, which gets passed to a Decorator.
type Statistics struct {
	ID        int
	Completed bool
	Total     int64
	Current   int64
}

// Decorator is an interface with one method:
//
//	Decor(st *Statistics, widthAccumulator chan<- int, widthDistributor <-chan int) string
//
// All decorators in this package implement this interface.
type Decorator interface {
	Decor(*Statistics, chan<- int, <-chan int) string
}

// OnCompleteMessenger is an interface with one method:
//
//	OnCompleteMessage(message string, wc ...WC)
//
// Decorators implementing this interface suppose to return provided string on complete event.
type OnCompleteMessenger interface {
	OnCompleteMessage(string, ...WC)
}

type AmountReceiver interface {
	NextAmount(int, ...time.Duration)
}

type ShutdownListener interface {
	Shutdown()
}

// DecoratorFunc is an adapter for Decorator interface
type DecoratorFunc func(*Statistics, chan<- int, <-chan int) string

func (f DecoratorFunc) Decor(s *Statistics, widthAccumulator chan<- int, widthDistributor <-chan int) string {
	return f(s, widthAccumulator, widthDistributor)
}

// Global convenience shortcuts
var (
	WCSyncWidth  = WC{C: DSyncWidth}
	WCSyncWidthR = WC{C: DSyncWidthR}
	WCSyncSpace  = WC{C: DSyncSpace}
	WCSyncSpaceR = WC{C: DSyncSpaceR}
)

// WC is a struct with two public fields W and C, both of int type.
// W represents width and C represents bit set of width related config.
type WC struct {
	W      int
	C      int
	format string
}

// FormatMsg formats final message according to WC.W and WC.C.
// Should be called by any Decorator implementation.
func (wc WC) FormatMsg(msg string, widthAccumulator chan<- int, widthDistributor <-chan int) string {
	if wc.C&DSyncWidth != 0 {
		widthAccumulator <- utf8.RuneCountInString(msg)
		max := <-widthDistributor
		if max == 0 {
			max = wc.W
		}
		if wc.C&DextraSpace != 0 {
			max++
		}
		return fmt.Sprintf(fmt.Sprintf(wc.format, max), msg)
	}
	return fmt.Sprintf(fmt.Sprintf(wc.format, wc.W), msg)
}

// BuildFormat builds initial format according to WC.C
func (wc *WC) BuildFormat() {
	wc.format = "%%"
	if wc.C&DidentRight != 0 {
		wc.format += "-"
	}
	wc.format += "%ds"
}

// OnComplete returns decorator, which wraps provided decorator, with sole
// purpose to display provided message on complete event.
//
//	`decorator` Decorator to wrap
//
//	`message` message to display on complete event
//
//	`wcc` optional WC config
func OnComplete(decorator Decorator, message string, wcc ...WC) Decorator {
	if cm, ok := decorator.(OnCompleteMessenger); ok {
		cm.OnCompleteMessage(message, wcc...)
		return decorator
	}
	msgDecorator := Name(message, wcc...)
	return DecoratorFunc(func(s *Statistics, widthAccumulator chan<- int, widthDistributor <-chan int) string {
		if s.Completed {
			return msgDecorator.Decor(s, widthAccumulator, widthDistributor)
		}
		return decorator.Decor(s, widthAccumulator, widthDistributor)
	})
}
<|endoftext|>


<commit_before>package datadog

import (
	"github.com/zorkian/go-datadog-api"
)

func createPlaceholderGraph() []datadog.Graph {
	// Return a dummy placeholder graph -An API call to create or update a dashboard will
	// fail if there are no graphs

	graph_definition := datadog.Graph{}.Definition
	graph_definition.Viz = "timeseries"
	r := datadog.Graph{}.Definition.Requests
	graph_definition.Requests = append(r, GraphDefintionRequests{Query: "avg:system.mem.free{*}", Stacked: false})
	graph := datadog.Graph{Title: "Mandatory placeholder graph", Definition: graph_definition}
	graphs := []datadog.Graph{}
	graphs = append(graphs, graph) // Should be done for each
	return graphs
}
<commit_msg>Rephrase comment.<commit_after>package datadog

import (
	"github.com/zorkian/go-datadog-api"
)

func createPlaceholderGraph() []datadog.Graph {
	// Return a dummy placeholder graph.
    // This should be used when creating new dashboards, or removing the last
    // in a board.
    // Background; An API call to create or update dashboards (Timeboards) will
    // fail if it contains zero graphs. This is a bug in the Datadog API,
    // as dashboards *can* exist without any graphs.

	graph_definition := datadog.Graph{}.Definition
	graph_definition.Viz = "timeseries"
	r := datadog.Graph{}.Definition.Requests
	graph_definition.Requests = append(r, GraphDefintionRequests{Query: "avg:system.mem.free{*}", Stacked: false})
	graph := datadog.Graph{Title: "Mandatory placeholder graph", Definition: graph_definition}
	graphs := []datadog.Graph{}
	graphs = append(graphs, graph)
	return graphs
}
<|endoftext|>


<commit_before>package buffalo

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/gobuffalo/buffalo/render"
	"github.com/gorilla/websocket"
	"github.com/pkg/errors"
)

// assert that DefaultContext is implementing Context
var _ Context = &DefaultContext{}
var _ context.Context = &DefaultContext{}

// DefaultContext is, as its name implies, a default
// implementation of the Context interface.
type DefaultContext struct {
	context.Context
	response    http.ResponseWriter
	request     *http.Request
	params      url.Values
	logger      Logger
	session     *Session
	contentType string
	data        map[string]interface{}
	flash       *Flash
}

// Response returns the original Response for the request.
func (d *DefaultContext) Response() http.ResponseWriter {
	return d.response
}

// Request returns the original Request.
func (d *DefaultContext) Request() *http.Request {
	return d.request
}

// Params returns all of the parameters for the request,
// including both named params and query string parameters.
// These parameters are automatically available in templates
// as "{{.params}}".
func (d *DefaultContext) Params() ParamValues {
	return d.params
}

// Logger returns the Logger for this context.
func (d *DefaultContext) Logger() Logger {
	return d.logger
}

// Param returns a param, either named or query string,
// based on the key.
func (d *DefaultContext) Param(key string) string {
	return d.Params().Get(key)
}

// ParamInt tries to convert the requested parameter to
// an int. It will return an error if there is a problem.
func (d *DefaultContext) ParamInt(key string) (int, error) {
	k := d.Params().Get(key)
	i, err := strconv.Atoi(k)
	return i, errors.WithMessage(err, fmt.Sprintf("could not convert %s to an int", k))
}

// Set a value onto the Context. Any value set onto the Context
// will be automatically available in templates.
func (d *DefaultContext) Set(key string, value interface{}) {
	d.data[key] = value
}

// Get is deprecated. Please use Value instead.
func (d *DefaultContext) Get(key string) interface{} {
	warningMsg := "Context#Get is deprecated. Please use Context#Value instead."

	_, file, no, ok := runtime.Caller(1)
	if ok {
		warningMsg = fmt.Sprintf("Context#Get is deprecated. Please use Context#Value instead. Called from %s:%d", file, no)
	}

	d.Logger().Warn(warningMsg)
	return d.Value(key)
}

// Value that has previously stored on the context.
func (d *DefaultContext) Value(key interface{}) interface{} {
	if k, ok := key.(string); ok {
		if v, ok := d.data[k]; ok {
			return v
		}
	}
	return d.Context.Value(key)
}

// Session for the associated Request.
func (d *DefaultContext) Session() *Session {
	return d.session
}

// Flash messages for the associated Request.
func (d *DefaultContext) Flash() *Flash {
	return d.flash
}

// Render a status code and render.Renderer to the associated Response.
// The request parameters will be made available to the render.Renderer
// "{{.params}}". Any values set onto the Context will also automatically
// be made available to the render.Renderer. To render "no content" pass
// in a nil render.Renderer.
func (d *DefaultContext) Render(status int, rr render.Renderer) error {
	now := time.Now()
	defer func() {
		d.LogField("render", time.Now().Sub(now))
	}()
	if rr != nil {
		data := d.data
		pp := map[string]string{}
		for k, v := range d.params {
			pp[k] = v[0]
		}
		data["params"] = pp
		data["flash"] = d.Flash().data
		bb := &bytes.Buffer{}

		err := rr.Render(bb, data)
		if err != nil {
			return HTTPError{Status: 500, Cause: errors.WithStack(err)}
		}

		if d.Session() != nil {
			d.Flash().Clear()
			d.Flash().persist(d.Session())
		}

		d.Response().Header().Set("Content-Type", rr.ContentType())
		d.Response().WriteHeader(status)
		_, err = io.Copy(d.Response(), bb)
		if err != nil {
			return HTTPError{Status: 500, Cause: errors.WithStack(err)}
		}

		return nil
	}
	d.Response().WriteHeader(status)
	return nil
}

// Bind the interface to the request.Body. The type of binding
// is dependent on the "Content-Type" for the request. If the type
// is "application/json" it will use "json.NewDecoder". If the type
// is "application/xml" it will use "xml.NewDecoder". The default
// binder is "http://www.gorillatoolkit.org/pkg/schema".
func (d *DefaultContext) Bind(value interface{}) error {
	ct := strings.ToLower(d.Request().Header.Get("Content-Type"))
	cts := strings.Split(ct, ";")
	for _, c := range cts {
		if b, ok := binders[strings.TrimSpace(c)]; ok {
			return b(d.Request(), value)
		}
	}
	return errors.Errorf("could not find a binder for %s", ct)
}

// LogField adds the key/value pair onto the Logger to be printed out
// as part of the request logging. This allows you to easily add things
// like metrics (think DB times) to your request.
func (d *DefaultContext) LogField(key string, value interface{}) {
	d.logger = d.logger.WithField(key, value)
}

// LogFields adds the key/value pairs onto the Logger to be printed out
// as part of the request logging. This allows you to easily add things
// like metrics (think DB times) to your request.
func (d *DefaultContext) LogFields(values map[string]interface{}) {
	d.logger = d.logger.WithFields(values)
}

func (d *DefaultContext) Error(status int, err error) error {
	return HTTPError{Status: status, Cause: errors.WithStack(err)}
}

// Websocket returns an upgraded github.com/gorilla/websocket.Conn
// that can then be used to work with websockets easily.
func (d *DefaultContext) Websocket() (*websocket.Conn, error) {
	return defaultUpgrader.Upgrade(d.Response(), d.Request(), nil)
}

// Redirect a request with the given status to the given URL.
func (d *DefaultContext) Redirect(status int, url string, args ...interface{}) error {
	d.Flash().persist(d.Session())

	http.Redirect(d.Response(), d.Request(), fmt.Sprintf(url, args...), status)
	return nil
}

// Data contains all the values set through Get/Set.
func (d *DefaultContext) Data() map[string]interface{} {
	return d.data
}

var defaultUpgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin:     func(r *http.Request) bool { return true },
}
<commit_msg>use only the first content-type requested<commit_after>package buffalo

import (
	"bytes"
	"context"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/gobuffalo/buffalo/render"
	"github.com/gorilla/websocket"
	"github.com/pkg/errors"
)

// assert that DefaultContext is implementing Context
var _ Context = &DefaultContext{}
var _ context.Context = &DefaultContext{}

// DefaultContext is, as its name implies, a default
// implementation of the Context interface.
type DefaultContext struct {
	context.Context
	response    http.ResponseWriter
	request     *http.Request
	params      url.Values
	logger      Logger
	session     *Session
	contentType string
	data        map[string]interface{}
	flash       *Flash
}

// Response returns the original Response for the request.
func (d *DefaultContext) Response() http.ResponseWriter {
	return d.response
}

// Request returns the original Request.
func (d *DefaultContext) Request() *http.Request {
	return d.request
}

// Params returns all of the parameters for the request,
// including both named params and query string parameters.
// These parameters are automatically available in templates
// as "{{.params}}".
func (d *DefaultContext) Params() ParamValues {
	return d.params
}

// Logger returns the Logger for this context.
func (d *DefaultContext) Logger() Logger {
	return d.logger
}

// Param returns a param, either named or query string,
// based on the key.
func (d *DefaultContext) Param(key string) string {
	return d.Params().Get(key)
}

// ParamInt tries to convert the requested parameter to
// an int. It will return an error if there is a problem.
func (d *DefaultContext) ParamInt(key string) (int, error) {
	k := d.Params().Get(key)
	i, err := strconv.Atoi(k)
	return i, errors.WithMessage(err, fmt.Sprintf("could not convert %s to an int", k))
}

// Set a value onto the Context. Any value set onto the Context
// will be automatically available in templates.
func (d *DefaultContext) Set(key string, value interface{}) {
	d.data[key] = value
}

// Get is deprecated. Please use Value instead.
func (d *DefaultContext) Get(key string) interface{} {
	warningMsg := "Context#Get is deprecated. Please use Context#Value instead."

	_, file, no, ok := runtime.Caller(1)
	if ok {
		warningMsg = fmt.Sprintf("Context#Get is deprecated. Please use Context#Value instead. Called from %s:%d", file, no)
	}

	d.Logger().Warn(warningMsg)
	return d.Value(key)
}

// Value that has previously stored on the context.
func (d *DefaultContext) Value(key interface{}) interface{} {
	if k, ok := key.(string); ok {
		if v, ok := d.data[k]; ok {
			return v
		}
	}
	return d.Context.Value(key)
}

// Session for the associated Request.
func (d *DefaultContext) Session() *Session {
	return d.session
}

// Flash messages for the associated Request.
func (d *DefaultContext) Flash() *Flash {
	return d.flash
}

// Render a status code and render.Renderer to the associated Response.
// The request parameters will be made available to the render.Renderer
// "{{.params}}". Any values set onto the Context will also automatically
// be made available to the render.Renderer. To render "no content" pass
// in a nil render.Renderer.
func (d *DefaultContext) Render(status int, rr render.Renderer) error {
	now := time.Now()
	defer func() {
		d.LogField("render", time.Now().Sub(now))
	}()
	if rr != nil {
		data := d.data
		pp := map[string]string{}
		for k, v := range d.params {
			pp[k] = v[0]
		}
		data["params"] = pp
		data["flash"] = d.Flash().data
		bb := &bytes.Buffer{}

		err := rr.Render(bb, data)
		if err != nil {
			return HTTPError{Status: 500, Cause: errors.WithStack(err)}
		}

		if d.Session() != nil {
			d.Flash().Clear()
			d.Flash().persist(d.Session())
		}

		d.Response().Header().Set("Content-Type", rr.ContentType())
		d.Response().WriteHeader(status)
		_, err = io.Copy(d.Response(), bb)
		if err != nil {
			return HTTPError{Status: 500, Cause: errors.WithStack(err)}
		}

		return nil
	}
	d.Response().WriteHeader(status)
	return nil
}

// Bind the interface to the request.Body. The type of binding
// is dependent on the "Content-Type" for the request. If the type
// is "application/json" it will use "json.NewDecoder". If the type
// is "application/xml" it will use "xml.NewDecoder". The default
// binder is "http://www.gorillatoolkit.org/pkg/schema".
func (d *DefaultContext) Bind(value interface{}) error {
	ct := strings.ToLower(d.Request().Header.Get("Content-Type"))
	cts := strings.Split(ct, ";")[0]
	if b, ok := binders[strings.TrimSpace(cts)]; ok {
		return b(d.Request(), value)
	}
	return errors.Errorf("could not find a binder for %s", ct)
}

// LogField adds the key/value pair onto the Logger to be printed out
// as part of the request logging. This allows you to easily add things
// like metrics (think DB times) to your request.
func (d *DefaultContext) LogField(key string, value interface{}) {
	d.logger = d.logger.WithField(key, value)
}

// LogFields adds the key/value pairs onto the Logger to be printed out
// as part of the request logging. This allows you to easily add things
// like metrics (think DB times) to your request.
func (d *DefaultContext) LogFields(values map[string]interface{}) {
	d.logger = d.logger.WithFields(values)
}

func (d *DefaultContext) Error(status int, err error) error {
	return HTTPError{Status: status, Cause: errors.WithStack(err)}
}

// Websocket returns an upgraded github.com/gorilla/websocket.Conn
// that can then be used to work with websockets easily.
func (d *DefaultContext) Websocket() (*websocket.Conn, error) {
	return defaultUpgrader.Upgrade(d.Response(), d.Request(), nil)
}

// Redirect a request with the given status to the given URL.
func (d *DefaultContext) Redirect(status int, url string, args ...interface{}) error {
	d.Flash().persist(d.Session())

	http.Redirect(d.Response(), d.Request(), fmt.Sprintf(url, args...), status)
	return nil
}

// Data contains all the values set through Get/Set.
func (d *DefaultContext) Data() map[string]interface{} {
	return d.data
}

var defaultUpgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin:     func(r *http.Request) bool { return true },
}
<|endoftext|>


<commit_before>package raft

import (
	"errors"
	"time"
)

var (
	ErrTimeout        = errors.New("timeout")
	ErrInvalidRequest = errors.New("invalid request")
)

// Peer is anything which provides a Raft-domain interface to a server. Peer is
// an interface to facilitate making servers available over different transport
// mechanisms (e.g. pure local, net/rpc, Protobufs, HTTP...). All peers should
// be 1:1 with a server. Things that implement Peer exist in the process-space
// of the local Raft node.
type Peer interface {
	Id() uint64
	AppendEntries(AppendEntries) AppendEntriesResponse
	RequestVote(RequestVote) RequestVoteResponse
	Command([]byte, chan []byte) error
}

// LocalPeer is the simplest kind of peer, mapped to a server in the
// same process-space. Useful for testing and demonstration; not so
// useful for networks of independent processes.
type LocalPeer struct {
	server *Server
}

func NewLocalPeer(server *Server) *LocalPeer { return &LocalPeer{server} }

func (p *LocalPeer) Id() uint64 { return p.server.Id() }

func (p *LocalPeer) AppendEntries(ae AppendEntries) AppendEntriesResponse {
	return p.server.AppendEntries(ae)
}

func (p *LocalPeer) RequestVote(rv RequestVote) RequestVoteResponse {
	return p.server.RequestVote(rv)
}

func (p *LocalPeer) Command(cmd []byte, response chan []byte) error {
	return p.server.Command(cmd, response)
}

// requestVoteTimeout issues the RequestVote to the given peer.
// If no response is received before timeout, an error is returned.
func requestVoteTimeout(p Peer, rv RequestVote, timeout time.Duration) (RequestVoteResponse, error) {
	c := make(chan RequestVoteResponse)
	go func() { c <- p.RequestVote(rv) }()

	select {
	case resp := <-c:
		return resp, nil
	case <-time.After(timeout):
		return RequestVoteResponse{}, ErrTimeout
	}
}

// Peers is a collection of Peer interfaces. It provides some convenience
// functions for actions that should apply to multiple Peers.
type Peers map[uint64]Peer

// MakePeers returns a Peers structure from the passed (vararg) list of peers.
func MakePeers(peers ...Peer) Peers {
	p := Peers{}
	for _, peer := range peers {
		p[peer.Id()] = peer
	}
	return p
}

func (p Peers) Except(id uint64) Peers {
	except := Peers{}
	for id0, peer := range p {
		if id0 == id {
			continue
		}
		except[id0] = peer
	}
	return except
}

func (p Peers) Count() int { return len(p) }

func (p Peers) Quorum() int {
	switch n := len(p); n {
	case 0, 1:
		return 1
	default:
		return (n / 2) + 1
	}
}

// requestVotes sends the passed RequestVote RPC to every peer in Peers. It
// forwards responses along the returned RequestVoteResponse channel. It makes
// the RPCs with a timeout of BroadcastInterval * 2 (chosen arbitrarily). Peers
// that don't respond within the timeout are retried forever. The retry loop
// stops only when all peers have responded, or a Cancel signal is sent via the
// returned Canceler.
func (p Peers) requestVotes(r RequestVote) (chan RequestVoteResponse, canceler) {
	// "[A server entering the candidate stage] issues RequestVote RPCs in
	// parallel to each of the other servers in the cluster. If the candidate
	// receives no response for an RPC, it reissues the RPC repeatedly until a
	// response arrives or the election concludes."

	// construct the channels we'll return
	abortChan := make(chan struct{})
	responsesChan := make(chan RequestVoteResponse)

	// compact a peer.RequestVote response to a single struct
	type tuple struct {
		Id                  uint64
		RequestVoteResponse RequestVoteResponse
		Err                 error
	}

	go func() {
		// We loop until all Peers have given us a response.
		// Track which Peers have responded.
		respondedAlready := Peers{} // none yet

		for {
			notYetResponded := disjoint(p, respondedAlready)
			if len(notYetResponded) <= 0 {
				return // done
			}

			// scatter
			tupleChan := make(chan tuple, len(notYetResponded))
			for id, peer := range notYetResponded {
				go func(id0 uint64, peer0 Peer) {
					resp, err := requestVoteTimeout(peer0, r, 2*BroadcastInterval())
					tupleChan <- tuple{id0, resp, err}
				}(id, peer)
			}

			// gather
			for i := 0; i < len(notYetResponded); i++ {
				select {
				case t := <-tupleChan:
					if t.Err != nil {
						continue // will need to retry
					}
					respondedAlready[t.Id] = nil           // value irrelevant
					responsesChan <- t.RequestVoteResponse // forward the vote
				case <-abortChan:
					return // give up
				}
			}
		}
	}()

	return responsesChan, cancel(abortChan)
}

type canceler interface {
	Cancel()
}

type cancel chan struct{}

func (c cancel) Cancel() { close(c) }

func disjoint(all, except Peers) Peers {
	d := Peers{}
	for id, peer := range all {
		if _, ok := except[id]; ok {
			continue
		}
		d[id] = peer
	}
	return d
}
<commit_msg>Fix leaky goroutine<commit_after>package raft

import (
	"errors"
	"time"
)

var (
	ErrTimeout        = errors.New("timeout")
	ErrInvalidRequest = errors.New("invalid request")
)

// Peer is anything which provides a Raft-domain interface to a server. Peer is
// an interface to facilitate making servers available over different transport
// mechanisms (e.g. pure local, net/rpc, Protobufs, HTTP...). All peers should
// be 1:1 with a server. Things that implement Peer exist in the process-space
// of the local Raft node.
type Peer interface {
	Id() uint64
	AppendEntries(AppendEntries) AppendEntriesResponse
	RequestVote(RequestVote) RequestVoteResponse
	Command([]byte, chan []byte) error
}

// LocalPeer is the simplest kind of peer, mapped to a server in the
// same process-space. Useful for testing and demonstration; not so
// useful for networks of independent processes.
type LocalPeer struct {
	server *Server
}

func NewLocalPeer(server *Server) *LocalPeer { return &LocalPeer{server} }

func (p *LocalPeer) Id() uint64 { return p.server.Id() }

func (p *LocalPeer) AppendEntries(ae AppendEntries) AppendEntriesResponse {
	return p.server.AppendEntries(ae)
}

func (p *LocalPeer) RequestVote(rv RequestVote) RequestVoteResponse {
	return p.server.RequestVote(rv)
}

func (p *LocalPeer) Command(cmd []byte, response chan []byte) error {
	return p.server.Command(cmd, response)
}

// requestVoteTimeout issues the RequestVote to the given peer.
// If no response is received before timeout, an error is returned.
func requestVoteTimeout(p Peer, rv RequestVote, timeout time.Duration) (RequestVoteResponse, error) {
	c := make(chan RequestVoteResponse, 1)
	go func() { c <- p.RequestVote(rv) }()

	select {
	case resp := <-c:
		return resp, nil
	case <-time.After(timeout):
		return RequestVoteResponse{}, ErrTimeout
	}
}

// Peers is a collection of Peer interfaces. It provides some convenience
// functions for actions that should apply to multiple Peers.
type Peers map[uint64]Peer

// MakePeers returns a Peers structure from the passed (vararg) list of peers.
func MakePeers(peers ...Peer) Peers {
	p := Peers{}
	for _, peer := range peers {
		p[peer.Id()] = peer
	}
	return p
}

func (p Peers) Except(id uint64) Peers {
	except := Peers{}
	for id0, peer := range p {
		if id0 == id {
			continue
		}
		except[id0] = peer
	}
	return except
}

func (p Peers) Count() int { return len(p) }

func (p Peers) Quorum() int {
	switch n := len(p); n {
	case 0, 1:
		return 1
	default:
		return (n / 2) + 1
	}
}

// requestVotes sends the passed RequestVote RPC to every peer in Peers. It
// forwards responses along the returned RequestVoteResponse channel. It makes
// the RPCs with a timeout of BroadcastInterval * 2 (chosen arbitrarily). Peers
// that don't respond within the timeout are retried forever. The retry loop
// stops only when all peers have responded, or a Cancel signal is sent via the
// returned Canceler.
func (p Peers) requestVotes(r RequestVote) (chan RequestVoteResponse, canceler) {
	// "[A server entering the candidate stage] issues RequestVote RPCs in
	// parallel to each of the other servers in the cluster. If the candidate
	// receives no response for an RPC, it reissues the RPC repeatedly until a
	// response arrives or the election concludes."

	// construct the channels we'll return
	abortChan := make(chan struct{})
	responsesChan := make(chan RequestVoteResponse)

	// compact a peer.RequestVote response to a single struct
	type tuple struct {
		Id                  uint64
		RequestVoteResponse RequestVoteResponse
		Err                 error
	}

	go func() {
		// We loop until all Peers have given us a response.
		// Track which Peers have responded.
		respondedAlready := Peers{} // none yet

		for {
			notYetResponded := disjoint(p, respondedAlready)
			if len(notYetResponded) <= 0 {
				return // done
			}

			// scatter
			tupleChan := make(chan tuple, len(notYetResponded))
			for id, peer := range notYetResponded {
				go func(id0 uint64, peer0 Peer) {
					resp, err := requestVoteTimeout(peer0, r, 2*BroadcastInterval())
					tupleChan <- tuple{id0, resp, err}
				}(id, peer)
			}

			// gather
			for i := 0; i < len(notYetResponded); i++ {
				select {
				case t := <-tupleChan:
					if t.Err != nil {
						continue // will need to retry
					}
					respondedAlready[t.Id] = nil           // value irrelevant
					responsesChan <- t.RequestVoteResponse // forward the vote
				case <-abortChan:
					return // give up
				}
			}
		}
	}()

	return responsesChan, cancel(abortChan)
}

type canceler interface {
	Cancel()
}

type cancel chan struct{}

func (c cancel) Cancel() { close(c) }

func disjoint(all, except Peers) Peers {
	d := Peers{}
	for id, peer := range all {
		if _, ok := except[id]; ok {
			continue
		}
		d[id] = peer
	}
	return d
}
<|endoftext|>


<commit_before>package ulog

import "testing"

func TestEcho(t *testing.T) {
	output := "worked"

	j := NewJob("test")
	cmd := j.Cmds.New("echo", output)
	if err := cmd.Run(); err != nil {
		t.Error(err)
	}
	if string(cmd.Buf.Bytes()) != output+"\n" {
		t.Errorf("Echo didn't print out to log correctly. Should have been: %s, was: %s\n", output, cmd.Buf.Bytes())
	}
}
<commit_msg>Fixing tests.<commit_after>package ulog

import (
	"strings"
	"testing"
)

func TestEcho(t *testing.T) {
	output := "worked"

	j := NewJob("test")
	cmd := j.Cmds.New("echo", output)
	if err := cmd.Run(); err != nil {
		t.Error(err)
	}
	if strings.Compare(cmd.Str, output+"\n") != 0 {
		t.Errorf("Echo didn't print out to log correctly. Should have been: %s, was: %s\n", output, cmd.Str)
	}
}
<|endoftext|>