<commit_before>package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path"
	"strconv"
	"strings"

	"github.com/NYTimes/gziphandler"
	"github.com/bouk/httprouter"
	"github.com/influxdata/chronograf" // When julienschmidt/httprouter v2 w/ context is out, switch
	"github.com/influxdata/chronograf/oauth2"
)

const (
	// JSONType the mimetype for a json request
	JSONType = "application/json"
)

// MuxOpts are the options for the router.  Mostly related to auth.
type MuxOpts struct {
	Logger        chronograf.Logger
	Develop       bool                 // Develop loads assets from filesystem instead of bindata
	Basepath      string               // URL path prefix under which all chronograf routes will be mounted
	PrefixRoutes  bool                 // Mounts all backend routes under route specified by the Basepath
	UseAuth       bool                 // UseAuth turns on Github OAuth and JWT
	Auth          oauth2.Authenticator // Auth is used to authenticate and authorize
	ProviderFuncs []func(func(oauth2.Provider, oauth2.Mux))
}

// NewMux attaches all the route handlers; handler returned servers chronograf.
func NewMux(opts MuxOpts, service Service) http.Handler {
	hr := httprouter.New()

	/* React Application */
	assets := Assets(AssetsOpts{
		Develop: opts.Develop,
		Logger:  opts.Logger,
	})

	// Prefix any URLs found in the React assets with any configured basepath
	prefixedAssets := NewDefaultURLPrefixer(basepath, assets, opts.Logger)

	// Compress the assets with gzip if an accepted encoding
	compressed := gziphandler.GzipHandler(prefixedAssets)

	// The react application handles all the routing if the server does not
	// know about the route.  This means that we never have unknown routes on
	// the server.
	hr.NotFound = compressed

	var router chronograf.Router = hr

	// Set route prefix for all routes if basepath is present
	if opts.PrefixRoutes {
		router = &MountableRouter{
			Prefix:   opts.Basepath,
			Delegate: hr,
		}

		//The assets handler is always unaware of basepaths, so the
		// basepath needs to always be removed before sending requests to it
		hr.NotFound = http.StripPrefix(opts.Basepath, hr.NotFound)
	}

	/* Documentation */
	router.GET("/swagger.json", Spec())
	router.GET("/docs", Redoc("/swagger.json"))

	/* API */
	// Sources
	router.GET("/chronograf/v1/sources", service.Sources)
	router.POST("/chronograf/v1/sources", service.NewSource)

	router.GET("/chronograf/v1/sources/:id", service.SourcesID)
	router.PATCH("/chronograf/v1/sources/:id", service.UpdateSource)
	router.DELETE("/chronograf/v1/sources/:id", service.RemoveSource)

	// Source Proxy to Influx; Has gzip compression around the handler
	influx := gziphandler.GzipHandler(http.HandlerFunc(service.Influx))
	router.Handler("POST", "/chronograf/v1/sources/:id/proxy", influx)

	// Write proxies line protocol write requests to InfluxDB
	router.POST("/chronograf/v1/sources/:id/write", service.Write)

	// Queries is used to analyze a specific queries
	router.POST("/chronograf/v1/sources/:id/queries", service.Queries)

	// All possible permissions for users in this source
	router.GET("/chronograf/v1/sources/:id/permissions", service.Permissions)

	// Users associated with the data source
	router.GET("/chronograf/v1/sources/:id/users", service.SourceUsers)
	router.POST("/chronograf/v1/sources/:id/users", service.NewSourceUser)

	router.GET("/chronograf/v1/sources/:id/users/:uid", service.SourceUserID)
	router.DELETE("/chronograf/v1/sources/:id/users/:uid", service.RemoveSourceUser)
	router.PATCH("/chronograf/v1/sources/:id/users/:uid", service.UpdateSourceUser)

	// Roles associated with the data source
	router.GET("/chronograf/v1/sources/:id/roles", service.Roles)
	router.POST("/chronograf/v1/sources/:id/roles", service.NewRole)

	router.GET("/chronograf/v1/sources/:id/roles/:rid", service.RoleID)
	router.DELETE("/chronograf/v1/sources/:id/roles/:rid", service.RemoveRole)
	router.PATCH("/chronograf/v1/sources/:id/roles/:rid", service.UpdateRole)

	// Kapacitor
	router.GET("/chronograf/v1/sources/:id/kapacitors", service.Kapacitors)
	router.POST("/chronograf/v1/sources/:id/kapacitors", service.NewKapacitor)

	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid", service.KapacitorsID)
	router.PATCH("/chronograf/v1/sources/:id/kapacitors/:kid", service.UpdateKapacitor)
	router.DELETE("/chronograf/v1/sources/:id/kapacitors/:kid", service.RemoveKapacitor)

	// Kapacitor rules
	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid/rules", service.KapacitorRulesGet)
	router.POST("/chronograf/v1/sources/:id/kapacitors/:kid/rules", service.KapacitorRulesPost)

	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesID)
	router.PUT("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesPut)
	router.PATCH("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesStatus)
	router.DELETE("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesDelete)

	// Kapacitor Proxy
	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyGet)
	router.POST("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyPost)
	router.PATCH("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyPatch)
	router.DELETE("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyDelete)

	// Mappings
	router.GET("/chronograf/v1/mappings", service.GetMappings)

	// Layouts
	router.GET("/chronograf/v1/layouts", service.Layouts)
	router.POST("/chronograf/v1/layouts", service.NewLayout)

	router.GET("/chronograf/v1/layouts/:id", service.LayoutsID)
	router.PUT("/chronograf/v1/layouts/:id", service.UpdateLayout)
	router.DELETE("/chronograf/v1/layouts/:id", service.RemoveLayout)

	// Users
	router.GET("/chronograf/v1/me", service.Me)

	// Dashboards
	router.GET("/chronograf/v1/dashboards", service.Dashboards)
	router.POST("/chronograf/v1/dashboards", service.NewDashboard)

	router.GET("/chronograf/v1/dashboards/:id", service.DashboardID)
	router.DELETE("/chronograf/v1/dashboards/:id", service.RemoveDashboard)
	router.PUT("/chronograf/v1/dashboards/:id", service.ReplaceDashboard)
	router.PATCH("/chronograf/v1/dashboards/:id", service.UpdateDashboard)
	// Dashboard Cells
	router.GET("/chronograf/v1/dashboards/:id/cells", service.DashboardCells)
	router.POST("/chronograf/v1/dashboards/:id/cells", service.NewDashboardCell)

	router.GET("/chronograf/v1/dashboards/:id/cells/:cid", service.DashboardCellID)
	router.DELETE("/chronograf/v1/dashboards/:id/cells/:cid", service.RemoveDashboardCell)
	router.PUT("/chronograf/v1/dashboards/:id/cells/:cid", service.ReplaceDashboardCell)
	// Dashboard Templates
	router.GET("/chronograf/v1/dashboards/:id/templates", service.Templates)
	router.POST("/chronograf/v1/dashboards/:id/templates", service.NewTemplate)

	router.GET("/chronograf/v1/dashboards/:id/templates/:tid", service.TemplateID)
	router.DELETE("/chronograf/v1/dashboards/:id/templates/:tid", service.RemoveTemplate)
	router.PUT("/chronograf/v1/dashboards/:id/templates/:tid", service.ReplaceTemplate)

	// Databases
	router.GET("/chronograf/v1/sources/:id/dbs", service.GetDatabases)
	router.POST("/chronograf/v1/sources/:id/dbs", service.NewDatabase)

	router.DELETE("/chronograf/v1/sources/:id/dbs/:dbid", service.DropDatabase)

	// Retention Policies
	router.GET("/chronograf/v1/sources/:id/dbs/:dbid/rps", service.RetentionPolicies)
	router.POST("/chronograf/v1/sources/:id/dbs/:dbid/rps", service.NewRetentionPolicy)

	router.PUT("/chronograf/v1/sources/:id/dbs/:dbid/rps/:rpid", service.UpdateRetentionPolicy)
	router.DELETE("/chronograf/v1/sources/:id/dbs/:dbid/rps/:rpid", service.DropRetentionPolicy)
	var authRoutes AuthRoutes
	var out http.Handler
	/* Authentication */
	logout := "/oauth/logout"
	basepath := ""
	if opts.PrefixRoutes {
		basepath = opts.Basepath
	}
	if opts.UseAuth {
		// Encapsulate the router with OAuth2
		var auth http.Handler
		auth, authRoutes = AuthAPI(opts, router)

		// Create middleware to redirect to the appropriate provider logout
		targetURL := "/"
		router.GET(logout, Logout(targetURL, basepath, authRoutes))
		out = Logger(opts.Logger, auth)
	} else {
		out = Logger(opts.Logger, router)
	}

	router.GET("/chronograf/v1/", AllRoutes(authRoutes, path.Join(basepath, logout), opts.Logger))

	return out
}

// AuthAPI adds the OAuth routes if auth is enabled.
func AuthAPI(opts MuxOpts, router chronograf.Router) (http.Handler, AuthRoutes) {
	routes := AuthRoutes{}
	for _, pf := range opts.ProviderFuncs {
		pf(func(p oauth2.Provider, m oauth2.Mux) {
			urlName := PathEscape(strings.ToLower(p.Name()))

			loginPath := path.Join("oauth", urlName, "login")
			logoutPath := path.Join("oauth", urlName, "logout")
			callbackPath := path.Join("oauth", urlName, "callback")

			basepath := ""
			if opts.PrefixRoutes {
				basepath = opts.Basepath
			}

			router.Handler("GET", loginPath, m.Login())
			router.Handler("GET", logoutPath, m.Logout())
			router.Handler("GET", callbackPath, m.Callback())
			routes = append(routes, AuthRoute{
				Name:     p.Name(),
				Label:    strings.Title(p.Name()),
				Login:    path.Join(basepath, loginPath),
				Logout:   path.Join(basepath, logoutPath),
				Callback: path.Join(basepath, callbackPath),
			})
		})
	}

	// Y U NO WORKY WITH PATH JOIN?
	//rootPath := path.Join(opts.Basepath, "/chronograf/v1/")
	//logoutPath := path.Join(opts.Basepath, "/oauth/logout")
	rootPath := opts.Basepath + "/chronograf/v1/"
	logoutPath := opts.Basepath + "/oauth/logout"

	tokenMiddleware := AuthorizedToken(opts.Auth, opts.Logger, router)
	// Wrap the API with token validation middleware.
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if strings.HasPrefix(r.URL.Path, rootPath) || r.URL.Path == logoutPath {
			tokenMiddleware.ServeHTTP(w, r)
			return
		}
		router.ServeHTTP(w, r)
	}), routes
}

func encodeJSON(w http.ResponseWriter, status int, v interface{}, logger chronograf.Logger) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	if err := json.NewEncoder(w).Encode(v); err != nil {
		unknownErrorWithMessage(w, err, logger)
	}
}

// Error writes an JSON message
func Error(w http.ResponseWriter, code int, msg string, logger chronograf.Logger) {
	e := ErrorMessage{
		Code:    code,
		Message: msg,
	}
	b, err := json.Marshal(e)
	if err != nil {
		code = http.StatusInternalServerError
		b = []byte(`{"code": 500, "message":"server_error"}`)
	}

	logger.
		WithField("component", "server").
		WithField("http_status ", code).
		Error("Error message ", msg)
	w.Header().Set("Content-Type", JSONType)
	w.WriteHeader(code)
	_, _ = w.Write(b)
}

func invalidData(w http.ResponseWriter, err error, logger chronograf.Logger) {
	Error(w, http.StatusUnprocessableEntity, fmt.Sprintf("%v", err), logger)
}

func invalidJSON(w http.ResponseWriter, logger chronograf.Logger) {
	Error(w, http.StatusBadRequest, "Unparsable JSON", logger)
}

func unknownErrorWithMessage(w http.ResponseWriter, err error, logger chronograf.Logger) {
	Error(w, http.StatusInternalServerError, fmt.Sprintf("Unknown error: %v", err), logger)
}

func notFound(w http.ResponseWriter, id int, logger chronograf.Logger) {
	Error(w, http.StatusNotFound, fmt.Sprintf("ID %d not found", id), logger)
}

func paramID(key string, r *http.Request) (int, error) {
	ctx := r.Context()
	param := httprouter.GetParamFromContext(ctx, key)
	id, err := strconv.Atoi(param)
	if err != nil {
		return -1, fmt.Errorf("Error converting ID %s", param)
	}
	return id, nil
}
<commit_msg>Use Basepath over string concatenation<commit_after>package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"path"
	"strconv"
	"strings"

	"github.com/NYTimes/gziphandler"
	"github.com/bouk/httprouter"
	"github.com/influxdata/chronograf" // When julienschmidt/httprouter v2 w/ context is out, switch
	"github.com/influxdata/chronograf/oauth2"
)

const (
	// JSONType the mimetype for a json request
	JSONType = "application/json"
)

// MuxOpts are the options for the router.  Mostly related to auth.
type MuxOpts struct {
	Logger        chronograf.Logger
	Develop       bool                 // Develop loads assets from filesystem instead of bindata
	Basepath      string               // URL path prefix under which all chronograf routes will be mounted
	PrefixRoutes  bool                 // Mounts all backend routes under route specified by the Basepath
	UseAuth       bool                 // UseAuth turns on Github OAuth and JWT
	Auth          oauth2.Authenticator // Auth is used to authenticate and authorize
	ProviderFuncs []func(func(oauth2.Provider, oauth2.Mux))
}

// NewMux attaches all the route handlers; handler returned servers chronograf.
func NewMux(opts MuxOpts, service Service) http.Handler {
	hr := httprouter.New()

	/* React Application */
	assets := Assets(AssetsOpts{
		Develop: opts.Develop,
		Logger:  opts.Logger,
	})

	// Prefix any URLs found in the React assets with any configured basepath
	prefixedAssets := NewDefaultURLPrefixer(basepath, assets, opts.Logger)

	// Compress the assets with gzip if an accepted encoding
	compressed := gziphandler.GzipHandler(prefixedAssets)

	// The react application handles all the routing if the server does not
	// know about the route.  This means that we never have unknown routes on
	// the server.
	hr.NotFound = compressed

	var router chronograf.Router = hr

	// Set route prefix for all routes if basepath is present
	if opts.PrefixRoutes {
		router = &MountableRouter{
			Prefix:   opts.Basepath,
			Delegate: hr,
		}

		//The assets handler is always unaware of basepaths, so the
		// basepath needs to always be removed before sending requests to it
		hr.NotFound = http.StripPrefix(opts.Basepath, hr.NotFound)
	}

	/* Documentation */
	router.GET("/swagger.json", Spec())
	router.GET("/docs", Redoc("/swagger.json"))

	/* API */
	// Sources
	router.GET("/chronograf/v1/sources", service.Sources)
	router.POST("/chronograf/v1/sources", service.NewSource)

	router.GET("/chronograf/v1/sources/:id", service.SourcesID)
	router.PATCH("/chronograf/v1/sources/:id", service.UpdateSource)
	router.DELETE("/chronograf/v1/sources/:id", service.RemoveSource)

	// Source Proxy to Influx; Has gzip compression around the handler
	influx := gziphandler.GzipHandler(http.HandlerFunc(service.Influx))
	router.Handler("POST", "/chronograf/v1/sources/:id/proxy", influx)

	// Write proxies line protocol write requests to InfluxDB
	router.POST("/chronograf/v1/sources/:id/write", service.Write)

	// Queries is used to analyze a specific queries
	router.POST("/chronograf/v1/sources/:id/queries", service.Queries)

	// All possible permissions for users in this source
	router.GET("/chronograf/v1/sources/:id/permissions", service.Permissions)

	// Users associated with the data source
	router.GET("/chronograf/v1/sources/:id/users", service.SourceUsers)
	router.POST("/chronograf/v1/sources/:id/users", service.NewSourceUser)

	router.GET("/chronograf/v1/sources/:id/users/:uid", service.SourceUserID)
	router.DELETE("/chronograf/v1/sources/:id/users/:uid", service.RemoveSourceUser)
	router.PATCH("/chronograf/v1/sources/:id/users/:uid", service.UpdateSourceUser)

	// Roles associated with the data source
	router.GET("/chronograf/v1/sources/:id/roles", service.Roles)
	router.POST("/chronograf/v1/sources/:id/roles", service.NewRole)

	router.GET("/chronograf/v1/sources/:id/roles/:rid", service.RoleID)
	router.DELETE("/chronograf/v1/sources/:id/roles/:rid", service.RemoveRole)
	router.PATCH("/chronograf/v1/sources/:id/roles/:rid", service.UpdateRole)

	// Kapacitor
	router.GET("/chronograf/v1/sources/:id/kapacitors", service.Kapacitors)
	router.POST("/chronograf/v1/sources/:id/kapacitors", service.NewKapacitor)

	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid", service.KapacitorsID)
	router.PATCH("/chronograf/v1/sources/:id/kapacitors/:kid", service.UpdateKapacitor)
	router.DELETE("/chronograf/v1/sources/:id/kapacitors/:kid", service.RemoveKapacitor)

	// Kapacitor rules
	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid/rules", service.KapacitorRulesGet)
	router.POST("/chronograf/v1/sources/:id/kapacitors/:kid/rules", service.KapacitorRulesPost)

	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesID)
	router.PUT("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesPut)
	router.PATCH("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesStatus)
	router.DELETE("/chronograf/v1/sources/:id/kapacitors/:kid/rules/:tid", service.KapacitorRulesDelete)

	// Kapacitor Proxy
	router.GET("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyGet)
	router.POST("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyPost)
	router.PATCH("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyPatch)
	router.DELETE("/chronograf/v1/sources/:id/kapacitors/:kid/proxy", service.KapacitorProxyDelete)

	// Mappings
	router.GET("/chronograf/v1/mappings", service.GetMappings)

	// Layouts
	router.GET("/chronograf/v1/layouts", service.Layouts)
	router.POST("/chronograf/v1/layouts", service.NewLayout)

	router.GET("/chronograf/v1/layouts/:id", service.LayoutsID)
	router.PUT("/chronograf/v1/layouts/:id", service.UpdateLayout)
	router.DELETE("/chronograf/v1/layouts/:id", service.RemoveLayout)

	// Users
	router.GET("/chronograf/v1/me", service.Me)

	// Dashboards
	router.GET("/chronograf/v1/dashboards", service.Dashboards)
	router.POST("/chronograf/v1/dashboards", service.NewDashboard)

	router.GET("/chronograf/v1/dashboards/:id", service.DashboardID)
	router.DELETE("/chronograf/v1/dashboards/:id", service.RemoveDashboard)
	router.PUT("/chronograf/v1/dashboards/:id", service.ReplaceDashboard)
	router.PATCH("/chronograf/v1/dashboards/:id", service.UpdateDashboard)
	// Dashboard Cells
	router.GET("/chronograf/v1/dashboards/:id/cells", service.DashboardCells)
	router.POST("/chronograf/v1/dashboards/:id/cells", service.NewDashboardCell)

	router.GET("/chronograf/v1/dashboards/:id/cells/:cid", service.DashboardCellID)
	router.DELETE("/chronograf/v1/dashboards/:id/cells/:cid", service.RemoveDashboardCell)
	router.PUT("/chronograf/v1/dashboards/:id/cells/:cid", service.ReplaceDashboardCell)
	// Dashboard Templates
	router.GET("/chronograf/v1/dashboards/:id/templates", service.Templates)
	router.POST("/chronograf/v1/dashboards/:id/templates", service.NewTemplate)

	router.GET("/chronograf/v1/dashboards/:id/templates/:tid", service.TemplateID)
	router.DELETE("/chronograf/v1/dashboards/:id/templates/:tid", service.RemoveTemplate)
	router.PUT("/chronograf/v1/dashboards/:id/templates/:tid", service.ReplaceTemplate)

	// Databases
	router.GET("/chronograf/v1/sources/:id/dbs", service.GetDatabases)
	router.POST("/chronograf/v1/sources/:id/dbs", service.NewDatabase)

	router.DELETE("/chronograf/v1/sources/:id/dbs/:dbid", service.DropDatabase)

	// Retention Policies
	router.GET("/chronograf/v1/sources/:id/dbs/:dbid/rps", service.RetentionPolicies)
	router.POST("/chronograf/v1/sources/:id/dbs/:dbid/rps", service.NewRetentionPolicy)

	router.PUT("/chronograf/v1/sources/:id/dbs/:dbid/rps/:rpid", service.UpdateRetentionPolicy)
	router.DELETE("/chronograf/v1/sources/:id/dbs/:dbid/rps/:rpid", service.DropRetentionPolicy)
	var authRoutes AuthRoutes
	var out http.Handler
	/* Authentication */
	logout := "/oauth/logout"
	basepath := ""
	if opts.PrefixRoutes {
		basepath = opts.Basepath
	}
	if opts.UseAuth {
		// Encapsulate the router with OAuth2
		var auth http.Handler
		auth, authRoutes = AuthAPI(opts, router)

		// Create middleware to redirect to the appropriate provider logout
		targetURL := "/"
		router.GET(logout, Logout(targetURL, basepath, authRoutes))
		out = Logger(opts.Logger, auth)
	} else {
		out = Logger(opts.Logger, router)
	}

	router.GET("/chronograf/v1/", AllRoutes(authRoutes, path.Join(basepath, logout), opts.Logger))

	return out
}

// AuthAPI adds the OAuth routes if auth is enabled.
func AuthAPI(opts MuxOpts, router chronograf.Router) (http.Handler, AuthRoutes) {
	routes := AuthRoutes{}
	for _, pf := range opts.ProviderFuncs {
		pf(func(p oauth2.Provider, m oauth2.Mux) {
			urlName := PathEscape(strings.ToLower(p.Name()))

			loginPath := path.Join("oauth", urlName, "login")
			logoutPath := path.Join("oauth", urlName, "logout")
			callbackPath := path.Join("oauth", urlName, "callback")

			basepath := ""
			if opts.PrefixRoutes {
				basepath = opts.Basepath
			}

			router.Handler("GET", loginPath, m.Login())
			router.Handler("GET", logoutPath, m.Logout())
			router.Handler("GET", callbackPath, m.Callback())
			routes = append(routes, AuthRoute{
				Name:     p.Name(),
				Label:    strings.Title(p.Name()),
				Login:    path.Join(basepath, loginPath),
				Logout:   path.Join(basepath, logoutPath),
				Callback: path.Join(basepath, callbackPath),
			})
		})
	}

	rootPath := path.Join(opts.Basepath, "/chronograf/v1/")
	logoutPath := path.Join(opts.Basepath, "/oauth/logout")

	tokenMiddleware := AuthorizedToken(opts.Auth, opts.Logger, router)
	// Wrap the API with token validation middleware.
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if (strings.HasPrefix(r.URL.Path, rootPath) && len(r.URL.Path) > len(rootPath)) || r.URL.Path == logoutPath {
			tokenMiddleware.ServeHTTP(w, r)
			return
		}
		router.ServeHTTP(w, r)
	}), routes
}

func encodeJSON(w http.ResponseWriter, status int, v interface{}, logger chronograf.Logger) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	if err := json.NewEncoder(w).Encode(v); err != nil {
		unknownErrorWithMessage(w, err, logger)
	}
}

// Error writes an JSON message
func Error(w http.ResponseWriter, code int, msg string, logger chronograf.Logger) {
	e := ErrorMessage{
		Code:    code,
		Message: msg,
	}
	b, err := json.Marshal(e)
	if err != nil {
		code = http.StatusInternalServerError
		b = []byte(`{"code": 500, "message":"server_error"}`)
	}

	logger.
		WithField("component", "server").
		WithField("http_status ", code).
		Error("Error message ", msg)
	w.Header().Set("Content-Type", JSONType)
	w.WriteHeader(code)
	_, _ = w.Write(b)
}

func invalidData(w http.ResponseWriter, err error, logger chronograf.Logger) {
	Error(w, http.StatusUnprocessableEntity, fmt.Sprintf("%v", err), logger)
}

func invalidJSON(w http.ResponseWriter, logger chronograf.Logger) {
	Error(w, http.StatusBadRequest, "Unparsable JSON", logger)
}

func unknownErrorWithMessage(w http.ResponseWriter, err error, logger chronograf.Logger) {
	Error(w, http.StatusInternalServerError, fmt.Sprintf("Unknown error: %v", err), logger)
}

func notFound(w http.ResponseWriter, id int, logger chronograf.Logger) {
	Error(w, http.StatusNotFound, fmt.Sprintf("ID %d not found", id), logger)
}

func paramID(key string, r *http.Request) (int, error) {
	ctx := r.Context()
	param := httprouter.GetParamFromContext(ctx, key)
	id, err := strconv.Atoi(param)
	if err != nil {
		return -1, fmt.Errorf("Error converting ID %s", param)
	}
	return id, nil
}
<|endoftext|>


<commit_before>package docker

import (
	log "github.com/Sirupsen/logrus"

	"github.com/rancherio/os/config"
	"github.com/rancherio/os/util"
	"github.com/rancherio/rancher-compose/project"
)

type ContainerFactory struct {
	cfg *config.Config
}

type containerBasedService struct {
	name          string
	project       *project.Project
	container     *Container
	serviceConfig *project.ServiceConfig
	cfg           *config.Config
}

func NewContainerFactory(cfg *config.Config) *ContainerFactory {
	return &ContainerFactory{
		cfg: cfg,
	}
}

func (c *containerBasedService) Up() error {
	container := c.container
	containerCfg := c.container.ContainerCfg

	create := containerCfg.CreateOnly

	if util.Contains(c.cfg.Disable, c.name) {
		create = true
	}

	if create {
		container.Create()
		c.project.Notify(project.CONTAINER_CREATED, c, map[string]string{
			project.CONTAINER_ID: container.Container.ID,
		})
	} else {
		container.StartAndWait()
		c.project.Notify(project.CONTAINER_STARTED, c, map[string]string{
			project.CONTAINER_ID: container.Container.ID,
		})
	}

	if container.Err != nil {
		log.Errorf("Failed to run %v: %v", containerCfg.Id, container.Err)
	}

	if container.Err == nil && containerCfg.ReloadConfig {
		return project.ErrRestart
	}

	return container.Err
}

func (c *containerBasedService) Config() *project.ServiceConfig {
	return c.serviceConfig
}

func (c *containerBasedService) Name() string {
	return c.name
}

func (c *ContainerFactory) Create(project *project.Project, name string, serviceConfig *project.ServiceConfig) (project.Service, error) {
	container := NewContainerFromService(config.DOCKER_SYSTEM_HOST, name, serviceConfig)

	if container.Err != nil {
		return nil, container.Err
	}

	return &containerBasedService{
		name:          name,
		project:       project,
		container:     container,
		serviceConfig: serviceConfig,
		cfg:           c.cfg,
	}, nil
}
<commit_msg>Only send project event on success<commit_after>package docker

import (
	log "github.com/Sirupsen/logrus"

	"github.com/rancherio/os/config"
	"github.com/rancherio/os/util"
	"github.com/rancherio/rancher-compose/project"
)

type ContainerFactory struct {
	cfg *config.Config
}

type containerBasedService struct {
	name          string
	project       *project.Project
	container     *Container
	serviceConfig *project.ServiceConfig
	cfg           *config.Config
}

func NewContainerFactory(cfg *config.Config) *ContainerFactory {
	return &ContainerFactory{
		cfg: cfg,
	}
}

func (c *containerBasedService) Up() error {
	container := c.container
	containerCfg := c.container.ContainerCfg

	create := containerCfg.CreateOnly

	if util.Contains(c.cfg.Disable, c.name) {
		create = true
	}

	var event project.Event

	if create {
		container.Create()
		event = project.CONTAINER_CREATED
	} else {
		container.StartAndWait()
		event = project.CONTAINER_STARTED
	}

	if container.Err != nil {
		log.Errorf("Failed to run %v: %v", containerCfg.Id, container.Err)
	}

	if container.Err == nil && containerCfg.ReloadConfig {
		return project.ErrRestart
	}

	if container.Container != nil {
		c.project.Notify(event, c, map[string]string{
			project.CONTAINER_ID: container.Container.ID,
		})
	}

	return container.Err
}

func (c *containerBasedService) Config() *project.ServiceConfig {
	return c.serviceConfig
}

func (c *containerBasedService) Name() string {
	return c.name
}

func (c *ContainerFactory) Create(project *project.Project, name string, serviceConfig *project.ServiceConfig) (project.Service, error) {
	container := NewContainerFromService(config.DOCKER_SYSTEM_HOST, name, serviceConfig)

	if container.Err != nil {
		return nil, container.Err
	}

	return &containerBasedService{
		name:          name,
		project:       project,
		container:     container,
		serviceConfig: serviceConfig,
		cfg:           c.cfg,
	}, nil
}
<|endoftext|>


<commit_before>package critbitgo

import (
	"bytes"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"os"
	"strconv"
	"sync"
)

var (
	msbOnce   sync.Once
	msbMatrix [256]byte // The matrix of most significant bit

	KeyExists   error = errors.New("A key already exists")
	KeyTailNull error = errors.New("Can't use a key with the NULL termination")
)

func buildMsbMatrix() {
	for i := 0; i < len(msbMatrix); i++ {
		b := byte(i)
		b |= b >> 1
		b |= b >> 2
		b |= b >> 4
		msbMatrix[i] = b &^ (b >> 1)
	}
}

type node struct {
	// internal or external
	internal bool

	// internal node attributes
	child  [2]*node
	offset int
	bit    byte

	// external node attributes
	key   []byte
	value interface{}
}

// finding the critical bit.
func (n *node) criticalBit(key []byte) (offset int, bit byte) {
	nlen := len(n.key)
	klen := len(key)
	mlen := nlen
	if nlen > klen {
		mlen = klen
	}

	// find first differing byte and bit
	for offset = 0; offset < mlen; offset++ {
		if a, b := key[offset], n.key[offset]; a != b {
			bit = msbMatrix[a^b]
			return
		}
	}

	if nlen < klen {
		bit = msbMatrix[key[offset]]
	} else if nlen > klen {
		bit = msbMatrix[n.key[offset]]
	} else {
		// two keys are equal
		offset = -1
	}
	return
}

// calculate direction.
func (n *node) direction(key []byte) int {
	if n.offset < len(key) && key[n.offset]&n.bit != 0 {
		return 1
	}
	return 0
}

// Crit-bit Tree
type Trie struct {
	root *node
	size int
}

// searching the tree.
func (t *Trie) search(key []byte) *node {
	n := t.root
	for n.internal {
		n = n.child[n.direction(key)]
	}
	return n
}

// membership testing.
func (t *Trie) Contains(key []byte) bool {
	if t.root == nil {
		return false
	}
	if n := t.search(key); n != nil && bytes.Equal(n.key, key) {
		return true
	}
	return false
}

// get member.
func (t *Trie) Get(key []byte) (value interface{}) {
	if t.root == nil {
		return
	}
	if n := t.search(key); n != nil && bytes.Equal(n.key, key) {
		value = n.value
	}
	return
}

// insert into the tree (replaceable).
func (t *Trie) insert(key []byte, value interface{}, replace bool) error {
	if klen := len(key); klen > 0 && key[klen-1] == 0 {
		return KeyTailNull
	}

	// an empty tree
	if t.root == nil {
		t.root = &node{
			key:   key,
			value: value,
		}
		t.size = 1
		return nil
	}

	n := t.search(key)
	newOffset, newBit := n.criticalBit(key)

	// already exists in the tree
	if newOffset == -1 {
		if replace {
			n.value = value
			return nil
		}
		return KeyExists
	}

	// allocate new node
	newNodes := [2]node{
		{
			internal: true,
			offset:   newOffset,
			bit:      newBit,
		},
		{
			key:   key,
			value: value,
		},
	}
	newNode := &newNodes[0]
	direction := newNode.direction(key)
	newNode.child[direction] = &newNodes[1]

	// insert new node
	var wherep **node = &t.root
	for p := *wherep; p.internal; p = *wherep {
		if p.offset > newOffset || (p.offset == newOffset && p.bit < newBit) {
			break
		}
		wherep = &p.child[p.direction(key)]
	}

	newNode.child[1-direction] = *wherep
	*wherep = newNode
	t.size += 1
	return nil
}

// insert into the tree.
func (t *Trie) Insert(key []byte, value interface{}) error {
	return t.insert(key, value, false)
}

// set into the tree.
func (t *Trie) Set(key []byte, value interface{}) error {
	return t.insert(key, value, true)
}

// deleting elements.
func (t *Trie) Delete(key []byte) bool {
	// an empty tree
	if t.root == nil {
		return false
	}

	var othern *node  // other child of the parent
	var whereq **node // pointer to the grandparent

	// finding the best candidate to delete
	var wherep **node = &t.root
	for p := *wherep; p.internal; p = *wherep {
		direction := p.direction(key)
		whereq = wherep
		wherep = &p.child[direction]
		othern = p.child[1-direction]
	}

	// checking that we have the right element
	if !bytes.Equal((*wherep).key, key) {
		return false
	}

	// removing the node
	if whereq == nil {
		t.root = nil
	} else {
		*whereq = othern
	}
	t.size -= 1
	return true
}

// clearing a tree.
func (t *Trie) Clear() {
	t.root = nil
	t.size = 0
}

// return the number of key in a tree.
func (t *Trie) Size() int {
	return t.size
}

// fetching elements with a given prefix.
// handle is called with arguments key and value (if handle returns `false`, the iteration is aborted)
func (t *Trie) Allprefixed(prefix []byte, handle func(key []byte, value interface{}) bool) bool {
	// an empty tree
	if t.root == nil {
		return true
	}

	// walk tree, maintaining top pointer
	p := t.root
	top := p
	if len(prefix) > 0 {
		for p.internal {
			top = p
			p = p.child[p.direction(prefix)]
		}

		// check prefix
		if !bytes.Contains(p.key, prefix) {
			return true
		}
	}

	return allprefixed(top, handle)
}

func allprefixed(n *node, handle func([]byte, interface{}) bool) bool {
	if n.internal {
		// dealing with an internal node while recursing
		for i := 0; i < 2; i++ {
			if !allprefixed(n.child[i], handle) {
				return false
			}
		}
	} else {
		// dealing with an external node while recursing
		return handle(n.key, n.value)
	}
	return true
}

// dump tree. (for debugging)
func (t *Trie) Dump(w io.Writer) {
	if t.root == nil {
		return
	}
	if w == nil {
		w = os.Stdout
	}
	dump(w, t.root, true, "")
}

func dump(w io.Writer, n *node, right bool, prefix string) {
	var ownprefix string
	if right {
		ownprefix = prefix
	} else {
		ownprefix = prefix[:len(prefix)-1] + "`"
	}

	if n.internal {
		fmt.Fprintf(w, "%s-- off=%d, bit=%08b (%02x)\n", ownprefix, n.offset, n.bit, n.bit)
		for i := 0; i < 2; i++ {
			var nextprefix string
			switch i {
			case 0:
				nextprefix = prefix + " |"
				right = true
			case 1:
				nextprefix = prefix + "  "
				right = false
			}
			dump(w, n.child[i], right, nextprefix)
		}
	} else {
		fmt.Fprintf(w, "%s-- key=%d (%s)\n", ownprefix, n.key, key2str(n.key))
	}
	return
}

func key2str(key []byte) string {
	for _, c := range key {
		if !strconv.IsPrint(rune(c)) {
			return hex.EncodeToString(key)
		}
	}
	return string(key)
}

// create a tree.
func NewTrie() *Trie {
	msbOnce.Do(buildMsbMatrix)
	return &Trie{}
}
<commit_msg>remove sync.Once<commit_after>package critbitgo

import (
	"bytes"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"os"
	"strconv"
)

var (
	msbMatrix [256]byte // The matrix of most significant bit

	KeyExists   error = errors.New("A key already exists")
	KeyTailNull error = errors.New("Can't use a key with the NULL termination")
)

func buildMsbMatrix() {
	for i := 0; i < len(msbMatrix); i++ {
		b := byte(i)
		b |= b >> 1
		b |= b >> 2
		b |= b >> 4
		msbMatrix[i] = b &^ (b >> 1)
	}
}

type node struct {
	// internal or external
	internal bool

	// internal node attributes
	child  [2]*node
	offset int
	bit    byte

	// external node attributes
	key   []byte
	value interface{}
}

// finding the critical bit.
func (n *node) criticalBit(key []byte) (offset int, bit byte) {
	nlen := len(n.key)
	klen := len(key)
	mlen := nlen
	if nlen > klen {
		mlen = klen
	}

	// find first differing byte and bit
	for offset = 0; offset < mlen; offset++ {
		if a, b := key[offset], n.key[offset]; a != b {
			bit = msbMatrix[a^b]
			return
		}
	}

	if nlen < klen {
		bit = msbMatrix[key[offset]]
	} else if nlen > klen {
		bit = msbMatrix[n.key[offset]]
	} else {
		// two keys are equal
		offset = -1
	}
	return
}

// calculate direction.
func (n *node) direction(key []byte) int {
	if n.offset < len(key) && key[n.offset]&n.bit != 0 {
		return 1
	}
	return 0
}

// Crit-bit Tree
type Trie struct {
	root *node
	size int
}

// searching the tree.
func (t *Trie) search(key []byte) *node {
	n := t.root
	for n.internal {
		n = n.child[n.direction(key)]
	}
	return n
}

// membership testing.
func (t *Trie) Contains(key []byte) bool {
	if t.root == nil {
		return false
	}
	if n := t.search(key); n != nil && bytes.Equal(n.key, key) {
		return true
	}
	return false
}

// get member.
func (t *Trie) Get(key []byte) (value interface{}) {
	if t.root == nil {
		return
	}
	if n := t.search(key); n != nil && bytes.Equal(n.key, key) {
		value = n.value
	}
	return
}

// insert into the tree (replaceable).
func (t *Trie) insert(key []byte, value interface{}, replace bool) error {
	if klen := len(key); klen > 0 && key[klen-1] == 0 {
		return KeyTailNull
	}

	// an empty tree
	if t.root == nil {
		t.root = &node{
			key:   key,
			value: value,
		}
		t.size = 1
		return nil
	}

	n := t.search(key)
	newOffset, newBit := n.criticalBit(key)

	// already exists in the tree
	if newOffset == -1 {
		if replace {
			n.value = value
			return nil
		}
		return KeyExists
	}

	// allocate new node
	newNodes := [2]node{
		{
			internal: true,
			offset:   newOffset,
			bit:      newBit,
		},
		{
			key:   key,
			value: value,
		},
	}
	newNode := &newNodes[0]
	direction := newNode.direction(key)
	newNode.child[direction] = &newNodes[1]

	// insert new node
	var wherep **node = &t.root
	for p := *wherep; p.internal; p = *wherep {
		if p.offset > newOffset || (p.offset == newOffset && p.bit < newBit) {
			break
		}
		wherep = &p.child[p.direction(key)]
	}

	newNode.child[1-direction] = *wherep
	*wherep = newNode
	t.size += 1
	return nil
}

// insert into the tree.
func (t *Trie) Insert(key []byte, value interface{}) error {
	return t.insert(key, value, false)
}

// set into the tree.
func (t *Trie) Set(key []byte, value interface{}) error {
	return t.insert(key, value, true)
}

// deleting elements.
func (t *Trie) Delete(key []byte) bool {
	// an empty tree
	if t.root == nil {
		return false
	}

	var othern *node  // other child of the parent
	var whereq **node // pointer to the grandparent

	// finding the best candidate to delete
	var wherep **node = &t.root
	for p := *wherep; p.internal; p = *wherep {
		direction := p.direction(key)
		whereq = wherep
		wherep = &p.child[direction]
		othern = p.child[1-direction]
	}

	// checking that we have the right element
	if !bytes.Equal((*wherep).key, key) {
		return false
	}

	// removing the node
	if whereq == nil {
		t.root = nil
	} else {
		*whereq = othern
	}
	t.size -= 1
	return true
}

// clearing a tree.
func (t *Trie) Clear() {
	t.root = nil
	t.size = 0
}

// return the number of key in a tree.
func (t *Trie) Size() int {
	return t.size
}

// fetching elements with a given prefix.
// handle is called with arguments key and value (if handle returns `false`, the iteration is aborted)
func (t *Trie) Allprefixed(prefix []byte, handle func(key []byte, value interface{}) bool) bool {
	// an empty tree
	if t.root == nil {
		return true
	}

	// walk tree, maintaining top pointer
	p := t.root
	top := p
	if len(prefix) > 0 {
		for p.internal {
			top = p
			p = p.child[p.direction(prefix)]
		}

		// check prefix
		if !bytes.Contains(p.key, prefix) {
			return true
		}
	}

	return allprefixed(top, handle)
}

func allprefixed(n *node, handle func([]byte, interface{}) bool) bool {
	if n.internal {
		// dealing with an internal node while recursing
		for i := 0; i < 2; i++ {
			if !allprefixed(n.child[i], handle) {
				return false
			}
		}
	} else {
		// dealing with an external node while recursing
		return handle(n.key, n.value)
	}
	return true
}

// dump tree. (for debugging)
func (t *Trie) Dump(w io.Writer) {
	if t.root == nil {
		return
	}
	if w == nil {
		w = os.Stdout
	}
	dump(w, t.root, true, "")
}

func dump(w io.Writer, n *node, right bool, prefix string) {
	var ownprefix string
	if right {
		ownprefix = prefix
	} else {
		ownprefix = prefix[:len(prefix)-1] + "`"
	}

	if n.internal {
		fmt.Fprintf(w, "%s-- off=%d, bit=%08b (%02x)\n", ownprefix, n.offset, n.bit, n.bit)
		for i := 0; i < 2; i++ {
			var nextprefix string
			switch i {
			case 0:
				nextprefix = prefix + " |"
				right = true
			case 1:
				nextprefix = prefix + "  "
				right = false
			}
			dump(w, n.child[i], right, nextprefix)
		}
	} else {
		fmt.Fprintf(w, "%s-- key=%d (%s)\n", ownprefix, n.key, key2str(n.key))
	}
	return
}

func key2str(key []byte) string {
	for _, c := range key {
		if !strconv.IsPrint(rune(c)) {
			return hex.EncodeToString(key)
		}
	}
	return string(key)
}

// create a tree.
func NewTrie() *Trie {
	return &Trie{}
}

func init() {
	buildMsbMatrix()
}
<|endoftext|>


<commit_before>package web

import (
	"net/http"
	"draringi/codejam2013/src/forecasting"
	"draringi/codejam2013/src/data"
//	"html/template"
	"fmt"
)

type dashboardHelper struct {

}

type Dashboard struct {
	channel chan (*data.CSVData)
	JSONAid dashboardHelper
	data *data.CSVData
}

func (self *Dashboard) Init () {
	self.channel = make(chan (*data.CSVData), 1)
	forecasting.PredictPulse(channel)
	go func () {
		for {
			if tmp := <-self.channel {
				self.data = tmp
			}
		}
	} ()
}

func (self *Dashboard) ServeHTTP (w http.ResponseWriter, request *http.Request) {
	fmt.Fprintln(w, "Placeholder")
}
<commit_msg>Even if this commit doesn't work, I'm off to eat dinner<commit_after>package web

import (
	"net/http"
	"draringi/codejam2013/src/forecasting"
	"draringi/codejam2013/src/data"
//	"html/template"
	"fmt"
)

type dashboardHelper struct {

}

type Dashboard struct {
	channel chan (*data.CSVData)
	JSONAid dashboardHelper
	data *data.CSVData
}

func (self *Dashboard) Init () {
	self.channel = make(chan (*data.CSVData), 1)
	forecasting.PredictPulse(self.channel)
	go func () {
		for {
			if tmp := <-self.channel {
				self.data = tmp
			}
		}
	} ()
}

func (self *Dashboard) ServeHTTP (w http.ResponseWriter, request *http.Request) {
	fmt.Fprintln(w, "Placeholder")
}
<|endoftext|>


<commit_before>// Copyright 2012 Apcera Inc. All rights reserved.

package test

import (
	"bufio"
	"fmt"
	"net"
	"testing"
	"time"
)

const PERF_PORT=8422

const defaultRecBufSize = 32768
const defaultSendBufSize = 16384

func flushConnection(b *testing.B, c net.Conn, buf []byte) {
	c.Write([]byte("PING\r\n"))
	c.SetReadDeadline(time.Now().Add(50 * time.Millisecond))
	n, err := c.Read(buf)
	if err != nil {
		b.Fatalf("Failed read: %v\n", err)
	}
	if n != 6 && buf[0] != 'P' {
		b.Fatalf("Failed read of PONG: %s\n", buf)
	}
}

func benchPub(b *testing.B, subject, payload string) {
	b.StopTimer()
	s = startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB %s %d\r\n%s\r\n", subject, len(payload), payload))
	b.SetBytes(int64(len(sendOp)))
	buf := make([]byte, 1024)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		bw.Write(sendOp)
	}
	bw.Flush()
	flushConnection(b, c, buf)
	b.StopTimer()
	c.Close()
	s.stopServer()
}

func Benchmark____PubNoPayload(b *testing.B) {
	benchPub(b, "a", "")
}

func Benchmark___PubMinPayload(b *testing.B) {
	benchPub(b, "a", "b")
}

func Benchmark__PubTinyPayload(b *testing.B) {
	benchPub(b, "foo", "ok")
}

func Benchmark_PubSmallPayload(b *testing.B) {
	benchPub(b, "foo", "hello world")
}

func Benchmark___PubMedPayload(b *testing.B) {
	benchPub(b, "foo", "The quick brown fox jumps over the lazy dog")
}

func Benchmark_PubLargePayload(b *testing.B) {
	b.StopTimer()
	var p string
	for i := 0 ; i < 200 ; i++ {
		p = p + "hello world "
	}
	b.StartTimer()
	benchPub(b, "foo", p)
}

func drainConnection(b *testing.B, c net.Conn, ch chan bool, expected int) {
	buf := make([]byte, defaultRecBufSize)
	bytes := 0

	for {
		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
		n, err := c.Read(buf)
		if err != nil {
			b.Errorf("Error on read: %v\n", err)
			break
		}
		bytes += n
		if bytes >= expected {
			break
		}
	}
	if bytes != expected {
		b.Errorf("Did not receive all bytes: %d vs %d\n", bytes, expected)
	}
	ch <- true
}

func Benchmark__________PubSub(b *testing.B) {
	b.StopTimer()
	s = startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	sendProto(b, c, "SUB foo 1\r\n")
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)
	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c, ch, expected)
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		_, err := bw.Write(sendOp)
		if err != nil {
			b.Errorf("Received error on PUB write: %v\n", err)
		}
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	s.stopServer()
}

func Benchmark__PubSubTwoConns(b *testing.B) {
	b.StopTimer()
	s = startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	bw := bufio.NewWriterSize(c, defaultSendBufSize)

	c2 := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c2)
	sendProto(b, c2, "SUB foo 1\r\n")

	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)

	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c2, ch, expected)

	b.StartTimer()
	for i := 0; i < b.N; i++ {
		bw.Write(sendOp)
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	c2.Close()
	s.stopServer()
}

func Benchmark__PubTwoQueueSub(b *testing.B) {
	b.StopTimer()
	s = startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	sendProto(b, c, "SUB foo group1 1\r\n")
	sendProto(b, c, "SUB foo group1 2\r\n")
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)
	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c, ch, expected)
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		_, err := bw.Write(sendOp)
		if err != nil {
			b.Errorf("Received error on PUB write: %v\n", err)
		}
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	s.stopServer()
}

func Benchmark_PubFourQueueSub(b *testing.B) {
	b.StopTimer()
	s = startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	sendProto(b, c, "SUB foo group1 1\r\n")
	sendProto(b, c, "SUB foo group1 2\r\n")
	sendProto(b, c, "SUB foo group1 3\r\n")
	sendProto(b, c, "SUB foo group1 4\r\n")
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)
	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c, ch, expected)
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		_, err := bw.Write(sendOp)
		if err != nil {
			b.Errorf("Received error on PUB write: %v\n", err)
		}
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	s.stopServer()
}

<commit_msg>More reasonable payload sizes for pub tests<commit_after>// Copyright 2012 Apcera Inc. All rights reserved.

package test

import (
	"bufio"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
	"net"
	"testing"
	"time"

	"github.com/apcera/gnatsd/server"
)

const PERF_PORT = 8422

// For Go routine based server.
func runBenchServer() *server.Server {
	opts := defaultServerOptions
	opts.Port = PERF_PORT
	return runServer(&opts)
}

const defaultRecBufSize = 32768
const defaultSendBufSize = 16384

func flushConnection(b *testing.B, c net.Conn, buf []byte) {
	c.Write([]byte("PING\r\n"))
	c.SetReadDeadline(time.Now().Add(50 * time.Millisecond))
	n, err := c.Read(buf)
	if err != nil {
		b.Fatalf("Failed read: %v\n", err)
	}
	if n != 6 && buf[0] != 'P' {
		b.Fatalf("Failed read of PONG: %s\n", buf)
	}
}

func benchPub(b *testing.B, subject, payload string) {
	b.StopTimer()
	s := startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB %s %d\r\n%s\r\n", subject, len(payload), payload))
	b.SetBytes(int64(len(sendOp)))
	buf := make([]byte, 1024)
	b.StartTimer()
	for i := 0; i < b.N; i++ {
		bw.Write(sendOp)
	}
	bw.Flush()
	flushConnection(b, c, buf)
	b.StopTimer()
	c.Close()
	s.stopServer()
}

func sizedString(sz int) string {
	u := make([]byte, sz)
	io.ReadFull(rand.Reader, u)
	return hex.EncodeToString(u)
}

func Benchmark___PubNo_Payload(b *testing.B) {
	benchPub(b, "a", "")
}

func Benchmark___Pub8b_Payload(b *testing.B) {
	b.StopTimer()
	s := sizedString(8)
	benchPub(b, "a", s)
}

func Benchmark__Pub32b_Payload(b *testing.B) {
	b.StopTimer()
	s := sizedString(32)
	benchPub(b, "a", s)
}

func Benchmark_Pub256B_Payload(b *testing.B) {
	b.StopTimer()
	s := sizedString(256)
	benchPub(b, "a", s)
}

func Benchmark___Pub1K_Payload(b *testing.B) {
	b.StopTimer()
	s := sizedString(1024)
	benchPub(b, "a", s)
}

func Benchmark___Pub4K_Payload(b *testing.B) {
	b.StopTimer()
	s := sizedString(4*1024)
	benchPub(b, "a", s)
}

func drainConnection(b *testing.B, c net.Conn, ch chan bool, expected int) {
	buf := make([]byte, defaultRecBufSize)
	bytes := 0

	for {
		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
		n, err := c.Read(buf)
		if err != nil {
			b.Errorf("Error on read: %v\n", err)
			break
		}
		bytes += n
		if bytes >= expected {
			break
		}
	}
	if bytes != expected {
		b.Errorf("Did not receive all bytes: %d vs %d\n", bytes, expected)
	}
	ch <- true
}

func Benchmark__________PubSub(b *testing.B) {
	b.StopTimer()
	s := startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	sendProto(b, c, "SUB foo 1\r\n")
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)
	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c, ch, expected)
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		_, err := bw.Write(sendOp)
		if err != nil {
			b.Errorf("Received error on PUB write: %v\n", err)
		}
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	s.stopServer()
}

func Benchmark__PubSubTwoConns(b *testing.B) {
	b.StopTimer()
	s := startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	bw := bufio.NewWriterSize(c, defaultSendBufSize)

	c2 := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c2)
	sendProto(b, c2, "SUB foo 1\r\n")

	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)

	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c2, ch, expected)

	b.StartTimer()
	for i := 0; i < b.N; i++ {
		bw.Write(sendOp)
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	c2.Close()
	s.stopServer()
}

func Benchmark__PubTwoQueueSub(b *testing.B) {
	b.StopTimer()
	s := startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	sendProto(b, c, "SUB foo group1 1\r\n")
	sendProto(b, c, "SUB foo group1 2\r\n")
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)
	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c, ch, expected)
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		_, err := bw.Write(sendOp)
		if err != nil {
			b.Errorf("Received error on PUB write: %v\n", err)
		}
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	s.stopServer()
}

func Benchmark_PubFourQueueSub(b *testing.B) {
	b.StopTimer()
	s := startServer(b, PERF_PORT, "")
	c := createClientConn(b, "localhost", PERF_PORT)
	doDefaultConnect(b, c)
	sendProto(b, c, "SUB foo group1 1\r\n")
	sendProto(b, c, "SUB foo group1 2\r\n")
	sendProto(b, c, "SUB foo group1 3\r\n")
	sendProto(b, c, "SUB foo group1 4\r\n")
	bw := bufio.NewWriterSize(c, defaultSendBufSize)
	sendOp := []byte(fmt.Sprintf("PUB foo 2\r\nok\r\n"))
	ch := make(chan bool)
	expected := len("MSG foo 1 2\r\nok\r\n") * b.N
	go drainConnection(b, c, ch, expected)
	b.StartTimer()

	for i := 0; i < b.N; i++ {
		_, err := bw.Write(sendOp)
		if err != nil {
			b.Errorf("Received error on PUB write: %v\n", err)
		}
	}
	err := bw.Flush()
	if err != nil {
		b.Errorf("Received error on FLUSH write: %v\n", err)
	}

	// Wait for connection to be drained
	<-ch

	b.StopTimer()
	c.Close()
	s.stopServer()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

func (m *machine) loadVectorWords() error {

	m.addGoWord("vec-set-at",
		" ( vec val idx -- vec ) ",
		GoWord(func(m *machine) error {
			idx := int(m.popValue().(Integer))
			val := m.popValue()
			arr := m.values[len(m.values)-1].(Array)
			if idx > len(arr)-1 || idx < 0 {
				return fmt.Errorf("index out of bounds: %v", idx)
			}
			arr[idx] = val
			return nil
		}))

	m.addGoWord("vec-at",
		" ( vec idx -- elem ) ",
		GoWord(func(m *machine) error {
			idx := int(m.popValue().(Integer))
			arr := m.popValue().(Array)
			if idx > len(arr)-1 || idx < 0 {
				return fmt.Errorf("index out of bounds: %v", idx)
			}
			m.pushValue(arr[idx])
			return nil
		}))

	// ( -- vector )
	m.addGoWord("<vector>",
		" ( -- vector )",
		GoWord(func(m *machine) error {
			m.pushValue(Array(make([]stackEntry, 0)))
			return nil
		}))

	m.addGoWord("vec-each",
		" ( vec quot -- .. ) ",
		GoWord(func(m *machine) error {
			quot := m.popValue().(*quotation)
			vect := m.popValue().(Array)
			for _, elem := range vect {
				m.pushValue(elem)
				m.pushValue(quot)
				err := m.executeQuotation()
				if err != nil {
					return err
				}
			}
			return nil
		}))

	m.addGoWord("vec-append",
		" ( vec elem -- newVect ) ",
		GoWord(func(m *machine) error {
			toAppend := m.popValue()
			arr := m.popValue().(Array)
			arr = append(arr, toAppend)
			m.pushValue(arr)
			return nil
		}))
	m.addGoWord("vec-prepend",
		" ( vec elem -- newVect ) ",
		GoWord(func(m *machine) error {
			toPrepend := m.popValue()
			arr := m.popValue().(Array)
			arr = append([]stackEntry{toPrepend}, arr...)
			m.pushValue(arr)
			return nil
		}))

	m.addGoWord("vec-popback",
		" ( vec -- vec elem ) ",
		GoWord(func(m *machine) error {
			arr := m.popValue().(Array)
			if len(arr) < 1 {
				return fmt.Errorf("no elements in array")
			}
			val := arr[len(arr)-1]
			arr = arr[:len(arr)-1]
			m.pushValue(arr)
			m.pushValue(val)
			return nil
		}))

	m.addGoWord("vec-popfront",
		" ( vec -- vec elem ) ",
		GoWord(func(m *machine) error {
			arr := m.popValue().(Array)
			if len(arr) < 1 {
				return fmt.Errorf("no elements in array")
			}
			val := arr[0]
			arr = arr[1:]
			m.pushValue(arr)
			m.pushValue(val)
			return nil
		}))
	return nil
}
<commit_msg>Clean up vectors to aid later debugging<commit_after>package main

import (
	"fmt"
)

func vecSetAt(m *machine) error {
	idx := int(m.popValue().(Integer))
	val := m.popValue()
	arr := m.values[len(m.values)-1].(Array)
	if idx > len(arr)-1 || idx < 0 {
		return fmt.Errorf("index out of bounds: %v", idx)
	}
	arr[idx] = val
	return nil
}

func vecAt(m *machine) error {
	idx := int(m.popValue().(Integer))
	arr := m.popValue().(Array)
	if idx > len(arr)-1 || idx < 0 {
		return fmt.Errorf("index out of bounds: %v", idx)
	}
	m.pushValue(arr[idx])
	return nil
}

func makeVec(m *machine) error {
	m.pushValue(Array(make([]stackEntry, 0)))
	return nil
}

func vecEach(m *machine) error {
	quot := m.popValue().(*quotation)
	vect := m.popValue().(Array)
	for _, elem := range vect {
		m.pushValue(elem)
		m.pushValue(quot)
		err := m.executeQuotation()
		if err != nil {
			return err
		}
	}
	return nil
}

func vecAppend(m *machine) error {
	toAppend := m.popValue()
	arr := m.popValue().(Array)
	arr = append(arr, toAppend)
	m.pushValue(arr)
	return nil
}

func vecPrepend(m *machine) error {
	toPrepend := m.popValue()
	arr := m.popValue().(Array)
	arr = append([]stackEntry{toPrepend}, arr...)
	m.pushValue(arr)
	return nil
}

func vecPopback(m *machine) error {
	arr := m.popValue().(Array)
	if len(arr) < 1 {
		return fmt.Errorf("no elements in array")
	}
	val := arr[len(arr)-1]
	arr = arr[:len(arr)-1]
	m.pushValue(arr)
	m.pushValue(val)
	return nil
}

func vecPopfront(m *machine) error {
	arr := m.popValue().(Array)
	if len(arr) < 1 {
		return fmt.Errorf("no elements in array")
	}
	val := arr[0]
	arr = arr[1:]
	m.pushValue(arr)
	m.pushValue(val)
	return nil
}

func (m *machine) loadVectorWords() error {
	m.addGoWord("vec-set-at", " ( vec val idx -- vec ) ", GoWord(vecSetAt))
	m.addGoWord("vec-at", " ( vec idx -- elem ) ", GoWord(vecAt))
	m.addGoWord("<vector>", " ( -- vector )", GoWord(makeVec))
	m.addGoWord("vec-each", " ( vec quot -- .. ) ", GoWord(vecEach))
	m.addGoWord("vec-append", " ( vec elem -- newVect ) ", GoWord(vecAppend))
	m.addGoWord("vec-prepend", " ( vec elem -- newVect ) ", GoWord(vecPrepend))
	m.addGoWord("vec-popback", " ( vec -- vec elem ) ", GoWord(vecPopback))
	m.addGoWord("vec-popfront", " ( vec -- vec elem ) ", GoWord(vecPopfront))
	return nil
}
<|endoftext|>


<commit_before>package peco

import "testing"

// some little test to validate ansi strips function
func TestANSIColorStrip(t *testing.T) {
	test := stripANSISequence("this is not a pipe")
	if test != "this is not a pipe" {
		t.Errorf("expected String = 'this is not a pipe', got '%s'", test)
	}
	test = stripANSISequence(" [01;34helloWorld [0m")
	if test != " [01;34helloWorld [0m" {
		t.Errorf("expected String = ' [01;34mhelloWorld [0m', got '%s'", test)
	}
	test = stripANSISequence("\x1b[01;34mthe answer to life is \x1b[0;42m42")
	if test != "the answer to life is 42" {
		t.Errorf("expected String = 'the answer to life is 42' , got '%s'", test)
	}
	test = stripANSISequence("x1b[01;34mthe answer to life is x1b[0;42m42")
	if test != "x1b[01;34mthe answer to life is x1b[0;42m42" {
		t.Errorf("expected String = 'x1b[01;34mthe answer to life is x1b[0;42m42' , got '%s'", test)
	}
}
<commit_msg>Add tests for NoMatch struct<commit_after>package peco

import (
	"strings"
	"testing"
)

// some little test to validate ansi strips function
func TestANSIColorStrip(t *testing.T) {
	test := stripANSISequence("this is not a pipe")
	if test != "this is not a pipe" {
		t.Errorf("expected String = 'this is not a pipe', got '%s'", test)
	}
	test = stripANSISequence(" [01;34helloWorld [0m")
	if test != " [01;34helloWorld [0m" {
		t.Errorf("expected String = ' [01;34mhelloWorld [0m', got '%s'", test)
	}
	test = stripANSISequence("\x1b[01;34mthe answer to life is \x1b[0;42m42")
	if test != "the answer to life is 42" {
		t.Errorf("expected String = 'the answer to life is 42' , got '%s'", test)
	}
	test = stripANSISequence("x1b[01;34mthe answer to life is x1b[0;42m42")
	if test != "x1b[01;34mthe answer to life is x1b[0;42m42" {
		t.Errorf("expected String = 'x1b[01;34mthe answer to life is x1b[0;42m42' , got '%s'", test)
	}
}

func TestNewNoMatch(t *testing.T) {
	var m *NoMatch

	m = NewNoMatch("Hello, World!", false)
	if m.Indices() != nil {
		t.Errorf("NoMatch.Indices() must always return nil")
	}

	nullsepCheck := func(buf string) {
		m = NewNoMatch(buf, true)
		if m.Buffer() != buf {
			t.Errorf("m.Buffer() should return '%s', got %s", buf, m.Buffer())
		}

		if sepLoc := strings.Index(buf, "\000"); sepLoc > -1 {
			if m.Line() != buf[0:sepLoc] {
				t.Errorf("m.Line() should return '%s', got '%s'", buf[0:sepLoc], m.Line())
			}
			if m.Output() != buf[sepLoc+1:] {
				t.Errorf("m.Output() should return '%s', got '%s'", buf[sepLoc+1:], m.Output())
			}
		} else {
			if m.Line() != m.Buffer() {
				t.Errorf("m.Line() should return '%s', got '%s'", m.Buffer(), m.Line())
			}
			if m.Output() != m.Buffer() {
				t.Errorf("m.Output() should return '%s', got '%s'", m.Buffer(), m.Output())
			}
		}
	}

	nullsepCheck("Hello, World!")
	nullsepCheck("Hello, World!\000Hello, peco!")
}
<|endoftext|>


<commit_before>package csvutil

import "github.com/coreos/go-semver/semver"

// Version of csvutil.
var Version = semver.Version{
	Major: 0,
	Minor: 15,
	Patch: 1,
}
<commit_msg>Version up to v0.16.0<commit_after>package csvutil

import "github.com/coreos/go-semver/semver"

// Version of csvutil.
var Version = semver.Version{
	Major: 0,
	Minor: 16,
	Patch: 0,
}
<|endoftext|>


<commit_before>package main

const VERSION = "0.7.3-alpha1"
<commit_msg>:+1: Bump up the version to 0.7.3-alpha2<commit_after>package main

const VERSION = "0.7.3-alpha2"
<|endoftext|>


<commit_before>package xtypes

import (
	"go/types"
)

var (
	TypBool   = types.Typ[types.Bool]
	TypInt    = types.Typ[types.Int64]
	TypFloat  = types.Typ[types.Float64]
	TypString = types.Typ[types.String]
	TypVoid   = types.Typ[types.Invalid]
)

func LookupField(name string, typ *types.Struct) int {
	for i := 0; i < typ.NumFields(); i++ {
		if typ.Field(i).Name() == name {
			return i
		}
	}
	return -1
}
<commit_msg>empty tuple object in xtypes<commit_after>package xtypes

import (
	"go/types"
)

var EmptyTuple = types.NewTuple()

var (
	TypBool   = types.Typ[types.Bool]
	TypInt    = types.Typ[types.Int64]
	TypFloat  = types.Typ[types.Float64]
	TypString = types.Typ[types.String]
	TypVoid   = types.Typ[types.Invalid]
)

func LookupField(name string, typ *types.Struct) int {
	for i := 0; i < typ.NumFields(); i++ {
		if typ.Field(i).Name() == name {
			return i
		}
	}
	return -1
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"time"
)

var version = "0.3.1"
var favicon []byte
var index []byte
var robots []byte
var readDeadline = 5 * time.Second

var runningProcs = 0
var totalTimeoutRequests = 0
var totalTCPRequests = 0
var totalIndexRequests = 0

var http10StatusOK = []byte("HTTP/1.0 200 OK\r\n")
var http11StatusOK = []byte("HTTP/1.1 200 OK\r\n")
var crlf = []byte("\r\n")

//plain-text
var invalidFormat = []byte("invalid_format")
var done = []byte("done")
var invalidCommand = []byte("Unknown command. Type 'info'\n")

//int
var one = []byte("1")

//json
var jsonTrue = []byte("true")

//js
var jsTrue = []byte("_settimeoutio=true")

//css
var cssShow = []byte(".settimeoutio {display: block;}")

//callback
var emptyCallback = []string{""}

var serverName = "settimeout/" + version

func main() {
	addr := flag.String("addr", ":80", "HTTP address to listen on (empty to disable)")
	tcpAddr := flag.String("tcpaddr", ":5103", "Socket address to listen on (empty to disable)")
	statsAddr := flag.String("statsaddr", "127.0.0.1:5104", "Socket address to listen on for stats (empty to disable)")
	flag.Parse()

	var err error
	favicon, err = Asset("assets/favicon.ico")
	if err != nil {
		log.Fatal("Failed to read favicon.ico: " + err.Error())
	}
	index, err = Asset("assets/index.html")
	if err != nil {
		log.Fatal("Failed to read index.html: " + err.Error())
	}
	robots, err = Asset("assets/robots.txt")
	if err != nil {
		log.Fatal("Failed to read robots.txt: " + err.Error())
	}

	go startHTTPServer(*addr)
	go startTCPServer(*tcpAddr)
	go startStatsTCPServer(*statsAddr)

	//wait for a SIGINT
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	<-c
}

func startTCPServer(addr string) {
	if addr == "" {
		return
	}
	listen, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal("Failed to start TCP server: " + err.Error())
	}
	for {
		conn, err := listen.Accept()
		if err != nil {
			// handle error
			continue
		}
		go socketHandler(conn)
	}
}

func startStatsTCPServer(addr string) {
	if addr == "" {
		return
	}
	listen, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal("Failed to start stats TCP server: " + err.Error())
	}
	for {
		conn, err := listen.Accept()
		if err != nil {
			// handle error
			continue
		}
		go func() {
			defer conn.Close()
			for {
				conn.SetReadDeadline(time.Now().Add(readDeadline))
				buf := bufio.NewReader(conn)
				str, err := buf.ReadString('\n')
				if err != nil {
					if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
						//if its a i/o timeout then just continue the loop again
						continue
					}
					return
				}
				str = strings.Trim(str, " \r\n\t")
				switch str {
				case "close", "quit", "exit":
					return
				case "info":
					infos := make([]string, 4)
					infos[0] = "Running Requests: " + strconv.Itoa(runningProcs)
					infos[1] = "Total HTTP Index Requests: " + strconv.Itoa(totalIndexRequests)
					infos[2] = "Total TCP Requests: " + strconv.Itoa(totalTCPRequests)
					infos[3] = "Total HTTP Timeout Requests: " + strconv.Itoa(totalTimeoutRequests)
					conn.Write([]byte(strings.Join(infos, "\n")))
				default:
					conn.Write(invalidCommand)
				}
			}
		}()
	}
}

func startHTTPServer(addr string) {
	if addr == "" {
		return
	}
	s := &http.Server{
		Addr:        addr,
		Handler:     http.HandlerFunc(httpHandler),
		ReadTimeout: readDeadline,
		//don't set a write deadline since it would set it from NOW which is not what we want
	}
	err := s.ListenAndServe()
	if err != nil {
		log.Fatal("Failed to start HTTP server: " + err.Error())
	}
}

func socketHandler(conn net.Conn) {
	defer closeAndWait(conn)
	conn.SetReadDeadline(time.Now().Add(readDeadline))
	buf := bufio.NewReader(conn)
	str, err := buf.ReadString('\n')
	if err != nil {
		return
	}
	totalTCPRequests++
	d, err := parseDurationString(str)
	if err != nil {
		conn.Write(invalidFormat)
		return
	}
	if waitForTimeoutClose(conn, d) {
		conn.Write(done)
	}
}

//returns if we should write or not becuase were leaving the writing to the caller
func waitForTimeoutClose(c net.Conn, timeout time.Duration) bool {
	if timeout.Nanoseconds() <= 0 {
		return true
	}

	runningProcs++
	closedCh := make(chan int)
	go func() {

		defer func() {
			runningProcs--
		}()

		singleChar := make([]byte, 1)
		for {
			c.SetReadDeadline(time.Now().Add(readDeadline))
			_, err := c.Read(singleChar)
			//if we got a read error and it wasn't a timeout then close the connection
			if netErr, ok := err.(net.Error); err != nil && (!ok || !netErr.Timeout()) {
				select {
				case closedCh <- 1:
				default:
				}
			}
			return
		}
	}()
	select {
	case <-closedCh:
		return false
	case <-time.After(timeout):
		return true
	}
}

func closeAndWait(c net.Conn) {
	defer c.Close()
	//from server.go which is from http://golang.org/issue/3595
	//close writing side first before actually closing the connection
	//and sending a RST
	if tcp, ok := c.(*net.TCPConn); ok {
		tcp.CloseWrite()
	}
	//using 500 milliseconds which is from rstAvoidanceDelay in server.go
	//rough estimate at the longest latency we'll have around the world
	time.Sleep(500 * time.Millisecond)
}

func httpHandler(w http.ResponseWriter, req *http.Request) {
	reqHeader := w.Header()
	reqHeader.Set("Access-Control-Allow-Origin", "*")
	reqHeader.Set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0")
	reqHeader.Set("Server", serverName)
	if req.Method != "GET" && req.Method != "POST" {
		//assume its the browser just checking headers
		w.WriteHeader(http.StatusOK)
		return
	}
	str := strings.TrimLeft(req.URL.Path, "/")

	switch str {
	case "": //index page
		reqHeader.Set("Cache-Control", "max-age=3600") //1 hour
		w.Write(index)
		totalIndexRequests++
	case "favicon.ico":
		reqHeader.Set("Cache-Control", "max-age=31536000") //1 year
		w.Write(favicon)
	case "robots.txt":
		reqHeader.Set("Cache-Control", "max-age=31536000") //1 year
		w.Write(robots)
	default:
		totalTimeoutRequests++
		d, err := parseDurationString(str)
		query := req.URL.Query()
		exists := func(key string) bool { _, ok := query[key]; return ok }
		var resp []byte
		var contentType string
		switch {
		case exists("js"):
			resp = jsTrue
			contentType = "application/javascript"
		case exists("callback"):
			callback, _ := query["callback"]
			if len(callback) == 0 {
				callback = emptyCallback
			}
			resp = []byte(callback[0] + "(true)")
			contentType = "application/javascript"
		case exists("int"):
			resp = one
			contentType = "text/plain"
		case exists("json"):
			resp = jsonTrue
			contentType = "application/json"
		case exists("css"):
			resp = cssShow
			contentType = "text/css"
		default:
			resp = done
			contentType = "text/plain"
		}

		reqHeader.Set("Content-Type", contentType+"; charset=utf-8")
		if err != nil {
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		hj, ok := w.(http.Hijacker)
		if !ok {
			log.Println("Connection doesn't support hijacking for some reason")
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		//now hijack the connection so we can see if they disconnected
		conn, bufrw, err := hj.Hijack()
		if err != nil {
			log.Println("Failed to hijack http connection: " + err.Error())
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		defer closeAndWait(conn)

		reqHeader.Set("Content-Length", strconv.Itoa(len(resp)))
		reqHeader.Set("Connection", "close")

		//send back headers
		statusLine := http10StatusOK
		if req.ProtoAtLeast(1, 1) {
			statusLine = http11StatusOK
		}
		bufrw.Write(statusLine)
		reqHeader.Write(bufrw)
		bufrw.Write(crlf)

		//if they're going to be waiting more than 3 seconds immediately
		//send back headers to prevent timeout
		if d.Seconds() > 3 {
			bufrw.Flush()
		}
		if waitForTimeoutClose(conn, d) {
			bufrw.Write(resp)
			bufrw.Flush()
		}
	}
}

func parseDurationString(timeStr string) (time.Duration, error) {
	timeStr = strings.Trim(timeStr, " \r\n\t")
	var d time.Duration
	ms, err := strconv.ParseUint(timeStr, 10, 64)
	if err != nil {
		d, err = time.ParseDuration(timeStr)
		if err != nil {
			return d, err
		}
	} else {
		d = time.Duration(ms) * time.Millisecond
	}
	return d, nil
}
<commit_msg>Include an extra \n at the end of the info response<commit_after>package main

import (
	"bufio"
	"flag"
	"log"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"time"
)

var version = "0.3.1"
var favicon []byte
var index []byte
var robots []byte
var readDeadline = 5 * time.Second

var runningProcs = 0
var totalTimeoutRequests = 0
var totalTCPRequests = 0
var totalIndexRequests = 0

var http10StatusOK = []byte("HTTP/1.0 200 OK\r\n")
var http11StatusOK = []byte("HTTP/1.1 200 OK\r\n")
var crlf = []byte("\r\n")

//plain-text
var invalidFormat = []byte("invalid_format")
var done = []byte("done")
var invalidCommand = []byte("Unknown command. Type 'info'\n")

//int
var one = []byte("1")

//json
var jsonTrue = []byte("true")

//js
var jsTrue = []byte("_settimeoutio=true")

//css
var cssShow = []byte(".settimeoutio {display: block;}")

//callback
var emptyCallback = []string{""}

var serverName = "settimeout/" + version

func main() {
	addr := flag.String("addr", ":80", "HTTP address to listen on (empty to disable)")
	tcpAddr := flag.String("tcpaddr", ":5103", "Socket address to listen on (empty to disable)")
	statsAddr := flag.String("statsaddr", "127.0.0.1:5104", "Socket address to listen on for stats (empty to disable)")
	flag.Parse()

	var err error
	favicon, err = Asset("assets/favicon.ico")
	if err != nil {
		log.Fatal("Failed to read favicon.ico: " + err.Error())
	}
	index, err = Asset("assets/index.html")
	if err != nil {
		log.Fatal("Failed to read index.html: " + err.Error())
	}
	robots, err = Asset("assets/robots.txt")
	if err != nil {
		log.Fatal("Failed to read robots.txt: " + err.Error())
	}

	go startHTTPServer(*addr)
	go startTCPServer(*tcpAddr)
	go startStatsTCPServer(*statsAddr)

	//wait for a SIGINT
	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt)
	<-c
}

func startTCPServer(addr string) {
	if addr == "" {
		return
	}
	listen, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal("Failed to start TCP server: " + err.Error())
	}
	for {
		conn, err := listen.Accept()
		if err != nil {
			// handle error
			continue
		}
		go socketHandler(conn)
	}
}

func startStatsTCPServer(addr string) {
	if addr == "" {
		return
	}
	listen, err := net.Listen("tcp", addr)
	if err != nil {
		log.Fatal("Failed to start stats TCP server: " + err.Error())
	}
	for {
		conn, err := listen.Accept()
		if err != nil {
			// handle error
			continue
		}
		go func() {
			defer conn.Close()
			for {
				conn.SetReadDeadline(time.Now().Add(readDeadline))
				buf := bufio.NewReader(conn)
				str, err := buf.ReadString('\n')
				if err != nil {
					if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
						//if its a i/o timeout then just continue the loop again
						continue
					}
					return
				}
				str = strings.Trim(str, " \r\n\t")
				switch str {
				case "close", "quit", "exit":
					return
				case "info":
					infos := make([]string, 5) //+1 for extra \n at the end
					infos[0] = "Running Requests: " + strconv.Itoa(runningProcs)
					infos[1] = "Total HTTP Index Requests: " + strconv.Itoa(totalIndexRequests)
					infos[2] = "Total TCP Requests: " + strconv.Itoa(totalTCPRequests)
					infos[3] = "Total HTTP Timeout Requests: " + strconv.Itoa(totalTimeoutRequests)
					conn.Write([]byte(strings.Join(infos, "\n")))
				default:
					conn.Write(invalidCommand)
				}
			}
		}()
	}
}

func startHTTPServer(addr string) {
	if addr == "" {
		return
	}
	s := &http.Server{
		Addr:        addr,
		Handler:     http.HandlerFunc(httpHandler),
		ReadTimeout: readDeadline,
		//don't set a write deadline since it would set it from NOW which is not what we want
	}
	err := s.ListenAndServe()
	if err != nil {
		log.Fatal("Failed to start HTTP server: " + err.Error())
	}
}

func socketHandler(conn net.Conn) {
	defer closeAndWait(conn)
	conn.SetReadDeadline(time.Now().Add(readDeadline))
	buf := bufio.NewReader(conn)
	str, err := buf.ReadString('\n')
	if err != nil {
		return
	}
	totalTCPRequests++
	d, err := parseDurationString(str)
	if err != nil {
		conn.Write(invalidFormat)
		return
	}
	if waitForTimeoutClose(conn, d) {
		conn.Write(done)
	}
}

//returns if we should write or not becuase were leaving the writing to the caller
func waitForTimeoutClose(c net.Conn, timeout time.Duration) bool {
	if timeout.Nanoseconds() <= 0 {
		return true
	}

	runningProcs++
	closedCh := make(chan int)
	go func() {

		defer func() {
			runningProcs--
		}()

		singleChar := make([]byte, 1)
		for {
			c.SetReadDeadline(time.Now().Add(readDeadline))
			_, err := c.Read(singleChar)
			//if we got a read error and it wasn't a timeout then close the connection
			if netErr, ok := err.(net.Error); err != nil && (!ok || !netErr.Timeout()) {
				select {
				case closedCh <- 1:
				default:
				}
			}
			return
		}
	}()
	select {
	case <-closedCh:
		return false
	case <-time.After(timeout):
		return true
	}
}

func closeAndWait(c net.Conn) {
	defer c.Close()
	//from server.go which is from http://golang.org/issue/3595
	//close writing side first before actually closing the connection
	//and sending a RST
	if tcp, ok := c.(*net.TCPConn); ok {
		tcp.CloseWrite()
	}
	//using 500 milliseconds which is from rstAvoidanceDelay in server.go
	//rough estimate at the longest latency we'll have around the world
	time.Sleep(500 * time.Millisecond)
}

func httpHandler(w http.ResponseWriter, req *http.Request) {
	reqHeader := w.Header()
	reqHeader.Set("Access-Control-Allow-Origin", "*")
	reqHeader.Set("Cache-Control", "no-store, no-cache, must-revalidate, post-check=0, pre-check=0")
	reqHeader.Set("Server", serverName)
	if req.Method != "GET" && req.Method != "POST" {
		//assume its the browser just checking headers
		w.WriteHeader(http.StatusOK)
		return
	}
	str := strings.TrimLeft(req.URL.Path, "/")

	switch str {
	case "": //index page
		reqHeader.Set("Cache-Control", "max-age=3600") //1 hour
		w.Write(index)
		totalIndexRequests++
	case "favicon.ico":
		reqHeader.Set("Cache-Control", "max-age=31536000") //1 year
		w.Write(favicon)
	case "robots.txt":
		reqHeader.Set("Cache-Control", "max-age=31536000") //1 year
		w.Write(robots)
	default:
		totalTimeoutRequests++
		d, err := parseDurationString(str)
		query := req.URL.Query()
		exists := func(key string) bool { _, ok := query[key]; return ok }
		var resp []byte
		var contentType string
		switch {
		case exists("js"):
			resp = jsTrue
			contentType = "application/javascript"
		case exists("callback"):
			callback, _ := query["callback"]
			if len(callback) == 0 {
				callback = emptyCallback
			}
			resp = []byte(callback[0] + "(true)")
			contentType = "application/javascript"
		case exists("int"):
			resp = one
			contentType = "text/plain"
		case exists("json"):
			resp = jsonTrue
			contentType = "application/json"
		case exists("css"):
			resp = cssShow
			contentType = "text/css"
		default:
			resp = done
			contentType = "text/plain"
		}

		reqHeader.Set("Content-Type", contentType+"; charset=utf-8")
		if err != nil {
			w.WriteHeader(http.StatusBadRequest)
			return
		}

		hj, ok := w.(http.Hijacker)
		if !ok {
			log.Println("Connection doesn't support hijacking for some reason")
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		//now hijack the connection so we can see if they disconnected
		conn, bufrw, err := hj.Hijack()
		if err != nil {
			log.Println("Failed to hijack http connection: " + err.Error())
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
		defer closeAndWait(conn)

		reqHeader.Set("Content-Length", strconv.Itoa(len(resp)))
		reqHeader.Set("Connection", "close")

		//send back headers
		statusLine := http10StatusOK
		if req.ProtoAtLeast(1, 1) {
			statusLine = http11StatusOK
		}
		bufrw.Write(statusLine)
		reqHeader.Write(bufrw)
		bufrw.Write(crlf)

		//if they're going to be waiting more than 3 seconds immediately
		//send back headers to prevent timeout
		if d.Seconds() > 3 {
			bufrw.Flush()
		}
		if waitForTimeoutClose(conn, d) {
			bufrw.Write(resp)
			bufrw.Flush()
		}
	}
}

func parseDurationString(timeStr string) (time.Duration, error) {
	timeStr = strings.Trim(timeStr, " \r\n\t")
	var d time.Duration
	ms, err := strconv.ParseUint(timeStr, 10, 64)
	if err != nil {
		d, err = time.ParseDuration(timeStr)
		if err != nil {
			return d, err
		}
	} else {
		d = time.Duration(ms) * time.Millisecond
	}
	return d, nil
}
<|endoftext|>


<commit_before>package main

const VERSION = "0.4.3"
<commit_msg>:+1: Bump up the version<commit_after>package main

const VERSION = "0.5.0-alpha1"
<|endoftext|>


<commit_before>package main

var VERSION string = "v2.2.0.1"
<commit_msg>v2.2.0.0 release<commit_after>package main

var VERSION string = "v2.2.0.0"
<|endoftext|>


<commit_before>package main

const Version = "0.1.3"
<commit_msg>Rebuild to capture go-zigbee @ 8a6cc427a5e30de91a1b36b5f5071735ff5621b0<commit_after>package main

const Version = "0.1.4"
<|endoftext|>


<commit_before>package main

const VERSION = "2.5.0"
<commit_msg>bump version to v2.5.1-beta<commit_after>package main

const VERSION = "2.5.1-beta"
<|endoftext|>


<commit_before>package atlas

const ourVersion = "0.5.0"

// APIVersion is the official API (not CLI) version.
func APIVersion() string {
	return ourVersion
}
<commit_msg>APIVersion was not necessary, sorry.<commit_after>package atlas

const ourVersion = "0.5.0"
<|endoftext|>


<commit_before>package main

// Name is executable name of this application.
const Name string = "mackerel-plugin-mogilefs"

// Version is version string of this application.
const Version string = "0.4.0"
<commit_msg>bumpup version<commit_after>package main

// Name is executable name of this application.
const Name string = "mackerel-plugin-mogilefs"

// Version is version string of this application.
const Version string = "0.4.1"
<|endoftext|>


<commit_before>package main

import (
	"fmt"
)

const Version = "dev"

var cmdVersion = &Command{
	Run:   runVersion,
	Usage: "version",
	Short: "Show gh version",
	Long:  `Version shows the gh client version showstring.`,
}

func runVersion(cmd *Command, args []string) {
	fmt.Println(Version)
}
<commit_msg>Bump version to 0.0.1<commit_after>package main

import (
	"fmt"
)

const Version = "0.0.1"

var cmdVersion = &Command{
	Run:   runVersion,
	Usage: "version",
	Short: "Show gh version",
	Long:  `Version shows the gh client version showstring.`,
}

func runVersion(cmd *Command, args []string) {
	fmt.Println(Version)
}
<|endoftext|>


<commit_before>package main

const VERSION = "0.7.1-alpha2"
<commit_msg>:+1: Bump up the version to 0.7.1-alpha3<commit_after>package main

const VERSION = "0.7.1-alpha3"
<|endoftext|>


<commit_before>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

// versionString is the sem-ver version string for yab.
// It will be bumped explicitly on releases.
var versionString = "0.3.0"
<commit_msg>Update version to 0.3.1-dev<commit_after>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package main

// versionString is the sem-ver version string for yab.
// It will be bumped explicitly on releases.
var versionString = "0.3.1-dev"
<|endoftext|>


<commit_before>// Copyright 2014 The Cayley Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package db

import (
	"fmt"
	"io"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"time"

	"github.com/peterh/liner"

	"github.com/google/cayley/config"
	"github.com/google/cayley/graph"
	"github.com/google/cayley/quad/cquads"
	"github.com/google/cayley/query"
	"github.com/google/cayley/query/gremlin"
	"github.com/google/cayley/query/mql"
	"github.com/google/cayley/query/sexp"
)

func trace(s string) (string, time.Time) {
	return s, time.Now()
}

func un(s string, startTime time.Time) {
	endTime := time.Now()

	fmt.Printf(s, float64(endTime.UnixNano()-startTime.UnixNano())/float64(1E6))
}

func Run(query string, ses query.Session) {
	nResults := 0
	startTrace, startTime := trace("Elapsed time: %g ms\n\n")
	defer func() {
		if nResults > 0 {
			un(startTrace, startTime)
		}
	}()
	fmt.Printf("\n")
	c := make(chan interface{}, 5)
	go ses.Execute(query, c, 100)
	for res := range c {
		fmt.Print(ses.Format(res))
		nResults++
	}
	if nResults > 0 {
		fmt.Printf("-----------\n%d Results\n", nResults)
	}
}

const (
	ps1 = "cayley> "
	ps2 = "...     "

	history = ".cayley_history"
)

func Repl(h *graph.Handle, queryLanguage string, cfg *config.Config) error {
	var ses query.Session
	switch queryLanguage {
	case "sexp":
		ses = sexp.NewSession(h.QuadStore)
	case "mql":
		ses = mql.NewSession(h.QuadStore)
	case "gremlin":
		fallthrough
	default:
		ses = gremlin.NewSession(h.QuadStore, cfg.Timeout, true)
	}

	term, err := terminal(history)
	if os.IsNotExist(err) {
		fmt.Printf("creating new history file: %q\n", history)
	}
	defer persist(term, history)

	var (
		prompt = ps1

		code string
	)

	for {
		if len(code) == 0 {
			prompt = ps1
		} else {
			prompt = ps2
		}
		line, err := term.Prompt(prompt)
		if err != nil {
			if err == io.EOF {
				fmt.Println()
				return nil
			}
			return err
		}

		term.AppendHistory(line)

		line = strings.TrimSpace(line)
		if len(line) == 0 || line[0] == '#' {
			continue
		}

		if code == "" {
			cmd, args := splitLine(line)

			switch cmd {
			case ":debug":
				args = strings.TrimSpace(args)
				var debug bool
				switch args {
				case "t":
					debug = true
				case "f":
					// Do nothing.
				default:
					debug, err = strconv.ParseBool(args)
					if err != nil {
						fmt.Printf("Error: cannot parse %q as a valid boolean - acceptable values: 't'|'true' or 'f'|'false'\n", args)
						continue
					}
				}
				ses.Debug(debug)
				fmt.Printf("Debug set to %t\n", debug)
				continue

			case ":a":
				quad, err := cquads.Parse(args)
				if err != nil {
					fmt.Printf("Error: not a valid quad: %v\n", err)
					continue
				}

				h.QuadWriter.AddQuad(quad)
				continue

			case ":d":
				quad, err := cquads.Parse(args)
				if err != nil {
					fmt.Printf("Error: not a valid quad: %v\n", err)
					continue
				}
				h.QuadWriter.RemoveQuad(quad)
				continue

			default:
				if cmd[0] == ':' {
					fmt.Printf("Unknown command: %q\n", cmd)
					continue
				}
			}
		}

		code += line

		result, err := ses.Parse(code)
		switch result {
		case query.Parsed:
			Run(code, ses)
			code = ""
		case query.ParseFail:
			fmt.Println("Error: ", err)
			code = ""
		case query.ParseMore:
		}
	}
}

// Splits a line into a command and its arguments
// e.g. ":a b c d ." will be split into ":a" and " b c d ."
func splitLine(line string) (string, string) {
	var command, arguments string

	line = strings.TrimSpace(line)

	// An empty line/a line consisting of whitespace contains neither command nor arguments
	if len(line) > 0 {
		command = strings.Fields(line)[0]

		// A line containing only a command has no arguments
		if len(line) > len(command) {
			arguments = line[len(command):]
		}
	}

	return command, arguments
}

func terminal(path string) (*liner.State, error) {
	term := liner.NewLiner()

	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)
		<-c

		err := persist(term, history)
		if err != nil {
			fmt.Fprintf(os.Stderr, "failed to properly clean up terminal: %v\n", err)
			os.Exit(1)
		}

		os.Exit(0)
	}()

	f, err := os.Open(path)
	if err != nil {
		return term, err
	}
	defer f.Close()
	_, err = term.ReadHistory(f)
	return term, err
}

func persist(term *liner.State, path string) error {
	f, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		return fmt.Errorf("could not open %q to append history: %v", path, err)
	}
	defer f.Close()
	_, err = term.WriteHistory(f)
	if err != nil {
		return fmt.Errorf("could not write history to %q: %v", path, err)
	}
	return term.Close()
}
<commit_msg>Fixes #261 -- Quit repl when user types "exit"<commit_after>// Copyright 2014 The Cayley Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package db

import (
	"fmt"
	"io"
	"os"
	"os/signal"
	"strconv"
	"strings"
	"time"

	"github.com/peterh/liner"

	"github.com/google/cayley/config"
	"github.com/google/cayley/graph"
	"github.com/google/cayley/quad/cquads"
	"github.com/google/cayley/query"
	"github.com/google/cayley/query/gremlin"
	"github.com/google/cayley/query/mql"
	"github.com/google/cayley/query/sexp"
)

func trace(s string) (string, time.Time) {
	return s, time.Now()
}

func un(s string, startTime time.Time) {
	endTime := time.Now()

	fmt.Printf(s, float64(endTime.UnixNano()-startTime.UnixNano())/float64(1E6))
}

func Run(query string, ses query.Session) {
	nResults := 0
	startTrace, startTime := trace("Elapsed time: %g ms\n\n")
	defer func() {
		if nResults > 0 {
			un(startTrace, startTime)
		}
	}()
	fmt.Printf("\n")
	c := make(chan interface{}, 5)
	go ses.Execute(query, c, 100)
	for res := range c {
		fmt.Print(ses.Format(res))
		nResults++
	}
	if nResults > 0 {
		fmt.Printf("-----------\n%d Results\n", nResults)
	}
}

const (
	ps1 = "cayley> "
	ps2 = "...     "

	history = ".cayley_history"
)

func Repl(h *graph.Handle, queryLanguage string, cfg *config.Config) error {
	var ses query.Session
	switch queryLanguage {
	case "sexp":
		ses = sexp.NewSession(h.QuadStore)
	case "mql":
		ses = mql.NewSession(h.QuadStore)
	case "gremlin":
		fallthrough
	default:
		ses = gremlin.NewSession(h.QuadStore, cfg.Timeout, true)
	}

	term, err := terminal(history)
	if os.IsNotExist(err) {
		fmt.Printf("creating new history file: %q\n", history)
	}
	defer persist(term, history)

	var (
		prompt = ps1

		code string
	)

	for {
		if len(code) == 0 {
			prompt = ps1
		} else {
			prompt = ps2
		}
		line, err := term.Prompt(prompt)
		if err != nil {
			if err == io.EOF {
				fmt.Println()
				return nil
			}
			return err
		}

		term.AppendHistory(line)

		line = strings.TrimSpace(line)
		if len(line) == 0 || line[0] == '#' {
			continue
		}

		if code == "" {
			cmd, args := splitLine(line)

			switch cmd {
			case ":debug":
				args = strings.TrimSpace(args)
				var debug bool
				switch args {
				case "t":
					debug = true
				case "f":
					// Do nothing.
				default:
					debug, err = strconv.ParseBool(args)
					if err != nil {
						fmt.Printf("Error: cannot parse %q as a valid boolean - acceptable values: 't'|'true' or 'f'|'false'\n", args)
						continue
					}
				}
				ses.Debug(debug)
				fmt.Printf("Debug set to %t\n", debug)
				continue

			case ":a":
				quad, err := cquads.Parse(args)
				if err != nil {
					fmt.Printf("Error: not a valid quad: %v\n", err)
					continue
				}

				h.QuadWriter.AddQuad(quad)
				continue

			case ":d":
				quad, err := cquads.Parse(args)
				if err != nil {
					fmt.Printf("Error: not a valid quad: %v\n", err)
					continue
				}
				h.QuadWriter.RemoveQuad(quad)
				continue

			case "exit":
				term.Close()
				os.Exit(0)

			default:
				if cmd[0] == ':' {
					fmt.Printf("Unknown command: %q\n", cmd)
					continue
				}
			}
		}

		code += line

		result, err := ses.Parse(code)
		switch result {
		case query.Parsed:
			Run(code, ses)
			code = ""
		case query.ParseFail:
			fmt.Println("Error: ", err)
			code = ""
		case query.ParseMore:
		}
	}
}

// Splits a line into a command and its arguments
// e.g. ":a b c d ." will be split into ":a" and " b c d ."
func splitLine(line string) (string, string) {
	var command, arguments string

	line = strings.TrimSpace(line)

	// An empty line/a line consisting of whitespace contains neither command nor arguments
	if len(line) > 0 {
		command = strings.Fields(line)[0]

		// A line containing only a command has no arguments
		if len(line) > len(command) {
			arguments = line[len(command):]
		}
	}

	return command, arguments
}

func terminal(path string) (*liner.State, error) {
	term := liner.NewLiner()

	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)
		<-c

		err := persist(term, history)
		if err != nil {
			fmt.Fprintf(os.Stderr, "failed to properly clean up terminal: %v\n", err)
			os.Exit(1)
		}

		os.Exit(0)
	}()

	f, err := os.Open(path)
	if err != nil {
		return term, err
	}
	defer f.Close()
	_, err = term.ReadHistory(f)
	return term, err
}

func persist(term *liner.State, path string) error {
	f, err := os.OpenFile(path, os.O_RDWR|os.O_APPEND|os.O_CREATE, 0666)
	if err != nil {
		return fmt.Errorf("could not open %q to append history: %v", path, err)
	}
	defer f.Close()
	_, err = term.WriteHistory(f)
	if err != nil {
		return fmt.Errorf("could not write history to %q: %v", path, err)
	}
	return term.Close()
}
<|endoftext|>


<commit_before>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state_test

import (
	jc "github.com/juju/testing/checkers"
	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/state"
)

type ActionSuite struct {
	ConnSuite
	charm   *state.Charm
	service *state.Service
	unit    *state.Unit
}

var _ = gc.Suite(&ActionSuite{})

func (s *ActionSuite) SetUpTest(c *gc.C) {
	s.ConnSuite.SetUpTest(c)
	s.charm = s.AddTestingCharm(c, "wordpress")
	var err error
	s.service = s.AddTestingService(c, "wordpress", s.charm)
	c.Assert(err, gc.IsNil)
	s.unit, err = s.service.AddUnit()
	c.Assert(err, gc.IsNil)
	c.Assert(s.unit.Series(), gc.Equals, "quantal")
}

func (s *ActionSuite) TestAddAction(c *gc.C) {
	actionName := "fakeaction"
	actionParams := map[string]interface{}{"outfile": "outfile.tar.bz2"}

	// verify can add an Action
	actionId, err := s.unit.AddAction(actionName, actionParams)
	c.Assert(err, gc.IsNil)
	assertSaneActionId(c, actionId, s.unit.Name())

	// verify we can get it back out by Id
	action, err := s.State.Action(actionId)
	c.Assert(err, gc.IsNil)
	c.Assert(action, gc.NotNil)
	c.Assert(action.Id(), gc.Equals, actionId)

	// verify we get out what we put in
	c.Assert(action.Name(), gc.Equals, actionName)
	c.Assert(action.Payload(), jc.DeepEquals, actionParams)
}

func (s *ActionSuite) TestAddActionLifecycle(c *gc.C) {
	unit, err := s.State.Unit(s.unit.Name())
	c.Assert(err, gc.IsNil)
	preventUnitDestroyRemove(c, unit)

	// make unit state Dying
	err = unit.Destroy()
	c.Assert(err, gc.IsNil)

	// can add action to a dying unit
	actionId, err := unit.AddAction("fakeaction1", map[string]interface{}{})
	c.Assert(err, gc.IsNil)
	assertSaneActionId(c, actionId, s.unit.Name())

	// make sure unit is dead
	err = unit.EnsureDead()
	c.Assert(err, gc.IsNil)

	// cannot add action to a dead unit
	_, err = unit.AddAction("fakeaction2", map[string]interface{}{})
	c.Assert(err, gc.ErrorMatches, "unit .* is dead")
}

func (s *ActionSuite) TestAddActionFailsOnDeadUnitInTransaction(c *gc.C) {
	unit, err := s.State.Unit(s.unit.Name())
	c.Assert(err, gc.IsNil)
	preventUnitDestroyRemove(c, unit)

	killUnit := state.TransactionHook{
		Before: func() {
			c.Assert(unit.Destroy(), gc.IsNil)
			c.Assert(unit.EnsureDead(), gc.IsNil)
		},
	}
	defer state.SetTransactionHooks(c, s.State, killUnit).Check()

	_, err = unit.AddAction("fakeaction", map[string]interface{}{})
	c.Assert(err, gc.ErrorMatches, "unit .* is dead")
}

// assertSaneActionId verifies that the actionId is of the expected
// form (unit id prefix + sequence)
// This is a temporary assertion, we shouldn't be leaking the actual
// mongo _id
func assertSaneActionId(c *gc.C, actionId, unitName string) {
	c.Assert(actionId, gc.Matches, "^u#"+unitName+"#a#\\d+")
}
<commit_msg>add test for Action.Fail<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package state_test

import (
	"github.com/juju/loggo"
	jc "github.com/juju/testing/checkers"
	gc "launchpad.net/gocheck"

	"launchpad.net/juju-core/state"
)

type ActionSuite struct {
	ConnSuite
	charm   *state.Charm
	service *state.Service
	unit    *state.Unit
}

var _ = gc.Suite(&ActionSuite{})

func (s *ActionSuite) SetUpTest(c *gc.C) {
	s.ConnSuite.SetUpTest(c)
	s.charm = s.AddTestingCharm(c, "wordpress")
	var err error
	s.service = s.AddTestingService(c, "wordpress", s.charm)
	c.Assert(err, gc.IsNil)
	s.unit, err = s.service.AddUnit()
	c.Assert(err, gc.IsNil)
	c.Assert(s.unit.Series(), gc.Equals, "quantal")
}

func (s *ActionSuite) TestAddAction(c *gc.C) {
	actionName := "fakeaction"
	actionParams := map[string]interface{}{"outfile": "outfile.tar.bz2"}

	// verify can add an Action
	actionId, err := s.unit.AddAction(actionName, actionParams)
	c.Assert(err, gc.IsNil)
	assertSaneActionId(c, actionId, s.unit.Name())

	// verify we can get it back out by Id
	action, err := s.State.Action(actionId)
	c.Assert(err, gc.IsNil)
	c.Assert(action, gc.NotNil)
	c.Assert(action.Id(), gc.Equals, actionId)

	// verify we get out what we put in
	c.Assert(action.Name(), gc.Equals, actionName)
	c.Assert(action.Payload(), jc.DeepEquals, actionParams)
}

func (s *ActionSuite) TestAddActionLifecycle(c *gc.C) {
	unit, err := s.State.Unit(s.unit.Name())
	c.Assert(err, gc.IsNil)
	preventUnitDestroyRemove(c, unit)

	// make unit state Dying
	err = unit.Destroy()
	c.Assert(err, gc.IsNil)

	// can add action to a dying unit
	actionId, err := unit.AddAction("fakeaction1", map[string]interface{}{})
	c.Assert(err, gc.IsNil)
	assertSaneActionId(c, actionId, s.unit.Name())

	// make sure unit is dead
	err = unit.EnsureDead()
	c.Assert(err, gc.IsNil)

	// cannot add action to a dead unit
	_, err = unit.AddAction("fakeaction2", map[string]interface{}{})
	c.Assert(err, gc.ErrorMatches, "unit .* is dead")
}

func (s *ActionSuite) TestAddActionFailsOnDeadUnitInTransaction(c *gc.C) {
	unit, err := s.State.Unit(s.unit.Name())
	c.Assert(err, gc.IsNil)
	preventUnitDestroyRemove(c, unit)

	killUnit := state.TransactionHook{
		Before: func() {
			c.Assert(unit.Destroy(), gc.IsNil)
			c.Assert(unit.EnsureDead(), gc.IsNil)
		},
	}
	defer state.SetTransactionHooks(c, s.State, killUnit).Check()

	_, err = unit.AddAction("fakeaction", map[string]interface{}{})
	c.Assert(err, gc.ErrorMatches, "unit .* is dead")
}

func (s *ActionSuite) TestFail(c *gc.C) {
	defer loggo.ResetWriters()
	logger := loggo.GetLogger("test")
	logger.SetLogLevel(loggo.DEBUG)
	tw := &loggo.TestWriter{}
	c.Assert(loggo.RegisterWriter("actions-tester", tw, loggo.DEBUG), gc.IsNil)

	unit, err := s.State.Unit(s.unit.Name())
	c.Assert(err, gc.IsNil)
	preventUnitDestroyRemove(c, unit)

	actionId, err := unit.AddAction("action1", nil)
	c.Assert(err, gc.IsNil)

	action, err := s.State.Action(actionId)
	c.Assert(err, gc.IsNil)

	reason := "test fail reason"
	err = action.Fail(reason)
	c.Assert(err, gc.IsNil)
	c.Assert(tw.Log, jc.LogMatches, jc.SimpleMessages{{loggo.WARNING, reason}})
}

// assertSaneActionId verifies that the actionId is of the expected
// form (unit id prefix + sequence)
// This is a temporary assertion, we shouldn't be leaking the actual
// mongo _id
func assertSaneActionId(c *gc.C, actionId, unitName string) {
	c.Assert(actionId, gc.Matches, "^u#"+unitName+"#a#\\d+")
}
<|endoftext|>