<commit_before>package main

import (
	"os"
	"fmt"
	"strings"
	"syscall"
	"../parse"
	"../edit"
)

const (
	FILE_CLOSE uintptr = ^uintptr(0)
)

var env map[string]string
var search_paths []string

func lackeol() {
	fmt.Println("\033[7m%\033[m")
}

// TODO return a separate error
func isExecutable(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	defer f.Close()

	fi, err := f.Stat()
	if err != nil {
		return false
	}
	fm := fi.Mode()
	return !fm.IsDir() && (fm & 0111 != 0)
}

// Search for executable `exe`.
// TODO return a separate error
func search(exe string) string {
	for _, p := range []string{"/", "./", "../"} {
		if strings.HasPrefix(exe, p) {
			return exe
		}
	}
	for _, p := range search_paths {
		full := p + "/" + exe
		if isExecutable(full) {
			return full
		}
	}
	return ""
}

func envAsSlice(env map[string]string) (s []string) {
	s = make([]string, len(env))
	for k, v := range env {
		s = append(s, fmt.Sprintf("%s=%s", k, v))
	}
	return
}

func envAsMap(env []string) (m map[string]string) {
	m = make(map[string]string)
	for _, e := range env {
		arr := strings.SplitN(e, "=", 2)
		if len(arr) == 2 {
			m[arr[0]] = arr[1]
		}
	}
	return
}

func evalTerm(n parse.Node) string {
	return n.(*parse.StringNode).Text
}

func evalCommandArgs(n *parse.CommandNode) (args []string) {
	args = make([]string, 0, len(n.Nodes))
	for _, w := range n.Nodes {
		args = append(args, evalTerm(w))
	}
	return
}

func main() {
	env := envAsMap(os.Environ())

	path_var, ok := env["PATH"]
	if ok {
		search_paths = strings.Split(path_var, ":")
		// fmt.Printf("Search paths are %v\n", search_paths)
	} else {
		search_paths = []string{"/bin"}
	}

	cmd_no := 0

repl:
	for {
		cmd_no++
		name := fmt.Sprintf("<interactive code %d>", cmd_no)

		ed, err := edit.Init(os.Stdin)
		if err != nil {
			panic(err)
		}
		lr := ed.ReadLine("das> ")
		err = ed.Cleanup()
		if err != nil {
			panic(err)
		}

		if lr.Eof {
			lackeol()
			break
		} else if lr.Err != nil {
			panic(lr.Err)
		}
		line := lr.Line
		tree, err := parse.Parse(name, line, false)
		if err != nil {
			fmt.Println("Parser error:", err)
			continue
		}

		cmd := tree.Root.(*parse.ListNode).Nodes[0].(*parse.CommandNode)
		args := evalCommandArgs(cmd)
		if len(args) == 0 {
			continue
		}
		full := search(args[0])
		if len(full) == 0 {
			fmt.Println("command not found:", args[0])
			continue
		}
		args[0] = full

		files := []uintptr{0, 1, 2}

		for _, r := range cmd.Redirs {
			fd := r.Fd()

			if fd > 2 {
				fmt.Fprintln(os.Stderr, "Redir on fd > 2 not yet supported")
				continue repl
			}

			switch r := r.(type) {
			case *parse.FdRedir:
				oldFd := r.OldFd
				if oldFd > 2 {
					fmt.Fprintln(os.Stderr, "FD redir from fd > 2 not yet supported")
					continue repl
				}
				files[fd] = files[oldFd]
			case *parse.CloseRedir:
				files[fd] = FILE_CLOSE
			case *parse.FilenameRedir:
				// TODO haz hardcoded permbits now
				fname := evalTerm(r.Filename)
				oldFd, err := syscall.Open(fname, r.Flag, 0644)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Failed to open file %q: %s\n",
					            r.Filename, err)
					continue repl
				} else {
					files[fd] = uintptr(oldFd)
				}
			default:
				panic("unreachable")
			}
		}

		sys := syscall.SysProcAttr{}
		attr := syscall.ProcAttr{Env: envAsSlice(env), Files: files, Sys: &sys}
		pid, err := syscall.ForkExec(full, args, &attr)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to fork/exec: %s", err)
			continue repl
		}

		var ws syscall.WaitStatus
		var ru syscall.Rusage

		// TODO Should check ws
		syscall.Wait4(pid, &ws, 0, &ru)
	}
}
<commit_msg>main: Print pid at startup to aid debugging<commit_after>package main

import (
	"os"
	"fmt"
	"strings"
	"syscall"
	"../parse"
	"../edit"
)

const (
	FILE_CLOSE uintptr = ^uintptr(0)
)

var env map[string]string
var search_paths []string

func lackeol() {
	fmt.Println("\033[7m%\033[m")
}

// TODO return a separate error
func isExecutable(path string) bool {
	f, err := os.Open(path)
	if err != nil {
		return false
	}
	defer f.Close()

	fi, err := f.Stat()
	if err != nil {
		return false
	}
	fm := fi.Mode()
	return !fm.IsDir() && (fm & 0111 != 0)
}

// Search for executable `exe`.
// TODO return a separate error
func search(exe string) string {
	for _, p := range []string{"/", "./", "../"} {
		if strings.HasPrefix(exe, p) {
			return exe
		}
	}
	for _, p := range search_paths {
		full := p + "/" + exe
		if isExecutable(full) {
			return full
		}
	}
	return ""
}

func envAsSlice(env map[string]string) (s []string) {
	s = make([]string, len(env))
	for k, v := range env {
		s = append(s, fmt.Sprintf("%s=%s", k, v))
	}
	return
}

func envAsMap(env []string) (m map[string]string) {
	m = make(map[string]string)
	for _, e := range env {
		arr := strings.SplitN(e, "=", 2)
		if len(arr) == 2 {
			m[arr[0]] = arr[1]
		}
	}
	return
}

func evalTerm(n parse.Node) string {
	return n.(*parse.StringNode).Text
}

func evalCommandArgs(n *parse.CommandNode) (args []string) {
	args = make([]string, 0, len(n.Nodes))
	for _, w := range n.Nodes {
		args = append(args, evalTerm(w))
	}
	return
}

func main() {
	fmt.Printf("My pid is %d\n", syscall.Getpid())
	env := envAsMap(os.Environ())

	path_var, ok := env["PATH"]
	if ok {
		search_paths = strings.Split(path_var, ":")
		// fmt.Printf("Search paths are %v\n", search_paths)
	} else {
		search_paths = []string{"/bin"}
	}

	cmd_no := 0

repl:
	for {
		cmd_no++
		name := fmt.Sprintf("<interactive code %d>", cmd_no)

		ed, err := edit.Init(os.Stdin)
		if err != nil {
			panic(err)
		}
		lr := ed.ReadLine("das> ")
		err = ed.Cleanup()
		if err != nil {
			panic(err)
		}

		if lr.Eof {
			lackeol()
			break
		} else if lr.Err != nil {
			panic(lr.Err)
		}
		line := lr.Line
		tree, err := parse.Parse(name, line, false)
		if err != nil {
			fmt.Println("Parser error:", err)
			continue
		}

		cmd := tree.Root.(*parse.ListNode).Nodes[0].(*parse.CommandNode)
		args := evalCommandArgs(cmd)
		if len(args) == 0 {
			continue
		}
		full := search(args[0])
		if len(full) == 0 {
			fmt.Println("command not found:", args[0])
			continue
		}
		args[0] = full

		files := []uintptr{0, 1, 2}

		for _, r := range cmd.Redirs {
			fd := r.Fd()

			if fd > 2 {
				fmt.Fprintln(os.Stderr, "Redir on fd > 2 not yet supported")
				continue repl
			}

			switch r := r.(type) {
			case *parse.FdRedir:
				oldFd := r.OldFd
				if oldFd > 2 {
					fmt.Fprintln(os.Stderr, "FD redir from fd > 2 not yet supported")
					continue repl
				}
				files[fd] = files[oldFd]
			case *parse.CloseRedir:
				files[fd] = FILE_CLOSE
			case *parse.FilenameRedir:
				// TODO haz hardcoded permbits now
				fname := evalTerm(r.Filename)
				oldFd, err := syscall.Open(fname, r.Flag, 0644)
				if err != nil {
					fmt.Fprintf(os.Stderr, "Failed to open file %q: %s\n",
					            r.Filename, err)
					continue repl
				} else {
					files[fd] = uintptr(oldFd)
				}
			default:
				panic("unreachable")
			}
		}

		sys := syscall.SysProcAttr{}
		attr := syscall.ProcAttr{Env: envAsSlice(env), Files: files, Sys: &sys}
		pid, err := syscall.ForkExec(full, args, &attr)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to fork/exec: %s", err)
			continue repl
		}

		var ws syscall.WaitStatus
		var ru syscall.Rusage

		// TODO Should check ws
		syscall.Wait4(pid, &ws, 0, &ru)
	}
}
<|endoftext|>


<commit_before>package main
import (
    "project.go/elev"
    "project.go/network"
    "time"
    "fmt"
    "encoding/json"
    "project.go/order"
    . "project.go/obj"
)
/*
const (
    INIT = iota
    IDLE
    RUN
    DOOR_OPEN
)*/

const (
    N_FLOORS = 4
    N_BUTTONS = 3
    DOOR_TIMEOUT = 3
)

func manager(push_light_channel, pop_light_channel chan<- Order, open_door_channel, direction_channel, check_stop_channel chan<- int) (chan<- Order, chan<- int, chan<- int) {
    local_addr, to_network_channel, from_network_channel, _, _ := network.Manager("33223");

    order_channel := make(chan Order);
    check_stop_channel := make(chan int);
    direction_request_channel := make(chan int);

    go func() {
        for {
            //system.Print();
            select {
            case msg := <-from_network_channel:
                addr := msg.Origin.IP.String();
                err := (error)(nil);
                order := &elev.Order{};
                i := (*int)(nil);
                switch msg.Code {
                case ORDER_PUSH, ORDER_POP:
                    err = json.Unmarshal(msg.Body, order);
                case FLOOR_HIT, DIRECTION_CHANGE:
                    err = json.Unmarshal(msg.Body, i);
                }
                if err != nil {
                    fmt.Println("Could not unmarshal order.");
                    break;
                }
                switch msg.Code {
                case ORDER_PUSH, ORDER_POP:
                    if msg.Code == ORDER_PUSH {
                        value := true;
                        push_light_channel <-order;
                        if carts[local_addr].Direction == 0 {
                            direction_channel <-getDirection();
                        }
                    } else {
                        value := false;
                        pop_light_channel <-order;
                    }
                    if order.Button == order.COMMAND {
                        cart[addr].Cab[order.Floor] = value;
                    } else {
                        hall[order.Floor][order.Button] = value;
                    }
                case FLOOR_HIT:
                    carts[addr].Floor = i;
                case DIRECTION_CHANGE:
                    carts[addr].Direction = i;
                }
            case order := <-order_channel:
                b, err := json.Marshal(order);
                if err != nil {
                    fmt.Println("Could not marshal order.");
                }
                to_network_channel <-*NewMessage(ORDER_PUSH, b, local_addr, nil);
            case <-check_stop_channel:
                 if checkIfStop() {
                      open_door_channel <-carts[local_addr].Floor;
                  }
            case direction_request_channel:
                direction_channel <-getDirection();

            }
        }
    }();
    return order_channel, check_stop_channel, direction_request_channel;
}

func main() {
    elev.Init()
    door_open_floor := -1;
    door_open := false;

    button_channel := elev.Button_checker();
    floor_signal_channel := elev.Floor_checker();
    stop_signal_channel := elev.Stop_checker();

    push_light_channel := make(chan Order);
    pop_light_channel := make(chan Order);
    open_door_channel := make(chan int);
    direction_channel := make(chan int);

    order_channel, direction_request_channel := manager(push_light_channel, pop_light_channel, open_door_channel, direction_channel);

    for {
        select {
        case order := <-push_light_channel:
            elev.SetButtonLamp(order.Floor, order.Button, true);
        case order := <-pop_light_channel:
            elev.SetButtonLamp(order.Floor, order.Button, false);
        case floor := <-open_door_channel:
            door_open = true;
            elev.SetDoorOpenLamp(true);
            elev.SetMotorDirection(0);
        case direction := <-direction_channel:
            elev.SetMotorDirection(direction);
        case floor := <-floor_signal_channel:
            check_stop_channel <-floor;
        case order := <-button_channel:
            if door_open && door_open_floor == order.Floor {
                door_timer.Start(3*time.Second);
            } else {
                order_channel <-order;
            }
        case <-door_timer.Timer.C:
            door_open = false;
            elev.SetDoorOpenLamp(false);
            direction_request_channel <-true;
        }
    }
}
<commit_msg>This thing sends messages.<commit_after>package main
import (
    "project.go/elev"
    "project.go/network"
    "time"
    "fmt"
    "encoding/json"
    "project.go/order"
    . "project.go/obj"
)
/*
const (
    INIT = iota
    IDLE
    RUN
    DOOR_OPEN
)*/

const (
    N_FLOORS = 4
    N_BUTTONS = 3
    DOOR_TIMEOUT = 3
)

func Manager(push_light_channel, pop_light_channel chan<- Order, open_door_channel, direction_channel, check_stop_channel chan<- int) (chan<- Order, chan<- int, chan<- int) {
    local_addr, to_network_channel, from_network_channel, _, _ := network.Manager("33223");

    order_channel := make(chan Order);
    check_stop_channel := make(chan int);
    direction_request_channel := make(chan int);

    go func() {
        for {
            //system.Print();
            select {
            case msg := <-from_network_channel:
                addr := msg.Origin.IP.String();
                err := (error)(nil);
                order := &elev.Order{};
                i := (*int)(nil);
                switch msg.Code {
                case ORDER_PUSH, ORDER_POP:
                    err = json.Unmarshal(msg.Body, order);
                case FLOOR_HIT, DIRECTION_CHANGE:
                    err = json.Unmarshal(msg.Body, i);
                }
                if err != nil {
                    fmt.Println("Could not unmarshal order.");
                    break;
                }
                switch msg.Code {
                case ORDER_PUSH, ORDER_POP:
                    if msg.Code == ORDER_PUSH {
                        value := true;
                        push_light_channel <-order;
                        if carts[local_addr].Direction == 0 {
                            direction_channel <-getDirection();
                        }
                    } else {
                        value := false;
                        pop_light_channel <-order;
                    }
                    if order.Button == order.COMMAND {
                        cart[addr].Cab[order.Floor] = value;
                    } else {
                        hall[order.Floor][order.Button] = value;
                    }
                case FLOOR_HIT:
                    carts[addr].Floor = i;
                case DIRECTION_CHANGE:
                    carts[addr].Direction = i;
                }
            case order := <-order_channel:
                b, err := json.Marshal(order);
                if err != nil {
                    fmt.Println("Could not marshal order.");
                } else {
                    to_network_channel <-*NewMessage(ORDER_PUSH, b, nil, nil);
                }
            case floor := <-check_stop_channel:
                b, err := json.Marshal(floor);
                if err != nil {
                    fmt.Println("Could not marshal direction.");
                } else {
                    to_network_channel <-*NewMessage(FLOOR_HIT, b, nil, nil);
                }
                carts[local_addr].Floor = floor;
                if checkIfStop() {
                    order := Order{Button: order.COMMAND, Floor: floor};
                    b, _ := json.Marshal(order);
                    to_network_channel <-*NewMessage(ORDER_POP, b, nil, nil);
                    direction := getDirection();
                    if direction == elev.UP {
                        order.Button = order.UP;
                    } else if direction == elev.DOWN {
                        order.Button = order.DOWN;
                    }
                    b, _ := json.Marshal(order);
                    to_network_channel <-*NewMessage(ORDER_POP, b, nil, nil);
                    open_door_channel <-floor;
                }
            case <-direction_request_channel:
                direction := getDirection();
                b, err := json.Marshal(direction);
                if err != nil {
                    fmt.Println ("Could not marshal direction.");
                } else {
                    to_network_channel <-*NewMessage(DIRECTION_CHANGE, b, nil, nil);
                }
                carts[local_addr].Direction = direction;
                direction_channel <-direction;
            }
        }
    }();
    return order_channel, check_stop_channel, direction_request_channel;
}

func main() {
    elev.Init()
    door_open_floor := -1;
    door_open := false;

    button_channel := elev.Button_checker();
    floor_signal_channel := elev.Floor_checker();
    stop_signal_channel := elev.Stop_checker();

    push_light_channel := make(chan Order);
    pop_light_channel := make(chan Order);
    open_door_channel := make(chan int);
    direction_channel := make(chan int);

    order_channel, direction_request_channel := Manager(push_light_channel, pop_light_channel, open_door_channel, direction_channel);

    for {
        select {
        case order := <-push_light_channel:
            elev.SetButtonLamp(order.Floor, order.Button, true);
        case order := <-pop_light_channel:
            elev.SetButtonLamp(order.Floor, order.Button, false);
        case floor := <-open_door_channel:
            door_open = true;
            elev.SetDoorOpenLamp(true);
            elev.SetMotorDirection(0);
        case direction := <-direction_channel:
            elev.SetMotorDirection(direction);
        case floor := <-floor_signal_channel:
            check_stop_channel <-floor;
        case order := <-button_channel:
            if door_open && door_open_floor == order.Floor {
                door_timer.Start(3*time.Second);
            } else {
                order_channel <-order;
            }
        case <-door_timer.Timer.C:
            door_open = false;
            elev.SetDoorOpenLamp(false);
            direction_request_channel <-true;
        }
    }
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime/pprof"
	"time"

	"github.com/biogo/hts/internal"
	"github.com/brentp/bix"
	"github.com/brentp/cgotabix"
	"github.com/brentp/irelate"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/xopen"
)

//	"/media/brentp/ffd28ae3-3dca-4f44-8aed-1685a55661f8/uw-course/thu/data/data-diseaseX/disease_x.merged.jointCalled.vcf.ann.Recalibrated.Merged.HC.vcf.VT.vep.vcf.gz",
var FS = []string{
	"/usr/local/src/gemini_install/data/gemini/data/clinvar_20150305.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ExAC.r0.3.sites.vep.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ALL.wgs.phase3_shapeit2_mvncall_integrated_v5a.20130502.sites.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ESP6500SI.all.snps_indels.tidy.v2.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ExAC.r0.3.sites.vep.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/GRCh37-gms-mappability.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/cosmic-v68-GRCh37.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/dbsnp.b141.20140813.hg19.tidy.vcf.gz",
}

func benchmarkBix(other string, ntimes int) {
	start := time.Now()
	tbxs := make([]*bix.Bix, ntimes)

	var err error
	for i := 0; i < ntimes; i++ {
		tbxs[i], err = bix.New(FS[i])
		if err != nil {
			log.Fatal(err)
		}
	}
	or, err := xopen.Ropen(other)
	if err != nil {
		log.Fatal(err)
	}
	vcf := irelate.Vopen(or, nil)

	out := bufio.NewWriter(ioutil.Discard)
	/*
		out, err := vcfgo.NewWriter(os.Stdout, vcf.Header)
		if err != nil {
			log.Fatal(err)
		}
	*/

	n := 0
	k := 0
	for {
		var v interfaces.IVariant

		v = vcf.Read()
		if v == nil {
			break
		}

		for _, tbx := range tbxs {
			//for _, r := range tbx.Get(v) {
			rdr, err := tbx.Query(v.Chrom(), int(v.Start()), int(v.End()), false)
			if err != nil {
				if err != internal.ErrInvalid {
					log.Fatal(err)
				} else {
					continue
				}
			}
			db := irelate.Vopen(rdr, vcf.Header)
			db.AddInfoToHeader("XXX", "1", "Float", "XXX")
			db.AddInfoToHeader("many", "3", "Float", "XXX")
			db.AddInfoToHeader("manyi", "3", "Integer", "XXX")
			db.AddInfoToHeader("flag", "1", "Flag", "XXX")
			for {
				r := db.Read()
				if r == nil {
					break
				}
				//sp := strings.Split(r, "\t")

				if !interfaces.Same(r, v, true) {
					continue
				}

				ov := r.(interfaces.IVariant)
				n += 1
				abool := n%2 == 0
				//log.Println(ov.Info.Get("culprit"))
				//ov.Info.Set("culprit", "hi")
				ov.Info().Set("DP", 23)
				// TODO: update header then Set
				v := []float32{33.0, 33.0, 44.0}
				ov.Info().Set("many", v)
				ov.Info().Set("flag", abool)

				ov.Info().Set("manyi", []int32{22, 1, 2})
				//ov.Info.Set("XXX", 23.4)
				////log.Println(ov.Info.Get("culprit"))
				vv, err := ov.Info().Get("many")
				if err != nil {
					panic("couldn't get many")
				}
				if len(vv.([]float32)) != 3 {
					panic("bad length")
				}

				v2, err := ov.Info().Get("manyi")
				if v2.([]int)[2] != 2 {
					log.Fatalf("bad int: %v\n", v2)
				}
				b, err := ov.Info().Get("flag")
				if b == nil && abool != false {
					log.Fatal("bad bool")
				} else if abool && !b.(bool) {
					log.Fatal("bad bool")
				}

				dp, err := ov.Info().Get("DP")
				if v, ok := dp.(int); !ok {
					//log.Println(ov.Info())
				} else {
					if v != 23 {
						log.Fatal("bad depth")
					}
				}

				fmt.Fprintf(out, "%s\t%d\t%d\t%s\t%s\t%s\n", r.Chrom(), r.Start(), r.End(), ov.Ref(), ov.Alt(), ov.Info().String())
				//log.Println(r.Chrom(), r.Start(), r.End(), ov.Ref, ov.Alt)
			}
			k += 1
		}

	}
	out.Flush()
	log.Printf("gobix\t%d\t%s\t%.3f\t%d", ntimes, other, time.Since(start).Seconds(), n)

}

func benchmarkTabix(other string, ntimes int) {

	start := time.Now()
	tbxs := make([]*cgotabix.Tabix, ntimes)

	var err error
	for i := 0; i < ntimes; i++ {
		tbxs[i], err = cgotabix.New(FS[i])
		if err != nil {
			log.Fatal(err)
		}
		tbxs[i].AddInfoToHeader("XXX", "1", "Float", "XXX")
		tbxs[i].AddInfoToHeader("many", "3", "Float", "XXX")
		tbxs[i].AddInfoToHeader("manyi", "3", "Integer", "XXX")
		tbxs[i].AddInfoToHeader("flag", "1", "Flag", "XXX")
	}

	or, err := xopen.Ropen(other)
	if err != nil {
		log.Fatal(err)
	}
	vcf := irelate.Vopen(or, nil)

	out := bufio.NewWriter(ioutil.Discard)
	/* out, err := vcfgo.NewWriter(os.Stdout, vcf.Header)
	if err != nil {
		log.Fatal(err)
	} */

	n := 0
	k := 0
	for {
		var v interfaces.IVariant

		v = vcf.Read()
		if v == nil {
			break
		}

		qstr := fmt.Sprintf("%s:%d-%d", v.Chrom(), v.Start(), v.End())

		for _, tbx := range tbxs {
			//for _, r := range tbx.Get(v) {
			for r := range tbx.At(qstr) {
				//sp := strings.Split(r, "\t")

				if !interfaces.Same(r, v, true) {
					continue
				}

				ov := r.(interfaces.IVariant)
				n += 1
				abool := n%2 == 0
				//log.Println(ov.Info.Get("culprit"))
				//ov.Info.Set("culprit", "hi")
				ov.Info().Set("DP", 23)
				// TODO: update header then Set
				v := []float32{33.0, 33.0, 44.0}
				ov.Info().Set("many", v)
				ov.Info().Set("flag", abool)

				ov.Info().Set("manyi", []int32{22, 1, 2})
				//ov.Info.Set("XXX", 23.4)
				////log.Println(ov.Info.Get("culprit"))
				vv, err := ov.Info().Get("many")
				if err != nil {
					panic("couldn't get many")
				}
				if len(vv.([]float32)) != 3 {
					panic("bad length")
				}

				v2, err := ov.Info().Get("manyi")
				if v2.([]int)[2] != 2 {
					log.Fatalf("bad int: %v\n", v2)
				}
				b, err := ov.Info().Get("flag")
				if b == nil && abool != false {
					log.Fatal("bad bool")
				} else if abool && !b.(bool) {
					log.Fatal("bad bool")
				}

				dp, err := ov.Info().Get("DP")
				if v, ok := dp.(int); !ok {
					//log.Println(ov.Info())
				} else {
					if v != 23 {
						log.Fatal("bad depth")
					}
				}

				fmt.Fprintf(out, "%s\t%d\t%d\t%s\t%s\t%s\n", r.Chrom(), r.Start(), r.End(), ov.Ref(), ov.Alt(), ov.Info().String())
				//log.Println(r.Chrom(), r.Start(), r.End(), ov.Ref, ov.Alt)
			}
			k += 1
		}

	}
	out.Flush()
	log.Printf("tabix\t%d\t%s\t%.3f\t%d", ntimes, other, time.Since(start).Seconds(), n)

}

func benchmarkIrelate(other string, ntimes int) {

	start := time.Now()
	relatables := make([]irelate.RelatableChannel, ntimes+1)
	for i := 0; i < ntimes; i++ {
		db, err := irelate.Streamer(FS[i], "")
		if err != nil {
			log.Fatal(err)
		}
		relatables[i+1] = db
	}

	vcf, err := irelate.Streamer(other, "")
	if err != nil {
		log.Fatal(err)
	}
	out := bufio.NewWriter(ioutil.Discard)
	relatables[0] = vcf
	n := 0

	for v := range irelate.IRelate(irelate.CheckRelatedByOverlap, 0, irelate.NaturalLessPrefix, relatables...) {
		qstr := fmt.Sprintf("%s:%d-%d", v.Chrom(), v.Start(), v.End())
		fmt.Fprintf(out, "%s\n", qstr)
		for _, o := range v.Related() {
			if interfaces.Same(o, v, true) {
				n += 1
			}
		}
	}
	out.Flush()
	log.Printf("irelate\t%d\t%s\t%.3f\t%d", ntimes, other, time.Since(start).Seconds(), n)

}

func main() {

	pf, err := os.Create("cpu.pprof")
	if err != nil {
		panic(err)
	}
	pprof.StartCPUProfile(pf)
	defer pprof.StopCPUProfile()

	var f string
	for _, n_query := range []int{100, 1000, 10000, 100000} {
		//for _, n_query := range []int{100000} {
		//for _, n_db := range []int{1, 2, 4, 8} {
		for _, n_db := range []int{8} {
			if n_query == 2 {
				f = "/media/brentp/ffd28ae3-3dca-4f44-8aed-1685a55661f8/uw-course/thu/data/data-diseaseX/disease_x.merged.jointCalled.vcf.ann.Recalibrated.Merged.HC.vcf.VT.vep.vcf.gz"
			} else {
				f = fmt.Sprintf("intervals.%d.vcf", n_query)
			}
			//f = "v.vcf"
			benchmarkTabix(f, n_db)
			benchmarkBix(f, n_db)
			benchmarkIrelate(f, n_db)
		}
	}
}
<commit_msg>do the same work for all<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"runtime/pprof"
	"time"

	"github.com/biogo/hts/internal"
	"github.com/brentp/bix"
	"github.com/brentp/cgotabix"
	"github.com/brentp/irelate"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/vcfgo"
	"github.com/brentp/xopen"
)

//	"/media/brentp/ffd28ae3-3dca-4f44-8aed-1685a55661f8/uw-course/thu/data/data-diseaseX/disease_x.merged.jointCalled.vcf.ann.Recalibrated.Merged.HC.vcf.VT.vep.vcf.gz",
var FS = []string{
	"/usr/local/src/gemini_install/data/gemini/data/clinvar_20150305.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ExAC.r0.3.sites.vep.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ALL.wgs.phase3_shapeit2_mvncall_integrated_v5a.20130502.sites.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ESP6500SI.all.snps_indels.tidy.v2.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/ExAC.r0.3.sites.vep.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/GRCh37-gms-mappability.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/cosmic-v68-GRCh37.tidy.vcf.gz",
	"/usr/local/src/gemini_install/data/gemini/data/dbsnp.b141.20140813.hg19.tidy.vcf.gz",
}

func benchmarkBix(other string, ntimes int) {
	start := time.Now()
	tbxs := make([]*bix.Bix, ntimes)

	var err error
	for i := 0; i < ntimes; i++ {
		tbxs[i], err = bix.New(FS[i])
		if err != nil {
			log.Fatal(err)
		}
	}
	or, err := xopen.Ropen(other)
	if err != nil {
		log.Fatal(err)
	}
	vcf := irelate.Vopen(or, nil)

	out := bufio.NewWriter(ioutil.Discard)
	/*
		out, err := vcfgo.NewWriter(os.Stdout, vcf.Header)
		if err != nil {
			log.Fatal(err)
		}
	*/

	n := 0
	k := 0
	for {
		var v interfaces.IVariant

		v = vcf.Read()
		if v == nil {
			break
		}

		for _, tbx := range tbxs {
			//for _, r := range tbx.Get(v) {
			rdr, err := tbx.Query(v.Chrom(), int(v.Start()), int(v.End()), false)
			if err != nil {
				if err != internal.ErrInvalid {
					log.Fatal(err)
				} else {
					continue
				}
			}
			db := irelate.Vopen(rdr, vcf.Header)
			db.AddInfoToHeader("XXX", "1", "Float", "XXX")
			db.AddInfoToHeader("many", "3", "Float", "XXX")
			db.AddInfoToHeader("manyi", "3", "Integer", "XXX")
			db.AddInfoToHeader("flag", "1", "Flag", "XXX")
			var r interfaces.IVariant
			for {
				r = db.Read()
				if r == nil {
					break
				}
				//sp := strings.Split(r, "\t")

				if !interfaces.Same(r, v, true) {
					continue
				}
				ov := doStuff(r.(interfaces.IVariant), &n)
				if ov == nil {
					continue
				}
				fmt.Fprintf(out, "%s\t%d\t%d\t%s\t%s\t%s\n", r.Chrom(), r.Start(), r.End(), ov.Ref(), ov.Alt(), ov.Info().String())
				//log.Println(r.Chrom(), r.Start(), r.End(), ov.Ref, ov.Alt)
			}
			k += 1
		}

	}
	out.Flush()
	log.Printf("gobix\t%d\t%s\t%.3f\t%d", ntimes, other, time.Since(start).Seconds(), n)

}

func doStuff(r interfaces.IVariant, n *int) interfaces.IVariant {

	*n += 1
	ov, ok := r.(interfaces.IVariant)
	if !ok {
		return nil
	}
	abool := *n%2 == 0
	//log.Println(ov.Info.Get("culprit"))
	//ov.Info.Set("culprit", "hi")
	ov.Info().Set("DP", 23)
	// TODO: update header then Set
	v := []float32{33.0, 33.0, 44.0}
	ov.Info().Set("many", v)
	ov.Info().Set("flag", abool)

	ov.Info().Set("manyi", []int32{22, 1, 2})
	//ov.Info.Set("XXX", 23.4)
	////log.Println(ov.Info.Get("culprit"))
	vv, err := ov.Info().Get("many")
	if err != nil {
		panic(fmt.Sprintf("couldn't get many: %v, %s", vv, err))
	}
	if len(vv.([]float32)) != 3 {
		panic("bad length")
	}

	v2, err := ov.Info().Get("manyi")
	if v2.([]int)[2] != 2 {
		log.Fatalf("bad int: %v\n", v2)
	}
	b, err := ov.Info().Get("flag")
	if b == nil && abool != false {
		log.Fatal("bad bool")
	} else if abool && !b.(bool) {
		log.Fatal("bad bool")
	}

	dp, err := ov.Info().Get("DP")
	if v, ok := dp.(int); !ok {
		//log.Println(ov.Info())
	} else {
		if v != 23 {
			log.Fatal("bad depth")
		}
	}
	return ov
}

func benchmarkTabix(other string, ntimes int) {

	start := time.Now()
	tbxs := make([]*cgotabix.Tabix, ntimes)

	var err error
	for i := 0; i < ntimes; i++ {
		tbxs[i], err = cgotabix.New(FS[i])
		if err != nil {
			log.Fatal(err)
		}
		tbxs[i].AddInfoToHeader("XXX", "1", "Float", "XXX")
		tbxs[i].AddInfoToHeader("many", "3", "Float", "XXX")
		tbxs[i].AddInfoToHeader("manyi", "3", "Integer", "XXX")
		tbxs[i].AddInfoToHeader("flag", "1", "Flag", "XXX")
	}

	or, err := xopen.Ropen(other)
	if err != nil {
		log.Fatal(err)
	}
	vcf := irelate.Vopen(or, nil)

	out := bufio.NewWriter(ioutil.Discard)
	/* out, err := vcfgo.NewWriter(os.Stdout, vcf.Header)
	if err != nil {
		log.Fatal(err)
	} */

	n := 0
	k := 0
	for {
		var v interfaces.IVariant

		v = vcf.Read()
		if v == nil {
			break
		}

		qstr := fmt.Sprintf("%s:%d-%d", v.Chrom(), v.Start(), v.End())

		for _, tbx := range tbxs {
			//for _, r := range tbx.Get(v) {
			for r := range tbx.At(qstr) {
				//sp := strings.Split(r, "\t")

				if !interfaces.Same(r, v, true) {
					continue
				}
				ov := doStuff(r.(interfaces.IVariant), &n)
				if ov == nil {
					continue
				}

				fmt.Fprintf(out, "%s\t%d\t%d\t%s\t%s\t%s\n", r.Chrom(), r.Start(), r.End(), ov.Ref(), ov.Alt(), ov.Info().String())
				//log.Println(r.Chrom(), r.Start(), r.End(), ov.Ref, ov.Alt)
			}
			k += 1
		}

	}
	out.Flush()
	log.Printf("tabix\t%d\t%s\t%.3f\t%d", ntimes, other, time.Since(start).Seconds(), n)

}

func benchmarkIrelate(other string, ntimes int) {

	start := time.Now()
	relatables := make([]irelate.RelatableChannel, ntimes+1)
	for i := 0; i < ntimes; i++ {
		db, err := irelate.Streamer(FS[i], "")
		if err != nil {
			log.Fatal(err)
		}
		relatables[i+1] = db
	}

	f, err := xopen.Ropen(other)
	if err != nil {
		log.Fatal(err)
	}
	vcf, err := vcfgo.NewReader(f, true)
	if err != nil {
		log.Fatal(err)
	}
	vcf.AddInfoToHeader("XXX", "1", "Float", "XXX")
	vcf.AddInfoToHeader("many", "3", "Float", "XXX")
	vcf.AddInfoToHeader("manyi", "3", "Integer", "XXX")
	vcf.AddInfoToHeader("flag", "1", "Flag", "XXX")

	vstream := irelate.StreamVCF(vcf)

	out := bufio.NewWriter(ioutil.Discard)
	relatables[0] = vstream
	n := 0

	for v := range irelate.IRelate(irelate.CheckRelatedByOverlap, 0, irelate.NaturalLessPrefix, relatables...) {
		qstr := fmt.Sprintf("%s:%d-%d", v.Chrom(), v.Start(), v.End())
		fmt.Fprintf(out, "%s\n", qstr)
		for _, o := range v.Related() {
			if interfaces.Same(o, v, true) {
				doStuff(v.(interfaces.IVariant), &n)
			}
		}
	}
	out.Flush()
	log.Printf("irelate\t%d\t%s\t%.3f\t%d", ntimes, other, time.Since(start).Seconds(), n)

}

func main() {

	pf, err := os.Create("cpu.pprof")
	if err != nil {
		panic(err)
	}
	pprof.StartCPUProfile(pf)
	defer pprof.StopCPUProfile()

	var f string
	for _, n_query := range []int{100, 1000, 10000, 100000} {
		//for _, n_query := range []int{100000} {
		//for _, n_db := range []int{1, 2, 4, 8} {
		for _, n_db := range []int{1} {
			if n_query == 2 {
				f = "/media/brentp/ffd28ae3-3dca-4f44-8aed-1685a55661f8/uw-course/thu/data/data-diseaseX/disease_x.merged.jointCalled.vcf.ann.Recalibrated.Merged.HC.vcf.VT.vep.vcf.gz"
			} else {
				f = fmt.Sprintf("intervals.%d.vcf", n_query)
			}
			//f = "v.vcf"
			benchmarkTabix(f, n_db)
			benchmarkBix(f, n_db)
			benchmarkIrelate(f, n_db)
		}
	}
}
<|endoftext|>


<commit_before>// Wrap the standard flag package parser to look for environment variables
// after command flags
package envflag

import (
	"flag"
	"os"
	"strings"
)

// Map the command flag to the environment variable
// This is only needed where a natural mapping of
//     flag-name -> FLAG_NAME
// is not there or a filter is needed to adapt the
// value from the environment variable
type FlagMap map[string]Flag

// Define a Flag's behavior where Name is the Environment variable
// and the Filter is function to be used on the value in order to
// transform into the expected value for a command-line flag
type Flag struct {
	Name   string
	Filter func(string) string
}

// Parse flags where command > environment > default
func Parse(m FlagMap) {
	flag.VisitAll(func(f *flag.Flag) {
		mapping := Flag{}
		if s, ok := m[f.Name]; ok {
			if len(s.Name) > 0 {
				mapping.Name = s.Name
			}
			if s.Filter != nil {
				mapping.Filter = s.Filter
			}
		}
		if len(mapping.Name) == 0 {
			mapping.Name = strings.ToUpper(strings.Replace(f.Name, "-", "_", -1))
		}
		if mapping.Filter == nil {
			mapping.Filter = func(s string) string { return s }
		}
		if v := os.Getenv(mapping.Name); len(v) > 0 {
			f.Value.Set(mapping.Filter(v))
		}
	})
}
<commit_msg>Oops, we weren't parsing the command line...<commit_after>// Wrap the standard flag package parser to look for environment variables
// after command flags
package envflag

import (
	"flag"
	"os"
	"strings"
)

// Map the command flag to the environment variable
// This is only needed where a natural mapping of
//     flag-name -> FLAG_NAME
// is not there or a filter is needed to adapt the
// value from the environment variable
type FlagMap map[string]Flag

// Define a Flag's behavior where Name is the Environment variable
// and the Filter is function to be used on the value in order to
// transform into the expected value for a command-line flag
type Flag struct {
	Name   string
	Filter func(string) string
}

// Parse flags where command > environment > default
func Parse(m FlagMap) {
	flag.Parse()
	flag.VisitAll(func(f *flag.Flag) {
		mapping := Flag{}
		if s, ok := m[f.Name]; ok {
			if len(s.Name) > 0 {
				mapping.Name = s.Name
			}
			if s.Filter != nil {
				mapping.Filter = s.Filter
			}
		}
		if len(mapping.Name) == 0 {
			mapping.Name = strings.ToUpper(strings.Replace(f.Name, "-", "_", -1))
		}
		if mapping.Filter == nil {
			mapping.Filter = func(s string) string { return s }
		}
		if v := os.Getenv(mapping.Name); len(v) > 0 {
			f.Value.Set(mapping.Filter(v))
		}
	})
}
<|endoftext|>


<commit_before>package events

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"sync"
	"time"
)

// LimitExceeded is returned when the number of simultaneous connections to
// Urban Airship's Event API is exceeded. The API responds with a 402 Payment
// Required status which is translated into this error.
var LimitExceeded = errors.New("request was rate limited")

// Event is the envelope for a single even from Urban Airship's event stream.
// Users should inspect the Event's Type and call the corresponding method to
// receive a typed event body.
type Event struct {
	// ID uniquely identifies the event.
	ID       string    `json:"id"`
	Type     Type      `json:"type"`
	Occurred time.Time `json:"occurred"`

	// Processed is when the event was ingested by Urban Airship. There may be
	// lag between when the event occurred, and when it was processed.
	Processed time.Time `json:"processed"`

	// Offset is the event's location in the stream. Used to resume the stream
	// after severing a connection. Clients should store this value for the case
	// that the connection is severed.
	Offset uint64 `json:"offset,string"`

	// Body is the raw event body. Use the Type specific methods to unmarshal the
	// body.
	Body   json.RawMessage `json:"body"`
	Device *Device         `json:"device,omitempty"`
}

type Push struct {
	// PushID is the unique identifier for the push, included in responses to the
	// push API.
	PushID string `json:"push_id"`

	// GroupID is an optional identifier of the group this push is associated
	// with; group IDs are created by both automation and push to local time.
	GroupID string `json:"group_id"`
}

type PushBody struct {
	Push

	// Payload is the specification of the push as sent via the API.
	Payload []byte `json:"payload"`
}

func (e *Event) PushBody() (*PushBody, error) {
	if e.Type != TypePush {
		return nil, WrongType
	}
	p := PushBody{}
	if err := json.Unmarshal(e.Body, &p); err != nil {
		return nil, err
	}
	return &p, nil
}

type Open struct {
	// LastDelivered contains the push identifier of the last notification Urban
	// Airship attempted to deliver to this device, if known. It may also include
	// a group identifier if the push was scheduled to the device’s local time or
	// if the push was an automation rule.
	//
	LastDelivered *Push `json:"last_delivered,omitempty"`

	// Triggering is present if the event was associated with a push. An
	// object containing the push ID of that notification. It may also include a
	// group ID if the push was a push to local time or automation rule.
	//
	TriggeringPush *Push `json:"triggering_push,omitempty"`

	// SessionID is an identifier for the "session" of user activity. This key
	// will be absent if the application was initialized while backgrounded.
	SessionID string `json:"session_id"`
}

// Open returns an Open struct for OPEN events. Non-OPEN events will return
// the WrongType error.
func (e *Event) Open() (*Open, error) {
	if e.Type != TypeOpen {
		return nil, WrongType
	}
	o := Open{}
	if err := json.Unmarshal(e.Body, &o); err != nil {
		return nil, err
	}
	return &o, nil
}

// Send events are emitted for each device identified by the audience selection
// of a push. device will be present in the event to specify which channel
// received the push.
type Send struct {
	Push

	// VariantID is only present if the notification was sent as part of an
	// experiment.  Identifies the payload ultimately sent to a device.
	VariantID string `json:"variant_id,omitempty"`
}

// Send returns a Send struct for SEND events. Non-SEND events will return the
// WrongType error.
func (e *Event) Send() (*Send, error) {
	if e.Type != TypeSend {
		return nil, WrongType
	}
	s := Send{}
	if err := json.Unmarshal(e.Body, &s); err != nil {
		return nil, err
	}
	return &s, nil
}

// Close events are emitted Each time a user closes the application. Note that
// close events are often latent, as they may not be delivered over the network
// until much later.
type Close struct {
	SessionID string `json:"session_id"`
}

func (e *Event) Close() (*Close, error) {
	if e.Type != TypeClose {
		return nil, WrongType
	}
	c := Close{}
	if err := json.Unmarshal(e.Body, &c); err != nil {
		return nil, err
	}
	return &c, nil
}

// TagChange events are emitted Each time a tag is added or removed from a
// channel.
type TagChange struct {
	// Add maps tag groups to tags. The set of tag group/tag pairs in this object
	// define the tags added to the device.
	Add map[string][]string `json:"add"`

	// Remove maps tag groups to tags. The set of tag group/tag pairs in this
	// object define the tags removed from the device.
	Remove map[string][]string `json:"remove"`

	// Current maps tag groups to tags. The set of tag group/tag pairs in this
	// object define the current state of the device AFTER the mutation has taken
	// effect.
	Current map[string][]string `json:"current"`
}

func (e *Event) TagChange() (*TagChange, error) {
	if e.Type != TypeTagChange {
		return nil, WrongType
	}
	t := TagChange{}
	if err := json.Unmarshal(e.Body, &t); err != nil {
		return nil, err
	}
	return &t, nil
}

// Location events include the latitude and longitude of the device.
type Location struct {
	Lat json.Number `json:"latitude"`
	Lon json.Number `json:"longitude"`

	// Foreground indicates whether the application was foregrounded when the
	// event fired.
	Foreground bool `json:"foreground"`
}

func (e *Event) Location() (*Location, error) {
	if e.Type != TypeLocation {
		return nil, WrongType
	}
	loc := Location{}
	if err := json.Unmarshal(e.Body, &loc); err != nil {
		return nil, err
	}
	return &loc, nil
}

type InAppMessageDisplay struct {
	Push

	// A triggering push is present if the user started the current session by opening
	// a push notification.
	TriggeringPush Push `json:"triggering_push"`
}

func (e *Event) InAppMessageDisplay() (*InAppMessageDisplay, error) {
	if e.Type != TypeInAppMessageDisplay {
		return nil, WrongType
	}
	disp := InAppMessageDisplay{}
	if err := json.Unmarshal(e.Body, &disp); err != nil {
		return nil, err
	}
	return &disp, nil
}

type InAppMessageResolution struct {
	InAppMessageDisplay

	TimeSent time.Time `json:"time_sent"`

	// Type indicates how the In-app message was resolved, and can take on one
	// of the following values: BUTTON_CLICK, MESSAGE_CLICK, TIMED_OUT, USER_DISMISSED
	Type string `json:"type"`

	// Duration is the amount of time for which the message was displayed, in milliseconds.
	Duration int64 `json:"duration"`

	// Additional optional fields describing the button that was clicked:
	ButtonID          string `json:"button_id,omitempty"`
	ButtonGroup       string `json:"button_group,omitempty"`
	ButtonDescription string `json:"button_description,omitempty"`
}

func (e *Event) InAppMessageResolution() (*InAppMessageResolution, error) {
	if e.Type != TypeInAppMessageResolution {
		return nil, WrongType
	}
	res := InAppMessageResolution{}
	if err := json.Unmarshal(e.Body, &res); err != nil {
		return nil, err
	}
	return &res, nil
}

type InAppMessageExpiration struct {
	InAppMessageResolution

	// ReplacingPush is present if Type is equal to REPLACED. It identifies
	// the push specification defining the In-App message which should replace the
	// current message.
	ReplacingPush Push `json:"replacing_push,omitempty"`
}

func (e *Event) InAppMessageExpiration() (*InAppMessageExpiration, error) {
	if e.Type != TypeInAppMessageExpiration {
		return nil, WrongType
	}
	exp := InAppMessageExpiration{}
	if err := json.Unmarshal(e.Body, &exp); err != nil {
		return nil, err
	}
	return &exp, nil
}

func (e *Event) RichEvent() (*Push, error) {
	if e.Type != TypeRichDelete && e.Type != TypeRichDelivery && e.Type != TypeRichRead {
		return nil, WrongType
	}
	p := Push{}
	if err := json.Unmarshal(e.Body, &p); err != nil {
		return nil, err
	}
	return &p, nil
}

// Response streams Events from a Fetch call.
type Response struct {
	// ID is the UA-Operation-Id header from Urban Airship's response.
	ID string

	out  chan *Event
	body io.ReadCloser

	mu     *sync.Mutex
	closed chan struct{}
	err    error
}

// NewResponse creates an events iterator from an http.Response. Fetch is a
// shortcut for creating a Response, but users can manually create a Response
// from a custom HTTP request with this function.
func NewResponse(resp *http.Response) (*Response, error) {
	if resp.StatusCode == 402 {
		return nil, LimitExceeded
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("unexpected non-200 response: %d", resp.StatusCode)
	}
	r := &Response{
		ID:     resp.Header.Get("UA-Operation-Id"),
		out:    make(chan *Event, 10), // provide some buffering
		body:   resp.Body,
		mu:     new(sync.Mutex),
		closed: make(chan struct{}),
	}
	go func() {
		// Always close Event chan to indicate to callers that response is done.
		defer close(r.out)
		dec := json.NewDecoder(r.body)
		for {
			var ev Event
			if err := dec.Decode(&ev); err != nil {
				select {
				case <-r.closed:
					//TODO Only ignore "closed" errors
					return
				default:
					r.mu.Lock()
					defer r.mu.Unlock()
					r.err = err
					return
				}
			}
			select {
			case r.out <- &ev:
			case <-r.closed:
				return
			}
		}
	}()
	return r, nil
}

// Events returns a chan that emits Events until closed. Events is safe for
// concurrent calls and shares an underlying chan. This means events are not
// duplicated between multiple receivers.
func (r *Response) Events() <-chan *Event { return r.out }

// Close the events stream. Safe to call concurrently.
func (r *Response) Close() {
	r.mu.Lock()
	defer r.mu.Unlock()
	select {
	case <-r.closed:
		return
	default:
		close(r.closed)
		r.body.Close()
	}
}

// Err returns the error which caused the event stream to end or nil. May be
// checked when the chan returned by Events() is closed. Safe for concurrent
// access.
func (r *Response) Err() error {
	r.mu.Lock()
	defer r.mu.Unlock()
	return r.err
}
<commit_msg>remove variant id<commit_after>package events

import (
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"sync"
	"time"
)

// LimitExceeded is returned when the number of simultaneous connections to
// Urban Airship's Event API is exceeded. The API responds with a 402 Payment
// Required status which is translated into this error.
var LimitExceeded = errors.New("request was rate limited")

// Event is the envelope for a single even from Urban Airship's event stream.
// Users should inspect the Event's Type and call the corresponding method to
// receive a typed event body.
type Event struct {
	// ID uniquely identifies the event.
	ID       string    `json:"id"`
	Type     Type      `json:"type"`
	Occurred time.Time `json:"occurred"`

	// Processed is when the event was ingested by Urban Airship. There may be
	// lag between when the event occurred, and when it was processed.
	Processed time.Time `json:"processed"`

	// Offset is the event's location in the stream. Used to resume the stream
	// after severing a connection. Clients should store this value for the case
	// that the connection is severed.
	Offset uint64 `json:"offset,string"`

	// Body is the raw event body. Use the Type specific methods to unmarshal the
	// body.
	Body   json.RawMessage `json:"body"`
	Device *Device         `json:"device,omitempty"`
}

type Push struct {
	// PushID is the unique identifier for the push, included in responses to the
	// push API.
	PushID string `json:"push_id"`

	// GroupID is an optional identifier of the group this push is associated
	// with; group IDs are created by both automation and push to local time.
	GroupID string `json:"group_id"`
}

type PushBody struct {
	Push

	// Payload is the specification of the push as sent via the API.
	Payload []byte `json:"payload"`
}

func (e *Event) PushBody() (*PushBody, error) {
	if e.Type != TypePush {
		return nil, WrongType
	}
	p := PushBody{}
	if err := json.Unmarshal(e.Body, &p); err != nil {
		return nil, err
	}
	return &p, nil
}

type Open struct {
	// LastDelivered contains the push identifier of the last notification Urban
	// Airship attempted to deliver to this device, if known. It may also include
	// a group identifier if the push was scheduled to the device’s local time or
	// if the push was an automation rule.
	//
	LastDelivered *Push `json:"last_delivered,omitempty"`

	// Triggering is present if the event was associated with a push. An
	// object containing the push ID of that notification. It may also include a
	// group ID if the push was a push to local time or automation rule.
	//
	TriggeringPush *Push `json:"triggering_push,omitempty"`

	// SessionID is an identifier for the "session" of user activity. This key
	// will be absent if the application was initialized while backgrounded.
	SessionID string `json:"session_id"`
}

// Open returns an Open struct for OPEN events. Non-OPEN events will return
// the WrongType error.
func (e *Event) Open() (*Open, error) {
	if e.Type != TypeOpen {
		return nil, WrongType
	}
	o := Open{}
	if err := json.Unmarshal(e.Body, &o); err != nil {
		return nil, err
	}
	return &o, nil
}

// Send events are emitted for each device identified by the audience selection
// of a push. device will be present in the event to specify which channel
// received the push.
type Send struct {
	Push
}

// Send returns a Send struct for SEND events. Non-SEND events will return the
// WrongType error.
func (e *Event) Send() (*Send, error) {
	if e.Type != TypeSend {
		return nil, WrongType
	}
	s := Send{}
	if err := json.Unmarshal(e.Body, &s); err != nil {
		return nil, err
	}
	return &s, nil
}

// Close events are emitted Each time a user closes the application. Note that
// close events are often latent, as they may not be delivered over the network
// until much later.
type Close struct {
	SessionID string `json:"session_id"`
}

func (e *Event) Close() (*Close, error) {
	if e.Type != TypeClose {
		return nil, WrongType
	}
	c := Close{}
	if err := json.Unmarshal(e.Body, &c); err != nil {
		return nil, err
	}
	return &c, nil
}

// TagChange events are emitted Each time a tag is added or removed from a
// channel.
type TagChange struct {
	// Add maps tag groups to tags. The set of tag group/tag pairs in this object
	// define the tags added to the device.
	Add map[string][]string `json:"add"`

	// Remove maps tag groups to tags. The set of tag group/tag pairs in this
	// object define the tags removed from the device.
	Remove map[string][]string `json:"remove"`

	// Current maps tag groups to tags. The set of tag group/tag pairs in this
	// object define the current state of the device AFTER the mutation has taken
	// effect.
	Current map[string][]string `json:"current"`
}

func (e *Event) TagChange() (*TagChange, error) {
	if e.Type != TypeTagChange {
		return nil, WrongType
	}
	t := TagChange{}
	if err := json.Unmarshal(e.Body, &t); err != nil {
		return nil, err
	}
	return &t, nil
}

// Location events include the latitude and longitude of the device.
type Location struct {
	Lat json.Number `json:"latitude"`
	Lon json.Number `json:"longitude"`

	// Foreground indicates whether the application was foregrounded when the
	// event fired.
	Foreground bool `json:"foreground"`
}

func (e *Event) Location() (*Location, error) {
	if e.Type != TypeLocation {
		return nil, WrongType
	}
	loc := Location{}
	if err := json.Unmarshal(e.Body, &loc); err != nil {
		return nil, err
	}
	return &loc, nil
}

type InAppMessageDisplay struct {
	Push

	// A triggering push is present if the user started the current session by opening
	// a push notification.
	TriggeringPush Push `json:"triggering_push"`
}

func (e *Event) InAppMessageDisplay() (*InAppMessageDisplay, error) {
	if e.Type != TypeInAppMessageDisplay {
		return nil, WrongType
	}
	disp := InAppMessageDisplay{}
	if err := json.Unmarshal(e.Body, &disp); err != nil {
		return nil, err
	}
	return &disp, nil
}

type InAppMessageResolution struct {
	InAppMessageDisplay

	TimeSent time.Time `json:"time_sent"`

	// Type indicates how the In-app message was resolved, and can take on one
	// of the following values: BUTTON_CLICK, MESSAGE_CLICK, TIMED_OUT, USER_DISMISSED
	Type string `json:"type"`

	// Duration is the amount of time for which the message was displayed, in milliseconds.
	Duration int64 `json:"duration"`

	// Additional optional fields describing the button that was clicked:
	ButtonID          string `json:"button_id,omitempty"`
	ButtonGroup       string `json:"button_group,omitempty"`
	ButtonDescription string `json:"button_description,omitempty"`
}

func (e *Event) InAppMessageResolution() (*InAppMessageResolution, error) {
	if e.Type != TypeInAppMessageResolution {
		return nil, WrongType
	}
	res := InAppMessageResolution{}
	if err := json.Unmarshal(e.Body, &res); err != nil {
		return nil, err
	}
	return &res, nil
}

type InAppMessageExpiration struct {
	InAppMessageResolution

	// ReplacingPush is present if Type is equal to REPLACED. It identifies
	// the push specification defining the In-App message which should replace the
	// current message.
	ReplacingPush Push `json:"replacing_push,omitempty"`
}

func (e *Event) InAppMessageExpiration() (*InAppMessageExpiration, error) {
	if e.Type != TypeInAppMessageExpiration {
		return nil, WrongType
	}
	exp := InAppMessageExpiration{}
	if err := json.Unmarshal(e.Body, &exp); err != nil {
		return nil, err
	}
	return &exp, nil
}

func (e *Event) RichEvent() (*Push, error) {
	if e.Type != TypeRichDelete && e.Type != TypeRichDelivery && e.Type != TypeRichRead {
		return nil, WrongType
	}
	p := Push{}
	if err := json.Unmarshal(e.Body, &p); err != nil {
		return nil, err
	}
	return &p, nil
}

// Response streams Events from a Fetch call.
type Response struct {
	// ID is the UA-Operation-Id header from Urban Airship's response.
	ID string

	out  chan *Event
	body io.ReadCloser

	mu     *sync.Mutex
	closed chan struct{}
	err    error
}

// NewResponse creates an events iterator from an http.Response. Fetch is a
// shortcut for creating a Response, but users can manually create a Response
// from a custom HTTP request with this function.
func NewResponse(resp *http.Response) (*Response, error) {
	if resp.StatusCode == 402 {
		return nil, LimitExceeded
	}
	if resp.StatusCode != 200 {
		return nil, fmt.Errorf("unexpected non-200 response: %d", resp.StatusCode)
	}
	r := &Response{
		ID:     resp.Header.Get("UA-Operation-Id"),
		out:    make(chan *Event, 10), // provide some buffering
		body:   resp.Body,
		mu:     new(sync.Mutex),
		closed: make(chan struct{}),
	}
	go func() {
		// Always close Event chan to indicate to callers that response is done.
		defer close(r.out)
		dec := json.NewDecoder(r.body)
		for {
			var ev Event
			if err := dec.Decode(&ev); err != nil {
				select {
				case <-r.closed:
					//TODO Only ignore "closed" errors
					return
				default:
					r.mu.Lock()
					defer r.mu.Unlock()
					r.err = err
					return
				}
			}
			select {
			case r.out <- &ev:
			case <-r.closed:
				return
			}
		}
	}()
	return r, nil
}

// Events returns a chan that emits Events until closed. Events is safe for
// concurrent calls and shares an underlying chan. This means events are not
// duplicated between multiple receivers.
func (r *Response) Events() <-chan *Event { return r.out }

// Close the events stream. Safe to call concurrently.
func (r *Response) Close() {
	r.mu.Lock()
	defer r.mu.Unlock()
	select {
	case <-r.closed:
		return
	default:
		close(r.closed)
		r.body.Close()
	}
}

// Err returns the error which caused the event stream to end or nil. May be
// checked when the chan returned by Events() is closed. Safe for concurrent
// access.
func (r *Response) Err() error {
	r.mu.Lock()
	defer r.mu.Unlock()
	return r.err
}
<|endoftext|>


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

package dashboard

// This file handles operations on the CL entity kind.

import (
	"bytes"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"sort"
	"strings"
	"time"

	"appengine"
	"appengine/datastore"
	"appengine/taskqueue"
	"appengine/urlfetch"
	"appengine/user"
)

func init() {
	http.HandleFunc("/assign", handleAssign)
	http.HandleFunc("/update-cl", handleUpdateCL)
}

const codereviewBase = "http://codereview.appspot.com"
const gobotBase = "http://research.swtch.com/gobot_codereview"

var clRegexp = regexp.MustCompile(`\d+`)

// CL represents a code review.
type CL struct {
	Number string // e.g. "5903061"
	Closed bool
	Owner  string // email address

	Created, Modified time.Time

	Description []byte `datastore:",noindex"`
	FirstLine   string `datastore:",noindex"`
	LGTMs       []string
	NotLGTMs    []string

	// Mail information.
	Subject       string   `datastore:",noindex"`
	Recipients    []string `datastore:",noindex"`
	LastMessageID string   `datastore:",noindex"`

	// These are person IDs (e.g. "rsc"); they may be empty
	Author   string
	Reviewer string
}

// DisplayOwner returns the CL's owner, either as their email address
// or the person ID if it's a reviewer. It is for display only.
func (cl *CL) DisplayOwner() string {
	if p, ok := emailToPerson[cl.Owner]; ok {
		return p
	}
	return cl.Owner
}

func (cl *CL) FirstLineHTML() template.HTML {
	s := template.HTMLEscapeString(cl.FirstLine)
	// Embolden the package name.
	if i := strings.Index(s, ":"); i >= 0 {
		s = "" + s[:i] + "" + s[i:]
	}
	return template.HTML(s)
}

func formatEmails(e []string) template.HTML {
	x := make([]string, len(e))
	for i, s := range e {
		s = template.HTMLEscapeString(s)
		if !strings.Contains(s, "@") {
			s = "" + s + ""
		}
		s = `<span class="email">` + s + ""
		x[i] = s
	}
	return template.HTML(strings.Join(x, ", "))
}

func (cl *CL) LGTMHTML() template.HTML {
	return formatEmails(cl.LGTMs)
}

func (cl *CL) NotLGTMHTML() template.HTML {
	return formatEmails(cl.NotLGTMs)
}

func (cl *CL) ModifiedAgo() string {
	// Just the first non-zero unit.
	units := [...]struct {
		suffix string
		unit   time.Duration
	}{
		{"d", 24 * time.Hour},
		{"h", time.Hour},
		{"m", time.Minute},
		{"s", time.Second},
	}
	d := time.Now().Sub(cl.Modified)
	for _, u := range units {
		if d > u.unit {
			return fmt.Sprintf("%d%s", d/u.unit, u.suffix)
		}
	}
	return "just now"
}

func handleAssign(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	if r.Method != "POST" {
		http.Error(w, "Bad method "+r.Method, 400)
		return
	}

	u := user.Current(c)
	person, ok := emailToPerson[u.Email]
	if !ok {
		http.Error(w, "Not allowed", http.StatusUnauthorized)
		return
	}

	n, rev := r.FormValue("cl"), r.FormValue("r")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}
	if _, ok := preferredEmail[rev]; !ok && rev != "" {
		c.Errorf("Unknown reviewer %q", rev)
		http.Error(w, "Unknown reviewer", 400)
		return
	}

	key := datastore.NewKey(c, "CL", n, 0, nil)

	if rev != "" {
		// Make sure the reviewer is listed in Rietveld as a reviewer.
		url := codereviewBase + "/" + n + "/fields"
		resp, err := urlfetch.Client(c).Get(url + "?field=reviewers")
		if err != nil {
			c.Errorf("Retrieving CL reviewer list failed: %v", err)
			http.Error(w, err.Error(), 500)
			return
		}
		defer resp.Body.Close()
		if resp.StatusCode != 200 {
			c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d", resp.StatusCode)
			http.Error(w, "Failed contacting Rietveld", 500)
			return
		}

		var apiResp struct {
			Reviewers []string `json:"reviewers"`
		}
		if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
			// probably can't be retried
			msg := fmt.Sprintf("Malformed JSON from %v: %v", url, err)
			c.Errorf("%s", msg)
			http.Error(w, msg, 500)
			return
		}
		found := false
		for _, r := range apiResp.Reviewers {
			if emailToPerson[r] == rev {
				found = true
				break
			}
		}
		if !found {
			c.Infof("Adding %v as a reviewer of CL %v", rev, n)

			url := fmt.Sprintf("%s?cl=%s&r=%s&obo=%s", gobotBase, n, rev, person)
			resp, err := urlfetch.Client(c).Get(url)
			if err != nil {
				c.Errorf("Gobot GET failed: %v", err)
				http.Error(w, err.Error(), 500)
				return
			}
			defer resp.Body.Close()
			if resp.StatusCode != 200 {
				c.Errorf("Gobot GET failed: got HTTP response %d", resp.StatusCode)
				http.Error(w, "Failed contacting Gobot", 500)
				return
			}

			c.Infof("Gobot said %q", resp.Status)
		}
	}

	// Update our own record.
	err := datastore.RunInTransaction(c, func(c appengine.Context) error {
		cl := new(CL)
		err := datastore.Get(c, key, cl)
		if err != nil {
			return err
		}
		cl.Reviewer = rev
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		msg := fmt.Sprintf("Assignment failed: %v", err)
		c.Errorf("%s", msg)
		http.Error(w, msg, 500)
		return
	}
	c.Infof("Assigned CL %v to %v", n, rev)
}

func UpdateCLLater(c appengine.Context, n string, delay time.Duration) {
	t := taskqueue.NewPOSTTask("/update-cl", url.Values{
		"cl": []string{n},
	})
	t.Delay = delay
	if _, err := taskqueue.Add(c, t, "update-cl"); err != nil {
		c.Errorf("Failed adding task: %v", err)
	}
}

func handleUpdateCL(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	n := r.FormValue("cl")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}

	if err := updateCL(c, n); err != nil {
		c.Errorf("Failed updating CL %v: %v", n, err)
		http.Error(w, "Failed update", 500)
		return
	}

	io.WriteString(w, "OK")
}

// updateCL updates a single CL. If a retryable failure occurs, an error is returned.
func updateCL(c appengine.Context, n string) error {
	c.Debugf("Updating CL %v", n)
	key := datastore.NewKey(c, "CL", n, 0, nil)

	url := codereviewBase + "/api/" + n + "?messages=true"
	resp, err := urlfetch.Client(c).Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	raw, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("Failed reading HTTP body: %v", err)
	}

	// Special case for abandoned CLs.
	if resp.StatusCode == 404 && bytes.Contains(raw, []byte("No issue exists with that id")) {
		// Don't bother checking for errors. The CL might never have been saved, for instance.
		datastore.Delete(c, key)
		c.Infof("Deleted abandoned CL %v", n)
		return nil
	}

	if resp.StatusCode != 200 {
		return fmt.Errorf("Update: got HTTP response %d", resp.StatusCode)
	}

	var apiResp struct {
		Description string   `json:"description"`
		Reviewers   []string `json:"reviewers"`
		Created     string   `json:"created"`
		OwnerEmail  string   `json:"owner_email"`
		Modified    string   `json:"modified"`
		Closed      bool     `json:"closed"`
		Subject     string   `json:"subject"`
		Messages    []struct {
			Text       string   `json:"text"`
			Sender     string   `json:"sender"`
			Recipients []string `json:"recipients"`
			Approval   bool     `json:"approval"`
		} `json:"messages"`
	}
	if err := json.Unmarshal(raw, &apiResp); err != nil {
		// probably can't be retried
		c.Errorf("Malformed JSON from %v: %v", url, err)
		return nil
	}
	//c.Infof("RAW: %+v", apiResp)

	cl := &CL{
		Number:      n,
		Closed:      apiResp.Closed,
		Owner:       apiResp.OwnerEmail,
		Description: []byte(apiResp.Description),
		FirstLine:   apiResp.Description,
		Subject:     apiResp.Subject,
		Author:      emailToPerson[apiResp.OwnerEmail],
	}
	cl.Created, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Created)
	if err != nil {
		c.Errorf("Bad creation time %q: %v", apiResp.Created, err)
	}
	cl.Modified, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Modified)
	if err != nil {
		c.Errorf("Bad modification time %q: %v", apiResp.Modified, err)
	}
	if i := strings.Index(cl.FirstLine, "\n"); i >= 0 {
		cl.FirstLine = cl.FirstLine[:i]
	}
	// Treat zero reviewers as a signal that the CL is completed.
	// This could be after the CL has been submitted, but before the CL author has synced,
	// but it could also be a CL manually edited to remove reviewers.
	if len(apiResp.Reviewers) == 0 {
		cl.Closed = true
	}

	lgtm := make(map[string]bool)
	notLGTM := make(map[string]bool)
	rcpt := make(map[string]bool)
	for _, msg := range apiResp.Messages {
		s, rev := msg.Sender, false
		if p, ok := emailToPerson[s]; ok {
			s, rev = p, true
		}

		// CLs submitted by someone other than the CL owner do not immediately
		// transition to "closed". Let's simulate the intention by treating
		// messages starting with "*** Submitted as " from a reviewer as a
		// signal that the CL is now closed.
		if rev && strings.HasPrefix(msg.Text, "*** Submitted as ") {
			cl.Closed = true
		}

		if msg.Approval {
			lgtm[s] = true
			delete(notLGTM, s) // "LGTM" overrules previous "NOT LGTM"
		}
		if strings.Contains(msg.Text, "NOT LGTM") {
			notLGTM[s] = true
			delete(lgtm, s) // "NOT LGTM" overrules previous "LGTM"
		}

		for _, r := range msg.Recipients {
			rcpt[r] = true
		}
	}
	for l := range lgtm {
		cl.LGTMs = append(cl.LGTMs, l)
	}
	for l := range notLGTM {
		cl.NotLGTMs = append(cl.NotLGTMs, l)
	}
	for r := range rcpt {
		cl.Recipients = append(cl.Recipients, r)
	}
	sort.Strings(cl.LGTMs)
	sort.Strings(cl.NotLGTMs)
	sort.Strings(cl.Recipients)

	err = datastore.RunInTransaction(c, func(c appengine.Context) error {
		ocl := new(CL)
		err := datastore.Get(c, key, ocl)
		if err != nil && err != datastore.ErrNoSuchEntity {
			return err
		} else if err == nil {
			// LastMessageID and Reviewer need preserving.
			cl.LastMessageID = ocl.LastMessageID
			cl.Reviewer = ocl.Reviewer
		}
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		return err
	}
	c.Infof("Updated CL %v", n)
	return nil
}
<commit_msg>misc/dashboard/codereview: add LastUpdate field to CL<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dashboard

// This file handles operations on the CL entity kind.

import (
	"bytes"
	"encoding/json"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"regexp"
	"sort"
	"strings"
	"time"

	"appengine"
	"appengine/datastore"
	"appengine/taskqueue"
	"appengine/urlfetch"
	"appengine/user"
)

func init() {
	http.HandleFunc("/assign", handleAssign)
	http.HandleFunc("/update-cl", handleUpdateCL)
}

const codereviewBase = "http://codereview.appspot.com"
const gobotBase = "http://research.swtch.com/gobot_codereview"

var clRegexp = regexp.MustCompile(`\d+`)

// CL represents a code review.
type CL struct {
	Number string // e.g. "5903061"
	Closed bool
	Owner  string // email address

	Created, Modified time.Time

	Description []byte `datastore:",noindex"`
	FirstLine   string `datastore:",noindex"`
	LGTMs       []string
	NotLGTMs    []string
	LastUpdate  string

	// Mail information.
	Subject       string   `datastore:",noindex"`
	Recipients    []string `datastore:",noindex"`
	LastMessageID string   `datastore:",noindex"`

	// These are person IDs (e.g. "rsc"); they may be empty
	Author   string
	Reviewer string
}

// DisplayOwner returns the CL's owner, either as their email address
// or the person ID if it's a reviewer. It is for display only.
func (cl *CL) DisplayOwner() string {
	if p, ok := emailToPerson[cl.Owner]; ok {
		return p
	}
	return cl.Owner
}

func (cl *CL) FirstLineHTML() template.HTML {
	s := template.HTMLEscapeString(cl.FirstLine)
	// Embolden the package name.
	if i := strings.Index(s, ":"); i >= 0 {
		s = "" + s[:i] + "" + s[i:]
	}
	return template.HTML(s)
}

func formatEmails(e []string) template.HTML {
	x := make([]string, len(e))
	for i, s := range e {
		s = template.HTMLEscapeString(s)
		if !strings.Contains(s, "@") {
			s = "" + s + ""
		}
		s = `<span class="email">` + s + ""
		x[i] = s
	}
	return template.HTML(strings.Join(x, ", "))
}

func (cl *CL) LGTMHTML() template.HTML {
	return formatEmails(cl.LGTMs)
}

func (cl *CL) NotLGTMHTML() template.HTML {
	return formatEmails(cl.NotLGTMs)
}

func (cl *CL) ModifiedAgo() string {
	// Just the first non-zero unit.
	units := [...]struct {
		suffix string
		unit   time.Duration
	}{
		{"d", 24 * time.Hour},
		{"h", time.Hour},
		{"m", time.Minute},
		{"s", time.Second},
	}
	d := time.Now().Sub(cl.Modified)
	for _, u := range units {
		if d > u.unit {
			return fmt.Sprintf("%d%s", d/u.unit, u.suffix)
		}
	}
	return "just now"
}

func handleAssign(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	if r.Method != "POST" {
		http.Error(w, "Bad method "+r.Method, 400)
		return
	}

	u := user.Current(c)
	person, ok := emailToPerson[u.Email]
	if !ok {
		http.Error(w, "Not allowed", http.StatusUnauthorized)
		return
	}

	n, rev := r.FormValue("cl"), r.FormValue("r")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}
	if _, ok := preferredEmail[rev]; !ok && rev != "" {
		c.Errorf("Unknown reviewer %q", rev)
		http.Error(w, "Unknown reviewer", 400)
		return
	}

	key := datastore.NewKey(c, "CL", n, 0, nil)

	if rev != "" {
		// Make sure the reviewer is listed in Rietveld as a reviewer.
		url := codereviewBase + "/" + n + "/fields"
		resp, err := urlfetch.Client(c).Get(url + "?field=reviewers")
		if err != nil {
			c.Errorf("Retrieving CL reviewer list failed: %v", err)
			http.Error(w, err.Error(), 500)
			return
		}
		defer resp.Body.Close()
		if resp.StatusCode != 200 {
			c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d", resp.StatusCode)
			http.Error(w, "Failed contacting Rietveld", 500)
			return
		}

		var apiResp struct {
			Reviewers []string `json:"reviewers"`
		}
		if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
			// probably can't be retried
			msg := fmt.Sprintf("Malformed JSON from %v: %v", url, err)
			c.Errorf("%s", msg)
			http.Error(w, msg, 500)
			return
		}
		found := false
		for _, r := range apiResp.Reviewers {
			if emailToPerson[r] == rev {
				found = true
				break
			}
		}
		if !found {
			c.Infof("Adding %v as a reviewer of CL %v", rev, n)

			url := fmt.Sprintf("%s?cl=%s&r=%s&obo=%s", gobotBase, n, rev, person)
			resp, err := urlfetch.Client(c).Get(url)
			if err != nil {
				c.Errorf("Gobot GET failed: %v", err)
				http.Error(w, err.Error(), 500)
				return
			}
			defer resp.Body.Close()
			if resp.StatusCode != 200 {
				c.Errorf("Gobot GET failed: got HTTP response %d", resp.StatusCode)
				http.Error(w, "Failed contacting Gobot", 500)
				return
			}

			c.Infof("Gobot said %q", resp.Status)
		}
	}

	// Update our own record.
	err := datastore.RunInTransaction(c, func(c appengine.Context) error {
		cl := new(CL)
		err := datastore.Get(c, key, cl)
		if err != nil {
			return err
		}
		cl.Reviewer = rev
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		msg := fmt.Sprintf("Assignment failed: %v", err)
		c.Errorf("%s", msg)
		http.Error(w, msg, 500)
		return
	}
	c.Infof("Assigned CL %v to %v", n, rev)
}

func UpdateCLLater(c appengine.Context, n string, delay time.Duration) {
	t := taskqueue.NewPOSTTask("/update-cl", url.Values{
		"cl": []string{n},
	})
	t.Delay = delay
	if _, err := taskqueue.Add(c, t, "update-cl"); err != nil {
		c.Errorf("Failed adding task: %v", err)
	}
}

func handleUpdateCL(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)

	n := r.FormValue("cl")
	if !clRegexp.MatchString(n) {
		c.Errorf("Bad CL %q", n)
		http.Error(w, "Bad CL", 400)
		return
	}

	if err := updateCL(c, n); err != nil {
		c.Errorf("Failed updating CL %v: %v", n, err)
		http.Error(w, "Failed update", 500)
		return
	}

	io.WriteString(w, "OK")
}

// updateCL updates a single CL. If a retryable failure occurs, an error is returned.
func updateCL(c appengine.Context, n string) error {
	c.Debugf("Updating CL %v", n)
	key := datastore.NewKey(c, "CL", n, 0, nil)

	url := codereviewBase + "/api/" + n + "?messages=true"
	resp, err := urlfetch.Client(c).Get(url)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	raw, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf("Failed reading HTTP body: %v", err)
	}

	// Special case for abandoned CLs.
	if resp.StatusCode == 404 && bytes.Contains(raw, []byte("No issue exists with that id")) {
		// Don't bother checking for errors. The CL might never have been saved, for instance.
		datastore.Delete(c, key)
		c.Infof("Deleted abandoned CL %v", n)
		return nil
	}

	if resp.StatusCode != 200 {
		return fmt.Errorf("Update: got HTTP response %d", resp.StatusCode)
	}

	var apiResp struct {
		Description string   `json:"description"`
		Reviewers   []string `json:"reviewers"`
		Created     string   `json:"created"`
		OwnerEmail  string   `json:"owner_email"`
		Modified    string   `json:"modified"`
		Closed      bool     `json:"closed"`
		Subject     string   `json:"subject"`
		Messages    []struct {
			Text       string   `json:"text"`
			Sender     string   `json:"sender"`
			Recipients []string `json:"recipients"`
			Approval   bool     `json:"approval"`
		} `json:"messages"`
	}
	if err := json.Unmarshal(raw, &apiResp); err != nil {
		// probably can't be retried
		c.Errorf("Malformed JSON from %v: %v", url, err)
		return nil
	}
	//c.Infof("RAW: %+v", apiResp)

	cl := &CL{
		Number:      n,
		Closed:      apiResp.Closed,
		Owner:       apiResp.OwnerEmail,
		Description: []byte(apiResp.Description),
		FirstLine:   apiResp.Description,
		Subject:     apiResp.Subject,
		Author:      emailToPerson[apiResp.OwnerEmail],
	}
	cl.Created, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Created)
	if err != nil {
		c.Errorf("Bad creation time %q: %v", apiResp.Created, err)
	}
	cl.Modified, err = time.Parse("2006-01-02 15:04:05.000000", apiResp.Modified)
	if err != nil {
		c.Errorf("Bad modification time %q: %v", apiResp.Modified, err)
	}
	if i := strings.Index(cl.FirstLine, "\n"); i >= 0 {
		cl.FirstLine = cl.FirstLine[:i]
	}
	// Treat zero reviewers as a signal that the CL is completed.
	// This could be after the CL has been submitted, but before the CL author has synced,
	// but it could also be a CL manually edited to remove reviewers.
	if len(apiResp.Reviewers) == 0 {
		cl.Closed = true
	}

	lgtm := make(map[string]bool)
	notLGTM := make(map[string]bool)
	rcpt := make(map[string]bool)
	for _, msg := range apiResp.Messages {
		s, rev := msg.Sender, false
		if p, ok := emailToPerson[s]; ok {
			s, rev = p, true
		}

		// CLs submitted by someone other than the CL owner do not immediately
		// transition to "closed". Let's simulate the intention by treating
		// messages starting with "*** Submitted as " from a reviewer as a
		// signal that the CL is now closed.
		if rev && strings.HasPrefix(msg.Text, "*** Submitted as ") {
			cl.Closed = true
		}

		if msg.Approval {
			lgtm[s] = true
			delete(notLGTM, s) // "LGTM" overrules previous "NOT LGTM"
		}
		if strings.Contains(msg.Text, "NOT LGTM") {
			notLGTM[s] = true
			delete(lgtm, s) // "NOT LGTM" overrules previous "LGTM"
		}

		for _, r := range msg.Recipients {
			rcpt[r] = true
		}
	}
	for l := range lgtm {
		cl.LGTMs = append(cl.LGTMs, l)
	}
	for l := range notLGTM {
		cl.NotLGTMs = append(cl.NotLGTMs, l)
	}
	for r := range rcpt {
		cl.Recipients = append(cl.Recipients, r)
	}
	sort.Strings(cl.LGTMs)
	sort.Strings(cl.NotLGTMs)
	sort.Strings(cl.Recipients)

	err = datastore.RunInTransaction(c, func(c appengine.Context) error {
		ocl := new(CL)
		err := datastore.Get(c, key, ocl)
		if err != nil && err != datastore.ErrNoSuchEntity {
			return err
		} else if err == nil {
			// LastMessageID and Reviewer need preserving.
			cl.LastMessageID = ocl.LastMessageID
			cl.Reviewer = ocl.Reviewer
		}
		_, err = datastore.Put(c, key, cl)
		return err
	}, nil)
	if err != nil {
		return err
	}
	c.Infof("Updated CL %v", n)
	return nil
}
<|endoftext|>


<commit_before>package main

import "github.com/yelinaung/eng-name"
import "fmt"

func main() {
	fmt.Println()
	fmt.Printf("Man name : %v \n", engname.GetMenName())
	fmt.Printf("Woman name : %v \n", engname.GetWomenName())
	fmt.Println()
}
<commit_msg>update example<commit_after>package main

import (
	"fmt"
	"github.com/yelinaung/eng-name"
	"time"
)

func main() {
	fmt.Println()
	// You have to seed yourself
	RandName := engname.New(time.Now().UTC().UnixNano())
	// Generating random men names
	fmt.Printf("Man name : %v \n", RandName.GetMenName())
	// Generating random women names
	fmt.Printf("Woman name : %v \n", RandName.GetWomenName())
	fmt.Println()
}
<|endoftext|>


<commit_before>package main

import (
	"time"

	"github.com/gonfire/oauth2"
	"golang.org/x/crypto/bcrypt"
)

type owner struct {
	id          string
	secret      []byte
	redirectURI string
}

var clients = map[string]owner{}

var users = map[string]owner{}

type token struct {
	clientID    string
	username    string
	signature   string
	expiresAt   time.Time
	scope       oauth2.Scope
	redirectURI string
}

var accessTokens = make(map[string]token)

var refreshTokens = make(map[string]token)

var authorizationCodes = make(map[string]token)

func addOwner(list map[string]owner, o owner) owner {
	list[o.id] = o
	return o
}

func addToken(list map[string]token, t token) token {
	list[t.signature] = t
	return t
}

func mustHash(password string) []byte {
	hash, err := bcrypt.GenerateFromPassword([]byte(password), 0)
	if err != nil {
		panic(err)
	}

	return hash
}

func sameHash(hash []byte, password string) bool {
	return bcrypt.CompareHashAndPassword(hash, []byte(password)) == nil
}

func mustGenerateToken() *oauth2.Token {
	token, err := oauth2.GenerateToken(secret, 16)
	if err != nil {
		panic(err)
	}

	return token
}
<commit_msg>use min cost to speedup tests<commit_after>package main

import (
	"time"

	"github.com/gonfire/oauth2"
	"golang.org/x/crypto/bcrypt"
)

type owner struct {
	id          string
	secret      []byte
	redirectURI string
}

var clients = map[string]owner{}

var users = map[string]owner{}

type token struct {
	clientID    string
	username    string
	signature   string
	expiresAt   time.Time
	scope       oauth2.Scope
	redirectURI string
}

var accessTokens = make(map[string]token)

var refreshTokens = make(map[string]token)

var authorizationCodes = make(map[string]token)

func addOwner(list map[string]owner, o owner) owner {
	list[o.id] = o
	return o
}

func addToken(list map[string]token, t token) token {
	list[t.signature] = t
	return t
}

func mustHash(password string) []byte {
	hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.MinCost)
	if err != nil {
		panic(err)
	}

	return hash
}

func sameHash(hash []byte, password string) bool {
	return bcrypt.CompareHashAndPassword(hash, []byte(password)) == nil
}

func mustGenerateToken() *oauth2.Token {
	token, err := oauth2.GenerateToken(secret, 16)
	if err != nil {
		panic(err)
	}

	return token
}
<|endoftext|>


<commit_before>package parser

import (
	"bufio"
	"fmt"
	"io"
	"strconv"
	"strings"
	"text/scanner"
)

const (
	// prefixComment is a prefix of a comment.
	prefixComment = "//"

	// vmScanMode is a mode for scanning VM code.
	vmScanMode = scanner.ScanIdents | scanner.ScanInts | scanner.SkipComments
)

// CommandType represents a type of VM command.
type CommandType int

// A list of command types.
const (
	unknown CommandType = iota
	Arithmetic
	Push
	Pop
	Label
	Goto
	If
	Function
	Return
	Call
)

// command has command information.
type command struct {
	typ  CommandType
	arg1 string
	arg2 uint
}

// Parser is a parser for VM code.
// Parser is not thread safe, so it should NOT be used in multiple goroutines.
type Parser struct {
	src    *bufio.Scanner
	line   string
	tokens []string
	cmd    command
}

// New creates a new parser object that reads and parses r.
func New(src io.Reader) *Parser {
	return &Parser{
		src: bufio.NewScanner(src),
	}
}

// HasMoreCommands reports whether there exist more commands in input.
func (p *Parser) HasMoreCommands() bool {
	// if Scan() == true && Text() is not a comment, return true
	// if Scan() == false, return false
	for p.src.Scan() {
		p.line = p.src.Text()
		p.tokens = p.tokens[:0]

		// prepare a Scanner
		var sc scanner.Scanner
		sc.Mode = vmScanMode
		sc.Init(strings.NewReader(p.line))

		// tokenize the current line
		var tok rune
		for tok != scanner.EOF {
			tok = sc.Scan()
			text := sc.TokenText()

			// ignore empty string
			if text == "" {
				continue
			}

			p.tokens = append(p.tokens, text)
		}

		if len(p.tokens) > 0 {
			return true
		}
	}

	p.tokens = p.tokens[:0]
	return false
}

// Advance reads next command from source and set the command to current one.
// If the next command is invalid, it returns an error.
// This method should be called only if HasMoreCommands() returns true.
func (p *Parser) Advance() error {
	tokens := p.tokens

	// check the length of tokens: only 1 or 3 is valid
	switch len(tokens) {
	case 1, 3:
		// valid length; skip
	default:
		return fmt.Errorf("invalid command: %q", p.line)
	}

	// parse the first token as an opcode
	cmd := tokens[0]
	typ := p.dispatchCommand(cmd)
	if typ == unknown {
		return fmt.Errorf("unknown command: %s", cmd)
	}
	p.cmd.typ = typ
	if typ == Arithmetic {
		p.cmd.arg1 = cmd
		p.cmd.arg2 = 0
		return nil
	}

	// parse the second token as a segment
	seg := tokens[1]
	if !segs.contains(seg) {
		return fmt.Errorf("unknown segment: %s", seg)
	}
	p.cmd.arg1 = seg

	// parse the third token as an integer
	a := tokens[2]
	i, err := strconv.Atoi(a)
	if i < 0 || err != nil {
		return fmt.Errorf("not a positive integer: %s", a)
	}
	p.cmd.arg2 = uint(i)

	return nil
}

// dispatchCommand dispatches CommandType from cmd.
// If cmd is not a valid command string, it returns `unknown`.
func (*Parser) dispatchCommand(cmd string) CommandType {
	switch cmd {
	case "add", "sub", "neg", "eq", "gt", "lt", "and", "or", "not":
		return Arithmetic
	case "push":
		return Push
	case "pop":
		return Pop
	case "label":
		return Label
	case "goto":
		return Goto
	case "if-goto":
		return If
	case "function":
		return Function
	case "call":
		return Call
	case "return":
		return Return
	default:
		return unknown
	}
}

// segments is a collection of segments.
type segments []string

// segs is a collection of all the segments on VM.
// TODO use map[string]struct{}
var segs = segments{
	"argument",
	"local",
	"static",
	"constant",
	"this", "that",
	"pointer",
	"temp",
}

// contains reports whether text is contained in s.
func (s segments) contains(text string) bool {
	for _, seg := range s {
		if seg == text {
			return true
		}
	}
	return false
}

// CommandType returns a type of a current VM command. In all arithmetic commands
// it returns Arithmetic.
func (p *Parser) CommandType() CommandType {
	return p.cmd.typ
}

// Arg1 returns the first argument in a current command. If a type of the current command is
// Arithmetic, it returns the command itself. This method should NOT be called if CommandType()
// returns Return.
func (p *Parser) Arg1() string {
	return p.cmd.arg1
}

// Arg2 returns the second argument in a current command. This method should be called
// only if CommandType() returns Push, Pop, Function or Call.
func (p *Parser) Arg2() uint {
	return p.cmd.arg2
}
<commit_msg>07/parser: declare scanner.Scanner only once in Parser.HasMoreCommands()<commit_after>package parser

import (
	"bufio"
	"fmt"
	"io"
	"strconv"
	"strings"
	"text/scanner"
)

const (
	// prefixComment is a prefix of a comment.
	prefixComment = "//"

	// vmScanMode is a mode for scanning VM code.
	vmScanMode = scanner.ScanIdents | scanner.ScanInts | scanner.SkipComments
)

// CommandType represents a type of VM command.
type CommandType int

// A list of command types.
const (
	unknown CommandType = iota
	Arithmetic
	Push
	Pop
	Label
	Goto
	If
	Function
	Return
	Call
)

// command has command information.
type command struct {
	typ  CommandType
	arg1 string
	arg2 uint
}

// Parser is a parser for VM code.
// Parser is not thread safe, so it should NOT be used in multiple goroutines.
type Parser struct {
	src    *bufio.Scanner
	line   string
	tokens []string
	cmd    command
}

// New creates a new parser object that reads and parses r.
func New(src io.Reader) *Parser {
	return &Parser{
		src: bufio.NewScanner(src),
	}
}

// HasMoreCommands reports whether there exist more commands in input.
func (p *Parser) HasMoreCommands() bool {
	var sc scanner.Scanner
	sc.Mode = vmScanMode

	// if Scan() == true && Text() is not a comment, return true
	// if Scan() == false, return false
	for p.src.Scan() {
		p.line = p.src.Text()
		p.tokens = p.tokens[:0]

		// prepare a Scanner
		sc.Init(strings.NewReader(p.line))

		// tokenize the current line
		var tok rune
		for tok != scanner.EOF {
			tok = sc.Scan()
			text := sc.TokenText()

			// ignore empty string
			if text == "" {
				continue
			}

			p.tokens = append(p.tokens, text)
		}

		if len(p.tokens) > 0 {
			return true
		}
	}

	p.tokens = p.tokens[:0]
	return false
}

// Advance reads next command from source and set the command to current one.
// If the next command is invalid, it returns an error.
// This method should be called only if HasMoreCommands() returns true.
func (p *Parser) Advance() error {
	tokens := p.tokens

	// check the length of tokens: only 1 or 3 is valid
	switch len(tokens) {
	case 1, 3:
		// valid length; skip
	default:
		return fmt.Errorf("invalid command: %q", p.line)
	}

	// parse the first token as an opcode
	cmd := tokens[0]
	typ := p.dispatchCommand(cmd)
	if typ == unknown {
		return fmt.Errorf("unknown command: %s", cmd)
	}
	p.cmd.typ = typ
	if typ == Arithmetic {
		p.cmd.arg1 = cmd
		p.cmd.arg2 = 0
		return nil
	}

	// parse the second token as a segment
	seg := tokens[1]
	if !segs.contains(seg) {
		return fmt.Errorf("unknown segment: %s", seg)
	}
	p.cmd.arg1 = seg

	// parse the third token as an integer
	a := tokens[2]
	i, err := strconv.Atoi(a)
	if i < 0 || err != nil {
		return fmt.Errorf("not a positive integer: %s", a)
	}
	p.cmd.arg2 = uint(i)

	return nil
}

// dispatchCommand dispatches CommandType from cmd.
// If cmd is not a valid command string, it returns `unknown`.
func (*Parser) dispatchCommand(cmd string) CommandType {
	switch cmd {
	case "add", "sub", "neg", "eq", "gt", "lt", "and", "or", "not":
		return Arithmetic
	case "push":
		return Push
	case "pop":
		return Pop
	case "label":
		return Label
	case "goto":
		return Goto
	case "if-goto":
		return If
	case "function":
		return Function
	case "call":
		return Call
	case "return":
		return Return
	default:
		return unknown
	}
}

// segments is a collection of segments.
type segments []string

// segs is a collection of all the segments on VM.
// TODO use map[string]struct{}
var segs = segments{
	"argument",
	"local",
	"static",
	"constant",
	"this", "that",
	"pointer",
	"temp",
}

// contains reports whether text is contained in s.
func (s segments) contains(text string) bool {
	for _, seg := range s {
		if seg == text {
			return true
		}
	}
	return false
}

// CommandType returns a type of a current VM command. In all arithmetic commands
// it returns Arithmetic.
func (p *Parser) CommandType() CommandType {
	return p.cmd.typ
}

// Arg1 returns the first argument in a current command. If a type of the current command is
// Arithmetic, it returns the command itself. This method should NOT be called if CommandType()
// returns Return.
func (p *Parser) Arg1() string {
	return p.cmd.arg1
}

// Arg2 returns the second argument in a current command. This method should be called
// only if CommandType() returns Push, Pop, Function or Call.
func (p *Parser) Arg2() uint {
	return p.cmd.arg2
}
<|endoftext|>


<commit_before>package namespace

import (
	"errors"
	"github.com/watermint/toolbox/domain/dropbox/api/dbx_conn"
	"github.com/watermint/toolbox/domain/dropbox/model/mo_namespace"
	"github.com/watermint/toolbox/domain/dropbox/service/sv_namespace"
	"github.com/watermint/toolbox/infra/control/app_control"
	"github.com/watermint/toolbox/infra/recipe/rc_exec"
	"github.com/watermint/toolbox/infra/recipe/rc_recipe"
	"github.com/watermint/toolbox/infra/report/rp_model"
	"github.com/watermint/toolbox/quality/recipe/qtr_endtoend"
)

type List struct {
	Peer      dbx_conn.ConnBusinessFile
	Namespace rp_model.RowReport
}

func (z *List) Preset() {
	z.Namespace.SetModel(&mo_namespace.Namespace{},
		rp_model.HiddenColumns(
			"namespace_id",
		),
	)
}

func (z *List) Exec(c app_control.Control) error {
	if err := z.Namespace.Open(); err != nil {
		return err
	}

	namespaces, err := sv_namespace.New(z.Peer.Context()).List()
	if err != nil {
		return err
	}

	for _, namespace := range namespaces {
		z.Namespace.Row(namespace)
	}
	return nil
}

func (z *List) Test(c app_control.Control) error {
	if err := rc_exec.Exec(c, &List{}, rc_recipe.NoCustomValues); err != nil {
		return err
	}
	return qtr_endtoend.TestRows(c, "namespace", func(cols map[string]string) error {
		if _, ok := cols["name"]; !ok {
			return errors.New("`name` is not found")
		}
		return nil
	})
}
<commit_msg>#410 : team namespace list<commit_after>package namespace

import (
	"errors"
	"github.com/watermint/toolbox/domain/dropbox/api/dbx_auth"
	"github.com/watermint/toolbox/domain/dropbox/api/dbx_conn"
	"github.com/watermint/toolbox/domain/dropbox/model/mo_namespace"
	"github.com/watermint/toolbox/domain/dropbox/service/sv_namespace"
	"github.com/watermint/toolbox/infra/control/app_control"
	"github.com/watermint/toolbox/infra/recipe/rc_exec"
	"github.com/watermint/toolbox/infra/recipe/rc_recipe"
	"github.com/watermint/toolbox/infra/report/rp_model"
	"github.com/watermint/toolbox/quality/recipe/qtr_endtoend"
)

type List struct {
	Peer      dbx_conn.ConnScopedTeam
	Namespace rp_model.RowReport
}

func (z *List) Preset() {
	z.Peer.SetScopes(
		dbx_auth.ScopeTeamDataMember,
	)
	z.Namespace.SetModel(&mo_namespace.Namespace{},
		rp_model.HiddenColumns(
			"namespace_id",
		),
	)
}

func (z *List) Exec(c app_control.Control) error {
	if err := z.Namespace.Open(); err != nil {
		return err
	}

	namespaces, err := sv_namespace.New(z.Peer.Context()).List()
	if err != nil {
		return err
	}

	for _, namespace := range namespaces {
		z.Namespace.Row(namespace)
	}
	return nil
}

func (z *List) Test(c app_control.Control) error {
	if err := rc_exec.Exec(c, &List{}, rc_recipe.NoCustomValues); err != nil {
		return err
	}
	return qtr_endtoend.TestRows(c, "namespace", func(cols map[string]string) error {
		if _, ok := cols["name"]; !ok {
			return errors.New("`name` is not found")
		}
		return nil
	})
}
<|endoftext|>


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

package rebuild

import (
	"time"

	"github.com/pkg/errors"
	"github.com/tsuru/monsterqueue"
	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/queue"
)

const routesRebuildTaskName = "rebuildRoutesTask"

var routesRebuildRetryTime = 10 * time.Second

var appFinder func(string) (RebuildApp, error)

type routesRebuildTask struct{}

func (t *routesRebuildTask) Name() string {
	return routesRebuildTaskName
}

func (t *routesRebuildTask) Run(job monsterqueue.Job) {
	params := job.Parameters()
	appName, ok := params["appName"].(string)
	if !ok {
		job.Error(errors.New("invalid parameters, expected appName"))
	}
	for !runRoutesRebuildOnce(appName, true) {
		time.Sleep(routesRebuildRetryTime)
	}
	job.Success(nil)
}

func RegisterTask(finder func(string) (RebuildApp, error)) error {
	appFinder = finder
	q, err := queue.Queue()
	if err != nil {
		return err
	}
	return q.RegisterTask(&routesRebuildTask{})
}

func runRoutesRebuildOnce(appName string, lock bool) bool {
	if appFinder == nil {
		return false
	}
	a, err := appFinder(appName)
	if err != nil {
		log.Errorf("[routes-rebuild-task] error getting app %q: %s", appName, err)
		return false
	}
	if a == nil {
		return true
	}
	if lock {
		var locked bool
		locked, err = a.InternalLock("rebuild-routes-task")
		if err != nil || !locked {
			return false
		}
		defer a.Unlock()
	}
	if err != nil {
		log.Errorf("[routes-rebuild-task] error getting app %q: %s", appName, err)
		return false
	}
	_, err = RebuildRoutes(a)
	if err != nil {
		log.Errorf("[routes-rebuild-task] error rebuilding app %q: %s", appName, err)
		return false
	}
	return true
}

func RoutesRebuildOrEnqueue(appName string) {
	routesRebuildOrEnqueueOptionalLock(appName, false)
}

func LockedRoutesRebuildOrEnqueue(appName string) {
	routesRebuildOrEnqueueOptionalLock(appName, true)
}

func routesRebuildOrEnqueueOptionalLock(appName string, lock bool) {
	if runRoutesRebuildOnce(appName, lock) {
		return
	}
	q, err := queue.Queue()
	if err != nil {
		log.Errorf("unable to enqueue rebuild routes task: %s", err)
		return
	}
	_, err = q.Enqueue(routesRebuildTaskName, monsterqueue.JobParams{
		"appName": appName,
	})
	if err != nil {
		log.Errorf("unable to enqueue rebuild routes task: %s", err)
		return
	}
}
<commit_msg>router/rebuild: removes unecessary error checking and adds log<commit_after>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rebuild

import (
	"time"

	"github.com/pkg/errors"
	"github.com/tsuru/monsterqueue"
	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/queue"
)

const routesRebuildTaskName = "rebuildRoutesTask"

var routesRebuildRetryTime = 10 * time.Second

var appFinder func(string) (RebuildApp, error)

type routesRebuildTask struct{}

func (t *routesRebuildTask) Name() string {
	return routesRebuildTaskName
}

func (t *routesRebuildTask) Run(job monsterqueue.Job) {
	params := job.Parameters()
	appName, ok := params["appName"].(string)
	if !ok {
		job.Error(errors.New("invalid parameters, expected appName"))
	}
	for !runRoutesRebuildOnce(appName, true) {
		time.Sleep(routesRebuildRetryTime)
	}
	job.Success(nil)
}

func RegisterTask(finder func(string) (RebuildApp, error)) error {
	appFinder = finder
	q, err := queue.Queue()
	if err != nil {
		return err
	}
	return q.RegisterTask(&routesRebuildTask{})
}

func runRoutesRebuildOnce(appName string, lock bool) bool {
	if appFinder == nil {
		return false
	}
	a, err := appFinder(appName)
	if err != nil {
		log.Errorf("[routes-rebuild-task] error getting app %q: %s", appName, err)
		return false
	}
	if a == nil {
		log.Errorf("[routes-rebuild-task] app %q not found, aborting", appName)
		return true
	}
	if lock {
		var locked bool
		locked, err = a.InternalLock("rebuild-routes-task")
		if err != nil || !locked {
			return false
		}
		defer a.Unlock()
	}
	_, err = RebuildRoutes(a)
	if err != nil {
		log.Errorf("[routes-rebuild-task] error rebuilding app %q: %s", appName, err)
		return false
	}
	return true
}

func RoutesRebuildOrEnqueue(appName string) {
	routesRebuildOrEnqueueOptionalLock(appName, false)
}

func LockedRoutesRebuildOrEnqueue(appName string) {
	routesRebuildOrEnqueueOptionalLock(appName, true)
}

func routesRebuildOrEnqueueOptionalLock(appName string, lock bool) {
	if runRoutesRebuildOnce(appName, lock) {
		return
	}
	q, err := queue.Queue()
	if err != nil {
		log.Errorf("unable to enqueue rebuild routes task: %s", err)
		return
	}
	_, err = q.Enqueue(routesRebuildTaskName, monsterqueue.JobParams{
		"appName": appName,
	})
	if err != nil {
		log.Errorf("unable to enqueue rebuild routes task: %s", err)
		return
	}
}
<|endoftext|>


<commit_before>package skiplist

import (
	"fmt"
	"testing"
)

func BenchmarkInsert_1000(b *testing.B)    { benchInsert(b, 1000) }
func BenchmarkInsert_10000(b *testing.B)   { benchInsert(b, 10000) }
func BenchmarkInsert_100000(b *testing.B)  { benchInsert(b, 100000) }
func BenchmarkInsert_1000000(b *testing.B) { benchInsert(b, 1000000) }

func benchInsert(b *testing.B, total int) {
	for i := 0; i < b.N; i++ {
		l := NewList()
		for i := 0; i < total; i++ {
			l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %i", i)))
		}
	}
}

func BenchmarkParallelInsert(b *testing.B) {
	l := NewList()
	i := 0
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			i++
			l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %i", i)))
		}
	})
}

func BenchmarkDelete_1000(b *testing.B)    { benchDelete(b, 1000) }
func BenchmarkDelete_10000(b *testing.B)   { benchDelete(b, 10000) }
func BenchmarkDelete_100000(b *testing.B)  { benchDelete(b, 100000) }
func BenchmarkDelete_1000000(b *testing.B) { benchDelete(b, 1000000) }

func benchDelete(b *testing.B, total int) {
	l := NewList()
	for i := 0; i < total; i++ {
		l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %i", i)))
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for i := 0; i < total; i++ {

			l.Delete(i)
		}
	}
}

func BenchmarkParallelDelete(b *testing.B) {
	l := NewList()
	for i := 0; i < 1000000; i++ {
		l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %i", i)))
	}
	b.ResetTimer()
	i := 0
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			i++
			l.Delete(i)
		}
	})
}
<commit_msg>Fix integer print in benchmarks<commit_after>package skiplist

import (
	"fmt"
	"testing"
)

func BenchmarkInsert_1000(b *testing.B)    { benchInsert(b, 1000) }
func BenchmarkInsert_10000(b *testing.B)   { benchInsert(b, 10000) }
func BenchmarkInsert_100000(b *testing.B)  { benchInsert(b, 100000) }
func BenchmarkInsert_1000000(b *testing.B) { benchInsert(b, 1000000) }

func benchInsert(b *testing.B, total int) {
	for i := 0; i < b.N; i++ {
		l := NewList()
		for i := 0; i < total; i++ {
			l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %d", i)))
		}
	}
}

func BenchmarkParallelInsert(b *testing.B) {
	l := NewList()
	i := 0
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			i++
			l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %d", i)))
		}
	})
}

func BenchmarkDelete_1000(b *testing.B)    { benchDelete(b, 1000) }
func BenchmarkDelete_10000(b *testing.B)   { benchDelete(b, 10000) }
func BenchmarkDelete_100000(b *testing.B)  { benchDelete(b, 100000) }
func BenchmarkDelete_1000000(b *testing.B) { benchDelete(b, 1000000) }

func benchDelete(b *testing.B, total int) {
	l := NewList()
	for i := 0; i < total; i++ {
		l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %d", i)))
	}
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		for i := 0; i < total; i++ {
			l.Delete(i)
		}
	}
}

func BenchmarkParallelDelete(b *testing.B) {
	l := NewList()
	for i := 0; i < 1000000; i++ {
		l.Insert(i, []byte(fmt.Sprintf("Skiplist node insert %d", i)))
	}
	b.ResetTimer()
	i := 0
	b.RunParallel(func(pb *testing.PB) {
		for pb.Next() {
			i++
			l.Delete(i)
		}
	})
}
<|endoftext|>