<commit_before>package server

import (
	"errors"
	"fmt"
	"syscall"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"

	"github.com/docker/containerd/api/grpc/types"
	"github.com/docker/containerd/runtime"
	"github.com/docker/containerd/specs"
	"github.com/docker/containerd/supervisor"
	"golang.org/x/net/context"
)

type apiServer struct {
	sv *supervisor.Supervisor
}

// NewServer returns grpc server instance
func NewServer(sv *supervisor.Supervisor) types.APIServer {
	return &apiServer{
		sv: sv,
	}
}

func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContainerRequest) (*types.CreateContainerResponse, error) {
	if c.BundlePath == "" {
		return nil, errors.New("empty bundle path")
	}
	e := &supervisor.StartTask{}
	e.ID = c.Id
	e.BundlePath = c.BundlePath
	e.Stdin = c.Stdin
	e.Stdout = c.Stdout
	e.Stderr = c.Stderr
	e.Labels = c.Labels
	e.StartResponse = make(chan supervisor.StartResponse, 1)
	createContainerConfigCheckpoint(e, c)
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	r := <-e.StartResponse
	apiC, err := createAPIContainer(r.Container, false)
	if err != nil {
		return nil, err
	}
	return &types.CreateContainerResponse{
		Container: apiC,
	}, nil
}

func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) {
	e := &supervisor.SignalTask{}
	e.ID = r.Id
	e.PID = r.Pid
	e.Signal = syscall.Signal(int(r.Signal))
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	return &types.SignalResponse{}, nil
}

func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest) (*types.AddProcessResponse, error) {
	process := &specs.ProcessSpec{
		Terminal: r.Terminal,
		Args:     r.Args,
		Env:      r.Env,
		Cwd:      r.Cwd,
	}
	setPlatformRuntimeProcessSpecUserFields(r, process)

	if r.Id == "" {
		return nil, fmt.Errorf("container id cannot be empty")
	}
	if r.Pid == "" {
		return nil, fmt.Errorf("process id cannot be empty")
	}
	e := &supervisor.AddProcessTask{}
	e.ID = r.Id
	e.PID = r.Pid
	e.ProcessSpec = process
	e.Stdin = r.Stdin
	e.Stdout = r.Stdout
	e.Stderr = r.Stderr
	e.StartResponse = make(chan supervisor.StartResponse, 1)
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	<-e.StartResponse
	return &types.AddProcessResponse{}, nil
}

func (s *apiServer) State(ctx context.Context, r *types.StateRequest) (*types.StateResponse, error) {
	e := &supervisor.GetContainersTask{}
	e.ID = r.Id
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	m := s.sv.Machine()
	state := &types.StateResponse{
		Machine: &types.Machine{
			Cpus:   uint32(m.Cpus),
			Memory: uint64(m.Memory),
		},
	}
	for _, c := range e.Containers {
		apiC, err := createAPIContainer(c, true)
		if err != nil {
			return nil, err
		}
		state.Containers = append(state.Containers, apiC)
	}
	return state, nil
}

func createAPIContainer(c runtime.Container, getPids bool) (*types.Container, error) {
	processes, err := c.Processes()
	if err != nil {
		return nil, grpc.Errorf(codes.Internal, "get processes for container")
	}
	var procs []*types.Process
	for _, p := range processes {
		oldProc := p.Spec()
		stdio := p.Stdio()
		appendToProcs := &types.Process{
			Pid:       p.ID(),
			SystemPid: uint32(p.SystemPid()),
			Terminal:  oldProc.Terminal,
			Args:      oldProc.Args,
			Env:       oldProc.Env,
			Cwd:       oldProc.Cwd,
			Stdin:     stdio.Stdin,
			Stdout:    stdio.Stdout,
			Stderr:    stdio.Stderr,
		}
		setUserFieldsInProcess(appendToProcs, oldProc)
		procs = append(procs, appendToProcs)
	}
	var pids []int
	state := c.State()
	if getPids && (state == runtime.Running || state == runtime.Paused) {
		if pids, err = c.Pids(); err != nil {
			return nil, grpc.Errorf(codes.Internal, "get all pids for container")
		}
	}
	return &types.Container{
		Id:         c.ID(),
		BundlePath: c.Path(),
		Processes:  procs,
		Labels:     c.Labels(),
		Status:     string(state),
		Pids:       toUint32(pids),
		Runtime:    c.Runtime(),
	}, nil
}

func toUint32(its []int) []uint32 {
	o := []uint32{}
	for _, i := range its {
		o = append(o, uint32(i))
	}
	return o
}

func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContainerRequest) (*types.UpdateContainerResponse, error) {
	e := &supervisor.UpdateTask{}
	e.ID = r.Id
	e.State = runtime.State(r.Status)
	if r.Resources != nil {
		rs := r.Resources
		e.Resources = &runtime.Resource{}
		if rs.CpuShares != 0 {
			e.Resources.CPUShares = int64(rs.CpuShares)
		}
		if rs.BlkioWeight != 0 {
			e.Resources.BlkioWeight = uint16(rs.BlkioWeight)
		}
		if rs.CpuPeriod != 0 {
			e.Resources.CPUPeriod = int64(rs.CpuPeriod)
		}
		if rs.CpuQuota != 0 {
			e.Resources.CPUQuota = int64(rs.CpuQuota)
		}
		if rs.CpusetCpus != "" {
			e.Resources.CpusetCpus = rs.CpusetCpus
		}
		if rs.CpusetMems != "" {
			e.Resources.CpusetMems = rs.CpusetMems
		}
		if rs.KernelMemoryLimit != 0 {
			e.Resources.KernelMemory = int64(rs.KernelMemoryLimit)
		}
		if rs.MemoryLimit != 0 {
			e.Resources.Memory = int64(rs.MemoryLimit)
		}
		if rs.MemoryReservation != 0 {
			e.Resources.MemoryReservation = int64(rs.MemoryReservation)
		}
		if rs.MemorySwap != 0 {
			e.Resources.MemorySwap = int64(rs.MemorySwap)
		}
	}
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	return &types.UpdateContainerResponse{}, nil
}

func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessRequest) (*types.UpdateProcessResponse, error) {
	e := &supervisor.UpdateProcessTask{}
	e.ID = r.Id
	e.PID = r.Pid
	e.Height = int(r.Height)
	e.Width = int(r.Width)
	e.CloseStdin = r.CloseStdin
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	return &types.UpdateProcessResponse{}, nil
}

func (s *apiServer) Events(r *types.EventsRequest, stream types.API_EventsServer) error {
	t := time.Time{}
	if r.Timestamp != 0 {
		t = time.Unix(int64(r.Timestamp), 0)
	}
	events := s.sv.Events(t)
	defer s.sv.Unsubscribe(events)
	for e := range events {
		if err := stream.Send(&types.Event{
			Id:        e.ID,
			Type:      e.Type,
			Timestamp: uint64(e.Timestamp.Unix()),
			Pid:       e.PID,
			Status:    uint32(e.Status),
		}); err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>Append error message to internal errors<commit_after>package server

import (
	"errors"
	"fmt"
	"syscall"
	"time"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"

	"github.com/docker/containerd/api/grpc/types"
	"github.com/docker/containerd/runtime"
	"github.com/docker/containerd/specs"
	"github.com/docker/containerd/supervisor"
	"golang.org/x/net/context"
)

type apiServer struct {
	sv *supervisor.Supervisor
}

// NewServer returns grpc server instance
func NewServer(sv *supervisor.Supervisor) types.APIServer {
	return &apiServer{
		sv: sv,
	}
}

func (s *apiServer) CreateContainer(ctx context.Context, c *types.CreateContainerRequest) (*types.CreateContainerResponse, error) {
	if c.BundlePath == "" {
		return nil, errors.New("empty bundle path")
	}
	e := &supervisor.StartTask{}
	e.ID = c.Id
	e.BundlePath = c.BundlePath
	e.Stdin = c.Stdin
	e.Stdout = c.Stdout
	e.Stderr = c.Stderr
	e.Labels = c.Labels
	e.StartResponse = make(chan supervisor.StartResponse, 1)
	createContainerConfigCheckpoint(e, c)
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	r := <-e.StartResponse
	apiC, err := createAPIContainer(r.Container, false)
	if err != nil {
		return nil, err
	}
	return &types.CreateContainerResponse{
		Container: apiC,
	}, nil
}

func (s *apiServer) Signal(ctx context.Context, r *types.SignalRequest) (*types.SignalResponse, error) {
	e := &supervisor.SignalTask{}
	e.ID = r.Id
	e.PID = r.Pid
	e.Signal = syscall.Signal(int(r.Signal))
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	return &types.SignalResponse{}, nil
}

func (s *apiServer) AddProcess(ctx context.Context, r *types.AddProcessRequest) (*types.AddProcessResponse, error) {
	process := &specs.ProcessSpec{
		Terminal: r.Terminal,
		Args:     r.Args,
		Env:      r.Env,
		Cwd:      r.Cwd,
	}
	setPlatformRuntimeProcessSpecUserFields(r, process)

	if r.Id == "" {
		return nil, fmt.Errorf("container id cannot be empty")
	}
	if r.Pid == "" {
		return nil, fmt.Errorf("process id cannot be empty")
	}
	e := &supervisor.AddProcessTask{}
	e.ID = r.Id
	e.PID = r.Pid
	e.ProcessSpec = process
	e.Stdin = r.Stdin
	e.Stdout = r.Stdout
	e.Stderr = r.Stderr
	e.StartResponse = make(chan supervisor.StartResponse, 1)
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	<-e.StartResponse
	return &types.AddProcessResponse{}, nil
}

func (s *apiServer) State(ctx context.Context, r *types.StateRequest) (*types.StateResponse, error) {
	e := &supervisor.GetContainersTask{}
	e.ID = r.Id
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	m := s.sv.Machine()
	state := &types.StateResponse{
		Machine: &types.Machine{
			Cpus:   uint32(m.Cpus),
			Memory: uint64(m.Memory),
		},
	}
	for _, c := range e.Containers {
		apiC, err := createAPIContainer(c, true)
		if err != nil {
			return nil, err
		}
		state.Containers = append(state.Containers, apiC)
	}
	return state, nil
}

func createAPIContainer(c runtime.Container, getPids bool) (*types.Container, error) {
	processes, err := c.Processes()
	if err != nil {
		return nil, grpc.Errorf(codes.Internal, "get processes for container: "+err.Error())
	}
	var procs []*types.Process
	for _, p := range processes {
		oldProc := p.Spec()
		stdio := p.Stdio()
		appendToProcs := &types.Process{
			Pid:       p.ID(),
			SystemPid: uint32(p.SystemPid()),
			Terminal:  oldProc.Terminal,
			Args:      oldProc.Args,
			Env:       oldProc.Env,
			Cwd:       oldProc.Cwd,
			Stdin:     stdio.Stdin,
			Stdout:    stdio.Stdout,
			Stderr:    stdio.Stderr,
		}
		setUserFieldsInProcess(appendToProcs, oldProc)
		procs = append(procs, appendToProcs)
	}
	var pids []int
	state := c.State()
	if getPids && (state == runtime.Running || state == runtime.Paused) {
		if pids, err = c.Pids(); err != nil {
			return nil, grpc.Errorf(codes.Internal, "get all pids for container: "+err.Error())
		}
	}
	return &types.Container{
		Id:         c.ID(),
		BundlePath: c.Path(),
		Processes:  procs,
		Labels:     c.Labels(),
		Status:     string(state),
		Pids:       toUint32(pids),
		Runtime:    c.Runtime(),
	}, nil
}

func toUint32(its []int) []uint32 {
	o := []uint32{}
	for _, i := range its {
		o = append(o, uint32(i))
	}
	return o
}

func (s *apiServer) UpdateContainer(ctx context.Context, r *types.UpdateContainerRequest) (*types.UpdateContainerResponse, error) {
	e := &supervisor.UpdateTask{}
	e.ID = r.Id
	e.State = runtime.State(r.Status)
	if r.Resources != nil {
		rs := r.Resources
		e.Resources = &runtime.Resource{}
		if rs.CpuShares != 0 {
			e.Resources.CPUShares = int64(rs.CpuShares)
		}
		if rs.BlkioWeight != 0 {
			e.Resources.BlkioWeight = uint16(rs.BlkioWeight)
		}
		if rs.CpuPeriod != 0 {
			e.Resources.CPUPeriod = int64(rs.CpuPeriod)
		}
		if rs.CpuQuota != 0 {
			e.Resources.CPUQuota = int64(rs.CpuQuota)
		}
		if rs.CpusetCpus != "" {
			e.Resources.CpusetCpus = rs.CpusetCpus
		}
		if rs.CpusetMems != "" {
			e.Resources.CpusetMems = rs.CpusetMems
		}
		if rs.KernelMemoryLimit != 0 {
			e.Resources.KernelMemory = int64(rs.KernelMemoryLimit)
		}
		if rs.MemoryLimit != 0 {
			e.Resources.Memory = int64(rs.MemoryLimit)
		}
		if rs.MemoryReservation != 0 {
			e.Resources.MemoryReservation = int64(rs.MemoryReservation)
		}
		if rs.MemorySwap != 0 {
			e.Resources.MemorySwap = int64(rs.MemorySwap)
		}
	}
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	return &types.UpdateContainerResponse{}, nil
}

func (s *apiServer) UpdateProcess(ctx context.Context, r *types.UpdateProcessRequest) (*types.UpdateProcessResponse, error) {
	e := &supervisor.UpdateProcessTask{}
	e.ID = r.Id
	e.PID = r.Pid
	e.Height = int(r.Height)
	e.Width = int(r.Width)
	e.CloseStdin = r.CloseStdin
	s.sv.SendTask(e)
	if err := <-e.ErrorCh(); err != nil {
		return nil, err
	}
	return &types.UpdateProcessResponse{}, nil
}

func (s *apiServer) Events(r *types.EventsRequest, stream types.API_EventsServer) error {
	t := time.Time{}
	if r.Timestamp != 0 {
		t = time.Unix(int64(r.Timestamp), 0)
	}
	events := s.sv.Events(t)
	defer s.sv.Unsubscribe(events)
	for e := range events {
		if err := stream.Send(&types.Event{
			Id:        e.ID,
			Type:      e.Type,
			Timestamp: uint64(e.Timestamp.Unix()),
			Pid:       e.PID,
			Status:    uint32(e.Status),
		}); err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package cloudatgost

import (
	"encoding/json"
	"net/http"
)

type Client struct {
	client *http.Client
	BaseURL string
	Login string
	Token string
}

func NewClient(email string, token string, httpClient *http.Client) *Client {
	if httpClient == nil {
		httpClient = http.DefaultClient
	}

	baseURL := "https://panel.cloudatcost.com/api/v1/"

	c := &Client{
		Login: email,
		Token: token,
		client: httpClient,
		BaseURL: baseURL
	}

	return c
}

func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) {
	resp, err := c.client.Do(req)
	if err != nil {
		return resp, err
	}

	defer resp.Body.Close()

	if v != nil {
		json.NewDecoder(resp.Body).Decode(v)
	}

	return resp, err
}
<commit_msg>fixing an error<commit_after>package cloudatgost

import (
	"encoding/json"
	"net/http"
)

type Client struct {
	client *http.Client
	BaseURL string
	Login string
	Token string
}

func NewClient(email string, token string, httpClient *http.Client) *Client {
	if httpClient == nil {
		httpClient = http.DefaultClient
	}

	baseURL := "https://panel.cloudatcost.com/api/v1/"

	c := &Client{
		Login: email,
		Token: token,
		client: httpClient,
		BaseURL: baseURL,
	}

	return c
}

func (c *Client) Do(req *http.Request, v interface{}) (*http.Response, error) {
	resp, err := c.client.Do(req)
	if err != nil {
		return resp, err
	}

	defer resp.Body.Close()

	if v != nil {
		json.NewDecoder(resp.Body).Decode(v)
	}

	return resp, err
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"math/rand"
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"

	_ "github.com/go-sql-driver/mysql"
	//"runtime"
)

const (
	// Database
	connectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world"
	worldRowCount      = 10000
	macIdleConnection  = 30
	maxConnectionCount = 256

	helloWorldString = "Hello, World!"
)

var (
	helloWorldBytes = []byte(helloWorldString)
)

type MessageStruct struct {
	Message string `json:"message"`
}

type World struct {
	Id           uint16 `orm:"pk" json:"id"`
	RandomNumber uint16 `orm:"column(randomNumber)" json:"randomNumber"`
}

type JsonController struct {
	beego.Controller
}

func (this *JsonController) Get() {
	m := MessageStruct{"Hello, World!"}
	this.Data["json"] = &m
	this.ServeJSON()
}

type PlaintextController struct {
	beego.Controller
}

func (this *PlaintextController) Get() {
	this.Ctx.Output.Header("Content-Type", "text/plain")
	this.Ctx.Output.Body(helloWorldBytes)
}

type DBController struct {
	beego.Controller
}

func (this *DBController) Get() {
	o := orm.NewOrm()
	w := World{Id: uint16(rand.Intn(worldRowCount) + 1)}
	err := o.Read(&w)
	if err != nil {
		log.Fatalf("Error read world row: %s", err.Error())
	}
	this.Data["json"] = &w
	this.ServeJSON()
}

func main() {
	//don't need this set, beego default set it
	//runtime.GOMAXPROCS(runtime.NumCPU())
	beego.BConfig.RunMode = "prod"
	beego.Router("/json", &JsonController{})
	beego.Router("/db", &DBController{})
	beego.Router("/plaintext", &PlaintextController{})
	beego.Run()
}

func init() {
	orm.RegisterModel(new(World))
	orm.RegisterDataBase("default", "mysql", connectionString, macIdleConnection, maxConnectionCount)
}
<commit_msg>Use interpolateParams option of MySQL driver<commit_after>package main

import (
	"log"
	"math/rand"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_ "github.com/go-sql-driver/mysql"
)

const (
	// Database
	connectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world?collation=utf8mb4_bin&interpolateParams=true"
	worldRowCount      = 10000
	macIdleConnection  = 30
	maxConnectionCount = 256

	helloWorldString = "Hello, World!"
)

var (
	helloWorldBytes = []byte(helloWorldString)
)

type MessageStruct struct {
	Message string `json:"message"`
}

type World struct {
	Id           uint16 `orm:"pk" json:"id"`
	RandomNumber uint16 `orm:"column(randomNumber)" json:"randomNumber"`
}

type JsonController struct {
	beego.Controller
}

func (this *JsonController) Get() {
	m := MessageStruct{"Hello, World!"}
	this.Data["json"] = &m
	this.ServeJSON()
}

type PlaintextController struct {
	beego.Controller
}

func (this *PlaintextController) Get() {
	this.Ctx.Output.Header("Content-Type", "text/plain")
	this.Ctx.Output.Body(helloWorldBytes)
}

type DBController struct {
	beego.Controller
}

func (this *DBController) Get() {
	o := orm.NewOrm()
	w := World{Id: uint16(rand.Intn(worldRowCount) + 1)}
	err := o.Read(&w)
	if err != nil {
		log.Fatalf("Error read world row: %s", err.Error())
	}
	this.Data["json"] = &w
	this.ServeJSON()
}

func main() {
	beego.BConfig.RunMode = "prod"
	beego.Router("/json", &JsonController{})
	beego.Router("/db", &DBController{})
	beego.Router("/plaintext", &PlaintextController{})
	beego.Run()
}

func init() {
	orm.RegisterModel(new(World))
	orm.RegisterDataBase("default", "mysql", connectionString, macIdleConnection, maxConnectionCount)
}
<|endoftext|>


<commit_before>package rules_test

import (
	"fmt"
	"lib/filelock"
	"lib/rules"
	"lib/testsupport"
	"os/exec"
	"runtime"
	"strings"
	"sync"

	goiptables "github.com/coreos/go-iptables/iptables"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
)

var _ = Describe("Locked IPTables Integration Test", func() {
	var (
		restorer  *rules.Restorer
		locker    *rules.IPTablesLocker
		lockedIPT *rules.LockedIPTables
		ipt       *goiptables.IPTables
	)

	BeforeEach(func() {
		flock := &filelock.Locker{
			Path: "/tmp/restorer.lock",
		}
		locker = &rules.IPTablesLocker{
			FileLocker: flock,
			Mutex:      &sync.Mutex{},
		}
		restorer = &rules.Restorer{}
		var err error
		ipt, err = goiptables.New()
		Expect(err).NotTo(HaveOccurred())
		lockedIPT = &rules.LockedIPTables{
			Locker:   locker,
			Restorer: restorer,
			IPTables: ipt,
		}
	})

	It("Writes IP tables rules", func() {
		onlyRunOnLinux()
		err := lockedIPT.BulkInsert("filter", "FORWARD", 1, []rules.GenericRule{
			rules.NewMarkSetRule("1.2.3.4", "A", fmt.Sprintf("guid-%d", 1)),
		}...)
		Expect(err).NotTo(HaveOccurred())
		Expect(AllIPTablesRules("filter")).To(ContainElement("-A FORWARD -s 1.2.3.4/32 -m comment --comment \"src:guid-1\" -j MARK --set-xmark 0xa/0xffffffff"))
	})

	It("supports concurrent bulk inserts", func() {
		onlyRunOnLinux()
		genericRules := []interface{}{}
		numRules := 100
		numWorkers := 10
		for i := 0; i < numRules; i++ {
			genericRules = append(genericRules, []rules.GenericRule{rules.NewMarkSetRule("1.2.3.4", "A", fmt.Sprintf("guid-%d", i))})
		}
		runner := testsupport.ParallelRunner{
			NumWorkers: numWorkers,
		}
		restoreWorker := func(item interface{}) {
			ruleItems := item.([]rules.GenericRule)
			err := lockedIPT.BulkInsert("filter", "FORWARD", 1, ruleItems...)
			Expect(err).NotTo(HaveOccurred())
		}
		runner.RunOnSlice(genericRules, restoreWorker)

		for i := 0; i < numRules; i++ {
			Expect(AllIPTablesRules("filter")).To(ContainElement(
				fmt.Sprintf("-A FORWARD -s 1.2.3.4/32 -m comment --comment \"src:guid-%d\" -j MARK --set-xmark 0xa/0xffffffff", i)))
		}
	})

	It("supports concurrent bulk inserts and append uniques", func() {
		onlyRunOnLinux()
		numRules := 100
		numWorkers := 10
		things := []string{}
		for i := 0; i < numRules; i++ {
			things = append(things, fmt.Sprintf("%d", i))
		}
		runner := testsupport.ParallelRunner{
			NumWorkers: numWorkers,
		}
		restoreWorker := func(item string) {
			ruleItems := []rules.GenericRule{rules.NewMarkSetRule("1.3.5.7", "A", fmt.Sprintf("bulk-%s", item))}
			err := lockedIPT.BulkInsert("filter", "FORWARD", 1, ruleItems...)
			Expect(err).NotTo(HaveOccurred())

			r := rules.NewMarkSetRule("2.4.6.8", "A", fmt.Sprintf("uniq-%s", item))
			err = lockedIPT.AppendUnique("filter", "FORWARD", r.Properties...)
			Expect(err).NotTo(HaveOccurred())
		}
		runner.RunOnSliceStrings(things, restoreWorker)

		for i := 0; i < numRules; i++ {
			Expect(AllIPTablesRules("filter")).To(ContainElement(
				fmt.Sprintf("-A FORWARD -s 1.3.5.7/32 -m comment --comment \"src:bulk-%d\" -j MARK --set-xmark 0xa/0xffffffff", i)))
			Expect(AllIPTablesRules("filter")).To(ContainElement(
				fmt.Sprintf("-A FORWARD -s 2.4.6.8/32 -m comment --comment \"src:uniq-%d\" -j MARK --set-xmark 0xa/0xffffffff", i)))
		}
	})

})

func onlyRunOnLinux() {
	if runtime.GOOS != "linux" {
		Skip("OS is not linux. Skipping...")
	}
}

func AllIPTablesRules(tableName string) []string {
	iptablesSession, err := gexec.Start(exec.Command("iptables", "-w", "-S", "-t", tableName), nil, nil)
	Expect(err).NotTo(HaveOccurred())
	Eventually(iptablesSession, "3s").Should(gexec.Exit(0))
	return strings.Split(strings.TrimSpace(string(iptablesSession.Out.Contents())), "\n")
}
<commit_msg>refactor integration test of rules<commit_after>package rules_test

import (
	"fmt"
	"lib/filelock"
	"lib/rules"
	"lib/testsupport"
	"os/exec"
	"runtime"
	"strings"
	"sync"

	goiptables "github.com/coreos/go-iptables/iptables"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gexec"
)

var _ = Describe("Locked IPTables Integration Test", func() {
	var (
		restorer  *rules.Restorer
		locker    *rules.IPTablesLocker
		lockedIPT *rules.LockedIPTables
		ipt       *goiptables.IPTables
	)

	BeforeEach(func() {
		flock := &filelock.Locker{
			Path: "/tmp/restorer.lock",
		}
		locker = &rules.IPTablesLocker{
			FileLocker: flock,
			Mutex:      &sync.Mutex{},
		}
		restorer = &rules.Restorer{}
		var err error
		ipt, err = goiptables.New()
		Expect(err).NotTo(HaveOccurred())
		lockedIPT = &rules.LockedIPTables{
			Locker:   locker,
			Restorer: restorer,
			IPTables: ipt,
		}
	})

	It("Writes IP tables rules", func() {
		onlyRunOnLinux()
		err := lockedIPT.BulkInsert("filter", "FORWARD", 1, []rules.GenericRule{
			rules.NewMarkSetRule("1.2.3.4", "A", fmt.Sprintf("guid-%d", 1)),
		}...)
		Expect(err).NotTo(HaveOccurred())
		Expect(AllIPTablesRules("filter")).To(ContainElement("-A FORWARD -s 1.2.3.4/32 -m comment --comment \"src:guid-1\" -j MARK --set-xmark 0xa/0xffffffff"))
	})

	It("supports concurrent bulk inserts", func() {
		onlyRunOnLinux()
		genericRules := []interface{}{}
		numRules := 100
		numWorkers := 10
		for i := 0; i < numRules; i++ {
			genericRules = append(genericRules, []rules.GenericRule{rules.NewMarkSetRule("1.2.3.4", "A", fmt.Sprintf("guid-%d", i))})
		}
		runner := testsupport.ParallelRunner{
			NumWorkers: numWorkers,
		}
		restoreWorker := func(item interface{}) {
			ruleItems := item.([]rules.GenericRule)
			err := lockedIPT.BulkInsert("filter", "FORWARD", 1, ruleItems...)
			Expect(err).NotTo(HaveOccurred())
		}
		runner.RunOnSlice(genericRules, restoreWorker)
		allRules := AllIPTablesRules("filter")
		for i := 0; i < numRules; i++ {
			Expect(allRules).To(ContainElement(
				fmt.Sprintf("-A FORWARD -s 1.2.3.4/32 -m comment --comment \"src:guid-%d\" -j MARK --set-xmark 0xa/0xffffffff", i)))
		}
	})

	It("supports concurrent bulk inserts and append uniques", func() {
		onlyRunOnLinux()
		numRules := 100
		numWorkers := 10
		things := []string{}
		for i := 0; i < numRules; i++ {
			things = append(things, fmt.Sprintf("%d", i))
		}
		runner := testsupport.ParallelRunner{
			NumWorkers: numWorkers,
		}
		restoreWorker := func(item string) {
			ruleItems := []rules.GenericRule{rules.NewMarkSetRule("1.3.5.7", "A", fmt.Sprintf("bulk-%s", item))}
			err := lockedIPT.BulkInsert("filter", "FORWARD", 1, ruleItems...)
			Expect(err).NotTo(HaveOccurred())

			r := rules.NewMarkSetRule("2.4.6.8", "A", fmt.Sprintf("uniq-%s", item))
			err = lockedIPT.AppendUnique("filter", "FORWARD", r.Properties...)
			Expect(err).NotTo(HaveOccurred())
		}
		runner.RunOnSliceStrings(things, restoreWorker)

		allRules := AllIPTablesRules("filter")
		for i := 0; i < numRules; i++ {
			Expect(allRules).To(ContainElement(
				fmt.Sprintf("-A FORWARD -s 1.3.5.7/32 -m comment --comment \"src:bulk-%d\" -j MARK --set-xmark 0xa/0xffffffff", i)))
			Expect(allRules).To(ContainElement(
				fmt.Sprintf("-A FORWARD -s 2.4.6.8/32 -m comment --comment \"src:uniq-%d\" -j MARK --set-xmark 0xa/0xffffffff", i)))
		}
	})

})

func onlyRunOnLinux() {
	if runtime.GOOS != "linux" {
		Skip("OS is not linux. Skipping...")
	}
}

func AllIPTablesRules(tableName string) []string {
	iptablesSession, err := gexec.Start(exec.Command("iptables", "-w", "-S", "-t", tableName), nil, nil)
	Expect(err).NotTo(HaveOccurred())
	Eventually(iptablesSession, "3s").Should(gexec.Exit(0))
	return strings.Split(strings.TrimSpace(string(iptablesSession.Out.Contents())), "\n")
}
<|endoftext|>


<commit_before>package edwards25519

import (
	"github.com/gtank/ristretto255/internal/radix51"
	"github.com/gtank/ristretto255/internal/scalar"
	"testing"
	"testing/quick"
)

// quickCheckConfig will make each quickcheck test run (1024 * -quickchecks)
// times. The default value of -quickchecks is 100.
var (
	quickCheckConfig = &quick.Config{MaxCountScale: 1 << 10}
)

func TestScalarMulSmallScalars(t *testing.T) {
	var z scalar.Scalar
	var p, check ProjP3
	p.ScalarMul(&z, &B)
	check.Zero()
	if check.Equal(&p) != 1 {
		t.Error("0*B != 0")
	}

	z = scalar.Scalar([32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
	p.ScalarMul(&z, &B)
	check.Set(&B)
	if check.Equal(&p) != 1 {
		t.Error("1*B != 1")
	}
}

func TestScalarMulVsDalek(t *testing.T) {
	expected := ProjP3{
		X: radix51.FieldElement([5]uint64{778774234987948, 1589187156384239, 1213330452914652, 186161118421127, 2186284806803213}),
		Y: radix51.FieldElement([5]uint64{1241255309069369, 1115278942994853, 1016511918109334, 1303231926552315, 1801448517689873}),
		Z: radix51.FieldElement([5]uint64{353337085654440, 1327844406437681, 2207296012811921, 707394926933424, 917408459573183}),
		T: radix51.FieldElement([5]uint64{585487439439725, 1792815221887900, 946062846079052, 1954901232609667, 1418300670001780}),
	}
	z := scalar.Scalar([32]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4})

	var p ProjP3
	p.ScalarMul(&z, &B)
	if expected.Equal(&p) != 1 {
		t.Error("Scalar mul does not match dalek")
	}
}

func TestScalarMulDistributesOverAdd(t *testing.T) {
	scalarMulDistributesOverAdd := func(x, y scalar.Scalar) bool {
		// The quickcheck generation strategy chooses a random
		// 32-byte array, but we require that the high bit is
		// unset.  FIXME: make Scalar opaque.  Until then,
		// mask the high bits:
		x[31] &= 127
		y[31] &= 127
		var z scalar.Scalar
		z.Add(&x, &y)
		var p, q, r, check ProjP3
		p.ScalarMul(&x, &B)
		q.ScalarMul(&y, &B)
		r.ScalarMul(&z, &B)
		check.Add(&p, &q)
		return check.Equal(&r) == 1
	}

	if err := quick.Check(scalarMulDistributesOverAdd, quickCheckConfig); err != nil {
		t.Error(err)
	}
}

func TestBasepointTableGeneration(t *testing.T) {
	// The basepoint table is 32 AffineLookupTables,
	// corresponding to (16^2i)*B for table i.

	tmp1 := &ProjP1xP1{}
	tmp2 := &ProjP2{}
	tmp3 := &ProjP3{}
	tmp3.Set(&B)
	table := make([]AffineLookupTable, 32)
	for i := 0; i < 32; i++ {
		// Build the table
		table[i].FromP3(tmp3)
		// Assert equality with the hardcoded one
		if table[i] != basepointTable[i] {
			t.Errorf("Basepoint table %d does not match", i)
		}

		// Set p = (16^2)*p = 256*p = 2^8*p
		tmp2.FromP3(tmp3)
		for j := 0; j < 7; j++ {
			tmp1.Double(tmp2)
			tmp2.FromP1xP1(tmp1)
		}
		tmp1.Double(tmp2)
		tmp3.FromP1xP1(tmp1)
	}

}
<commit_msg>internal/ed25519: extract common test variables<commit_after>package edwards25519

import (
	"github.com/gtank/ristretto255/internal/radix51"
	"github.com/gtank/ristretto255/internal/scalar"
	"testing"
	"testing/quick"
)

// quickCheckConfig will make each quickcheck test run (1024 * -quickchecks)
// times. The default value of -quickchecks is 100.
var (
	quickCheckConfig = &quick.Config{MaxCountScale: 1 << 10}

	// a random scalar generated using dalek.
	dalekScalar = scalar.Scalar([32]byte{219, 106, 114, 9, 174, 249, 155, 89, 69, 203, 201, 93, 92, 116, 234, 187, 78, 115, 103, 172, 182, 98, 62, 103, 187, 136, 13, 100, 248, 110, 12, 4})
	// the above, times the Ed25519 basepoint.
	dalekScalarBasepoint = ProjP3{
		X: radix51.FieldElement([5]uint64{778774234987948, 1589187156384239, 1213330452914652, 186161118421127, 2186284806803213}),
		Y: radix51.FieldElement([5]uint64{1241255309069369, 1115278942994853, 1016511918109334, 1303231926552315, 1801448517689873}),
		Z: radix51.FieldElement([5]uint64{353337085654440, 1327844406437681, 2207296012811921, 707394926933424, 917408459573183}),
		T: radix51.FieldElement([5]uint64{585487439439725, 1792815221887900, 946062846079052, 1954901232609667, 1418300670001780}),
	}
)

func TestScalarMulSmallScalars(t *testing.T) {
	var z scalar.Scalar
	var p, check ProjP3
	p.ScalarMul(&z, &B)
	check.Zero()
	if check.Equal(&p) != 1 {
		t.Error("0*B != 0")
	}

	z = scalar.Scalar([32]byte{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
	p.ScalarMul(&z, &B)
	check.Set(&B)
	if check.Equal(&p) != 1 {
		t.Error("1*B != 1")
	}
}

func TestScalarMulVsDalek(t *testing.T) {
	var p ProjP3
	p.ScalarMul(&dalekScalar, &B)
	if dalekScalarBasepoint.Equal(&p) != 1 {
		t.Error("Scalar mul does not match dalek")
	}
}

func TestScalarMulDistributesOverAdd(t *testing.T) {
	scalarMulDistributesOverAdd := func(x, y scalar.Scalar) bool {
		// The quickcheck generation strategy chooses a random
		// 32-byte array, but we require that the high bit is
		// unset.  FIXME: make Scalar opaque.  Until then,
		// mask the high bits:
		x[31] &= 127
		y[31] &= 127
		var z scalar.Scalar
		z.Add(&x, &y)
		var p, q, r, check ProjP3
		p.ScalarMul(&x, &B)
		q.ScalarMul(&y, &B)
		r.ScalarMul(&z, &B)
		check.Add(&p, &q)
		return check.Equal(&r) == 1
	}

	if err := quick.Check(scalarMulDistributesOverAdd, quickCheckConfig); err != nil {
		t.Error(err)
	}
}

func TestBasepointTableGeneration(t *testing.T) {
	// The basepoint table is 32 AffineLookupTables,
	// corresponding to (16^2i)*B for table i.

	tmp1 := &ProjP1xP1{}
	tmp2 := &ProjP2{}
	tmp3 := &ProjP3{}
	tmp3.Set(&B)
	table := make([]AffineLookupTable, 32)
	for i := 0; i < 32; i++ {
		// Build the table
		table[i].FromP3(tmp3)
		// Assert equality with the hardcoded one
		if table[i] != basepointTable[i] {
			t.Errorf("Basepoint table %d does not match", i)
		}

		// Set p = (16^2)*p = 256*p = 2^8*p
		tmp2.FromP3(tmp3)
		for j := 0; j < 7; j++ {
			tmp1.Double(tmp2)
			tmp2.FromP1xP1(tmp1)
		}
		tmp1.Double(tmp2)
		tmp3.FromP1xP1(tmp1)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"github.com/oschwald/geoip2-golang"
	"log"
	"net"
	"net/http"
	"os"
	"strconv"
)

var db *sql.DB
var visitorsStmt *sql.Stmt
var visitStmt *sql.Stmt

type Visit struct {
	timse    string
	location string
	ip       string
}

func handler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" || r.Method == "" {
		get(w)
	} else if r.Method == "POST" {
		post(w, r)
	}
}

func get(w http.ResponseWriter) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	rows, err := db.Query("select count(id), strftime(\"%Y-%m-%d %H:00:00\", datetime(time, 'localtime')) from visits where time > datetime('now', '-500 hours') group by strftime(\"%Y%j%H\", time);")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	result := map[string][]map[string]string{}
	counts := []map[string]string{}
	for rows.Next() {
		var count string
		var time string

		rows.Scan(&count, &time)
		counts = append(counts, map[string]string{
			"time":  time,
			"count": count,
		})
	}
	result["counts"] = counts

	lrows, err := db.Query("select count(city), city, country, iso from visitors group by city, iso;")
	if err != nil {
		log.Fatal(err)
	}
	defer lrows.Close()
	locations := []map[string]string{}
	for lrows.Next() {
		var count string
		var city string
		var country string
		var iso string

		lrows.Scan(&count, &city, &country, &iso)
		locations = append(locations, map[string]string{
			"city": city,
			"country": country,
			"iso": iso,
			"count": count,
		})
	}
	result["locations"] = locations

	b, _ := json.Marshal(result)
	fmt.Fprintf(w, string(b))

	rows.Close()
}

func post(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	if r.FormValue("action") == "enter" {
		var id int64
		avid := r.FormValue("avid")

		if avid == "" {
			host, _, _ := net.SplitHostPort(r.RemoteAddr)
			if host != "" {
				gr := geo(host)
				result, err := visitorsStmt.Exec(gr["city"], gr["country"], gr["iso"], host)

				if err != nil {
					log.Print(err)
					return
				}

				id, _ = result.LastInsertId()
				response := map[string]string{}
				response["vid"] = strconv.FormatInt(id, 10)

				rj, _ := json.Marshal(response)
				fmt.Fprintf(w, string(rj))
			}
		} else {
			id_s, _ := strconv.Atoi(avid)
			id = int64(id_s)
		}

		_, err := visitStmt.Exec(r.FormValue("url"), r.FormValue("referrer"), id)

		if err != nil {
			log.Print(err)
			return
		}
	}
}

func geo(ipstring string) map[string]string {
	db, err := geoip2.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	ip := net.ParseIP(ipstring)
	if ip != nil {
		record, err := db.City(ip)
		if err != nil {
			log.Fatal(err)
		}
		return map[string]string{
			"city":    record.City.Names["en"],
			"country": record.Country.Names["en"],
			"iso":     record.Country.IsoCode,
		}
	}

	return map[string]string{
		"city":    "",
		"country": "",
		"iso":     "",
	}
}

func main() {
	isNew := false

	_, err := os.Open("./alight.db")
	if err != nil {
		isNew = true
	}

	db, err = sql.Open("sqlite3", "./alight.db")
	defer db.Close()

	if isNew {
		sqlStmt := `
		create table visits (id integer primary key, url text, time integer, referrer text, vid integer, foreign key(vid) references visitors(vid));
		create table visitors (vid integer primary key, city text, country text, iso text, ip text);
		`

		_, err = db.Exec(sqlStmt)
		if err != nil {
			os.Remove("./alight.db")
			log.Printf("%q: %s\n", err, sqlStmt)
			return
		}
	}

	db.Exec("pragma synchronous = OFF")

	visitorsStmt, err = db.Prepare("insert into visitors values (null, ?, ?, ?, ?)")
	if err != nil {
		log.Fatal(err)
	}
	visitStmt, err = db.Prepare("insert into visits values (null, ?, datetime('now'), ?, ?);")
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/", handler)
	http.ListenAndServe(":8000", nil)
}
<commit_msg>add go-sqlite<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"github.com/oschwald/geoip2-golang"
	"log"
	"net"
	"net/http"
	"os"
	"strconv"
)

var db *sql.DB
var visitorsStmt *sql.Stmt
var visitStmt *sql.Stmt

type Visit struct {
	timse    string
	location string
	ip       string
}

func handler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" || r.Method == "" {
		get(w)
	} else if r.Method == "POST" {
		post(w, r)
	}
}

func get(w http.ResponseWriter) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	rows, err := db.Query("select count(id), strftime(\"%Y-%m-%d %H:00:00\", datetime(time, 'localtime')) from visits where time > datetime('now', '-500 hours') group by strftime(\"%Y%j%H\", time);")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	result := map[string][]map[string]string{}
	counts := []map[string]string{}
	for rows.Next() {
		var count string
		var time string

		rows.Scan(&count, &time)
		counts = append(counts, map[string]string{
			"time":  time,
			"count": count,
		})
	}
	result["counts"] = counts

	lrows, err := db.Query("select count(city), city, country, iso from visitors group by city, iso;")
	if err != nil {
		log.Fatal(err)
	}
	defer lrows.Close()
	locations := []map[string]string{}
	for lrows.Next() {
		var count string
		var city string
		var country string
		var iso string

		lrows.Scan(&count, &city, &country, &iso)
		locations = append(locations, map[string]string{
			"city": city,
			"country": country,
			"iso": iso,
			"count": count,
		})
	}
	result["locations"] = locations

	b, _ := json.Marshal(result)
	fmt.Fprintf(w, string(b))

	rows.Close()
}

func post(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	if r.FormValue("action") == "enter" {
		var id int64
		avid := r.FormValue("avid")

		if avid == "" {
			host, _, _ := net.SplitHostPort(r.RemoteAddr)
			if host != "" {
				gr := geo(host)
				result, err := visitorsStmt.Exec(gr["city"], gr["country"], gr["iso"], host)

				if err != nil {
					log.Print(err)
					return
				}

				id, _ = result.LastInsertId()
				response := map[string]string{}
				response["vid"] = strconv.FormatInt(id, 10)

				rj, _ := json.Marshal(response)
				fmt.Fprintf(w, string(rj))
			}
		} else {
			id_s, _ := strconv.Atoi(avid)
			id = int64(id_s)
		}

		_, err := visitStmt.Exec(r.FormValue("url"), r.FormValue("referrer"), id)

		if err != nil {
			log.Print(err)
			return
		}
	}
}

func geo(ipstring string) map[string]string {
	db, err := geoip2.Open("GeoLite2-City.mmdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()
	ip := net.ParseIP(ipstring)
	if ip != nil {
		record, err := db.City(ip)
		if err != nil {
			log.Fatal(err)
		}
		return map[string]string{
			"city":    record.City.Names["en"],
			"country": record.Country.Names["en"],
			"iso":     record.Country.IsoCode,
		}
	}

	return map[string]string{
		"city":    "",
		"country": "",
		"iso":     "",
	}
}

func main() {
	isNew := false

	_, err := os.Open("./alight.db")
	if err != nil {
		isNew = true
	}

	db, err = sql.Open("sqlite3", "./alight.db")
	defer db.Close()

	if isNew {
		sqlStmt := `
		create table visits (id integer primary key, url text, time integer, referrer text, vid integer, foreign key(vid) references visitors(vid));
		create table visitors (vid integer primary key, city text, country text, iso text, ip text);
		`

		_, err = db.Exec(sqlStmt)
		if err != nil {
			os.Remove("./alight.db")
			log.Printf("%q: %s\n", err, sqlStmt)
			return
		}
	}

	db.Exec("pragma synchronous = OFF")

	visitorsStmt, err = db.Prepare("insert into visitors values (null, ?, ?, ?, ?)")
	if err != nil {
		log.Fatal(err)
	}
	visitStmt, err = db.Prepare("insert into visits values (null, ?, datetime('now'), ?, ?);")
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/", handler)
	http.ListenAndServe(":8000", nil)
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"net"

	log "github.com/Sirupsen/logrus"
	"github.com/agave/ah-microservices/services/users/db"
	"github.com/agave/ah-microservices/services/users/user"
	userGen "github.com/agave/ah-microservices/services/users/user/generated"
	xContext "golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

// UserServer implements user service functionality through grpc
type userServer struct{}

// GetUser looks for the Id param in the database and returns user details if found
func (s *userServer) GetUser(ctx xContext.Context, id *userGen.Id) (*userGen.Profile, error) {
	log.WithFields(log.Fields{
		"GUID": id.GetGuid(), "data": id.String(),
	}).Info("Received request")

	log.WithField("GUID", id.GetGuid()).Info("Searching for user in db")

	u := user.Users{ID: id.GetId()}
	h, err := db.Engine.Get(&u)
	if err != nil {
		log.WithField("GUID", id.GetGuid()).Info("Internal DB Error")
		return &userGen.Profile{}, grpc.Errorf(codes.Internal, "%s", err.Error())
	}

	if h {
		log.WithField("GUID", id.GetGuid()).Info("Found")
		p := userGen.Profile(u)
		return &p, nil
	}

	log.WithField("GUID", id.GetGuid()).Info("Not Found")
	return &userGen.Profile{}, grpc.Errorf(codes.NotFound, "Not Found")
}

// CreateUser creates a user in the database based on the Create param
func (s *userServer) CreateUser(ctx xContext.Context, c *userGen.Create) (*userGen.Profile, error) {
	//TODO: email format/security validation
	if c.GetEmail() == "" {
		return &userGen.Profile{},
			grpc.Errorf(codes.InvalidArgument, "Email can't be empty")
	}

	if c.Balance < 0 {
		return &userGen.Profile{},
			grpc.Errorf(codes.InvalidArgument, "Balance can't be negative")
	}

	user := user.Users{Email: c.GetEmail()}

	log.WithField("userEmail", user.Email).Info("Looking for user in db")
	exists, err := db.Engine.Get(&user)
	if err != nil {
		return &userGen.Profile{},
			grpc.Errorf(codes.Unknown, "Unable to create user")
	}

	if exists {
		return &userGen.Profile{},
			grpc.Errorf(codes.AlreadyExists, "User already exists")
	}

	user.Balance = c.GetBalance()

	// create user in db
	affectedRows, err := db.Engine.InsertOne(&user)
	if err == nil && affectedRows == 1 {
		p := userGen.Profile(user)
		return &p, nil
	}

	return &userGen.Profile{},
		grpc.Errorf(codes.Unknown, "Unable to create user")
}

// StartServer configures and starts our Users grpc server
func StartServer() {
	lis, err := net.Listen("tcp", fmt.Sprintf(":80"))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	grpcServer := grpc.NewServer()
	userGen.RegisterUserServer(grpcServer, &userServer{})
	// determine whether to use TLS
	grpcServer.Serve(lis)
}
<commit_msg>remove useless log<commit_after>package server

import (
	"fmt"
	"net"

	log "github.com/Sirupsen/logrus"
	"github.com/agave/ah-microservices/services/users/db"
	"github.com/agave/ah-microservices/services/users/user"
	userGen "github.com/agave/ah-microservices/services/users/user/generated"
	xContext "golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

// UserServer implements user service functionality through grpc
type userServer struct{}

// GetUser looks for the Id param in the database and returns user details if found
func (s *userServer) GetUser(ctx xContext.Context, id *userGen.Id) (*userGen.Profile, error) {
	log.WithFields(log.Fields{
		"GUID": id.GetGuid(), "data": id.String(),
	}).Info("Received request")

	log.WithField("GUID", id.GetGuid()).Info("Searching for user in db")

	u := user.Users{ID: id.GetId()}
	h, err := db.Engine.Get(&u)
	if err != nil {
		log.WithField("GUID", id.GetGuid()).Info("Internal DB Error")
		return &userGen.Profile{}, grpc.Errorf(codes.Internal, "%s", err.Error())
	}

	if h {
		log.WithField("GUID", id.GetGuid()).Info("Found")
		p := userGen.Profile(u)
		return &p, nil
	}

	log.WithField("GUID", id.GetGuid()).Info("Not Found")
	return &userGen.Profile{}, grpc.Errorf(codes.NotFound, "Not Found")
}

// CreateUser creates a user in the database based on the Create param
func (s *userServer) CreateUser(ctx xContext.Context, c *userGen.Create) (*userGen.Profile, error) {
	//TODO: email format/security validation
	if c.GetEmail() == "" {
		return &userGen.Profile{},
			grpc.Errorf(codes.InvalidArgument, "Email can't be empty")
	}

	if c.Balance < 0 {
		return &userGen.Profile{},
			grpc.Errorf(codes.InvalidArgument, "Balance can't be negative")
	}

	user := user.Users{Email: c.GetEmail()}
	exists, err := db.Engine.Get(&user)
	if err != nil {
		return &userGen.Profile{},
			grpc.Errorf(codes.Unknown, "Unable to create user")
	}

	if exists {
		return &userGen.Profile{},
			grpc.Errorf(codes.AlreadyExists, "User already exists")
	}

	user.Balance = c.GetBalance()

	// create user in db
	affectedRows, err := db.Engine.InsertOne(&user)
	if err == nil && affectedRows == 1 {
		p := userGen.Profile(user)
		return &p, nil
	}

	return &userGen.Profile{},
		grpc.Errorf(codes.Unknown, "Unable to create user")
}

// StartServer configures and starts our Users grpc server
func StartServer() {
	lis, err := net.Listen("tcp", fmt.Sprintf(":80"))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	grpcServer := grpc.NewServer()
	userGen.RegisterUserServer(grpcServer, &userServer{})
	// determine whether to use TLS
	grpcServer.Serve(lis)
}
<|endoftext|>


<commit_before>package spigot

import "fmt"

func ExamplePi10() {
	for i := range Pi(20) {
		fmt.Print(i)
	}
	// Output:
	// 314159265358979323846
}

func ExamplePi100() {
	for i := range Pi(100) {
		fmt.Print(i)
	}
	// Output:
	// 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679
}

func ExamplePi1000() {
	for i := range Pi(1000) {
		fmt.Print(i)
	}
	// Output:
	// 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989
}

func ExampleE10() {
	for i := range E(20) {
		fmt.Print(i)
	}
	// Output:
	// 271828182845904523536
}

func ExampleE100() {
	for i := range E(100) {
		fmt.Print(i)
	}
	// Output:
	// 27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274
}

func ExampleE1000() {
	for i := range E(1000) {
		fmt.Print(i)
	}
	// Output:
	// 27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354
}
<commit_msg>Reduce to 1000 sample<commit_after>package spigot

import "fmt"

func ExamplePi() {
	for i := range Pi(1000) {
		fmt.Print(i)
	}
	// Output:
	// 31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989
}

func ExampleE() {
	for i := range E(1000) {
		fmt.Print(i)
	}
	// Output:
	// 27182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274274663919320030599218174135966290435729003342952605956307381323286279434907632338298807531952510190115738341879307021540891499348841675092447614606680822648001684774118537423454424371075390777449920695517027618386062613313845830007520449338265602976067371132007093287091274437470472306969772093101416928368190255151086574637721112523897844250569536967707854499699679468644549059879316368892300987931277361782154249992295763514822082698951936680331825288693984964651058209392398294887933203625094431173012381970684161403970198376793206832823764648042953118023287825098194558153017567173613320698112509961818815930416903515988885193458072738667385894228792284998920868058257492796104841984443634632449684875602336248270419786232090021609902353043699418491463140934317381436405462531520961836908887070167683964243781405927145635490613031072085103837505101157477041718986106873969655212671546889570350354
}
<|endoftext|>


<commit_before>package io

import (
	"context"
	"errors"
	"fmt"
	"io"

	mdag "github.com/ipfs/go-ipfs/merkledag"
	ft "github.com/ipfs/go-ipfs/unixfs"
	ftpb "github.com/ipfs/go-ipfs/unixfs/pb"

	ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format"
	proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
	cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid"
)

// PBDagReader provides a way to easily read the data contained in a dag.
type PBDagReader struct {
	serv ipld.NodeGetter

	// the node being read
	node *mdag.ProtoNode

	// cached protobuf structure from node.Data
	pbdata *ftpb.Data

	// the current data buffer to be read from
	// will either be a bytes.Reader or a child DagReader
	buf ReadSeekCloser

	// NodePromises for each of 'nodes' child links
	promises []*ipld.NodePromise

	// the cid of each child of the current node
	links []*cid.Cid

	// the index of the child link currently being read from
	linkPosition int

	// current offset for the read head within the 'file'
	offset int64

	// Our context
	ctx context.Context

	// context cancel for children
	cancel func()
}

var _ DagReader = (*PBDagReader)(nil)

// NewPBFileReader constructs a new PBFileReader.
func NewPBFileReader(ctx context.Context, n *mdag.ProtoNode, pb *ftpb.Data, serv ipld.NodeGetter) *PBDagReader {
	fctx, cancel := context.WithCancel(ctx)
	curLinks := getLinkCids(n)
	return &PBDagReader{
		node:     n,
		serv:     serv,
		buf:      NewBufDagReader(pb.GetData()),
		promises: make([]*ipld.NodePromise, len(curLinks)),
		links:    curLinks,
		ctx:      fctx,
		cancel:   cancel,
		pbdata:   pb,
	}
}

const preloadSize = 10

func (dr *PBDagReader) preloadNextNodes(ctx context.Context) {
	beg := dr.linkPosition
	end := beg + preloadSize
	if end >= len(dr.links) {
		end = len(dr.links)
	}

	copy(dr.promises[beg:], ipld.GetNodes(ctx, dr.serv, dr.links[beg:end]))
}

// precalcNextBuf follows the next link in line and loads it from the
// DAGService, setting the next buffer to read from
func (dr *PBDagReader) precalcNextBuf(ctx context.Context) error {
	if dr.buf != nil {
		dr.buf.Close() // Just to make sure
		dr.buf = nil
	}

	if dr.linkPosition >= len(dr.promises) {
		return io.EOF
	}

	if dr.promises[dr.linkPosition] == nil {
		dr.preloadNextNodes(ctx)
	}

	nxt, err := dr.promises[dr.linkPosition].Get(ctx)
	if err != nil {
		return err
	}
	dr.promises[dr.linkPosition] = nil
	dr.linkPosition++

	switch nxt := nxt.(type) {
	case *mdag.ProtoNode:
		pb := new(ftpb.Data)
		err = proto.Unmarshal(nxt.Data(), pb)
		if err != nil {
			return fmt.Errorf("incorrectly formatted protobuf: %s", err)
		}

		switch pb.GetType() {
		case ftpb.Data_Directory, ftpb.Data_HAMTShard:
			// A directory should not exist within a file
			return ft.ErrInvalidDirLocation
		case ftpb.Data_File:
			dr.buf = NewPBFileReader(dr.ctx, nxt, pb, dr.serv)
			return nil
		case ftpb.Data_Raw:
			dr.buf = NewBufDagReader(pb.GetData())
			return nil
		case ftpb.Data_Metadata:
			return errors.New("shouldnt have had metadata object inside file")
		case ftpb.Data_Symlink:
			return errors.New("shouldnt have had symlink inside file")
		default:
			return ft.ErrUnrecognizedType
		}
	default:
		var err error
		dr.buf, err = NewDagReader(ctx, nxt, dr.serv)
		return err
	}
}

func getLinkCids(n ipld.Node) []*cid.Cid {
	links := n.Links()
	out := make([]*cid.Cid, 0, len(links))
	for _, l := range links {
		out = append(out, l.Cid)
	}
	return out
}

// Size return the total length of the data from the DAG structured file.
func (dr *PBDagReader) Size() uint64 {
	return dr.pbdata.GetFilesize()
}

// Read reads data from the DAG structured file
func (dr *PBDagReader) Read(b []byte) (int, error) {
	return dr.CtxReadFull(dr.ctx, b)
}

// CtxReadFull reads data from the DAG structured file
func (dr *PBDagReader) CtxReadFull(ctx context.Context, b []byte) (int, error) {
	if dr.buf == nil {
		if err := dr.precalcNextBuf(ctx); err != nil {
			return 0, err
		}
	}

	// If no cached buffer, load one
	total := 0
	for {
		// Attempt to fill bytes from cached buffer
		n, err := io.ReadFull(dr.buf, b[total:])
		total += n
		dr.offset += int64(n)
		switch err {
		// io.EOF will happen is dr.buf had noting more to read (n == 0)
		case io.EOF, io.ErrUnexpectedEOF:
			// do nothing
		case nil:
			return total, nil
		default:
			return total, err
		}

		// if we are not done with the output buffer load next block
		err = dr.precalcNextBuf(ctx)
		if err != nil {
			return total, err
		}
	}
}

// WriteTo writes to the given writer.
func (dr *PBDagReader) WriteTo(w io.Writer) (int64, error) {
	if dr.buf == nil {
		if err := dr.precalcNextBuf(dr.ctx); err != nil {
			return 0, err
		}
	}

	// If no cached buffer, load one
	total := int64(0)
	for {
		// Attempt to write bytes from cached buffer
		n, err := dr.buf.WriteTo(w)
		total += n
		dr.offset += n
		if err != nil {
			if err != io.EOF {
				return total, err
			}
		}

		// Otherwise, load up the next block
		err = dr.precalcNextBuf(dr.ctx)
		if err != nil {
			if err == io.EOF {
				return total, nil
			}
			return total, err
		}
	}
}

// Close closes the reader.
func (dr *PBDagReader) Close() error {
	dr.cancel()
	return nil
}

// Offset returns the current reader offset
func (dr *PBDagReader) Offset() int64 {
	return dr.offset
}

// Seek implements io.Seeker, and will seek to a given offset in the file
// interface matches standard unix seek
// TODO: check if we can do relative seeks, to reduce the amount of dagreader
// recreations that need to happen.
func (dr *PBDagReader) Seek(offset int64, whence int) (int64, error) {
	switch whence {
	case io.SeekStart:
		if offset < 0 {
			return -1, errors.New("invalid offset")
		}
		if offset == dr.offset {
			return offset, nil
		}

		// Grab cached protobuf object (solely to make code look cleaner)
		pb := dr.pbdata

		// left represents the number of bytes remaining to seek to (from beginning)
		left := offset
		if int64(len(pb.Data)) >= offset {
			// Close current buf to close potential child dagreader
			if dr.buf != nil {
				dr.buf.Close()
			}
			dr.buf = NewBufDagReader(pb.GetData()[offset:])

			// start reading links from the beginning
			dr.linkPosition = 0
			dr.offset = offset
			return offset, nil
		}

		// skip past root block data
		left -= int64(len(pb.Data))

		// iterate through links and find where we need to be
		for i := 0; i < len(pb.Blocksizes); i++ {
			if pb.Blocksizes[i] > uint64(left) {
				dr.linkPosition = i
				break
			} else {
				left -= int64(pb.Blocksizes[i])
			}
		}

		// start sub-block request
		err := dr.precalcNextBuf(dr.ctx)
		if err != nil {
			return 0, err
		}

		// set proper offset within child readseeker
		n, err := dr.buf.Seek(left, io.SeekStart)
		if err != nil {
			return -1, err
		}

		// sanity
		left -= n
		if left != 0 {
			return -1, errors.New("failed to seek properly")
		}
		dr.offset = offset
		return offset, nil
	case io.SeekCurrent:
		// TODO: be smarter here
		if offset == 0 {
			return dr.offset, nil
		}

		noffset := dr.offset + offset
		return dr.Seek(noffset, io.SeekStart)
	case io.SeekEnd:
		noffset := int64(dr.pbdata.GetFilesize()) - offset
		n, err := dr.Seek(noffset, io.SeekStart)

		// Return negative number if we can't figure out the file size. Using io.EOF
		// for this seems to be good(-enough) solution as it's only returned by
		// precalcNextBuf when we step out of file range.
		// This is needed for gateway to function properly
		if err == io.EOF && *dr.pbdata.Type == ftpb.Data_File {
			return -1, nil
		}
		return n, err
	default:
		return 0, errors.New("invalid whence")
	}
}
<commit_msg>better handle context cancellations in the PBDagReader<commit_after>package io

import (
	"context"
	"errors"
	"fmt"
	"io"

	mdag "github.com/ipfs/go-ipfs/merkledag"
	ft "github.com/ipfs/go-ipfs/unixfs"
	ftpb "github.com/ipfs/go-ipfs/unixfs/pb"

	ipld "gx/ipfs/QmWi2BYBL5gJ3CiAiQchg6rn1A8iBsrWy51EYxvHVjFvLb/go-ipld-format"
	proto "gx/ipfs/QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV/gogo-protobuf/proto"
	cid "gx/ipfs/QmapdYm1b22Frv3k17fqrBYTFRxwiaVJkB299Mfn33edeB/go-cid"
)

// PBDagReader provides a way to easily read the data contained in a dag.
type PBDagReader struct {
	serv ipld.NodeGetter

	// the node being read
	node *mdag.ProtoNode

	// cached protobuf structure from node.Data
	pbdata *ftpb.Data

	// the current data buffer to be read from
	// will either be a bytes.Reader or a child DagReader
	buf ReadSeekCloser

	// NodePromises for each of 'nodes' child links
	promises []*ipld.NodePromise

	// the cid of each child of the current node
	links []*cid.Cid

	// the index of the child link currently being read from
	linkPosition int

	// current offset for the read head within the 'file'
	offset int64

	// Our context
	ctx context.Context

	// context cancel for children
	cancel func()
}

var _ DagReader = (*PBDagReader)(nil)

// NewPBFileReader constructs a new PBFileReader.
func NewPBFileReader(ctx context.Context, n *mdag.ProtoNode, pb *ftpb.Data, serv ipld.NodeGetter) *PBDagReader {
	fctx, cancel := context.WithCancel(ctx)
	curLinks := getLinkCids(n)
	return &PBDagReader{
		node:     n,
		serv:     serv,
		buf:      NewBufDagReader(pb.GetData()),
		promises: make([]*ipld.NodePromise, len(curLinks)),
		links:    curLinks,
		ctx:      fctx,
		cancel:   cancel,
		pbdata:   pb,
	}
}

const preloadSize = 10

func (dr *PBDagReader) preloadNextNodes(ctx context.Context) {
	beg := dr.linkPosition
	end := beg + preloadSize
	if end >= len(dr.links) {
		end = len(dr.links)
	}

	copy(dr.promises[beg:], ipld.GetNodes(ctx, dr.serv, dr.links[beg:end]))
}

// precalcNextBuf follows the next link in line and loads it from the
// DAGService, setting the next buffer to read from
func (dr *PBDagReader) precalcNextBuf(ctx context.Context) error {
	if dr.buf != nil {
		dr.buf.Close() // Just to make sure
		dr.buf = nil
	}

	if dr.linkPosition >= len(dr.promises) {
		return io.EOF
	}

	if dr.promises[dr.linkPosition] == nil {
		dr.preloadNextNodes(ctx)
	}

	nxt, err := dr.promises[dr.linkPosition].Get(ctx)
	dr.promises[dr.linkPosition] = nil
	switch err {
	case nil:
	case context.DeadlineExceeded, context.Canceled:
		err = ctx.Err()
		if err != nil {
			return ctx.Err()
		}
		// In this case, the context used to *preload* the node has been canceled.
		// We need to retry the load with our context and we might as
		// well preload some extra nodes while we're at it.
		dr.preload(ctx, dr.linkPosition)
		nxt, err = dr.promises[dr.linkPosition].Get(ctx)
		dr.promises[dr.linkPosition] = nil
		if err != nil {
			return err
		}
	default:
		return err
	}

	dr.linkPosition++

	switch nxt := nxt.(type) {
	case *mdag.ProtoNode:
		pb := new(ftpb.Data)
		err = proto.Unmarshal(nxt.Data(), pb)
		if err != nil {
			return fmt.Errorf("incorrectly formatted protobuf: %s", err)
		}

		switch pb.GetType() {
		case ftpb.Data_Directory, ftpb.Data_HAMTShard:
			// A directory should not exist within a file
			return ft.ErrInvalidDirLocation
		case ftpb.Data_File:
			dr.buf = NewPBFileReader(dr.ctx, nxt, pb, dr.serv)
			return nil
		case ftpb.Data_Raw:
			dr.buf = NewBufDagReader(pb.GetData())
			return nil
		case ftpb.Data_Metadata:
			return errors.New("shouldnt have had metadata object inside file")
		case ftpb.Data_Symlink:
			return errors.New("shouldnt have had symlink inside file")
		default:
			return ft.ErrUnrecognizedType
		}
	default:
		var err error
		dr.buf, err = NewDagReader(ctx, nxt, dr.serv)
		return err
	}
}

func getLinkCids(n ipld.Node) []*cid.Cid {
	links := n.Links()
	out := make([]*cid.Cid, 0, len(links))
	for _, l := range links {
		out = append(out, l.Cid)
	}
	return out
}

// Size return the total length of the data from the DAG structured file.
func (dr *PBDagReader) Size() uint64 {
	return dr.pbdata.GetFilesize()
}

// Read reads data from the DAG structured file
func (dr *PBDagReader) Read(b []byte) (int, error) {
	return dr.CtxReadFull(dr.ctx, b)
}

// CtxReadFull reads data from the DAG structured file
func (dr *PBDagReader) CtxReadFull(ctx context.Context, b []byte) (int, error) {
	if dr.buf == nil {
		if err := dr.precalcNextBuf(ctx); err != nil {
			return 0, err
		}
	}

	// If no cached buffer, load one
	total := 0
	for {
		// Attempt to fill bytes from cached buffer
		n, err := io.ReadFull(dr.buf, b[total:])
		total += n
		dr.offset += int64(n)
		switch err {
		// io.EOF will happen is dr.buf had noting more to read (n == 0)
		case io.EOF, io.ErrUnexpectedEOF:
			// do nothing
		case nil:
			return total, nil
		default:
			return total, err
		}

		// if we are not done with the output buffer load next block
		err = dr.precalcNextBuf(ctx)
		if err != nil {
			return total, err
		}
	}
}

// WriteTo writes to the given writer.
func (dr *PBDagReader) WriteTo(w io.Writer) (int64, error) {
	if dr.buf == nil {
		if err := dr.precalcNextBuf(dr.ctx); err != nil {
			return 0, err
		}
	}

	// If no cached buffer, load one
	total := int64(0)
	for {
		// Attempt to write bytes from cached buffer
		n, err := dr.buf.WriteTo(w)
		total += n
		dr.offset += n
		if err != nil {
			if err != io.EOF {
				return total, err
			}
		}

		// Otherwise, load up the next block
		err = dr.precalcNextBuf(dr.ctx)
		if err != nil {
			if err == io.EOF {
				return total, nil
			}
			return total, err
		}
	}
}

// Close closes the reader.
func (dr *PBDagReader) Close() error {
	dr.cancel()
	return nil
}

// Offset returns the current reader offset
func (dr *PBDagReader) Offset() int64 {
	return dr.offset
}

// Seek implements io.Seeker, and will seek to a given offset in the file
// interface matches standard unix seek
// TODO: check if we can do relative seeks, to reduce the amount of dagreader
// recreations that need to happen.
func (dr *PBDagReader) Seek(offset int64, whence int) (int64, error) {
	switch whence {
	case io.SeekStart:
		if offset < 0 {
			return -1, errors.New("invalid offset")
		}
		if offset == dr.offset {
			return offset, nil
		}

		// Grab cached protobuf object (solely to make code look cleaner)
		pb := dr.pbdata

		// left represents the number of bytes remaining to seek to (from beginning)
		left := offset
		if int64(len(pb.Data)) >= offset {
			// Close current buf to close potential child dagreader
			if dr.buf != nil {
				dr.buf.Close()
			}
			dr.buf = NewBufDagReader(pb.GetData()[offset:])

			// start reading links from the beginning
			dr.linkPosition = 0
			dr.offset = offset
			return offset, nil
		}

		// skip past root block data
		left -= int64(len(pb.Data))

		// iterate through links and find where we need to be
		for i := 0; i < len(pb.Blocksizes); i++ {
			if pb.Blocksizes[i] > uint64(left) {
				dr.linkPosition = i
				break
			} else {
				left -= int64(pb.Blocksizes[i])
			}
		}

		// start sub-block request
		err := dr.precalcNextBuf(dr.ctx)
		if err != nil {
			return 0, err
		}

		// set proper offset within child readseeker
		n, err := dr.buf.Seek(left, io.SeekStart)
		if err != nil {
			return -1, err
		}

		// sanity
		left -= n
		if left != 0 {
			return -1, errors.New("failed to seek properly")
		}
		dr.offset = offset
		return offset, nil
	case io.SeekCurrent:
		// TODO: be smarter here
		if offset == 0 {
			return dr.offset, nil
		}

		noffset := dr.offset + offset
		return dr.Seek(noffset, io.SeekStart)
	case io.SeekEnd:
		noffset := int64(dr.pbdata.GetFilesize()) - offset
		n, err := dr.Seek(noffset, io.SeekStart)

		// Return negative number if we can't figure out the file size. Using io.EOF
		// for this seems to be good(-enough) solution as it's only returned by
		// precalcNextBuf when we step out of file range.
		// This is needed for gateway to function properly
		if err == io.EOF && *dr.pbdata.Type == ftpb.Data_File {
			return -1, nil
		}
		return n, err
	default:
		return 0, errors.New("invalid whence")
	}
}
<|endoftext|>


<commit_before>package twitter

import (
	"context"
	"encoding/json"
	"net/url"
	"strconv"
)

// MentionsTimelineParams represents the query parameters for a
// /statuses/mentions_timeline.json request.
type MentionsTimelineParams struct {
	Count              int    `json:"count"`
	SinceID            string `json:"since_id"`
	MaxID              string `json:"max_id"`
	TrimUser           bool   `json:"trim_user"`
	ContributorDetails bool   `json:"contributor_details"`
	ExcludeEntities    bool   `json:"exclude_entities"`
}

// MentionsTimeline calls the Twitter /statuses/mentions_timeline.json endpoint.
func (c *Client) MentionsTimeline(ctx context.Context, params MentionsTimelineParams) (*TweetsResponse, error) {
	values := mentionsTimelineToQuery(params)
	resp, err := c.do(ctx, "GET", "https://api.twitter.com/1.1/statuses/mentions_timeline.json", values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var tweets []Tweet
	err = json.NewDecoder(resp.Body).Decode(resp.Body)
	if err != nil {
		return nil, err
	}
	return &TweetsResponse{
		Tweets:    tweets,
		RateLimit: getRateLimit(resp.Header),
	}, nil
}

func mentionsTimelineToQuery(params MentionsTimelineParams) url.Values {
	values := url.Values{}
	if params.Count > 0 {
		values.Set("count", strconv.Itoa(params.Count))
	}
	if params.SinceID != "" {
		values.Set("since_id", params.SinceID)
	}
	if params.MaxID != "" {
		values.Set("max_id", params.MaxID)
	}
	if params.TrimUser {
		values.Set("trim_user", "true")
	}
	if params.ContributorDetails {
		values.Set("contributor_details", "true")
	}
	if params.ExcludeEntities {
		values.Set("include_entities", "false")
	}
	return values
}

// UserTimelineParams represents the query parameters for a
// /statuses/user_timeline.json request.
type UserTimelineParams struct {
	UserID             string `json:"user_id"`
	ScreenName         string `json:"screen_name"`
	SinceID            string `json:"since_id"`
	Count              int    `json:"count"`
	MaxID              string `json:"max_id"`
	TrimUser           bool   `json:"trim_user"`
	ExcludeReplies     bool   `json:"exclude_replies"`
	ContributorDetails bool   `json:"contributor_details"`
	ExcludeRTS         bool   `json:"exclude_rts"`
}

// UserTimeline calls the Twitter /statuses/user_timeline.json endpoint.
func (c *Client) UserTimeline(ctx context.Context, params UserTimelineParams) (*TweetsResponse, error) {
	values := userTimelineToQuery(params)
	resp, err := c.do(ctx, "GET", "https://api.twitter.com/1.1/statuses/user_timeline.json", values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var tweets []Tweet
	err = json.NewDecoder(resp.Body).Decode(resp.Body)
	if err != nil {
		return nil, err
	}
	return &TweetsResponse{
		Tweets:    tweets,
		RateLimit: getRateLimit(resp.Header),
	}, nil
}

func userTimelineToQuery(params UserTimelineParams) url.Values {
	values := url.Values{}
	if params.UserID != "" {
		values.Set("user_id", params.UserID)
	}
	if params.ScreenName != "" {
		values.Set("screen_name", params.ScreenName)
	}
	if params.SinceID != "" {
		values.Set("since_id", params.SinceID)
	}
	if params.Count > 0 {
		values.Set("count", strconv.Itoa(params.Count))
	}
	if params.MaxID != "" {
		values.Set("max_id", params.MaxID)
	}
	if params.TrimUser {
		values.Set("trim_user", "true")
	}
	if params.ExcludeReplies {
		values.Set("exclude_replies", "true")
	}
	if params.ContributorDetails {
		values.Set("contributor_details", "true")
	}
	if params.ExcludeRTS {
		values.Set("include_rts", "false")
	}
	return values
}

// HomeTimelineParams represents the query parameters for a
// /statuses/home_timeline.json request.
type HomeTimelineParams struct {
	Count              int    `json:"count"`
	SinceID            string `json:"since_id"`
	MaxID              string `json:"max_id"`
	TrimUser           bool   `json:"trim_user"`
	ExcludeReplies     bool   `json:"exclude_replies"`
	ContributorDetails bool   `json:"contributor_details"`
	ExcludeEntities    bool   `json:"exclude_entities"`
}

// HomeTimeline calls the Twitter /statuses/home_timeline.json endpoint.
func (c *Client) HomeTimeline(ctx context.Context, params HomeTimelineParams) (*TweetsResponse, error) {
	values := homeTimelineToQuery(params)
	resp, err := c.do(ctx, "GET", "https://api.twitter.com/1.1/statuses/home_timeline.json", values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var tweets []Tweet
	err = json.NewDecoder(resp.Body).Decode(resp.Body)
	if err != nil {
		return nil, err
	}
	return &TweetsResponse{
		Tweets:    tweets,
		RateLimit: getRateLimit(resp.Header),
	}, nil
}

func homeTimelineToQuery(params HomeTimelineParams) url.Values {
	values := url.Values{}
	if params.Count > 0 {
		values.Set("count", strconv.Itoa(params.Count))
	}
	if params.SinceID != "" {
		values.Set("since_id", params.SinceID)
	}
	if params.MaxID != "" {
		values.Set("max_id", params.MaxID)
	}
	if params.TrimUser {
		values.Set("trim_user", "true")
	}
	if params.ExcludeReplies {
		values.Set("exclude_replies", "true")
	}
	if params.ContributorDetails {
		values.Set("contributor_details", "true")
	}
	if params.ExcludeEntities {
		values.Set("include_entities", "false")
	}
	return values
}
<commit_msg>Add retweets of me endpoint<commit_after>package twitter

import (
	"context"
	"encoding/json"
	"net/url"
	"strconv"
)

// MentionsTimelineParams represents the query parameters for a
// /statuses/mentions_timeline.json request.
type MentionsTimelineParams struct {
	Count              int    `json:"count"`
	SinceID            string `json:"since_id"`
	MaxID              string `json:"max_id"`
	TrimUser           bool   `json:"trim_user"`
	ContributorDetails bool   `json:"contributor_details"`
	ExcludeEntities    bool   `json:"exclude_entities"`
}

// MentionsTimeline calls the Twitter /statuses/mentions_timeline.json endpoint.
func (c *Client) MentionsTimeline(ctx context.Context, params MentionsTimelineParams) (*TweetsResponse, error) {
	values := mentionsTimelineToQuery(params)
	resp, err := c.do(ctx, "GET", "https://api.twitter.com/1.1/statuses/mentions_timeline.json", values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var tweets []Tweet
	err = json.NewDecoder(resp.Body).Decode(resp.Body)
	if err != nil {
		return nil, err
	}
	return &TweetsResponse{
		Tweets:    tweets,
		RateLimit: getRateLimit(resp.Header),
	}, nil
}

func mentionsTimelineToQuery(params MentionsTimelineParams) url.Values {
	values := url.Values{}
	if params.Count > 0 {
		values.Set("count", strconv.Itoa(params.Count))
	}
	if params.SinceID != "" {
		values.Set("since_id", params.SinceID)
	}
	if params.MaxID != "" {
		values.Set("max_id", params.MaxID)
	}
	if params.TrimUser {
		values.Set("trim_user", "true")
	}
	if params.ContributorDetails {
		values.Set("contributor_details", "true")
	}
	if params.ExcludeEntities {
		values.Set("include_entities", "false")
	}
	return values
}

// UserTimelineParams represents the query parameters for a
// /statuses/user_timeline.json request.
type UserTimelineParams struct {
	UserID             string `json:"user_id"`
	ScreenName         string `json:"screen_name"`
	SinceID            string `json:"since_id"`
	Count              int    `json:"count"`
	MaxID              string `json:"max_id"`
	TrimUser           bool   `json:"trim_user"`
	ExcludeReplies     bool   `json:"exclude_replies"`
	ContributorDetails bool   `json:"contributor_details"`
	ExcludeRTS         bool   `json:"exclude_rts"`
}

// UserTimeline calls the Twitter /statuses/user_timeline.json endpoint.
func (c *Client) UserTimeline(ctx context.Context, params UserTimelineParams) (*TweetsResponse, error) {
	values := userTimelineToQuery(params)
	resp, err := c.do(ctx, "GET", "https://api.twitter.com/1.1/statuses/user_timeline.json", values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var tweets []Tweet
	err = json.NewDecoder(resp.Body).Decode(resp.Body)
	if err != nil {
		return nil, err
	}
	return &TweetsResponse{
		Tweets:    tweets,
		RateLimit: getRateLimit(resp.Header),
	}, nil
}

func userTimelineToQuery(params UserTimelineParams) url.Values {
	values := url.Values{}
	if params.UserID != "" {
		values.Set("user_id", params.UserID)
	}
	if params.ScreenName != "" {
		values.Set("screen_name", params.ScreenName)
	}
	if params.SinceID != "" {
		values.Set("since_id", params.SinceID)
	}
	if params.Count > 0 {
		values.Set("count", strconv.Itoa(params.Count))
	}
	if params.MaxID != "" {
		values.Set("max_id", params.MaxID)
	}
	if params.TrimUser {
		values.Set("trim_user", "true")
	}
	if params.ExcludeReplies {
		values.Set("exclude_replies", "true")
	}
	if params.ContributorDetails {
		values.Set("contributor_details", "true")
	}
	if params.ExcludeRTS {
		values.Set("include_rts", "false")
	}
	return values
}

// HomeTimelineParams represents the query parameters for a
// /statuses/home_timeline.json request.
type HomeTimelineParams struct {
	Count              int    `json:"count"`
	SinceID            string `json:"since_id"`
	MaxID              string `json:"max_id"`
	TrimUser           bool   `json:"trim_user"`
	ExcludeReplies     bool   `json:"exclude_replies"`
	ContributorDetails bool   `json:"contributor_details"`
	ExcludeEntities    bool   `json:"exclude_entities"`
}

// HomeTimeline calls the Twitter /statuses/home_timeline.json endpoint.
func (c *Client) HomeTimeline(ctx context.Context, params HomeTimelineParams) (*TweetsResponse, error) {
	values := homeTimelineToQuery(params)
	resp, err := c.do(ctx, "GET", "https://api.twitter.com/1.1/statuses/home_timeline.json", values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var tweets []Tweet
	err = json.NewDecoder(resp.Body).Decode(resp.Body)
	if err != nil {
		return nil, err
	}
	return &TweetsResponse{
		Tweets:    tweets,
		RateLimit: getRateLimit(resp.Header),
	}, nil
}

func homeTimelineToQuery(params HomeTimelineParams) url.Values {
	values := url.Values{}
	if params.Count > 0 {
		values.Set("count", strconv.Itoa(params.Count))
	}
	if params.SinceID != "" {
		values.Set("since_id", params.SinceID)
	}
	if params.MaxID != "" {
		values.Set("max_id", params.MaxID)
	}
	if params.TrimUser {
		values.Set("trim_user", "true")
	}
	if params.ExcludeReplies {
		values.Set("exclude_replies", "true")
	}
	if params.ContributorDetails {
		values.Set("contributor_details", "true")
	}
	if params.ExcludeEntities {
		values.Set("include_entities", "false")
	}
	return values
}

// RetweetsOfMeParams represents the query parameters for a
// /statuses/retweets_of_me.json request.
type RetweetsOfMeParams struct {
	Count               int    `json:"count"`
	SinceID             string `json:"since_id"`
	MaxID               string `json:"max_id"`
	TrimUser            bool   `json:"trim_user"`
	ExcludeEntities     bool   `json:"exclude_entities"`
	ExcludeUserEntities bool   `json:"exclude_user_entities"`
}

// RetweetsOfMe calls the Twitter /statuses/retweets_of_me.json endpoint.
func (c *Client) RetweetsOfMe(ctx context.Context, params RetweetsOfMeParams) (*TweetsResponse, error) {
	values := retweetsOfMeToQuery(params)
	resp, err := c.do(ctx, "GET", "https://api.twitter.com/1.1/statuses/retweets_of_me.json", values)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var tweets []Tweet
	err = json.NewDecoder(resp.Body).Decode(resp.Body)
	if err != nil {
		return nil, err
	}
	return &TweetsResponse{
		Tweets:    tweets,
		RateLimit: getRateLimit(resp.Header),
	}, nil
}

func retweetsOfMeToQuery(params RetweetsOfMeParams) url.Values {
	values := url.Values{}
	if params.Count > 0 {
		values.Set("count", strconv.Itoa(params.Count))
	}
	if params.SinceID != "" {
		values.Set("since_id", params.SinceID)
	}
	if params.MaxID != "" {
		values.Set("max_id", params.MaxID)
	}
	if params.TrimUser {
		values.Set("trim_user", "true")
	}
	if params.ExcludeEntities {
		values.Set("include_entities", "false")
	}
	if params.ExcludeUserEntities {
		values.Set("include_user_entities", "false")
	}
	return values
}
<|endoftext|>


<commit_before>package main

var (
	basketsPageContent = []byte(`<!DOCTYPE html>

  <title>Request Baskets - Administration</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">

        Request Baskets

        <form class="navbar-form navbar-right">

              <input type="radio" name="options" id="list_quick" autocomplete="off" checked>

              </input>

              <input type="radio" name="options" id="list_details" autocomplete="off">

              </input>

        </form>

          <button type="button" class="close" data-dismiss="modal">×</button>

HTTP error

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

Master Token

        <form id="master_token_form">

By providing the master token you will gain access to all baskets.

            Token:
            <input type="password" class="form-control" id="master_token">

          Back to list of your baskets
          <button type="submit" class="btn btn-success" data-dismiss="modal">Authorize</button>

        </form>

All Baskets

            Basket
            Requests
            Details

        more...

Powered by request-baskets

`)
)
<commit_msg>fixed broken link<commit_after>package main

var (
	basketsPageContent = []byte(`<!DOCTYPE html>

  <title>Request Baskets - Administration</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" integrity="sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1" crossorigin="anonymous">

        Request Baskets

        <form class="navbar-form navbar-right">

              <input type="radio" name="options" id="list_quick" autocomplete="off" checked>

              </input>

              <input type="radio" name="options" id="list_details" autocomplete="off">

              </input>

        </form>

          <button type="button" class="close" data-dismiss="modal">×</button>

HTTP error

          <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>

Master Token

        <form id="master_token_form">

By providing the master token you will gain access to all baskets.

            Token:
            <input type="password" class="form-control" id="master_token">

          Back to list of your baskets
          <button type="submit" class="btn btn-success" data-dismiss="modal">Authorize</button>

        </form>

All Baskets

            Basket
            Requests
            Details

        more...

Powered by request-baskets

`)
)
<|endoftext|>


<commit_before>package mpuwsgivassal

import (
	"encoding/json"
	"flag"
	"net"
	"net/http"
	"strings"

	mp "github.com/mackerelio/go-mackerel-plugin"
)

// UWSGIVassalPlugin mackerel plugin for uWSGI
type UWSGIVassalPlugin struct {
	Socket      string
	Prefix      string
	LabelPrefix string
}

// {
//   "workers": [{
//     "id": 1,
//     "pid": 31759,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }, {
//     "id": 2,
//     "pid": 31760,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }, {
//     "id": 3,
//     "pid": 31761,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }, {
//     "id": 4,
//     "pid": 31762,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }
// }

// field types vary between versions

// UWSGIWorker struct
type UWSGIWorker struct {
	Requests uint64 `json:"requests"`
	Status   string `json:"status"`
}

// UWSGIWorkers sturct for json struct
type UWSGIWorkers struct {
	Workers []UWSGIWorker `json:"workers"`
}

// FetchMetrics interface for mackerelplugin
func (p UWSGIVassalPlugin) FetchMetrics() (map[string]float64, error) {
	stat := make(map[string]float64)
	stat["busy"] = 0.0
	stat["idle"] = 0.0
	stat["cheap"] = 0.0
	stat["pause"] = 0.0
	stat["requests"] = 0.0

	var decoder *json.Decoder
	if strings.HasPrefix(p.Socket, "unix://") {
		conn, err := net.Dial("unix", strings.TrimPrefix(p.Socket, "unix://"))
		if err != nil {
			return nil, err
		}
		defer conn.Close()
		decoder = json.NewDecoder(conn)
	} else if strings.HasPrefix(p.Socket, "http://") {
		resp, err := http.Get(p.Socket)
		if err != nil {
			return nil, err
		}
		defer resp.Body.Close()
		decoder = json.NewDecoder(resp.Body)
	}

	var workers UWSGIWorkers
	if err := decoder.Decode(&workers); err != nil {
		return nil, err
	}

	for _, worker := range workers.Workers {
		switch worker.Status {
		case "idle", "busy", "cheap", "pause":
			stat[worker.Status]++
		}
		stat["requests"] += float64(worker.Requests)
	}

	return stat, nil
}

// GraphDefinition interface for mackerelplugin
func (p UWSGIVassalPlugin) GraphDefinition() map[string]mp.Graphs {
	labelPrefix := strings.Title(p.Prefix)

	var graphdef = map[string]mp.Graphs{
		(p.Prefix + ".workers"): {
			Label: labelPrefix + " Workers",
			Unit:  "integer",
			Metrics: []mp.Metrics{
				{Name: "busy", Label: "Busy", Diff: false, Stacked: true},
				{Name: "idle", Label: "Idle", Diff: false, Stacked: true},
				{Name: "cheap", Label: "Cheap", Diff: false, Stacked: true},
				{Name: "pause", Label: "Pause", Diff: false, Stacked: true},
			},
		},
		(p.Prefix + ".req"): {
			Label: labelPrefix + " Requests",
			Unit:  "float",
			Metrics: []mp.Metrics{
				{Name: "requests", Label: "Requests", Diff: true},
			},
		},
	}

	return graphdef
}

// MetricKeyPrefix interface for PluginWithPrefix
func (p UWSGIVassalPlugin) MetricKeyPrefix() string {
	if p.Prefix == "" {
		p.Prefix = "uWSGI"
	}
	return p.Prefix
}

// Do the plugin
func Do() {
	optSocket := flag.String("socket", "", "Socket")
	optPrefix := flag.String("metric-key-prefix", "uWSGI", "Prefix")
	optTempfile := flag.String("tempfile", "", "Temp file name")
	flag.Parse()

	uwsgi := UWSGIVassalPlugin{Socket: *optSocket, Prefix: *optPrefix}
	if uwsgi.LabelPrefix == "" {
		uwsgi.LabelPrefix = strings.Title(uwsgi.Prefix)
	}

	helper := mp.NewMackerelPlugin(uwsgi)
	helper.Tempfile = *optTempfile
	helper.Run()
}
<commit_msg>Remove obsolete if statement<commit_after>package mpuwsgivassal

import (
	"encoding/json"
	"flag"
	"net"
	"net/http"
	"strings"

	mp "github.com/mackerelio/go-mackerel-plugin"
)

// UWSGIVassalPlugin mackerel plugin for uWSGI
type UWSGIVassalPlugin struct {
	Socket      string
	Prefix      string
	LabelPrefix string
}

// {
//   "workers": [{
//     "id": 1,
//     "pid": 31759,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }, {
//     "id": 2,
//     "pid": 31760,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }, {
//     "id": 3,
//     "pid": 31761,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }, {
//     "id": 4,
//     "pid": 31762,
//     "requests": 0,
//     "exceptions": 0,
//     "status": "idle",
//     "rss": 0,
//     "vsz": 0,
//     "running_time": 0,
//     "last_spawn": 1317235041,
//     "respawn_count": 1,
//     "tx": 0,
//     "avg_rt": 0,
//     "apps": [{
//       "id": 0,
//       "modifier1": 0,
//       "mountpoint": "",
//       "requests": 0,
//       "exceptions": 0,
//       "chdir": ""
//     }]
//   }
// }

// field types vary between versions

// UWSGIWorker struct
type UWSGIWorker struct {
	Requests uint64 `json:"requests"`
	Status   string `json:"status"`
}

// UWSGIWorkers sturct for json struct
type UWSGIWorkers struct {
	Workers []UWSGIWorker `json:"workers"`
}

// FetchMetrics interface for mackerelplugin
func (p UWSGIVassalPlugin) FetchMetrics() (map[string]float64, error) {
	stat := make(map[string]float64)
	stat["busy"] = 0.0
	stat["idle"] = 0.0
	stat["cheap"] = 0.0
	stat["pause"] = 0.0
	stat["requests"] = 0.0

	var decoder *json.Decoder
	if strings.HasPrefix(p.Socket, "unix://") {
		conn, err := net.Dial("unix", strings.TrimPrefix(p.Socket, "unix://"))
		if err != nil {
			return nil, err
		}
		defer conn.Close()
		decoder = json.NewDecoder(conn)
	} else if strings.HasPrefix(p.Socket, "http://") {
		resp, err := http.Get(p.Socket)
		if err != nil {
			return nil, err
		}
		defer resp.Body.Close()
		decoder = json.NewDecoder(resp.Body)
	}

	var workers UWSGIWorkers
	if err := decoder.Decode(&workers); err != nil {
		return nil, err
	}

	for _, worker := range workers.Workers {
		switch worker.Status {
		case "idle", "busy", "cheap", "pause":
			stat[worker.Status]++
		}
		stat["requests"] += float64(worker.Requests)
	}

	return stat, nil
}

// GraphDefinition interface for mackerelplugin
func (p UWSGIVassalPlugin) GraphDefinition() map[string]mp.Graphs {
	labelPrefix := strings.Title(p.Prefix)

	var graphdef = map[string]mp.Graphs{
		(p.Prefix + ".workers"): {
			Label: labelPrefix + " Workers",
			Unit:  "integer",
			Metrics: []mp.Metrics{
				{Name: "busy", Label: "Busy", Diff: false, Stacked: true},
				{Name: "idle", Label: "Idle", Diff: false, Stacked: true},
				{Name: "cheap", Label: "Cheap", Diff: false, Stacked: true},
				{Name: "pause", Label: "Pause", Diff: false, Stacked: true},
			},
		},
		(p.Prefix + ".req"): {
			Label: labelPrefix + " Requests",
			Unit:  "float",
			Metrics: []mp.Metrics{
				{Name: "requests", Label: "Requests", Diff: true},
			},
		},
	}

	return graphdef
}

// MetricKeyPrefix interface for PluginWithPrefix
func (p UWSGIVassalPlugin) MetricKeyPrefix() string {
	if p.Prefix == "" {
		p.Prefix = "uWSGI"
	}
	return p.Prefix
}

// Do the plugin
func Do() {
	optSocket := flag.String("socket", "", "Socket")
	optPrefix := flag.String("metric-key-prefix", "uWSGI", "Prefix")
	optTempfile := flag.String("tempfile", "", "Temp file name")
	flag.Parse()

	uwsgi := UWSGIVassalPlugin{Socket: *optSocket, Prefix: *optPrefix}
	uwsgi.LabelPrefix = strings.Title(uwsgi.Prefix)

	helper := mp.NewMackerelPlugin(uwsgi)
	helper.Tempfile = *optTempfile
	helper.Run()
}
<|endoftext|>