<commit_before>package simulation_test

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os/exec"
	"runtime"
	"strings"

	"github.com/cloudfoundry-incubator/auction/auctionrep"
	"github.com/cloudfoundry-incubator/auction/auctionrunner"
	"github.com/cloudfoundry-incubator/auction/auctiontypes"
	"github.com/cloudfoundry-incubator/auction/communication/nats/auction_nats_client"
	"github.com/cloudfoundry-incubator/auction/simulation/auctiondistributor"
	"github.com/cloudfoundry-incubator/auction/simulation/communication/inprocess"
	"github.com/cloudfoundry-incubator/auction/simulation/simulationrepdelegate"
	"github.com/cloudfoundry-incubator/auction/simulation/visualization"
	"github.com/cloudfoundry-incubator/auction/util"
	"github.com/cloudfoundry/gunk/natsrunner"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/pivotal-golang/lager"

	"testing"
	"time"
)

var communicationMode string
var auctioneerMode string

const InProcess = "inprocess"
const NATS = "nats"
const RemoteAuctioneerMode = "remote"

const numAuctioneers = 10
const numReps = 100

var repResources = auctiontypes.Resources{
	MemoryMB:   100.0,
	DiskMB:     100.0,
	Containers: 100,
}

var maxConcurrentPerExecutor int

var timeout time.Duration
var runTimeout time.Duration
var auctionDistributor *auctiondistributor.AuctionDistributor

var svgReport *visualization.SVGReport
var reports []*visualization.Report

var sessionsToTerminate []*gexec.Session
var natsRunner *natsrunner.NATSRunner
var client auctiontypes.SimulationRepPoolClient
var repGuids []string

var disableSVGReport bool

func init() {
	flag.StringVar(&communicationMode, "communicationMode", "inprocess", "one of inprocess or nats")
	flag.StringVar(&auctioneerMode, "auctioneerMode", "inprocess", "one of inprocess or remote")
	flag.DurationVar(&timeout, "timeout", 500*time.Millisecond, "timeout when waiting for responses from remote calls")
	flag.DurationVar(&runTimeout, "runTimeout", 10*time.Second, "timeout when waiting for the run command to respond")

	flag.StringVar(&(auctionrunner.DefaultStartAuctionRules.Algorithm), "algorithm", auctionrunner.DefaultStartAuctionRules.Algorithm, "the auction algorithm to use")
	flag.IntVar(&(auctionrunner.DefaultStartAuctionRules.MaxRounds), "maxRounds", auctionrunner.DefaultStartAuctionRules.MaxRounds, "the maximum number of rounds per auction")
	flag.Float64Var(&(auctionrunner.DefaultStartAuctionRules.MaxBiddingPoolFraction), "maxBiddingPoolFraction", auctionrunner.DefaultStartAuctionRules.MaxBiddingPoolFraction, "the maximum number of participants in the pool")

	flag.IntVar(&maxConcurrentPerExecutor, "maxConcurrentPerExecutor", 20, "the maximum number of concurrent auctions to run, per executor")

	flag.BoolVar(&disableSVGReport, "disableSVGReport", false, "disable displaying SVG reports of the simulation runs")
}

func TestAuction(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Auction Suite")
}

var _ = BeforeSuite(func() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	fmt.Printf("Running in %s communicationMode\n", communicationMode)
	fmt.Printf("Running in %s auctioneerMode\n", auctioneerMode)

	startReport()

	sessionsToTerminate = []*gexec.Session{}
	hosts := []string{}
	switch communicationMode {
	case InProcess:
		client, repGuids = buildInProcessReps()
		if auctioneerMode == RemoteAuctioneerMode {
			panic("it doesn't make sense to use remote auctioneers when the reps are in-process")
		}
	case NATS:
		natsAddrs := startNATS()
		var err error

		natsLogger := lager.NewLogger("test")
		natsLogger.RegisterSink(lager.NewWriterSink(GinkgoWriter, lager.DEBUG))

		client, err = auction_nats_client.New(natsRunner.MessageBus, timeout, runTimeout, natsLogger)
		Ω(err).ShouldNot(HaveOccurred())
		repGuids = launchExternalReps("-natsAddrs", natsAddrs)
		if auctioneerMode == RemoteAuctioneerMode {
			hosts = launchExternalAuctioneers("-natsAddrs", natsAddrs)
		}
	default:
		panic(fmt.Sprintf("unknown communication mode: %s", communicationMode))
	}

	if auctioneerMode == InProcess {
		auctionDistributor = auctiondistributor.NewInProcessAuctionDistributor(client)
	} else if auctioneerMode == RemoteAuctioneerMode {
		auctionDistributor = auctiondistributor.NewRemoteAuctionDistributor(hosts, client)
	}
})

var _ = BeforeEach(func() {
	for _, repGuid := range repGuids {
		client.Reset(repGuid)
	}

	util.ResetGuids()
})

var _ = AfterSuite(func() {
	if !disableSVGReport {
		finishReport()
	}
	for _, sess := range sessionsToTerminate {
		sess.Kill().Wait()
	}

	if natsRunner != nil {
		natsRunner.Stop()
	}
})

func buildInProcessReps() (auctiontypes.SimulationRepPoolClient, []string) {
	inprocess.LatencyMin = 50 * time.Millisecond
	inprocess.LatencyMax = 100 * time.Millisecond

	repGuids := []string{}
	repMap := map[string]*auctionrep.AuctionRep{}

	for i := 0; i < numReps; i++ {
		repGuid := util.NewGuid("REP")
		repGuids = append(repGuids, repGuid)

		repDelegate := simulationrepdelegate.New(repResources)
		repMap[repGuid] = auctionrep.New(repGuid, repDelegate)
	}

	client := inprocess.New(repMap)
	return client, repGuids
}

func startNATS() string {
	natsPort := 5222 + GinkgoParallelNode()
	natsAddrs := []string{fmt.Sprintf("127.0.0.1:%d", natsPort)}
	natsRunner = natsrunner.NewNATSRunner(natsPort)
	natsRunner.Start()
	return strings.Join(natsAddrs, ",")
}

func launchExternalReps(communicationFlag string, communicationValue string) []string {
	repNodeBinary, err := gexec.Build("github.com/cloudfoundry-incubator/auction/simulation/repnode")
	Ω(err).ShouldNot(HaveOccurred())

	repGuids := []string{}

	for i := 0; i < numReps; i++ {
		repGuid := util.NewGuid("REP")

		serverCmd := exec.Command(
			repNodeBinary,
			"-repGuid", repGuid,
			communicationFlag, communicationValue,
			"-memoryMB", fmt.Sprintf("%d", repResources.MemoryMB),
			"-diskMB", fmt.Sprintf("%d", repResources.DiskMB),
			"-containers", fmt.Sprintf("%d", repResources.Containers),
		)

		sess, err := gexec.Start(serverCmd, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(sess).Should(gbytes.Say("listening"))
		sessionsToTerminate = append(sessionsToTerminate, sess)

		repGuids = append(repGuids, repGuid)
	}

	return repGuids
}

func launchExternalAuctioneers(communicationFlag string, communicationValue string) []string {
	auctioneerNodeBinary, err := gexec.Build("github.com/cloudfoundry-incubator/auction/simulation/auctioneernode")
	Ω(err).ShouldNot(HaveOccurred())

	auctioneerHosts := []string{}
	for i := 0; i < numAuctioneers; i++ {
		port := 48710 + i
		auctioneerCmd := exec.Command(
			auctioneerNodeBinary,
			communicationFlag, communicationValue,
			"-timeout", fmt.Sprintf("%s", timeout),
			"-httpAddr", fmt.Sprintf("127.0.0.1:%d", port),
		)
		auctioneerHosts = append(auctioneerHosts, fmt.Sprintf("127.0.0.1:%d", port))

		sess, err := gexec.Start(auctioneerCmd, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(sess).Should(gbytes.Say("auctioneering"))
		sessionsToTerminate = append(sessionsToTerminate, sess)
	}

	return auctioneerHosts
}

func startReport() {
	svgReport = visualization.StartSVGReport("./report.svg", 4, 4)
	svgReport.DrawHeader(communicationMode, auctionrunner.DefaultStartAuctionRules, maxConcurrentPerExecutor)
}

func finishReport() {
	svgReport.Done()
	exec.Command("rsvg-convert", "-h", "2000", "--background-color=#fff", "./report.svg", "-o", "./report.png").Run()
	exec.Command("open", "./report.png").Run()

	data, err := json.Marshal(reports)
	Ω(err).ShouldNot(HaveOccurred())
	ioutil.WriteFile("./report.json", data, 0777)
}
<commit_msg>reorganize latency numbers<commit_after>package simulation_test

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"os/exec"
	"runtime"
	"strings"

	"github.com/cloudfoundry-incubator/auction/auctionrep"
	"github.com/cloudfoundry-incubator/auction/auctionrunner"
	"github.com/cloudfoundry-incubator/auction/auctiontypes"
	"github.com/cloudfoundry-incubator/auction/communication/nats/auction_nats_client"
	"github.com/cloudfoundry-incubator/auction/simulation/auctiondistributor"
	"github.com/cloudfoundry-incubator/auction/simulation/communication/inprocess"
	"github.com/cloudfoundry-incubator/auction/simulation/simulationrepdelegate"
	"github.com/cloudfoundry-incubator/auction/simulation/visualization"
	"github.com/cloudfoundry-incubator/auction/util"
	"github.com/cloudfoundry/gunk/natsrunner"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/pivotal-golang/lager"

	"testing"
	"time"
)

var communicationMode string
var auctioneerMode string

const InProcess = "inprocess"
const NATS = "nats"
const RemoteAuctioneerMode = "remote"

const numAuctioneers = 10
const numReps = 100
const LatencyMin = 50 * time.Millisecond
const LatencyMax = 100 * time.Millisecond

var repResources = auctiontypes.Resources{
	MemoryMB:   100.0,
	DiskMB:     100.0,
	Containers: 100,
}

var maxConcurrentPerExecutor int

var timeout time.Duration
var runTimeout time.Duration
var auctionDistributor *auctiondistributor.AuctionDistributor

var svgReport *visualization.SVGReport
var reports []*visualization.Report

var sessionsToTerminate []*gexec.Session
var natsRunner *natsrunner.NATSRunner
var client auctiontypes.SimulationRepPoolClient
var repGuids []string

var disableSVGReport bool

func init() {
	flag.StringVar(&communicationMode, "communicationMode", "inprocess", "one of inprocess or nats")
	flag.StringVar(&auctioneerMode, "auctioneerMode", "inprocess", "one of inprocess or remote")
	flag.DurationVar(&timeout, "timeout", 500*time.Millisecond, "timeout when waiting for responses from remote calls")
	flag.DurationVar(&runTimeout, "runTimeout", 10*time.Second, "timeout when waiting for the run command to respond")

	flag.StringVar(&(auctionrunner.DefaultStartAuctionRules.Algorithm), "algorithm", auctionrunner.DefaultStartAuctionRules.Algorithm, "the auction algorithm to use")
	flag.IntVar(&(auctionrunner.DefaultStartAuctionRules.MaxRounds), "maxRounds", auctionrunner.DefaultStartAuctionRules.MaxRounds, "the maximum number of rounds per auction")
	flag.Float64Var(&(auctionrunner.DefaultStartAuctionRules.MaxBiddingPoolFraction), "maxBiddingPoolFraction", auctionrunner.DefaultStartAuctionRules.MaxBiddingPoolFraction, "the maximum number of participants in the pool")

	flag.IntVar(&maxConcurrentPerExecutor, "maxConcurrentPerExecutor", 20, "the maximum number of concurrent auctions to run, per executor")

	flag.BoolVar(&disableSVGReport, "disableSVGReport", false, "disable displaying SVG reports of the simulation runs")
}

func TestAuction(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Auction Suite")
}

var _ = BeforeSuite(func() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	fmt.Printf("Running in %s communicationMode\n", communicationMode)
	fmt.Printf("Running in %s auctioneerMode\n", auctioneerMode)

	startReport()

	sessionsToTerminate = []*gexec.Session{}
	hosts := []string{}
	switch communicationMode {
	case InProcess:
		client, repGuids = buildInProcessReps()
		if auctioneerMode == RemoteAuctioneerMode {
			panic("it doesn't make sense to use remote auctioneers when the reps are in-process")
		}
	case NATS:
		natsAddrs := startNATS()
		var err error

		natsLogger := lager.NewLogger("test")
		natsLogger.RegisterSink(lager.NewWriterSink(GinkgoWriter, lager.DEBUG))

		client, err = auction_nats_client.New(natsRunner.MessageBus, timeout, runTimeout, natsLogger)
		Ω(err).ShouldNot(HaveOccurred())
		repGuids = launchExternalReps("-natsAddrs", natsAddrs)
		if auctioneerMode == RemoteAuctioneerMode {
			hosts = launchExternalAuctioneers("-natsAddrs", natsAddrs)
		}
	default:
		panic(fmt.Sprintf("unknown communication mode: %s", communicationMode))
	}

	if auctioneerMode == InProcess {
		auctionDistributor = auctiondistributor.NewInProcessAuctionDistributor(client)
	} else if auctioneerMode == RemoteAuctioneerMode {
		auctionDistributor = auctiondistributor.NewRemoteAuctionDistributor(hosts, client)
	}
})

var _ = BeforeEach(func() {
	for _, repGuid := range repGuids {
		client.Reset(repGuid)
	}

	util.ResetGuids()
})

var _ = AfterSuite(func() {
	if !disableSVGReport {
		finishReport()
	}
	for _, sess := range sessionsToTerminate {
		sess.Kill().Wait()
	}

	if natsRunner != nil {
		natsRunner.Stop()
	}
})

func buildInProcessReps() (auctiontypes.SimulationRepPoolClient, []string) {
	inprocess.LatencyMin = LatencyMin
	inprocess.LatencyMax = LatencyMax

	repGuids := []string{}
	repMap := map[string]*auctionrep.AuctionRep{}

	for i := 0; i < numReps; i++ {
		repGuid := util.NewGuid("REP")
		repGuids = append(repGuids, repGuid)

		repDelegate := simulationrepdelegate.New(repResources)
		repMap[repGuid] = auctionrep.New(repGuid, repDelegate)
	}

	client := inprocess.New(repMap)
	return client, repGuids
}

func startNATS() string {
	natsPort := 5222 + GinkgoParallelNode()
	natsAddrs := []string{fmt.Sprintf("127.0.0.1:%d", natsPort)}
	natsRunner = natsrunner.NewNATSRunner(natsPort)
	natsRunner.Start()
	return strings.Join(natsAddrs, ",")
}

func launchExternalReps(communicationFlag string, communicationValue string) []string {
	repNodeBinary, err := gexec.Build("github.com/cloudfoundry-incubator/auction/simulation/repnode")
	Ω(err).ShouldNot(HaveOccurred())

	repGuids := []string{}

	for i := 0; i < numReps; i++ {
		repGuid := util.NewGuid("REP")

		serverCmd := exec.Command(
			repNodeBinary,
			"-repGuid", repGuid,
			communicationFlag, communicationValue,
			"-memoryMB", fmt.Sprintf("%d", repResources.MemoryMB),
			"-diskMB", fmt.Sprintf("%d", repResources.DiskMB),
			"-containers", fmt.Sprintf("%d", repResources.Containers),
		)

		sess, err := gexec.Start(serverCmd, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(sess).Should(gbytes.Say("listening"))
		sessionsToTerminate = append(sessionsToTerminate, sess)

		repGuids = append(repGuids, repGuid)
	}

	return repGuids
}

func launchExternalAuctioneers(communicationFlag string, communicationValue string) []string {
	auctioneerNodeBinary, err := gexec.Build("github.com/cloudfoundry-incubator/auction/simulation/auctioneernode")
	Ω(err).ShouldNot(HaveOccurred())

	auctioneerHosts := []string{}
	for i := 0; i < numAuctioneers; i++ {
		port := 48710 + i
		auctioneerCmd := exec.Command(
			auctioneerNodeBinary,
			communicationFlag, communicationValue,
			"-timeout", fmt.Sprintf("%s", timeout),
			"-httpAddr", fmt.Sprintf("127.0.0.1:%d", port),
		)
		auctioneerHosts = append(auctioneerHosts, fmt.Sprintf("127.0.0.1:%d", port))

		sess, err := gexec.Start(auctioneerCmd, GinkgoWriter, GinkgoWriter)
		Ω(err).ShouldNot(HaveOccurred())
		Eventually(sess).Should(gbytes.Say("auctioneering"))
		sessionsToTerminate = append(sessionsToTerminate, sess)
	}

	return auctioneerHosts
}

func startReport() {
	svgReport = visualization.StartSVGReport("./report.svg", 4, 4)
	svgReport.DrawHeader(communicationMode, auctionrunner.DefaultStartAuctionRules, maxConcurrentPerExecutor)
}

func finishReport() {
	svgReport.Done()
	exec.Command("rsvg-convert", "-h", "2000", "--background-color=#fff", "./report.svg", "-o", "./report.png").Run()
	exec.Command("open", "./report.png").Run()

	data, err := json.Marshal(reports)
	Ω(err).ShouldNot(HaveOccurred())
	ioutil.WriteFile("./report.json", data, 0777)
}
<|endoftext|>


<commit_before>package lrpstatus

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

	"code.cloudfoundry.org/bbs"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/clock"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/tps/handler/cc_conv"

	"code.cloudfoundry.org/runtimeschema/cc_messages"
)

type handler struct {
	apiClient bbs.Client
	clock     clock.Clock
	logger    lager.Logger
}

func NewHandler(apiClient bbs.Client, clk clock.Clock, logger lager.Logger) http.Handler {
	return &handler{
		apiClient: apiClient,
		clock:     clk,
		logger:    logger,
	}
}

func (handler *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	guid := r.FormValue(":guid")
	logger := handler.logger.Session("lrp-status", lager.Data{"process-guid": guid})

	logger.Info("fetching-actual-lrp-info")
	actualLRPGroups, err := handler.apiClient.ActualLRPGroupsByProcessGuid(logger, guid)
	if err != nil {
		logger.Error("failed-fetching-actual-lrp-info", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	instances := LRPInstances(actualLRPGroups,
		func(instance *cc_messages.LRPInstance, actual *models.ActualLRP) {
			instance.Details = actual.PlacementError
		},
		handler.clock,
	)

	err = json.NewEncoder(w).Encode(instances)
	if err != nil {
		logger.Error("stream-response-failed", err)
	}
}

func LRPInstances(
	actualLRPGroups []*models.ActualLRPGroup,
	addInfo func(*cc_messages.LRPInstance, *models.ActualLRP),
	clk clock.Clock,
) []cc_messages.LRPInstance {
	instances := make([]cc_messages.LRPInstance, len(actualLRPGroups))
	for i, actualLRPGroup := range actualLRPGroups {
		actual, _ := actualLRPGroup.Resolve()

		instance := cc_messages.LRPInstance{
			ProcessGuid:  actual.ProcessGuid,
			InstanceGuid: actual.InstanceGuid,
			Index:        uint(actual.Index),
			Since:        actual.Since / 1e9,
			Uptime:       (clk.Now().UnixNano() - actual.Since) / 1e9,
			State:        cc_conv.StateFor(actual.State, actual.PlacementError),
			NetInfo:      actual.ActualLRPNetInfo,
		}

		if addInfo != nil {
			addInfo(&instance, actual)
		}

		instances[i] = instance
	}

	return instances
}
<commit_msg>Fix compilation error in deprecated tps-listener<commit_after>package lrpstatus

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

	"code.cloudfoundry.org/bbs"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/clock"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/tps/handler/cc_conv"

	"code.cloudfoundry.org/runtimeschema/cc_messages"
)

type handler struct {
	apiClient bbs.Client
	clock     clock.Clock
	logger    lager.Logger
}

func NewHandler(apiClient bbs.Client, clk clock.Clock, logger lager.Logger) http.Handler {
	return &handler{
		apiClient: apiClient,
		clock:     clk,
		logger:    logger,
	}
}

func (handler *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	guid := r.FormValue(":guid")
	logger := handler.logger.Session("lrp-status", lager.Data{"process-guid": guid})

	logger.Info("fetching-actual-lrp-info")
	actualLRPGroups, err := handler.apiClient.ActualLRPGroupsByProcessGuid(logger, guid)
	if err != nil {
		logger.Error("failed-fetching-actual-lrp-info", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}

	instances := LRPInstances(actualLRPGroups,
		func(instance *cc_messages.LRPInstance, actual *models.ActualLRP) {
			instance.Details = actual.PlacementError
		},
		handler.clock,
	)

	err = json.NewEncoder(w).Encode(instances)
	if err != nil {
		logger.Error("stream-response-failed", err)
	}
}

func LRPInstances(
	actualLRPGroups []*models.ActualLRPGroup,
	addInfo func(*cc_messages.LRPInstance, *models.ActualLRP),
	clk clock.Clock,
) []cc_messages.LRPInstance {
	instances := make([]cc_messages.LRPInstance, len(actualLRPGroups))
	for i, actualLRPGroup := range actualLRPGroups {
		actual, _, _ := actualLRPGroup.Resolve()

		instance := cc_messages.LRPInstance{
			ProcessGuid:  actual.ProcessGuid,
			InstanceGuid: actual.InstanceGuid,
			Index:        uint(actual.Index),
			Since:        actual.Since / 1e9,
			Uptime:       (clk.Now().UnixNano() - actual.Since) / 1e9,
			State:        cc_conv.StateFor(actual.State, actual.PlacementError),
			NetInfo:      actual.ActualLRPNetInfo,
		}

		if addInfo != nil {
			addInfo(&instance, actual)
		}

		instances[i] = instance
	}

	return instances
}
<|endoftext|>


<commit_before>package node

import (
	"erlang/term"
)

type GenServer interface {
	Init(args ...interface{})
	HandleCast(message *term.Term)
	HandleCall(message *term.Term, from *term.Tuple) (reply *term.Term)
	HandleInfo(message *term.Term)
	Terminate(reason interface{})
}

type GenServerImpl struct {
	node *Node
	self term.Pid
}

func (gs *GenServerImpl) Options() map[string]interface{} {
	return map[string]interface{}{
		"chan-size":     100,
		"ctl-chan-size": 100,
	}
}

func (gs *GenServerImpl) ProcessLoop(node *Node, pid term.Pid, pcs procChannels, pd Process, args ...interface{}) {
	gs.setNode(node)
	gs.setPid(pid)
	pd.(GenServer).Init(args...)
	//pcs.ctl <- term.Tuple{term.Atom("$go_ctl"), term.Tuple{term.Atom("control-message"), term.Atom("example")}}
	for {
		var message term.Term
		var fromPid term.Pid
		select {
		case msg := <-pcs.in:
			message = msg
		case msgFrom := <-pcs.inFrom:
			message = msgFrom[1]
			fromPid = msgFrom[0].(term.Pid)
		case ctlMsg := <-pcs.ctl:
			switch m := ctlMsg.(type) {
			case term.Tuple:
				switch mtag := m[0].(type) {
				case term.Atom:
					switch mtag {
					case term.Atom("$go_ctl"):
						nLog("Control message: %#v", m)
					default:
						nLog("Unknown message: %#v", m)
					}
				default:
					nLog("Unknown message: %#v", m)
				}
			default:
				nLog("Unknown message: %#v", m)
			}
			continue
		}
		nLog("Message from %#v", fromPid)
		switch m := message.(type) {
		case term.Tuple:
			switch mtag := m[0].(type) {
			case term.Atom:
				switch mtag {
				case term.Atom("$go_ctl"):
					nLog("Control message: %#v", message)
				case term.Atom("$gen_call"):
					fromTuple := m[1].(term.Tuple)
					reply := pd.(GenServer).HandleCall(&m[2], &fromTuple)
					if reply != nil {
						gs.Reply(&fromTuple, reply)
					}
				case term.Atom("$gen_cast"):
					pd.(GenServer).HandleCast(&m[1])
				default:
					pd.(GenServer).HandleInfo(&message)
				}
			default:
				nLog("mtag: %#v", mtag)
				pd.(GenServer).HandleInfo(&message)
			}
		default:
			nLog("m: %#v", m)
			pd.(GenServer).HandleInfo(&message)
		}
	}
}

func (gs *GenServerImpl) Reply(fromTuple *term.Tuple, reply *term.Term) {
	gs.node.Send((*fromTuple)[0].(term.Pid), term.Tuple{(*fromTuple)[1], *reply})
}

func (gs *GenServerImpl) setNode(node *Node) {
	gs.node = node
}

func (gs *GenServerImpl) setPid(pid term.Pid) {
	gs.self = pid
}
<commit_msg>Handle process crash (incomplete)<commit_after>package node

import (
	"erlang/term"
	"log"
)

type GenServer interface {
	Init(args ...interface{})
	HandleCast(message *term.Term)
	HandleCall(message *term.Term, from *term.Tuple) (reply *term.Term)
	HandleInfo(message *term.Term)
	Terminate(reason interface{})
}

type GenServerImpl struct {
	node *Node
	self term.Pid
}

func (gs *GenServerImpl) Options() map[string]interface{} {
	return map[string]interface{}{
		"chan-size":     100,
		"ctl-chan-size": 100,
	}
}

func (gs *GenServerImpl) ProcessLoop(node *Node, pid term.Pid, pcs procChannels, pd Process, args ...interface{}) {
	gs.setNode(node)
	gs.setPid(pid)
	pd.(GenServer).Init(args...)
	//pcs.ctl <- term.Tuple{term.Atom("$go_ctl"), term.Tuple{term.Atom("control-message"), term.Atom("example")}}
	defer func() {
		if r := recover(); r != nil {
			// TODO: send message to parent process
			log.Printf("GenServer recovered: %#v", r)
		}
	}()
	for {
		var message term.Term
		var fromPid term.Pid
		select {
		case msg := <-pcs.in:
			message = msg
		case msgFrom := <-pcs.inFrom:
			message = msgFrom[1]
			fromPid = msgFrom[0].(term.Pid)
		case ctlMsg := <-pcs.ctl:
			switch m := ctlMsg.(type) {
			case term.Tuple:
				switch mtag := m[0].(type) {
				case term.Atom:
					switch mtag {
					case term.Atom("$go_ctl"):
						nLog("Control message: %#v", m)
					default:
						nLog("Unknown message: %#v", m)
					}
				default:
					nLog("Unknown message: %#v", m)
				}
			default:
				nLog("Unknown message: %#v", m)
			}
			continue
		}
		nLog("Message from %#v", fromPid)
		switch m := message.(type) {
		case term.Tuple:
			switch mtag := m[0].(type) {
			case term.Atom:
				switch mtag {
				case term.Atom("$go_ctl"):
					nLog("Control message: %#v", message)
				case term.Atom("$gen_call"):
					fromTuple := m[1].(term.Tuple)
					reply := pd.(GenServer).HandleCall(&m[2], &fromTuple)
					if reply != nil {
						gs.Reply(&fromTuple, reply)
					}
				case term.Atom("$gen_cast"):
					pd.(GenServer).HandleCast(&m[1])
				default:
					pd.(GenServer).HandleInfo(&message)
				}
			default:
				nLog("mtag: %#v", mtag)
				pd.(GenServer).HandleInfo(&message)
			}
		default:
			nLog("m: %#v", m)
			pd.(GenServer).HandleInfo(&message)
		}
	}
}

func (gs *GenServerImpl) Reply(fromTuple *term.Tuple, reply *term.Term) {
	gs.node.Send((*fromTuple)[0].(term.Pid), term.Tuple{(*fromTuple)[1], *reply})
}

func (gs *GenServerImpl) setNode(node *Node) {
	gs.node = node
}

func (gs *GenServerImpl) setPid(pid term.Pid) {
	gs.self = pid
}
<|endoftext|>


<commit_before>package godbg

import (
	"fmt"
	"os"
	"runtime"
	"testing"
	. "github.com/smartystreets/goconvey/convey"
)

func TestProject(t *testing.T) {
	SkipConvey("Test buffers", t, func() {

		Convey("By Default, equals to std", func() {
			So(Out(), ShouldEqual, os.Stdout)
			So(Err(), ShouldEqual, os.Stderr)
		})
		Convey("When set to buffer, no longer equals to std", func() {
			SetBuffers(nil)
			So(Out(), ShouldNotEqual, os.Stdout)
			So(Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance buffer equals to std", func() {
			apdbg := NewPdbg()
			So(apdbg.Out(), ShouldEqual, os.Stdout)
			So(apdbg.Err(), ShouldEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance set to buffer writes no longer equals to std", func() {
			apdbg := NewPdbg(SetBuffers)
			So(apdbg.Out(), ShouldNotEqual, os.Stdout)
			So(apdbg.Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("Test custom buffer on global pdbg", func() {
			pdbg.bout = nil
			pdbg.sout = nil
			pdbg.berr = nil
			pdbg.serr = nil
			fmt.Fprintln(Out(), "test0 content0")
			So(OutString(), ShouldEqual, ``)
			fmt.Fprintln(Err(), "err0 content0")
			So(ErrString(), ShouldEqual, ``)
			SetBuffers(nil)
			fmt.Fprintln(Out(), "test content")
			fmt.Fprintln(Err(), "err1 cerr")
			fmt.Fprintln(Err(), "err2 cerr2")
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test content
test2 content2`)
			So(ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})

		Convey("Test custom buffer reset on global pdbg", func() {
			SetBuffers(nil)
			fmt.Fprint(Out(), "test content")
			So(OutString(), ShouldEqual, `test content`)
			fmt.Fprint(Err(), "err1 cerr")
			So(ErrString(), ShouldEqual, `err1 cerr`)
			ResetIOs()
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(Err(), "err2 cerr2")
			So(ErrString(), ShouldEqual, `err2 cerr2`)
		})

		Convey("Test custom buffer on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprintln(apdbg.Out(), "test content")
			fmt.Fprintln(apdbg.Err(), "err1 cerr")
			fmt.Fprintln(apdbg.Err(), "err2 cerr2")
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test content
test2 content2`)
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer reset on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprint(apdbg.Out(), "test content")
			So(apdbg.OutString(), ShouldEqual, `test content`)
			fmt.Fprint(apdbg.Err(), "err1 cerr")
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr`)
			apdbg.ResetIOs()
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(apdbg.Err(), "err2 cerr2")
			So(apdbg.ErrString(), ShouldEqual, `err2 cerr2`)
		})
	})

	SkipConvey("Test pdbg print functions", t, func() {
		Convey("Test pdbg print with global instance", func() {
			SetBuffers(nil)
			Pdbgf("test")
			So(ErrString(), ShouldEqual,
				`[func.012:96]
  test
`)
			ResetIOs()
			prbgtest()
			So(ErrString(), ShouldEqual,
				` [prbgtest:4] (func.012:102)
   prbgtest content
`)
		})

		Convey("Test pdbg print with custom instance", func() {
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test2")
			So(apdbg.ErrString(), ShouldEqual,
				`[func.013:111]
  test2
`)
			apdbg.ResetIOs()
			prbgtestCustom(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				` [prbgtestCustom:8] (func.013:117)
   prbgtest content2
`)
			apdbg.ResetIOs()
			apdbg.pdbgTestInstance()
			So(apdbg.ErrString(), ShouldEqual,
				` [*Pdbg.pdbgTestInstance:12] (func.013:123)
   pdbgTestInstance content3
`)
		})
		Convey("Test pdbg prints nothing if runtime.Caller fails", func() {
			mycaller = failCaller
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test fail")
			So(apdbg.ErrString(), ShouldEqual, `  test fail
`)
			mycaller = runtime.Caller
		})
	})

	Convey("Test pdbg excludes functions", t, func() {
		Convey("Test pdbg exclude with global instance", func() {
			SetBuffers(nil)
			pdbg.SetExcludes([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				` [globalPdbgExcludeTest:16] (func.016:143)
   calling no
   [globalCNo:26] (globalPdbgExcludeTest:17) (func.016:143)
     gcalled2
`)
		})
		Convey("Test pdbg exclude with custom instance", func() {
			apdbg := NewPdbg(SetBuffers, OptExcludes([]string{"customNo"}))
			customPdbgExcludeTest(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				` [customPdbgExcludeTest:30] (func.017:153)
   calling cno
   [customCNo:40] (customPdbgExcludeTest:31) (func.017:153)
     ccalled2
`)
		})
	})

	SkipConvey("Test pdbg skips functions", t, func() {
		Convey("Test pdbg skip with global instance", func() {
			SetBuffers(nil)
			pdbg.SetSkips([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				`  [globalPdbgExcludeTest:16] (func.019:167)
    calling no
    [globalPdbgExcludeTest:17] (func.019:167)
      gcalled1
      [globalCNo:26] (globalPdbgExcludeTest:17) (func.019:167)
        gcalled2
`)
		})
	})
}

func failCaller(skip int) (pc uintptr, file string, line int, ok bool) {
	return 0, "fail", skip, false
}
<commit_msg>Fix expected test result for exclude<commit_after>package godbg

import (
	"fmt"
	"os"
	"runtime"
	"testing"
	. "github.com/smartystreets/goconvey/convey"
)

func TestProject(t *testing.T) {
	SkipConvey("Test buffers", t, func() {

		Convey("By Default, equals to std", func() {
			So(Out(), ShouldEqual, os.Stdout)
			So(Err(), ShouldEqual, os.Stderr)
		})
		Convey("When set to buffer, no longer equals to std", func() {
			SetBuffers(nil)
			So(Out(), ShouldNotEqual, os.Stdout)
			So(Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance buffer equals to std", func() {
			apdbg := NewPdbg()
			So(apdbg.Out(), ShouldEqual, os.Stdout)
			So(apdbg.Err(), ShouldEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance set to buffer writes no longer equals to std", func() {
			apdbg := NewPdbg(SetBuffers)
			So(apdbg.Out(), ShouldNotEqual, os.Stdout)
			So(apdbg.Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("Test custom buffer on global pdbg", func() {
			pdbg.bout = nil
			pdbg.sout = nil
			pdbg.berr = nil
			pdbg.serr = nil
			fmt.Fprintln(Out(), "test0 content0")
			So(OutString(), ShouldEqual, ``)
			fmt.Fprintln(Err(), "err0 content0")
			So(ErrString(), ShouldEqual, ``)
			SetBuffers(nil)
			fmt.Fprintln(Out(), "test content")
			fmt.Fprintln(Err(), "err1 cerr")
			fmt.Fprintln(Err(), "err2 cerr2")
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test content
test2 content2`)
			So(ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})

		Convey("Test custom buffer reset on global pdbg", func() {
			SetBuffers(nil)
			fmt.Fprint(Out(), "test content")
			So(OutString(), ShouldEqual, `test content`)
			fmt.Fprint(Err(), "err1 cerr")
			So(ErrString(), ShouldEqual, `err1 cerr`)
			ResetIOs()
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(Err(), "err2 cerr2")
			So(ErrString(), ShouldEqual, `err2 cerr2`)
		})

		Convey("Test custom buffer on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprintln(apdbg.Out(), "test content")
			fmt.Fprintln(apdbg.Err(), "err1 cerr")
			fmt.Fprintln(apdbg.Err(), "err2 cerr2")
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test content
test2 content2`)
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer reset on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprint(apdbg.Out(), "test content")
			So(apdbg.OutString(), ShouldEqual, `test content`)
			fmt.Fprint(apdbg.Err(), "err1 cerr")
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr`)
			apdbg.ResetIOs()
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(apdbg.Err(), "err2 cerr2")
			So(apdbg.ErrString(), ShouldEqual, `err2 cerr2`)
		})
	})

	SkipConvey("Test pdbg print functions", t, func() {
		Convey("Test pdbg print with global instance", func() {
			SetBuffers(nil)
			Pdbgf("test")
			So(ErrString(), ShouldEqual,
				`[func.012:96]
  test
`)
			ResetIOs()
			prbgtest()
			So(ErrString(), ShouldEqual,
				` [prbgtest:4] (func.012:102)
   prbgtest content
`)
		})

		Convey("Test pdbg print with custom instance", func() {
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test2")
			So(apdbg.ErrString(), ShouldEqual,
				`[func.013:111]
  test2
`)
			apdbg.ResetIOs()
			prbgtestCustom(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				` [prbgtestCustom:8] (func.013:117)
   prbgtest content2
`)
			apdbg.ResetIOs()
			apdbg.pdbgTestInstance()
			So(apdbg.ErrString(), ShouldEqual,
				` [*Pdbg.pdbgTestInstance:12] (func.013:123)
   pdbgTestInstance content3
`)
		})
		Convey("Test pdbg prints nothing if runtime.Caller fails", func() {
			mycaller = failCaller
			apdbg := NewPdbg(SetBuffers)
			apdbg.Pdbgf("test fail")
			So(apdbg.ErrString(), ShouldEqual, `  test fail
`)
			mycaller = runtime.Caller
		})
	})

	Convey("Test pdbg excludes functions", t, func() {
		Convey("Test pdbg exclude with global instance", func() {
			SetBuffers(nil)
			pdbg.SetExcludes([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				`  [globalPdbgExcludeTest:16] (func.016:143)
    calling no
      [globalCNo:26] (globalPdbgExcludeTest:17) (func.016:143)
        gcalled2
`)
		})
		Convey("Test pdbg exclude with custom instance", func() {
			apdbg := NewPdbg(SetBuffers, OptExcludes([]string{"customNo"}))
			customPdbgExcludeTest(apdbg)
			So(apdbg.ErrString(), ShouldEqual,
				`  [customPdbgExcludeTest:30] (func.017:153)
    calling cno
      [customCNo:40] (customPdbgExcludeTest:31) (func.017:153)
        ccalled2
`)
		})
	})

	SkipConvey("Test pdbg skips functions", t, func() {
		Convey("Test pdbg skip with global instance", func() {
			SetBuffers(nil)
			pdbg.SetSkips([]string{"globalNo"})
			globalPdbgExcludeTest()
			So(ErrString(), ShouldEqual,
				`  [globalPdbgExcludeTest:16] (func.019:167)
    calling no
    [globalPdbgExcludeTest:17] (func.019:167)
      gcalled1
      [globalCNo:26] (globalPdbgExcludeTest:17) (func.019:167)
        gcalled2
`)
		})
	})
}

func failCaller(skip int) (pc uintptr, file string, line int, ok bool) {
	return 0, "fail", skip, false
}
<|endoftext|>


<commit_before>package godbg

import (
	"fmt"
	"os"
	"testing"
	. "github.com/smartystreets/goconvey/convey"
)

func TestProject(t *testing.T) {
	Convey("Test buffers", t, func() {

		Convey("By Default, equals to std", func() {
			So(Out(), ShouldEqual, os.Stdout)
			So(Err(), ShouldEqual, os.Stderr)
		})
		Convey("When set to buffer, no longer equals to std", func() {
			SetBuffers(nil)
			So(Out(), ShouldNotEqual, os.Stdout)
			So(Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance buffer equals to std", func() {
			apdbg := NewPdbg()
			So(apdbg.Out(), ShouldEqual, os.Stdout)
			So(apdbg.Err(), ShouldEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance set to buffer writes no longer equals to std", func() {
			apdbg := NewPdbg(SetBuffers)
			So(apdbg.Out(), ShouldNotEqual, os.Stdout)
			So(apdbg.Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("Test custom buffer on global pdbg", func() {
			pdbg.bout = nil
			pdbg.sout = nil
			pdbg.berr = nil
			pdbg.serr = nil
			fmt.Fprintln(Out(), "test0 content0")
			So(OutString(), ShouldEqual, ``)
			fmt.Fprintln(Err(), "err0 content0")
			So(ErrString(), ShouldEqual, ``)
			SetBuffers(nil)
			fmt.Fprintln(Out(), "test content")
			fmt.Fprintln(Err(), "err1 cerr")
			fmt.Fprintln(Err(), "err2 cerr2")
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test content
test2 content2`)
			So(ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprintln(apdbg.Out(), "test content")
			fmt.Fprintln(apdbg.Err(), "err1 cerr")
			fmt.Fprintln(apdbg.Err(), "err2 cerr2")
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test content
test2 content2`)
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer reset on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprint(apdbg.Out(), "test content")
			So(apdbg.OutString(), ShouldEqual, `test content`)
			fmt.Fprint(apdbg.Err(), "err1 cerr")
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr`)
			apdbg.ResetIOs()
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(apdbg.Err(), "err2 cerr2")
			So(apdbg.ErrString(), ShouldEqual, `err2 cerr2`)
		})
	})

	Convey("Test pdbg print functions", t, func() {
		Convey("Test pdbg print with global instance", func() {
			Pdbgf("test")
		})
	})
}
<commit_msg>First Pdbgf test<commit_after>package godbg

import (
	"fmt"
	"os"
	"testing"
	. "github.com/smartystreets/goconvey/convey"
)

func TestProject(t *testing.T) {
	Convey("Test buffers", t, func() {

		Convey("By Default, equals to std", func() {
			So(Out(), ShouldEqual, os.Stdout)
			So(Err(), ShouldEqual, os.Stderr)
		})
		Convey("When set to buffer, no longer equals to std", func() {
			SetBuffers(nil)
			So(Out(), ShouldNotEqual, os.Stdout)
			So(Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance buffer equals to std", func() {
			apdbg := NewPdbg()
			So(apdbg.Out(), ShouldEqual, os.Stdout)
			So(apdbg.Err(), ShouldEqual, os.Stderr)
		})
		Convey("By Default, a new pdbg instance set to buffer writes no longer equals to std", func() {
			apdbg := NewPdbg(SetBuffers)
			So(apdbg.Out(), ShouldNotEqual, os.Stdout)
			So(apdbg.Err(), ShouldNotEqual, os.Stderr)
		})
		Convey("Test custom buffer on global pdbg", func() {
			pdbg.bout = nil
			pdbg.sout = nil
			pdbg.berr = nil
			pdbg.serr = nil
			fmt.Fprintln(Out(), "test0 content0")
			So(OutString(), ShouldEqual, ``)
			fmt.Fprintln(Err(), "err0 content0")
			So(ErrString(), ShouldEqual, ``)
			SetBuffers(nil)
			fmt.Fprintln(Out(), "test content")
			fmt.Fprintln(Err(), "err1 cerr")
			fmt.Fprintln(Err(), "err2 cerr2")
			fmt.Fprint(Out(), "test2 content2")
			So(OutString(), ShouldEqual, `test content
test2 content2`)
			So(ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprintln(apdbg.Out(), "test content")
			fmt.Fprintln(apdbg.Err(), "err1 cerr")
			fmt.Fprintln(apdbg.Err(), "err2 cerr2")
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test content
test2 content2`)
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr
err2 cerr2
`)
		})
		Convey("Test custom buffer reset on custom pdbg", func() {
			apdbg := NewPdbg(SetBuffers)
			fmt.Fprint(apdbg.Out(), "test content")
			So(apdbg.OutString(), ShouldEqual, `test content`)
			fmt.Fprint(apdbg.Err(), "err1 cerr")
			So(apdbg.ErrString(), ShouldEqual, `err1 cerr`)
			apdbg.ResetIOs()
			fmt.Fprint(apdbg.Out(), "test2 content2")
			So(apdbg.OutString(), ShouldEqual, `test2 content2`)
			fmt.Fprint(apdbg.Err(), "err2 cerr2")
			So(apdbg.ErrString(), ShouldEqual, `err2 cerr2`)
		})
	})

	Convey("Test pdbg print functions", t, func() {
		Convey("Test pdbg print with global instance", func() {
			SetBuffers(nil)
			Pdbgf("test")
			So(ErrString(), ShouldEqual, `[func.009:81]
  test
`)
		})
	})
}
<|endoftext|>


<commit_before>//example to demonstrate reading query parameters using net/http library
<commit_msg>Update read-query-paramTODO.go<commit_after>//example to demonstrate reading query parameters using net/http library. example: https://localhost:8080/customer?country=usa
//TODO: need to run and test
package main

import (
  "net/http"
)

func HandleActivitiesGet(w http.ResponseWriter, r *http.Request) {
  vars, err := url.ParseQuery(r.URL.RawQuery)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
	}

  country := ""
	if val, exists := vars["country"]; exists {
		country = val[0]
	}
  fmt.Fprintln(w, country)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"log"
	"os"

	"github.com/cubicdaiya/gonp"
)

func getLines(f string) ([]string, error) {
	fp, err := os.Open(f)
	if err != nil {
		return []string{}, err
	}
	defer fp.Close()

	scanner := bufio.NewScanner(fp)
	lines := make([]string, 0)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, nil
}

func main() {
	if len(os.Args) < 3 {
		log.Fatal("./unifilediff filename11 filename2")
	}

	f1 := os.Args[1]
	f2 := os.Args[2]

	var (
		a   []string
		b   []string
		err error
	)

	a, err = getLines(f1)
	if err != nil {
		log.Fatalf("%s: %s", f1, err)
	}

	b, err = getLines(f2)
	if err != nil {
		log.Fatalf("%s: %s", f2, err)
	}

	diff := gonp.New(a, b)
	diff.Compose()
	diff.PrintUniHunks(diff.UnifiedHunks())
}
<commit_msg>typo fixed.<commit_after>package main

import (
	"bufio"
	"log"
	"os"

	"github.com/cubicdaiya/gonp"
)

func getLines(f string) ([]string, error) {
	fp, err := os.Open(f)
	if err != nil {
		return []string{}, err
	}
	defer fp.Close()

	scanner := bufio.NewScanner(fp)
	lines := make([]string, 0)
	for scanner.Scan() {
		lines = append(lines, scanner.Text())
	}
	return lines, nil
}

func main() {
	if len(os.Args) < 3 {
		log.Fatal("./unifilediff filename1 filename2")
	}

	f1 := os.Args[1]
	f2 := os.Args[2]

	var (
		a   []string
		b   []string
		err error
	)

	a, err = getLines(f1)
	if err != nil {
		log.Fatalf("%s: %s", f1, err)
	}

	b, err = getLines(f2)
	if err != nil {
		log.Fatalf("%s: %s", f2, err)
	}

	diff := gonp.New(a, b)
	diff.Compose()
	diff.PrintUniHunks(diff.UnifiedHunks())
}
<|endoftext|>


<commit_before>// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

package main

import (
	"fmt"

	"github.com/go-vgo/robotgo"
	// "go-vgo/robotgo"
)

func window() {
	////////////////////////////////////////////////////////////////////////////////
	// Window Handle
	////////////////////////////////////////////////////////////////////////////////

	// show Alert Window
	abool := robotgo.ShowAlert("hello", "robotgo")
	if abool == 0 {
		fmt.Println("ok@@@", "ok")
	}
	robotgo.ShowAlert("hello", "robotgo", "Ok", "Cancel")

	// get the current process id
	pid := robotgo.GetPID()
	fmt.Println("pid----", pid)

	// get current Window Active
	mdata := robotgo.GetActive()

	// get current Window Handle
	hwnd := robotgo.GetHandle()
	fmt.Println("hwnd---", hwnd)

	// get current Window Handle
	bhwnd := robotgo.GetBHandle()
	fmt.Println("bhwnd---", bhwnd)

	// get current Window title
	title := robotgo.GetTitle()
	fmt.Println("title-----", title)

	// set Window Active
	robotgo.SetActive(mdata)

	// find the process id by the process name
	fpid, err := robotgo.FindIds("Google")
	if err == nil {
		fmt.Println("pids...", fpid)
		if len(fpid) > 0 {
			robotgo.ActivePID(fpid[0])

			tl := robotgo.GetTitle(fpid[0])
			fmt.Println("pid[0] title is: ", tl)

			x, y, w, h := robotgo.GetBounds(fpid[0])
			fmt.Println("GetBounds is: ", x, y, w, h)

			// Windows
			// hwnd := robotgo.FindWindow("google")
			// hwnd := robotgo.GetHWND()
			robotgo.MinWindow(fpid[0])
			robotgo.MaxWindow(fpid[0])
			robotgo.CloseWindow(fpid[0])

			robotgo.Kill(fpid[0])
		}
	}

	robotgo.ActiveName("chrome")

	// determine whether the process exists
	isExist, err := robotgo.PidExists(100)
	if err == nil && isExist {
		fmt.Println("pid exists is", isExist)

		robotgo.Kill(100)
	}

	// get the all process id
	pids, err := robotgo.Pids()
	if err == nil {
		fmt.Println("pids: ", pids)
	}

	// find the process name by the process id
	name, err := robotgo.FindName(100)
	if err == nil {
		fmt.Println("name: ", name)
	}

	// find the all process name
	names, err := robotgo.FindNames()
	if err == nil {
		fmt.Println("name: ", names)
	}

	// get the all process struct
	ps, err := robotgo.Process()
	if err == nil {
		fmt.Println("process: ", ps)
	}

	// close current Window
	robotgo.CloseWindow()
}

func main() {
	window()
}
<commit_msg>Refactoring window example code<commit_after>// Copyright 2016 The go-vgo Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// https://github.com/go-vgo/robotgo/blob/master/LICENSE
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

package main

import (
	"fmt"

	"github.com/go-vgo/robotgo"
	// "go-vgo/robotgo"
)

func alert() {
	// show Alert Window
	abool := robotgo.ShowAlert("hello", "robotgo")
	if abool == 0 {
		fmt.Println("ok@@@", "ok")
	}
	robotgo.ShowAlert("hello", "robotgo", "Ok", "Cancel")

}

func get() {
	// get the current process id
	pid := robotgo.GetPID()
	fmt.Println("pid----", pid)

	// get current Window Active
	mdata := robotgo.GetActive()

	// get current Window Handle
	hwnd := robotgo.GetHandle()
	fmt.Println("hwnd---", hwnd)

	// get current Window Handle
	bhwnd := robotgo.GetBHandle()
	fmt.Println("bhwnd---", bhwnd)

	// get current Window title
	title := robotgo.GetTitle()
	fmt.Println("title-----", title)

	// set Window Active
	robotgo.SetActive(mdata)
}

func findIds() {
	// find the process id by the process name
	fpid, err := robotgo.FindIds("Google")
	if err == nil {
		fmt.Println("pids...", fpid)
		if len(fpid) > 0 {
			robotgo.ActivePID(fpid[0])

			tl := robotgo.GetTitle(fpid[0])
			fmt.Println("pid[0] title is: ", tl)

			x, y, w, h := robotgo.GetBounds(fpid[0])
			fmt.Println("GetBounds is: ", x, y, w, h)

			// Windows
			// hwnd := robotgo.FindWindow("google")
			// hwnd := robotgo.GetHWND()
			robotgo.MinWindow(fpid[0])
			robotgo.MaxWindow(fpid[0])
			robotgo.CloseWindow(fpid[0])

			robotgo.Kill(fpid[0])
		}
	}
}

func findName() {
	// find the process name by the process id
	name, err := robotgo.FindName(100)
	if err == nil {
		fmt.Println("name: ", name)
	}

	// find the all process name
	names, err := robotgo.FindNames()
	if err == nil {
		fmt.Println("name: ", names)
	}
}

func ps() {
	// determine whether the process exists
	isExist, err := robotgo.PidExists(100)
	if err == nil && isExist {
		fmt.Println("pid exists is", isExist)

		robotgo.Kill(100)
	}

	// get the all process id
	pids, err := robotgo.Pids()
	if err == nil {
		fmt.Println("pids: ", pids)
	}

	// get the all process struct
	ps, err := robotgo.Process()
	if err == nil {
		fmt.Println("process: ", ps)
	}
}

func window() {
	////////////////////////////////////////////////////////////////////////////////
	// Window Handle
	////////////////////////////////////////////////////////////////////////////////

	alert()

	get()

	findIds()

	robotgo.ActiveName("chrome")

	findName()

	ps()

	// close current Window
	robotgo.CloseWindow()
}

func main() {
	window()
}
<|endoftext|>


<commit_before>package jsonpointer

import (
	"errors"
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/dustin/gojson"
)

var unparsable = errors.New("I can't parse this")

func arreq(a, b []string) bool {
	if len(a) == len(b) {
		for i := range a {
			if a[i] != b[i] {
				return false
			}
		}
		return true
	}

	return false
}

var decoder = strings.NewReplacer("~1", "/", "~0", "~")

func parsePointer(s string) []string {
	a := strings.Split(s[1:], "/")

	for i := range a {
		if strings.Contains(a[i], "~") {
			a[i] = decoder.Replace(a[i])
		}
	}
	return a
}

func encodePointer(p []string) string {
	out := make([]rune, 0, 64)

	for _, s := range p {
		out = append(out, '/')
		for _, c := range s {
			switch c {
			case '/':
				out = append(out, '~', '1')
			case '~':
				out = append(out, '~', '0')
			default:
				out = append(out, c)
			}
		}
	}
	return string(out)
}

func grokLiteral(b []byte) string {
	s, ok := json.UnquoteBytes(b)
	if !ok {
		panic("could not grok literal " + string(b))
	}
	return string(s)
}

func isSpace(c rune) bool {
	return c == ' ' || c == '\t' || c == '\r' || c == '\n'
}

// Find an object by JSONPointer path.  Decode result.  Errors if a
// properly formatted JSON document can't be found at the given path.
func FindDecode(data []byte, path string, into interface{}) error {
	d, err := Find(data, path)
	if err != nil {
		return err
	}
	return json.Unmarshal(d, into)
}

// Find a section of raw JSON by specifying a JSONPointer.
func Find(data []byte, path string) ([]byte, error) {
	if path == "" {
		return data, nil
	}

	needle := parsePointer(path)

	scan := &json.Scanner{}
	scan.Reset()

	offset := 0
	beganLiteral := 0
	current := []string{}
	for {
		if offset >= len(data) {
			break
		}
		newOp := scan.Step(scan, int(data[offset]))
		offset++

		switch newOp {
		case json.ScanBeginArray:
			current = append(current, "0")
		case json.ScanObjectKey:
			current = append(current, grokLiteral(data[beganLiteral-1:offset-1]))
		case json.ScanBeginLiteral:
			beganLiteral = offset
		case json.ScanArrayValue:
			n := mustParseInt(current[len(current)-1])
			current[len(current)-1] = strconv.Itoa(n + 1)
		case json.ScanObjectValue, json.ScanEndArray, json.ScanEndObject:
			current = sliceToEnd(current)
		case json.ScanContinue, json.ScanSkipSpace,
			json.ScanBeginObject, json.ScanEnd:
		default:
			return nil, fmt.Errorf("Found unhandled json op: %v", newOp)
		}

		if (newOp == json.ScanBeginArray || newOp == json.ScanArrayValue ||
			newOp == json.ScanObjectKey) && arreq(needle, current) {
			otmp := offset
			for isSpace(rune(data[otmp])) {
				otmp++
			}
			if data[otmp] == ']' {
				// special case an array offset miss
				offset = otmp
				return nil, nil
			}
			val, _, err := json.NextValue(data[offset:], scan)
			return val, err
		}
	}

	return nil, nil
}

func sliceToEnd(s []string) []string {
	end := len(s) - 1
	if end >= 0 {
		s = s[:end]
	}
	return s

}

func mustParseInt(s string) int {
	n, err := strconv.Atoi(s)
	if err == nil {
		return n
	}
	panic(err)
}

// List all possible pointers from the given input.
func ListPointers(data []byte) ([]string, error) {
	rv := []string{""}

	scan := &json.Scanner{}
	scan.Reset()

	offset := 0
	beganLiteral := 0
	var current []string
	for {
		if offset >= len(data) {
			break
		}
		newOp := scan.Step(scan, int(data[offset]))
		offset++

		switch newOp {
		case json.ScanBeginArray:
			current = append(current, "0")
		case json.ScanObjectKey:
			current = append(current, grokLiteral(data[beganLiteral-1:offset-1]))
		case json.ScanBeginLiteral:
			beganLiteral = offset
		case json.ScanArrayValue:
			n := mustParseInt(current[len(current)-1])
			current[len(current)-1] = strconv.Itoa(n + 1)
		case json.ScanObjectValue, json.ScanEndArray, json.ScanEndObject:
			current = sliceToEnd(current)
		}

		if newOp == json.ScanBeginArray || newOp == json.ScanArrayValue ||
			newOp == json.ScanObjectKey {
			rv = append(rv, encodePointer(current))
		}
	}

	return rv, nil
}

// Find a section of raw JSON by specifying a JSONPointer.
func FindMany(data []byte, paths []string) (map[string][]byte, error) {
	tpaths := make([]string, 0, len(paths))
	m := map[string][]byte{}
	for _, p := range paths {
		if p == "" {
			m[p] = data
		} else {
			tpaths = append(tpaths, p)
		}
	}
	sort.Strings(tpaths)

	scan := &json.Scanner{}
	scan.Reset()

	offset := 0
	todo := len(tpaths)
	beganLiteral := 0
	matchedAt := 0
	var current []string
	for todo > 0 {
		if offset >= len(data) {
			break
		}
		newOp := scan.Step(scan, int(data[offset]))
		offset++

		switch newOp {
		case json.ScanBeginArray:
			current = append(current, "0")
		case json.ScanObjectKey:
			current = append(current, grokLiteral(data[beganLiteral-1:offset-1]))
		case json.ScanBeginLiteral:
			beganLiteral = offset
		case json.ScanArrayValue:
			n, err := strconv.Atoi(current[len(current)-1])
			if err != nil {
				return nil, err
			}
			current[len(current)-1] = strconv.Itoa(n + 1)
		case json.ScanObjectValue, json.ScanEndArray, json.ScanEndObject:
			current = current[:len(current)-1]
		}

		if newOp == json.ScanBeginArray || newOp == json.ScanArrayValue ||
			newOp == json.ScanObjectKey {

			if matchedAt < len(current)-1 {
				continue
			}
			if matchedAt > len(current) {
				matchedAt = len(current)
			}

			currentStr := encodePointer(current)
			off := sort.SearchStrings(tpaths, currentStr)
			if off < len(tpaths) {
				// Check to see if the path we're
				// going down could even lead to a
				// possible match.
				if strings.HasPrefix(tpaths[off], currentStr) {
					matchedAt++
				}
				// And if it's not an exact match, keep parsing.
				if tpaths[off] != currentStr {
					continue
				}
			} else {
				// Fell of the end of the list, no possible match
				continue
			}

			// At this point, we have an exact match, so grab it.
			stmp := &json.Scanner{}
			val, _, err := json.NextValue(data[offset:], stmp)
			if err != nil {
				return m, err
			}
			m[currentStr] = val
			todo--
		}
	}

	return m, nil
}
<commit_msg>Use mustParseInt where I'm making my own ints<commit_after>package jsonpointer

import (
	"errors"
	"fmt"
	"sort"
	"strconv"
	"strings"

	"github.com/dustin/gojson"
)

var unparsable = errors.New("I can't parse this")

func arreq(a, b []string) bool {
	if len(a) == len(b) {
		for i := range a {
			if a[i] != b[i] {
				return false
			}
		}
		return true
	}

	return false
}

var decoder = strings.NewReplacer("~1", "/", "~0", "~")

func parsePointer(s string) []string {
	a := strings.Split(s[1:], "/")

	for i := range a {
		if strings.Contains(a[i], "~") {
			a[i] = decoder.Replace(a[i])
		}
	}
	return a
}

func encodePointer(p []string) string {
	out := make([]rune, 0, 64)

	for _, s := range p {
		out = append(out, '/')
		for _, c := range s {
			switch c {
			case '/':
				out = append(out, '~', '1')
			case '~':
				out = append(out, '~', '0')
			default:
				out = append(out, c)
			}
		}
	}
	return string(out)
}

func grokLiteral(b []byte) string {
	s, ok := json.UnquoteBytes(b)
	if !ok {
		panic("could not grok literal " + string(b))
	}
	return string(s)
}

func isSpace(c rune) bool {
	return c == ' ' || c == '\t' || c == '\r' || c == '\n'
}

// Find an object by JSONPointer path.  Decode result.  Errors if a
// properly formatted JSON document can't be found at the given path.
func FindDecode(data []byte, path string, into interface{}) error {
	d, err := Find(data, path)
	if err != nil {
		return err
	}
	return json.Unmarshal(d, into)
}

// Find a section of raw JSON by specifying a JSONPointer.
func Find(data []byte, path string) ([]byte, error) {
	if path == "" {
		return data, nil
	}

	needle := parsePointer(path)

	scan := &json.Scanner{}
	scan.Reset()

	offset := 0
	beganLiteral := 0
	current := []string{}
	for {
		if offset >= len(data) {
			break
		}
		newOp := scan.Step(scan, int(data[offset]))
		offset++

		switch newOp {
		case json.ScanBeginArray:
			current = append(current, "0")
		case json.ScanObjectKey:
			current = append(current, grokLiteral(data[beganLiteral-1:offset-1]))
		case json.ScanBeginLiteral:
			beganLiteral = offset
		case json.ScanArrayValue:
			n := mustParseInt(current[len(current)-1])
			current[len(current)-1] = strconv.Itoa(n + 1)
		case json.ScanObjectValue, json.ScanEndArray, json.ScanEndObject:
			current = sliceToEnd(current)
		case json.ScanContinue, json.ScanSkipSpace,
			json.ScanBeginObject, json.ScanEnd:
		default:
			return nil, fmt.Errorf("Found unhandled json op: %v", newOp)
		}

		if (newOp == json.ScanBeginArray || newOp == json.ScanArrayValue ||
			newOp == json.ScanObjectKey) && arreq(needle, current) {
			otmp := offset
			for isSpace(rune(data[otmp])) {
				otmp++
			}
			if data[otmp] == ']' {
				// special case an array offset miss
				offset = otmp
				return nil, nil
			}
			val, _, err := json.NextValue(data[offset:], scan)
			return val, err
		}
	}

	return nil, nil
}

func sliceToEnd(s []string) []string {
	end := len(s) - 1
	if end >= 0 {
		s = s[:end]
	}
	return s

}

func mustParseInt(s string) int {
	n, err := strconv.Atoi(s)
	if err == nil {
		return n
	}
	panic(err)
}

// List all possible pointers from the given input.
func ListPointers(data []byte) ([]string, error) {
	rv := []string{""}

	scan := &json.Scanner{}
	scan.Reset()

	offset := 0
	beganLiteral := 0
	var current []string
	for {
		if offset >= len(data) {
			break
		}
		newOp := scan.Step(scan, int(data[offset]))
		offset++

		switch newOp {
		case json.ScanBeginArray:
			current = append(current, "0")
		case json.ScanObjectKey:
			current = append(current, grokLiteral(data[beganLiteral-1:offset-1]))
		case json.ScanBeginLiteral:
			beganLiteral = offset
		case json.ScanArrayValue:
			n := mustParseInt(current[len(current)-1])
			current[len(current)-1] = strconv.Itoa(n + 1)
		case json.ScanObjectValue, json.ScanEndArray, json.ScanEndObject:
			current = sliceToEnd(current)
		}

		if newOp == json.ScanBeginArray || newOp == json.ScanArrayValue ||
			newOp == json.ScanObjectKey {
			rv = append(rv, encodePointer(current))
		}
	}

	return rv, nil
}

// Find a section of raw JSON by specifying a JSONPointer.
func FindMany(data []byte, paths []string) (map[string][]byte, error) {
	tpaths := make([]string, 0, len(paths))
	m := map[string][]byte{}
	for _, p := range paths {
		if p == "" {
			m[p] = data
		} else {
			tpaths = append(tpaths, p)
		}
	}
	sort.Strings(tpaths)

	scan := &json.Scanner{}
	scan.Reset()

	offset := 0
	todo := len(tpaths)
	beganLiteral := 0
	matchedAt := 0
	var current []string
	for todo > 0 {
		if offset >= len(data) {
			break
		}
		newOp := scan.Step(scan, int(data[offset]))
		offset++

		switch newOp {
		case json.ScanBeginArray:
			current = append(current, "0")
		case json.ScanObjectKey:
			current = append(current, grokLiteral(data[beganLiteral-1:offset-1]))
		case json.ScanBeginLiteral:
			beganLiteral = offset
		case json.ScanArrayValue:
			n := mustParseInt(current[len(current)-1])
			current[len(current)-1] = strconv.Itoa(n + 1)
		case json.ScanObjectValue, json.ScanEndArray, json.ScanEndObject:
			current = current[:len(current)-1]
		}

		if newOp == json.ScanBeginArray || newOp == json.ScanArrayValue ||
			newOp == json.ScanObjectKey {

			if matchedAt < len(current)-1 {
				continue
			}
			if matchedAt > len(current) {
				matchedAt = len(current)
			}

			currentStr := encodePointer(current)
			off := sort.SearchStrings(tpaths, currentStr)
			if off < len(tpaths) {
				// Check to see if the path we're
				// going down could even lead to a
				// possible match.
				if strings.HasPrefix(tpaths[off], currentStr) {
					matchedAt++
				}
				// And if it's not an exact match, keep parsing.
				if tpaths[off] != currentStr {
					continue
				}
			} else {
				// Fell of the end of the list, no possible match
				continue
			}

			// At this point, we have an exact match, so grab it.
			stmp := &json.Scanner{}
			val, _, err := json.NextValue(data[offset:], stmp)
			if err != nil {
				return m, err
			}
			m[currentStr] = val
			todo--
		}
	}

	return m, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/garyburd/redigo/redis"
)

const prefix = "genproxy:"

type Cache struct {
	pool   *redis.Pool
	prefix string
}

// set records a key in cache (redis)
func (c *Cache) set(key string, value interface{}) error {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("SET", fmt.Sprintf(c.prefix+key), value)

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to SET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key/value SET successfuly!")
	}

	return err
}

// get returns key from cache
func (c *Cache) get(key string) (interface{}, error) {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	value, err := client.Do("GET", fmt.Sprintf(c.prefix+key))

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to GET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key found!")
	}

	return value, err
}

// getRedisPool returns thread safe Redis connection pool
func getRedisPool() *redis.Pool {

	// getting redis connection
	maxConnections := 10
	mc := os.Getenv("MaxConnections")
	if mc != "" {
		maxCons, err := strconv.Atoi(mc)
		if err != nil {
			maxConnections = 10
		} else {
			maxConnections = maxCons
		}
	}
	// getting redis client for state storing
	redisPool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", AppConfig.redisAddress)

		if err != nil {
			log.WithFields(log.Fields{"Error": err.Error()}).Panic("Failed to create Redis connection pool!")
			return nil, err
		}
		if AppConfig.redisPassword != "" {
			if _, err := c.Do("AUTH", AppConfig.redisPassword); err != nil {
				log.WithFields(log.Fields{
					"Error":        err.Error(),
					"PasswordUsed": AppConfig.redisPassword,
				}).Panic("Failed to authenticate to Redis!")
				c.Close()
				return nil, err
			} else {
				log.Info("Authenticated to Redis successfully! ")
			}
		}

		return c, err
	}, maxConnections)

	return redisPool
}
<commit_msg>get all keys function<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/garyburd/redigo/redis"
)

const prefix = "genproxy:"

type Cache struct {
	pool   *redis.Pool
	prefix string
}

// set records a key in cache (redis)
func (c *Cache) set(key string, value interface{}) error {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("SET", fmt.Sprintf(c.prefix+key), value)

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to SET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key/value SET successfuly!")
	}

	return err
}

// getAllKeys returns all keys for specified (or default) prefix
func (c *Cache) getAllKeys() ([]string, error) {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	values, err := redis.Strings(client.Do("KEYS", "genproxy_test:*"))

	return values, err
}
// get returns key from cache
func (c *Cache) get(key string) (interface{}, error) {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	value, err := client.Do("GET", fmt.Sprintf(c.prefix+key))

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to GET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key found!")
	}

	return value, err
}

// getRedisPool returns thread safe Redis connection pool
func getRedisPool() *redis.Pool {

	// getting redis connection
	maxConnections := 10
	mc := os.Getenv("MaxConnections")
	if mc != "" {
		maxCons, err := strconv.Atoi(mc)
		if err != nil {
			maxConnections = 10
		} else {
			maxConnections = maxCons
		}
	}
	// getting redis client for state storing
	redisPool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", AppConfig.redisAddress)

		if err != nil {
			log.WithFields(log.Fields{"Error": err.Error()}).Panic("Failed to create Redis connection pool!")
			return nil, err
		}
		if AppConfig.redisPassword != "" {
			if _, err := c.Do("AUTH", AppConfig.redisPassword); err != nil {
				log.WithFields(log.Fields{
					"Error":        err.Error(),
					"PasswordUsed": AppConfig.redisPassword,
				}).Panic("Failed to authenticate to Redis!")
				c.Close()
				return nil, err
			} else {
				log.Info("Authenticated to Redis successfully! ")
			}
		}

		return c, err
	}, maxConnections)

	return redisPool
}
<|endoftext|>


<commit_before>package sarah

import (
	"fmt"
	"github.com/patrickmn/go-cache"
	"time"
)

type CacheConfig struct {
	ExpiresIn       time.Duration
	CleanupInterval time.Duration
}

func NewCacheConfig() *CacheConfig {
	return &CacheConfig{
		ExpiresIn:       3 * time.Minute,
		CleanupInterval: 10 * time.Minute,
	}
}

type UserContext struct {
	Next ContextualFunc
}

func NewUserContext(next ContextualFunc) *UserContext {
	return &UserContext{
		Next: next,
	}
}

type UserContexts interface {
	Get(string) (*UserContext, error)
	Set(string, *UserContext)
	Delete(string)
	Flush()
}

type CachedUserContexts struct {
	cache *cache.Cache
}

func NewCachedUserContexts(config *CacheConfig) UserContexts {
	return &CachedUserContexts{
		cache: cache.New(config.ExpiresIn, config.CleanupInterval),
	}
}

func (contexts *CachedUserContexts) Get(key string) (*UserContext, error) {
	val, hasKey := contexts.cache.Get(key)
	if !hasKey || val == nil {
		return nil, nil
	}

	switch v := val.(type) {
	case *UserContext:
		return v, nil
	default:
		return nil, fmt.Errorf("cached value has illegal type of %T", v)
	}
}

func (contexts *CachedUserContexts) Delete(key string) {
	contexts.cache.Delete(key)
}

func (contexts *CachedUserContexts) Set(key string, userContext *UserContext) {
	contexts.cache.Set(key, userContext, cache.DefaultExpiration)
}

func (contexts *CachedUserContexts) Flush() {
	contexts.cache.Flush()
}
<commit_msg>Cache config is now JSON/YAML unmarshalable<commit_after>package sarah

import (
	"fmt"
	"github.com/patrickmn/go-cache"
	"time"
)

type CacheConfig struct {
	ExpiresIn       time.Duration `json:"expires_in" yaml:"expires_in"`
	CleanupInterval time.Duration `json:"cleanup_interval" yaml:"cleanup_interval"`
}

func NewCacheConfig() *CacheConfig {
	return &CacheConfig{
		ExpiresIn:       3 * time.Minute,
		CleanupInterval: 10 * time.Minute,
	}
}

type UserContext struct {
	Next ContextualFunc
}

func NewUserContext(next ContextualFunc) *UserContext {
	return &UserContext{
		Next: next,
	}
}

type UserContexts interface {
	Get(string) (*UserContext, error)
	Set(string, *UserContext)
	Delete(string)
	Flush()
}

type CachedUserContexts struct {
	cache *cache.Cache
}

func NewCachedUserContexts(config *CacheConfig) UserContexts {
	return &CachedUserContexts{
		cache: cache.New(config.ExpiresIn, config.CleanupInterval),
	}
}

func (contexts *CachedUserContexts) Get(key string) (*UserContext, error) {
	val, hasKey := contexts.cache.Get(key)
	if !hasKey || val == nil {
		return nil, nil
	}

	switch v := val.(type) {
	case *UserContext:
		return v, nil
	default:
		return nil, fmt.Errorf("cached value has illegal type of %T", v)
	}
}

func (contexts *CachedUserContexts) Delete(key string) {
	contexts.cache.Delete(key)
}

func (contexts *CachedUserContexts) Set(key string, userContext *UserContext) {
	contexts.cache.Set(key, userContext, cache.DefaultExpiration)
}

func (contexts *CachedUserContexts) Flush() {
	contexts.cache.Flush()
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"os"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/garyburd/redigo/redis"
)

const prefix = "genproxy:"

type Cache struct {
	pool   *redis.Pool
	prefix string
}

// set records a key in cache (redis)
func (c *Cache) set(key string, value interface{}) error {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("SET", fmt.Sprintf(c.prefix+key), value)

	if err != nil {
		// getting payload for debugging
		var payload string
		switch v := value.(type) {
		case bytes.Buffer: // return as is
			payload = v.String() // Here v is of type bytes.Buffer
		}
		log.WithFields(log.Fields{
			"error":   err.Error(),
			"key":     fmt.Sprintf(c.prefix + key),
			"payload": payload,
		}).Error("Failed to SET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key/value SET successfuly!")
	}

	return err
}

// getAllKeys returns all keys for specified (or default) prefix
func (c *Cache) getAllKeys() ([]string, error) {

	client := c.pool.Get()
	defer client.Close()

	values, err := redis.Strings(client.Do("KEYS", fmt.Sprintf(c.prefix+"*")))

	return values, err
}

// getAllValues returns values for specified keys
func (c *Cache) getAllValues(keys []string) ([]string, error) {

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Getting all supplied values")

	client := c.pool.Get()
	defer client.Close()

	// preparing keys
	var args []interface{}
	for _, k := range keys {
		args = append(args, k)
	}

	jsonStr, err := redis.Strings(client.Do("MGET", args...))

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Returning supplied values")

	return jsonStr, err

}

// get returns key from cache
func (c *Cache) get(key string) (interface{}, error) {

	client := c.pool.Get()
	defer client.Close()

	value, err := client.Do("GET", fmt.Sprintf(c.prefix+key))

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to GET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Debug("Key found!")
	}

	return value, err
}

// delete removes specified entry from cache
func (c *Cache) delete(key string) error {
	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("DEL", key)

	return err

}

// getRedisPool returns thread safe Redis connection pool
func getRedisPool() *redis.Pool {

	// getting redis connection
	maxConnections := 10
	mc := os.Getenv("MaxConnections")
	if mc != "" {
		maxCons, err := strconv.Atoi(mc)
		if err != nil {
			maxConnections = 10
		} else {
			maxConnections = maxCons
		}
	}

	// getting redis client for state storing
	redisPool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", AppConfig.redisAddress)

		if err != nil {
			log.WithFields(log.Fields{
				"Error": err.Error(),
			}).Warn("Failed to create Redis connection pool!")
			return nil, err
		}
		if AppConfig.redisPassword != "" {
			if _, err := c.Do("AUTH", AppConfig.redisPassword); err != nil {
				log.WithFields(log.Fields{
					"Error":        err.Error(),
					"PasswordUsed": AppConfig.redisPassword,
				}).Warn("Failed to authenticate to Redis!")
				c.Close()
				return nil, err
			} else {
				log.Debug("Authenticated to Redis successfully! ")
			}
		}

		return c, err
	}, maxConnections)

	return redisPool
}
<commit_msg>returning bytes for all get calls<commit_after>// redis cache backend implementation for persistent storage

package main

import (
	"bytes"
	"fmt"
	"os"
	"strconv"

	log "github.com/Sirupsen/logrus"
	"github.com/garyburd/redigo/redis"
)

const prefix = "genproxy:"

type Cache struct {
	pool   *redis.Pool
	prefix string
}

// set records a key in cache (redis)
func (c *Cache) set(key string, value interface{}) error {

	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("SET", fmt.Sprintf(c.prefix+key), value)

	if err != nil {
		// getting payload for debugging
		var payload string
		switch v := value.(type) {
		case bytes.Buffer: // return as is
			payload = v.String() // Here v is of type bytes.Buffer
		}
		log.WithFields(log.Fields{
			"error":   err.Error(),
			"key":     fmt.Sprintf(c.prefix + key),
			"payload": payload,
		}).Error("Failed to SET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Info("Key/value SET successfuly!")
	}

	return err
}

// getAllKeys returns all keys for specified (or default) prefix
func (c *Cache) getAllKeys() ([]string, error) {

	client := c.pool.Get()
	defer client.Close()

	values, err := redis.Strings(client.Do("KEYS", fmt.Sprintf(c.prefix+"*")))

	return values, err
}

// getAllValues returns values for specified keys
func (c *Cache) getAllValues(keys []string) ([]string, error) {

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Getting all supplied values")

	client := c.pool.Get()
	defer client.Close()

	// preparing keys
	var args []interface{}
	for _, k := range keys {
		args = append(args, k)
	}

	jsonStr, err := redis.Strings(client.Do("MGET", args...))

	log.WithFields(log.Fields{
		"keys": keys,
	}).Debug("Returning supplied values")

	return jsonStr, err

}

// get returns key from cache
func (c *Cache) get(key string) ([]byte, error) {

	client := c.pool.Get()
	defer client.Close()

	value, err := redis.Bytes(client.Do("GET", fmt.Sprintf(c.prefix+key)))

	if err != nil {
		log.WithFields(log.Fields{
			"error": err.Error(),
			"key":   fmt.Sprintf(c.prefix + key),
		}).Error("Failed to GET key...")
	} else {
		log.WithFields(log.Fields{
			"key": fmt.Sprintf(c.prefix + key),
		}).Debug("Key found!")
	}

	return value, err
}

// delete removes specified entry from cache
func (c *Cache) delete(key string) error {
	if c.prefix == "" {
		c.prefix = prefix
	}

	client := c.pool.Get()
	defer client.Close()

	_, err := client.Do("DEL", key)

	return err

}

// getRedisPool returns thread safe Redis connection pool
func getRedisPool() *redis.Pool {

	// getting redis connection
	maxConnections := 10
	mc := os.Getenv("MaxConnections")
	if mc != "" {
		maxCons, err := strconv.Atoi(mc)
		if err != nil {
			maxConnections = 10
		} else {
			maxConnections = maxCons
		}
	}

	// getting redis client for state storing
	redisPool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", AppConfig.redisAddress)

		if err != nil {
			log.WithFields(log.Fields{
				"Error": err.Error(),
			}).Warn("Failed to create Redis connection pool!")
			return nil, err
		}
		if AppConfig.redisPassword != "" {
			if _, err := c.Do("AUTH", AppConfig.redisPassword); err != nil {
				log.WithFields(log.Fields{
					"Error":        err.Error(),
					"PasswordUsed": AppConfig.redisPassword,
				}).Warn("Failed to authenticate to Redis!")
				c.Close()
				return nil, err
			} else {
				log.Debug("Authenticated to Redis successfully! ")
			}
		}

		return c, err
	}, maxConnections)

	return redisPool
}
<|endoftext|>


<commit_before>package canstop

import (
	"log"
	"math"
	"runtime"
	"sync"
	"time"
)

type Manageable func(t *Lifecycle) error

type Lifecycle struct {
	wg                  *sync.WaitGroup
	once                *sync.Once
	services            map[chan string]string
	interrupt           chan bool
	serviceRegistration chan chan string
}

func NewLifecycle() *Lifecycle {
	wg := &sync.WaitGroup{}
	wg.Add(1)
	reg := make(chan chan string)
	services := make(map[chan string]string)
	// listen for services registering
	go func() {
		for {
			ch := <-reg
			services[ch] = <-ch
		}
	}()
	return &Lifecycle{wg, &sync.Once{}, services, make(chan bool), reg}
}

func (self *Lifecycle) Session(f Manageable) {
	self.wg.Add(1)
	var err error
	defer func() {
		if r := recover(); r != nil {
			log.Printf("Session ended in panic: %s\n", r)
		}
		if err != nil {
			log.Printf("Session ended in error: %s\n", err)
		}
		self.wg.Done()
	}()
	err = f(self)
}

func loopCalmly(l *Lifecycle, f Manageable, name string) {
	defer func() {
		if r := recover(); r != nil {
			log.Printf("Service %s panicked: %s\n", name, r)
		}
		runtime.Gosched() // break up panic hotloops
	}()
	err := f(l)
	if err != nil {
		log.Printf("Service %s errored: %s\n", name, err)
	}
}

func (self *Lifecycle) Service(f Manageable, name string) {
	// we pass a channel back to the Lifecycle registration goroutine
	// over which we communicate the name of the registering service.
	// closure of this channel is used to indicate clean termination
	imFinished := make(chan string)
	self.serviceRegistration <- imFinished
	imFinished <- name
	self.wg.Add(1)
	defer self.wg.Done()
	defer close(imFinished)
	// services should be restarted if they stop running for any reason
	// hopefully f itself is a loop that is also reading from the interrupt
	// channel; we should only hit the top of this loop on errors/panics
	for !self.IsInterrupted() {
		loopCalmly(self, f, name)
	}
}

func (self *Lifecycle) Interrupt() <-chan bool {
	return self.interrupt
}

func (self *Lifecycle) StopAndWait() {
	self.Stop(math.MaxInt16 * time.Hour)
}

func waitOnWaitGroup(wg *sync.WaitGroup) (ch chan bool) {
	ch = make(chan bool)
	waiter := func(ch chan bool, wg *sync.WaitGroup) {
		wg.Wait()
		ch <- true
	}
	go waiter(ch, wg)
	return ch
}

func (self *Lifecycle) Stop(maxWait time.Duration) {
	log.Printf("Orderly shutdown commenced")
	self.once.Do(func() {
		self.stopBody(maxWait)
	})
}

func (self *Lifecycle) stopBody(maxWait time.Duration) {
	close(self.interrupt)
	self.wg.Done()
	waiter := waitOnWaitGroup(self.wg)
	select {
	case <-waiter:
		{
			return
		}
	case <-time.After(maxWait):
		{
			laggards := make([]string, 0)
			for finishedChan, service := range self.services {
				select {
				case _, closed := <-finishedChan:
					if closed {
						continue
					}
				default:
					{
						laggards = append(laggards, service)
					}
				}
			}
			if len(laggards) > 0 {
				log.Printf("The following services did not terminate in a timely fashion: %s\n", laggards)
			}
		}
	}
}

/**
 * convenience method for checking for interrupt for non-select{} usecases
 */
func (l *Lifecycle) IsInterrupted() bool {
	select {
	case <-l.Interrupt():
		return true
	default:
		return false
	}
}
<commit_msg>got calledout by @wadey for being iconsistent in my case pedantry<commit_after>package canstop

import (
	"log"
	"math"
	"runtime"
	"sync"
	"time"
)

type Manageable func(t *Lifecycle) error

type Lifecycle struct {
	wg                  *sync.WaitGroup
	once                *sync.Once
	services            map[chan string]string
	interrupt           chan bool
	serviceRegistration chan chan string
}

func NewLifecycle() *Lifecycle {
	wg := &sync.WaitGroup{}
	wg.Add(1)
	reg := make(chan chan string)
	services := make(map[chan string]string)
	// listen for services registering
	go func() {
		for {
			ch := <-reg
			services[ch] = <-ch
		}
	}()
	return &Lifecycle{wg, &sync.Once{}, services, make(chan bool), reg}
}

func (self *Lifecycle) Session(f Manageable) {
	self.wg.Add(1)
	var err error
	defer func() {
		if r := recover(); r != nil {
			log.Printf("Session ended in panic: %s\n", r)
		}
		if err != nil {
			log.Printf("Session ended in error: %s\n", err)
		}
		self.wg.Done()
	}()
	err = f(self)
}

func loopCalmly(l *Lifecycle, f Manageable, name string) {
	defer func() {
		if r := recover(); r != nil {
			log.Printf("Service %s panicked: %s\n", name, r)
		}
		runtime.Gosched() // break up panic hotloops
	}()
	err := f(l)
	if err != nil {
		log.Printf("Service %s errored: %s\n", name, err)
	}
}

func (self *Lifecycle) Service(f Manageable, name string) {
	// we pass a channel back to the Lifecycle registration goroutine
	// over which we communicate the name of the registering service.
	// closure of this channel is used to indicate clean termination
	imFinished := make(chan string)
	self.serviceRegistration <- imFinished
	imFinished <- name
	self.wg.Add(1)
	defer self.wg.Done()
	defer close(imFinished)
	// services should be restarted if they stop running for any reason
	// hopefully f itself is a loop that is also reading from the interrupt
	// channel; we should only hit the top of this loop on errors/panics
	for !self.IsInterrupted() {
		loopCalmly(self, f, name)
	}
}

func (self *Lifecycle) Interrupt() <-chan bool {
	return self.interrupt
}

func (self *Lifecycle) StopAndWait() {
	self.Stop(math.MaxInt16 * time.Hour)
}

func waitOnWaitGroup(wg *sync.WaitGroup) (ch chan bool) {
	ch = make(chan bool)
	waiter := func(ch chan bool, wg *sync.WaitGroup) {
		wg.Wait()
		ch <- true
	}
	go waiter(ch, wg)
	return ch
}

func (self *Lifecycle) Stop(maxWait time.Duration) {
	log.Printf("Orderly shutdown commenced")
	self.once.Do(func() {
		self.stopBody(maxWait)
	})
}

func (self *Lifecycle) stopBody(maxWait time.Duration) {
	close(self.interrupt)
	self.wg.Done()
	waiter := waitOnWaitGroup(self.wg)
	select {
	case <-waiter:
		{
			return
		}
	case <-time.After(maxWait):
		{
			laggards := make([]string, 0)
			for finishedChan, service := range self.services {
				select {
				case _, closed := <-finishedChan:
					{
						if closed {
							continue
						}
					}
				default:
					{
						laggards = append(laggards, service)
					}
				}
			}
			if len(laggards) > 0 {
				log.Printf("The following services did not terminate in a timely fashion: %s\n", laggards)
			}
		}
	}
}

/**
 * convenience method for checking for interrupt for non-sregelect{} usecases
 */
func (l *Lifecycle) IsInterrupted() bool {
	select {
	case <-l.Interrupt():
		{
			return true
		}
	default:
		{
			return false
		}
	}
}
<|endoftext|>