<commit_before>package main

import (
	"fmt"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"sort"
	"strings"
	"syscall"

	"github.com/Sirupsen/logrus"
	"github.com/containers/storage/pkg/reexec"
	"github.com/kubernetes-incubator/cri-o/server"
	"github.com/opencontainers/selinux/go-selinux"
	"github.com/urfave/cli"
	"google.golang.org/grpc"
	"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)

const crioConfigPath = "/etc/crio/crio.conf"

func mergeConfig(config *server.Config, ctx *cli.Context) error {
	// Don't parse the config if the user explicitly set it to "".
	if path := ctx.GlobalString("config"); path != "" {
		if err := config.FromFile(path); err != nil {
			if ctx.GlobalIsSet("config") || !os.IsNotExist(err) {
				return err
			}

			// We don't error out if --config wasn't explicitly set and the
			// default doesn't exist. But we will log a warning about it, so
			// the user doesn't miss it.
			logrus.Warnf("default configuration file does not exist: %s", crioConfigPath)
		}
	}

	// Override options set with the CLI.
	if ctx.GlobalIsSet("conmon") {
		config.Conmon = ctx.GlobalString("conmon")
	}
	if ctx.GlobalIsSet("pause-command") {
		config.PauseCommand = ctx.GlobalString("pause-command")
	}
	if ctx.GlobalIsSet("pause-image") {
		config.PauseImage = ctx.GlobalString("pause-image")
	}
	if ctx.GlobalIsSet("signature-policy") {
		config.SignaturePolicyPath = ctx.GlobalString("signature-policy")
	}
	if ctx.GlobalIsSet("root") {
		config.Root = ctx.GlobalString("root")
	}
	if ctx.GlobalIsSet("runroot") {
		config.RunRoot = ctx.GlobalString("runroot")
	}
	if ctx.GlobalIsSet("storage-driver") {
		config.Storage = ctx.GlobalString("storage-driver")
	}
	if ctx.GlobalIsSet("storage-opt") {
		config.StorageOptions = ctx.GlobalStringSlice("storage-opt")
	}
	if ctx.GlobalIsSet("insecure-registry") {
		config.InsecureRegistries = ctx.GlobalStringSlice("insecure-registries")
	}
	if ctx.GlobalIsSet("default-transport") {
		config.DefaultTransport = ctx.GlobalString("default-transport")
	}
	if ctx.GlobalIsSet("listen") {
		config.Listen = ctx.GlobalString("listen")
	}
	if ctx.GlobalIsSet("stream-address") {
		config.StreamAddress = ctx.GlobalString("stream-address")
	}
	if ctx.GlobalIsSet("stream-port") {
		config.StreamPort = ctx.GlobalString("stream-port")
	}
	if ctx.GlobalIsSet("runtime") {
		config.Runtime = ctx.GlobalString("runtime")
	}
	if ctx.GlobalIsSet("selinux") {
		config.SELinux = ctx.GlobalBool("selinux")
	}
	if ctx.GlobalIsSet("seccomp-profile") {
		config.SeccompProfile = ctx.GlobalString("seccomp-profile")
	}
	if ctx.GlobalIsSet("apparmor-profile") {
		config.ApparmorProfile = ctx.GlobalString("apparmor-profile")
	}
	if ctx.GlobalIsSet("cgroup-manager") {
		config.CgroupManager = ctx.GlobalString("cgroup-manager")
	}
	if ctx.GlobalIsSet("cni-config-dir") {
		config.NetworkDir = ctx.GlobalString("cni-config-dir")
	}
	if ctx.GlobalIsSet("cni-plugin-dir") {
		config.PluginDir = ctx.GlobalString("cni-plugin-dir")
	}
	return nil
}

func catchShutdown(gserver *grpc.Server, sserver *server.Server, signalled *bool) {
	sig := make(chan os.Signal, 10)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		for s := range sig {
			switch s {
			case syscall.SIGINT:
				logrus.Debugf("Caught SIGINT")
			case syscall.SIGTERM:
				logrus.Debugf("Caught SIGTERM")
			default:
				continue
			}
			*signalled = true
			gserver.GracefulStop()
			return
		}
	}()
}

func main() {
	if reexec.Init() {
		return
	}
	app := cli.NewApp()
	app.Name = "crio"
	app.Usage = "crio server"
	app.Version = "1.0.0-alpha.0"
	app.Metadata = map[string]interface{}{
		"config": server.DefaultConfig(),
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config",
			Value: crioConfigPath,
			Usage: "path to configuration file",
		},
		cli.StringFlag{
			Name:  "conmon",
			Usage: "path to the conmon executable",
		},
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output for logging",
		},
		cli.StringFlag{
			Name:  "listen",
			Usage: "path to crio socket",
		},
		cli.StringFlag{
			Name:  "stream-address",
			Usage: "bind address for streaming socket",
		},
		cli.StringFlag{
			Name:  "stream-port",
			Usage: "bind port for streaming socket (default: \"10010\")",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "",
			Usage: "set the log file path where internal debug information is written",
		},
		cli.StringFlag{
			Name:  "log-format",
			Value: "text",
			Usage: "set the format used by logs ('text' (default), or 'json')",
		},
		cli.StringFlag{
			Name:  "pause-command",
			Usage: "name of the pause command in the pause image",
		},
		cli.StringFlag{
			Name:  "pause-image",
			Usage: "name of the pause image",
		},
		cli.StringFlag{
			Name:  "signature-policy",
			Usage: "path to signature policy file",
		},
		cli.StringFlag{
			Name:  "root",
			Usage: "crio root dir",
		},
		cli.StringFlag{
			Name:  "runroot",
			Usage: "crio state dir",
		},
		cli.StringFlag{
			Name:  "storage-driver",
			Usage: "storage driver",
		},
		cli.StringSliceFlag{
			Name:  "storage-opt",
			Usage: "storage driver option",
		},
		cli.StringSliceFlag{
			Name:  "insecure-registry",
			Usage: "whether to disable TLS verification for the given registry",
		},
		cli.StringFlag{
			Name:  "default-transport",
			Usage: "default transport",
		},
		cli.StringFlag{
			Name:  "runtime",
			Usage: "OCI runtime path",
		},
		cli.StringFlag{
			Name:  "seccomp-profile",
			Usage: "default seccomp profile path",
		},
		cli.StringFlag{
			Name:  "apparmor-profile",
			Usage: "default apparmor profile name (default: \"crio-default\")",
		},
		cli.BoolFlag{
			Name:  "selinux",
			Usage: "enable selinux support",
		},
		cli.StringFlag{
			Name:  "cgroup-manager",
			Usage: "cgroup manager (cgroupfs or systemd)",
		},
		cli.StringFlag{
			Name:  "cni-config-dir",
			Usage: "CNI configuration files directory",
		},
		cli.StringFlag{
			Name:  "cni-plugin-dir",
			Usage: "CNI plugin binaries directory",
		},
		cli.BoolFlag{
			Name:  "profile",
			Usage: "enable pprof remote profiler on localhost:6060",
		},
	}

	sort.Sort(cli.FlagsByName(app.Flags))
	sort.Sort(cli.FlagsByName(configCommand.Flags))

	app.Commands = []cli.Command{
		configCommand,
	}

	app.Before = func(c *cli.Context) error {
		// Load the configuration file.
		config := c.App.Metadata["config"].(*server.Config)
		if err := mergeConfig(config, c); err != nil {
			return err
		}

		cf := &logrus.TextFormatter{
			TimestampFormat: "2006-01-02 15:04:05.000000000Z07:00",
			FullTimestamp:   true,
		}

		logrus.SetFormatter(cf)

		if c.GlobalBool("debug") {
			logrus.SetLevel(logrus.DebugLevel)
		}

		if path := c.GlobalString("log"); path != "" {
			f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0666)
			if err != nil {
				return err
			}
			logrus.SetOutput(f)
		}

		switch c.GlobalString("log-format") {
		case "text":
			// retain logrus's default.
		case "json":
			logrus.SetFormatter(new(logrus.JSONFormatter))
		default:
			return fmt.Errorf("unknown log-format %q", c.GlobalString("log-format"))
		}

		return nil
	}

	app.Action = func(c *cli.Context) error {
		if c.GlobalBool("profile") {
			go func() {
				http.ListenAndServe("localhost:6060", nil)
			}()
		}

		config := c.App.Metadata["config"].(*server.Config)

		if !config.SELinux {
			selinux.SetDisabled()
		}

		if _, err := os.Stat(config.Runtime); os.IsNotExist(err) {
			// path to runtime does not exist
			return fmt.Errorf("invalid --runtime value %q", err)
		}

		// Remove the socket if it already exists
		if _, err := os.Stat(config.Listen); err == nil {
			if err := os.Remove(config.Listen); err != nil {
				logrus.Fatal(err)
			}
		}
		lis, err := net.Listen("unix", config.Listen)
		if err != nil {
			logrus.Fatalf("failed to listen: %v", err)
		}

		s := grpc.NewServer()

		service, err := server.New(config)
		if err != nil {
			logrus.Fatal(err)
		}

		graceful := false
		catchShutdown(s, service, &graceful)
		runtime.RegisterRuntimeServiceServer(s, service)
		runtime.RegisterImageServiceServer(s, service)

		// after the daemon is done setting up we can notify systemd api
		notifySystem()

		err = s.Serve(lis)
		if graceful && strings.Contains(strings.ToLower(err.Error()), "use of closed network connection") {
			err = nil
		}

		if err2 := service.Shutdown(); err2 != nil {
			logrus.Infof("error shutting down layer storage: %v", err2)
		}

		if err != nil {
			logrus.Fatal(err)
		}
		return nil
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}
<commit_msg>cmd/crio: fix reading insecure-registry flags<commit_after>package main

import (
	"fmt"
	"net"
	"net/http"
	_ "net/http/pprof"
	"os"
	"os/signal"
	"sort"
	"strings"
	"syscall"

	"github.com/Sirupsen/logrus"
	"github.com/containers/storage/pkg/reexec"
	"github.com/kubernetes-incubator/cri-o/server"
	"github.com/opencontainers/selinux/go-selinux"
	"github.com/urfave/cli"
	"google.golang.org/grpc"
	"k8s.io/kubernetes/pkg/kubelet/api/v1alpha1/runtime"
)

const crioConfigPath = "/etc/crio/crio.conf"

func mergeConfig(config *server.Config, ctx *cli.Context) error {
	// Don't parse the config if the user explicitly set it to "".
	if path := ctx.GlobalString("config"); path != "" {
		if err := config.FromFile(path); err != nil {
			if ctx.GlobalIsSet("config") || !os.IsNotExist(err) {
				return err
			}

			// We don't error out if --config wasn't explicitly set and the
			// default doesn't exist. But we will log a warning about it, so
			// the user doesn't miss it.
			logrus.Warnf("default configuration file does not exist: %s", crioConfigPath)
		}
	}

	// Override options set with the CLI.
	if ctx.GlobalIsSet("conmon") {
		config.Conmon = ctx.GlobalString("conmon")
	}
	if ctx.GlobalIsSet("pause-command") {
		config.PauseCommand = ctx.GlobalString("pause-command")
	}
	if ctx.GlobalIsSet("pause-image") {
		config.PauseImage = ctx.GlobalString("pause-image")
	}
	if ctx.GlobalIsSet("signature-policy") {
		config.SignaturePolicyPath = ctx.GlobalString("signature-policy")
	}
	if ctx.GlobalIsSet("root") {
		config.Root = ctx.GlobalString("root")
	}
	if ctx.GlobalIsSet("runroot") {
		config.RunRoot = ctx.GlobalString("runroot")
	}
	if ctx.GlobalIsSet("storage-driver") {
		config.Storage = ctx.GlobalString("storage-driver")
	}
	if ctx.GlobalIsSet("storage-opt") {
		config.StorageOptions = ctx.GlobalStringSlice("storage-opt")
	}
	if ctx.GlobalIsSet("insecure-registry") {
		config.InsecureRegistries = ctx.GlobalStringSlice("insecure-registry")
	}
	if ctx.GlobalIsSet("default-transport") {
		config.DefaultTransport = ctx.GlobalString("default-transport")
	}
	if ctx.GlobalIsSet("listen") {
		config.Listen = ctx.GlobalString("listen")
	}
	if ctx.GlobalIsSet("stream-address") {
		config.StreamAddress = ctx.GlobalString("stream-address")
	}
	if ctx.GlobalIsSet("stream-port") {
		config.StreamPort = ctx.GlobalString("stream-port")
	}
	if ctx.GlobalIsSet("runtime") {
		config.Runtime = ctx.GlobalString("runtime")
	}
	if ctx.GlobalIsSet("selinux") {
		config.SELinux = ctx.GlobalBool("selinux")
	}
	if ctx.GlobalIsSet("seccomp-profile") {
		config.SeccompProfile = ctx.GlobalString("seccomp-profile")
	}
	if ctx.GlobalIsSet("apparmor-profile") {
		config.ApparmorProfile = ctx.GlobalString("apparmor-profile")
	}
	if ctx.GlobalIsSet("cgroup-manager") {
		config.CgroupManager = ctx.GlobalString("cgroup-manager")
	}
	if ctx.GlobalIsSet("cni-config-dir") {
		config.NetworkDir = ctx.GlobalString("cni-config-dir")
	}
	if ctx.GlobalIsSet("cni-plugin-dir") {
		config.PluginDir = ctx.GlobalString("cni-plugin-dir")
	}
	return nil
}

func catchShutdown(gserver *grpc.Server, sserver *server.Server, signalled *bool) {
	sig := make(chan os.Signal, 10)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		for s := range sig {
			switch s {
			case syscall.SIGINT:
				logrus.Debugf("Caught SIGINT")
			case syscall.SIGTERM:
				logrus.Debugf("Caught SIGTERM")
			default:
				continue
			}
			*signalled = true
			gserver.GracefulStop()
			return
		}
	}()
}

func main() {
	if reexec.Init() {
		return
	}
	app := cli.NewApp()
	app.Name = "crio"
	app.Usage = "crio server"
	app.Version = "1.0.0-alpha.0"
	app.Metadata = map[string]interface{}{
		"config": server.DefaultConfig(),
	}

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "config",
			Value: crioConfigPath,
			Usage: "path to configuration file",
		},
		cli.StringFlag{
			Name:  "conmon",
			Usage: "path to the conmon executable",
		},
		cli.BoolFlag{
			Name:  "debug",
			Usage: "enable debug output for logging",
		},
		cli.StringFlag{
			Name:  "listen",
			Usage: "path to crio socket",
		},
		cli.StringFlag{
			Name:  "stream-address",
			Usage: "bind address for streaming socket",
		},
		cli.StringFlag{
			Name:  "stream-port",
			Usage: "bind port for streaming socket (default: \"10010\")",
		},
		cli.StringFlag{
			Name:  "log",
			Value: "",
			Usage: "set the log file path where internal debug information is written",
		},
		cli.StringFlag{
			Name:  "log-format",
			Value: "text",
			Usage: "set the format used by logs ('text' (default), or 'json')",
		},
		cli.StringFlag{
			Name:  "pause-command",
			Usage: "name of the pause command in the pause image",
		},
		cli.StringFlag{
			Name:  "pause-image",
			Usage: "name of the pause image",
		},
		cli.StringFlag{
			Name:  "signature-policy",
			Usage: "path to signature policy file",
		},
		cli.StringFlag{
			Name:  "root",
			Usage: "crio root dir",
		},
		cli.StringFlag{
			Name:  "runroot",
			Usage: "crio state dir",
		},
		cli.StringFlag{
			Name:  "storage-driver",
			Usage: "storage driver",
		},
		cli.StringSliceFlag{
			Name:  "storage-opt",
			Usage: "storage driver option",
		},
		cli.StringSliceFlag{
			Name:  "insecure-registry",
			Usage: "whether to disable TLS verification for the given registry",
		},
		cli.StringFlag{
			Name:  "default-transport",
			Usage: "default transport",
		},
		cli.StringFlag{
			Name:  "runtime",
			Usage: "OCI runtime path",
		},
		cli.StringFlag{
			Name:  "seccomp-profile",
			Usage: "default seccomp profile path",
		},
		cli.StringFlag{
			Name:  "apparmor-profile",
			Usage: "default apparmor profile name (default: \"crio-default\")",
		},
		cli.BoolFlag{
			Name:  "selinux",
			Usage: "enable selinux support",
		},
		cli.StringFlag{
			Name:  "cgroup-manager",
			Usage: "cgroup manager (cgroupfs or systemd)",
		},
		cli.StringFlag{
			Name:  "cni-config-dir",
			Usage: "CNI configuration files directory",
		},
		cli.StringFlag{
			Name:  "cni-plugin-dir",
			Usage: "CNI plugin binaries directory",
		},
		cli.BoolFlag{
			Name:  "profile",
			Usage: "enable pprof remote profiler on localhost:6060",
		},
	}

	sort.Sort(cli.FlagsByName(app.Flags))
	sort.Sort(cli.FlagsByName(configCommand.Flags))

	app.Commands = []cli.Command{
		configCommand,
	}

	app.Before = func(c *cli.Context) error {
		// Load the configuration file.
		config := c.App.Metadata["config"].(*server.Config)
		if err := mergeConfig(config, c); err != nil {
			return err
		}

		cf := &logrus.TextFormatter{
			TimestampFormat: "2006-01-02 15:04:05.000000000Z07:00",
			FullTimestamp:   true,
		}

		logrus.SetFormatter(cf)

		if c.GlobalBool("debug") {
			logrus.SetLevel(logrus.DebugLevel)
		}

		if path := c.GlobalString("log"); path != "" {
			f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND|os.O_SYNC, 0666)
			if err != nil {
				return err
			}
			logrus.SetOutput(f)
		}

		switch c.GlobalString("log-format") {
		case "text":
			// retain logrus's default.
		case "json":
			logrus.SetFormatter(new(logrus.JSONFormatter))
		default:
			return fmt.Errorf("unknown log-format %q", c.GlobalString("log-format"))
		}

		return nil
	}

	app.Action = func(c *cli.Context) error {
		if c.GlobalBool("profile") {
			go func() {
				http.ListenAndServe("localhost:6060", nil)
			}()
		}

		config := c.App.Metadata["config"].(*server.Config)

		if !config.SELinux {
			selinux.SetDisabled()
		}

		if _, err := os.Stat(config.Runtime); os.IsNotExist(err) {
			// path to runtime does not exist
			return fmt.Errorf("invalid --runtime value %q", err)
		}

		// Remove the socket if it already exists
		if _, err := os.Stat(config.Listen); err == nil {
			if err := os.Remove(config.Listen); err != nil {
				logrus.Fatal(err)
			}
		}
		lis, err := net.Listen("unix", config.Listen)
		if err != nil {
			logrus.Fatalf("failed to listen: %v", err)
		}

		s := grpc.NewServer()

		service, err := server.New(config)
		if err != nil {
			logrus.Fatal(err)
		}

		graceful := false
		catchShutdown(s, service, &graceful)
		runtime.RegisterRuntimeServiceServer(s, service)
		runtime.RegisterImageServiceServer(s, service)

		// after the daemon is done setting up we can notify systemd api
		notifySystem()

		err = s.Serve(lis)
		if graceful && strings.Contains(strings.ToLower(err.Error()), "use of closed network connection") {
			err = nil
		}

		if err2 := service.Shutdown(); err2 != nil {
			logrus.Infof("error shutting down layer storage: %v", err2)
		}

		if err != nil {
			logrus.Fatal(err)
		}
		return nil
	}

	if err := app.Run(os.Args); err != nil {
		logrus.Fatal(err)
	}
}
<|endoftext|>


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

// The godex command prints (dumps) exported information of packages
// or selected package objects.
//
// In contrast to godoc, godex extracts this information from compiled
// object files. Hence the exported data is truly what a compiler will
// see, at the cost of missing commentary.
//
// Usage: godex [flags] {path[.name]}
//
// Each argument must be a (possibly partial) package path, optionally
// followed by a dot and the name of a package object:
//
//	godex math
//	godex math.Sin
//	godex math.Sin fmt.Printf
//      godex go/types
//
// All but the last path element may contain dots. godex automatically
// tries all possible package path prefixes for non-standard library
// packages if only a partial package path is given. For instance, for
// the path "go/types", godex prepends "code.google.com/p/go.tools".
//
// The prefixes are computed by searching the directories specified by
// the GOPATH environment variable (and by excluding the build os and
// architecture specific directory names from the path). The search
// order is depth-first and alphabetic; for a partial path "foo", a
// package "a/foo" is found before "b/foo".
//
// The flags are:
//
//	-s=""
//		only consider packages from src, where src is one of the supported compilers
//	-v=false
//		verbose mode
//
// The following sources (-s arguments) are supported:
//
//	gc
//		gc-generated object files
//	gccgo
//		gccgo-generated object files
//	gccgo-new
//		gccgo-generated object files using a condensed format (experimental)
//	source
//		(uncompiled) source code (not yet implemented)
//
// If no -s argument is provided, godex will try to find a matching source.
//
package main

// BUG(gri) std-library packages should also benefit from auto-generated prefixes.
<commit_msg>go.tools/cmd/godex: update documentation<commit_after>// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The godex command prints (dumps) exported information of packages
// or selected package objects.
//
// In contrast to godoc, godex extracts this information from compiled
// object files. Hence the exported data is truly what a compiler will
// see, at the cost of missing commentary.
//
// Usage: godex [flags] {path[.name]}
//
// Each argument must be a (possibly partial) package path, optionally
// followed by a dot and the name of a package object:
//
//	godex math
//	godex math.Sin
//	godex math.Sin fmt.Printf
//	godex go/types
//
// godex automatically tries all possible package path prefixes if only a
// partial package path is given. For instance, for the path "go/types",
// godex prepends "code.google.com/p/go.tools".
//
// The prefixes are computed by searching the directories specified by
// the GOROOT and GOPATH environment variables (and by excluding the
// build OS- and architecture-specific directory names from the path).
// The search order is depth-first and alphabetic; for a partial path
// "foo", a package "a/foo" is found before "b/foo".
//
// Absolute and relative paths may be provided, which disable automatic
// prefix generation:
//
//	godex $GOROOT/pkg/darwin_amd64/sort
//	godex ./sort
//
// All but the last path element may contain dots; a dot in the last path
// element separates the package path from the package object name. If the
// last path element contains a dot, terminate the argument with another
// dot (indicating an empty object name). For instance, the path for a
// package foo.bar would be specified as in:
//
//	godex foo.bar.
//
// The flags are:
//
//	-s=""
//		only consider packages from src, where src is one of the supported compilers
//	-v=false
//		verbose mode
//
// The following sources (-s arguments) are supported:
//
//	gc
//		gc-generated object files
//	gccgo
//		gccgo-generated object files
//	gccgo-new
//		gccgo-generated object files using a condensed format (experimental)
//	source
//		(uncompiled) source code (not yet implemented)
//
// If no -s argument is provided, godex will try to find a matching source.
//
package main

// BUG(gri): support for -s=source is not yet implemented
// BUG(gri): gccgo-importing appears to have occasional problems stalling godex; try -s=gc as work-around
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/nmaggioni/golb"
	"gopkg.in/alecthomas/kingpin.v2"
	"runtime"
)

var (
	verbose  = kingpin.Flag("verbose", "Enable verbose output (overrides the configuration value).").Default("false").Short('v').Bool()
	confPath = kingpin.Flag("config", "The path to the configuration file.").Short('c').PlaceHolder("PATH").ExistingFile()
)

func main() {
	kingpin.CommandLine.HelpFlag.Short('h')
	kingpin.Parse()

	confPath, err := golb.FindConfigPath(*confPath)
	if err != nil {
		kingpin.FatalUsage("Unable to find a configuration file: %v.", err)
	}
	err = golb.ParseConfig(confPath)
	if err != nil {
		kingpin.Fatalf("Failed to decode the configuration file, check the TOML syntax:\n%v", err)
	}

	if *verbose {
		fmt.Printf("Loaded configuration from file: %s\n", confPath)
		golb.SetVerbose(true)
	}

	runtime.GOMAXPROCS(runtime.NumCPU())
	golb.Listen()
}
<commit_msg>Exit on Listen error<commit_after>package main

import (
	"fmt"
	"github.com/nmaggioni/golb"
	"gopkg.in/alecthomas/kingpin.v2"
	"runtime"
)

var (
	verbose  = kingpin.Flag("verbose", "Enable verbose output (overrides the configuration value).").Default("false").Short('v').Bool()
	confPath = kingpin.Flag("config", "The path to the configuration file.").Short('c').PlaceHolder("PATH").ExistingFile()
)

func main() {
	kingpin.CommandLine.HelpFlag.Short('h')
	kingpin.Parse()

	confPath, err := golb.FindConfigPath(*confPath)
	if err != nil {
		kingpin.FatalUsage("Unable to find a configuration file: %v.", err)
	}
	err = golb.ParseConfig(confPath)
	if err != nil {
		kingpin.Fatalf("Failed to decode the configuration file, check the TOML syntax:\n%v", err)
	}

	if *verbose {
		fmt.Printf("Loaded configuration from file: %s\n", confPath)
		golb.SetVerbose(true)
	}

	runtime.GOMAXPROCS(runtime.NumCPU())
	err = golb.Listen()
	kingpin.FatalIfError(err, "")
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
)

func main() {
  fmt.Println("Hello IPFS .")
}
<commit_msg>add os control<commit_after>package main

import (
  "fmt"
  "os"
)

func main() {
  os.Exit(mainRet())
}

func mainRet() int {
  fmt.Println("Hello IPFS .")
  return 1
}
<|endoftext|>


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

package main

import (
	"encoding/json"
	"fmt"
	"github.com/globocom/tsuru/cmd"
	"io/ioutil"
	"net/http"
	"time"
)

type AppLog struct {
	GuessingCommand
}

func (c *AppLog) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "log",
		Usage: "log [--app appname]",
		Desc: `show logs for an app.

If you don't provide the app name, tsuru will try to guess it.`,
		MinArgs: 0,
	}
}

type Log struct {
	Date    time.Time
	Message string
}

func (c *AppLog) Run(context *cmd.Context, client cmd.Doer) error {
	appName, err := c.Guess()
	if err != nil {
		return err
	}
	url := cmd.GetUrl(fmt.Sprintf("/apps/%s/log", appName))
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return err
	}
	response, err := client.Do(request)
	if err != nil {
		return err
	}
	if response.StatusCode == http.StatusNoContent {
		return nil
	}
	defer response.Body.Close()
	result, err := ioutil.ReadAll(response.Body)
	logs := []Log{}
	err = json.Unmarshal(result, &logs)
	if err != nil {
		return err
	}
	for _, log := range logs {
		context.Stdout.Write([]byte(log.Date.String() + " - " + log.Message + "\n"))
	}
	return err
}
<commit_msg>Unexport log struct.<commit_after>// Copyright 2012 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"encoding/json"
	"fmt"
	"github.com/globocom/tsuru/cmd"
	"io/ioutil"
	"net/http"
	"time"
)

type AppLog struct {
	GuessingCommand
}

func (c *AppLog) Info() *cmd.Info {
	return &cmd.Info{
		Name:  "log",
		Usage: "log [--app appname]",
		Desc: `show logs for an app.

If you don't provide the app name, tsuru will try to guess it.`,
		MinArgs: 0,
	}
}

type log struct {
	Date    time.Time
	Message string
}

func (c *AppLog) Run(context *cmd.Context, client cmd.Doer) error {
	appName, err := c.Guess()
	if err != nil {
		return err
	}
	url := cmd.GetUrl(fmt.Sprintf("/apps/%s/log", appName))
	request, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return err
	}
	response, err := client.Do(request)
	if err != nil {
		return err
	}
	if response.StatusCode == http.StatusNoContent {
		return nil
	}
	defer response.Body.Close()
	result, err := ioutil.ReadAll(response.Body)
	logs := []log{}
	err = json.Unmarshal(result, &logs)
	if err != nil {
		return err
	}
	for _, l := range logs {
		context.Stdout.Write([]byte(l.Date.String() + " - " + l.Message + "\n"))
	}
	return err
}
<|endoftext|>


<commit_before>package goworld

import (
	"time"

	"github.com/xiaonanln/goTimer"
	"github.com/xiaonanln/goworld/components/game"
	"github.com/xiaonanln/goworld/engine/common"
	"github.com/xiaonanln/goworld/engine/config"
	"github.com/xiaonanln/goworld/engine/entity"
	"github.com/xiaonanln/goworld/engine/gwlog"
	"github.com/xiaonanln/goworld/engine/kvdb"
	"github.com/xiaonanln/goworld/engine/post"
	"github.com/xiaonanln/goworld/engine/service"
	"github.com/xiaonanln/goworld/engine/storage"
)

const (
	// ENTITYID_LENGTH 是EntityID的长度，目前为16
	ENTITYID_LENGTH = common.ENTITYID_LENGTH
)

// GameID 是Game进程的ID。
// GoWorld要求GameID的数值必须是从1~N的连续N个数字，其中N为服务器配置文件中配置的game进程数目。
type GameID = uint16

// GateID 是Gate进程的ID。
// GoWorld要求GateID的数值必须是从1~N的连续N个数字，其中N为服务器配置文件中配置的game进程数目。
type GateID = uint16

// DispatcherID 是Dispatcher进程的ID
// GoWorld要求DispatcherID的数值必须是从1~N的连续N个数字，其中N为服务器配置文件中配置的dispatcher进程数目
type DispatcherID uint16

// EntityID 唯一代表一个Entity。EntityID是一个字符串（string），长度固定（ENTITYID_LENGTH）。
// EntityID是全局唯一的。不同进程上产生的EntityID都是唯一的，不会出现重复。一般来说即使是不用的游戏服务器产生的EntityID也是唯一的。
type EntityID = common.EntityID

// Entity 类型代表游戏服务器中的一个对象。开发者可以使用GoWorld提供的接口进行对象创建、载入。对象载入之后，GoWorld提供定时的对象数据存盘。
// 同一个game进程中的Entity之间可以拿到相互的引用（指针）并直接进行相关的函数调用。不同game进程中的Entity之间可以使用RPC进行相互通信。
type Entity = entity.Entity

// Space 类型代表一个游戏服务器中的一个场景。一个场景中可以包含多个Entity。Space和其中的Entity都存在于一个game进程中。
// Entity可以通过调用EnterSpace函数来切换Space。如果EnterSpace调用所指定的Space在其他game进程上，Entity将被迁移到对应的game进程并添加到Space中。
type Space = entity.Space

// Kind 类型表示Space的种类。开发者在创建Space的时候需要提供Kind参数，从而创建特定Kind的Space。NilSpace的Kind总是为0，并且开发者不能创建Kind=0的Space。
// 开发者可以根据Kind的值来区分不同的场景，具体的区分规则由开发者自己决定。
type Kind = int

// Vector3 是服务端用于存储Entity位置的类型，包含X, Y, Z三个字段。
// GoWorld使用X轴和Z轴坐标进行AOI管理，无视Y轴坐标值。
type Vector3 = entity.Vector3

// Run 开始运行game服务。开发者需要为自己的游戏服务器提供一个main模块和main函数，并在main函数里正确初始化GoWorld服务器并启动服务器。
// 一般来说，开发者需要在main函数中注册相应的Space类型、Service类型、Entity类型，然后调用 goworld.Run() 启动GoWorld服务器即可，可参考：
// https://github.com/xiaonanln/goworld/blob/master/examples/unity_demo/unity_demo.go
func Run() {
	game.Run()
}

// RegisterSpace 注册一个Space对象类型。开发者必须并且只能调用这个接口一次，从而注册特定的Space类型。一个合法的Space类型必须继承goworld.Space类型。
func RegisterSpace(spacePtr entity.ISpace) {
	entity.RegisterSpace(spacePtr)
}

// RegisterEntity 注册一个对象类型到game中。所注册的对象必须是Entity类型的子类（包含一个匿名Entity字段）。
// 使用方法可以参考：https://github.com/xiaonanln/goworld/blob/master/examples/unity_demo/unity_demo.go
func RegisterEntity(typeName string, entityPtr entity.IEntity) *entity.EntityTypeDesc {
	return entity.RegisterEntity(typeName, entityPtr, false)
}

// RegisterService 注册一个Service类型到game中。Service是一种全局唯一的特殊的Entity对象。
// 每个game进程中初始化的时候都应该注册所有的Service。GoWorld服务器会在某一个game进程中自动创建或载入Service对象（取决于Service类型是否是Persistent）。
// 开发者不能手动创建Service对象。
func RegisterService(typeName string, entityPtr entity.IEntity) {
	service.RegisterService(typeName, entityPtr)
}

// CreateSpaceAnywhere 在一个随机选择的game（以后会支持自动负载均衡）上创建一个特定Kind的Space对象。
func CreateSpaceAnywhere(kind Kind) EntityID {
	if kind == 0 {
		gwlog.Panicf("Can not create nil space with kind=0. Game will create 1 nil space automatically.")
	}
	return entity.CreateSpaceSomewhere(0, kind)
}

// CreateSpaceOnGame creates a space with specified kind on the specified game
//
// returns the space EntityID
func CreateSpaceOnGame(gameid uint16, kind int) EntityID {
	return entity.CreateSpaceSomewhere(gameid, kind)
}

// CreateSpaceLocally 在本地game进程上创建一个指定Kind的Space。
func CreateSpaceLocally(kind Kind) *Space {
	if kind == 0 {
		gwlog.Panicf("Can not create nil space with kind=0. Game will create 1 nil space automatically.")
	}
	return entity.CreateSpaceLocally(kind)
}

// CreateEntityLocally 在本地game进程上创建一个指定类型的Entity
func CreateEntityLocally(typeName string) *Entity {
	return entity.CreateEntityLocally(typeName, nil)
}

// CreateEntityAnywhere 在随机选择的game进程上创建一个特定类型的Entity
func CreateEntityAnywhere(typeName string) EntityID {
	return entity.CreateEntitySomewhere(0, typeName)
}

func CreateEntityOnGame(gameid uint16, typeName string) EntityID {
	return entity.CreateEntitySomewhere(gameid, typeName)
}

// LoadEntityAnywhere 在随机选择的game进程上载入指定的Entity。
// GoWorld保证每个Entity最多只会存在于一个game进程，即只有一份实例。
// 如果这个Entity当前已经存在，则GoWorld不会做任何操作。
func LoadEntityAnywhere(typeName string, entityID EntityID) {
	entity.LoadEntityAnywhere(typeName, entityID)
}

// LoadEntityOnGame 在指定的game进程上载入特定的Entity对象。
// 如果这个Entity当前已经存在，则GoWorld不会做任何操作。因此在调用LoadEntityOnGame之后并不能严格保证Entity必然存在于所指定的game进程中。
func LoadEntityOnGame(typeName string, entityID EntityID, gameid GameID) {
	entity.LoadEntityOnGame(typeName, entityID, gameid)
}

// LoadEntityLocally 在当前的game进程中载入特定的Entity对象
// 如果这个Entity当前已经存在，则GoWorld不会做任何操作。因此在调用LoadEntityOnGame之后并不能严格保证Entity必然存在于当前game进程中。
func LoadEntityLocally(typeName string, entityID EntityID) {
	entity.LoadEntityOnGame(typeName, entityID, GetGameID())
}

// ListEntityIDs 获得某个类型的所有Entity对象的EntityID列表
// （这个接口将被弃用）
func ListEntityIDs(typeName string, callback storage.ListCallbackFunc) {
	storage.ListEntityIDs(typeName, callback)
}

// Exists 检查某个特定的Entity是否存在（已创建存盘）
func Exists(typeName string, entityID EntityID, callback storage.ExistsCallbackFunc) {
	storage.Exists(typeName, entityID, callback)
}

// GetEntity 获得当前game进程中的指定EntityID的Entity对象。不存在则返回nil。
func GetEntity(id EntityID) *Entity {
	return entity.GetEntity(id)
}

// GetSpace 获得当前进程中指定EntityID的Space对象。不存在则返回nil。
func GetSpace(id EntityID) *Space {
	return entity.GetSpace(id)
}

// GetGameID 获得当前game进程的GameID
func GetGameID() GameID {
	return game.GetGameID()
}

// MapAttr 创建一个新的空MapAttr对象
func MapAttr() *entity.MapAttr {
	return entity.NewMapAttr()
}

// ListAttr 创建一个新的空ListAttr对象
func ListAttr() *entity.ListAttr {
	return entity.NewListAttr()
}

// Entities 返回所有的Entity对象（通过EntityMap类型返回）
// 此接口将被弃用
func Entities() entity.EntityMap {
	return entity.Entities()
}

// Call 函数调用指定Entity的指定方法，并传递参数。
// 如果指定的Entity在当前game进程中，则会立刻调用其方法。否则将通过RPC发送函数调用和参数到所对应的game进程中。
func Call(id EntityID, method string, args ...interface{}) {
	entity.Call(id, method, args)
}

// CallService 发起一次Service调用。开发者只需要传入指定的Service名字，不需要指知道Service的EntityID或者当前在哪个game进程。
func CallService(serviceName string, method string, args ...interface{}) {
	service.CallService(serviceName, method, args)
}

// GetServiceEntityID 返回Service对象的EntityID。这个函数可以用来确定Service对象是否已经在某个game进程上成功创建或载入。
func GetServiceEntityID(serviceName string) common.EntityID {
	return service.GetServiceEntityID(serviceName)
}

// CallNilSpaces 向所有game进程中的NilSpace发起RPC调用。
// 由于每个game进程中都有一个唯一的NilSpace，因此这个函数想每个game进程都发起了一次函数调用。
func CallNilSpaces(method string, args ...interface{}) {
	entity.CallNilSpaces(method, args, game.GetGameID())
}

// GetNilSpaceID 返回特定game进程中的NilSpace的EntityID。
// GoWorld为每个game进程中的NilSpace使用了固定的EntityID值，例如目前GoWorld实现中在game1上NilSpace的EntityID总是"AAAAAAAAAAAAAAAx"，每次重启服务器都不会变化。
func GetNilSpaceID(gameid GameID) EntityID {
	return entity.GetNilSpaceID(gameid)
}

// GetNilSpace 返回当前game进程总的NilSpace对象
func GetNilSpace() *Space {
	return entity.GetNilSpace()
}

// GetKVDB 获得KVDB中指定key的值
func GetKVDB(key string, callback kvdb.KVDBGetCallback) {
	kvdb.Get(key, callback)
}

// PutKVDB 将制定的key-value对存入到KVDB中
func PutKVDB(key string, val string, callback kvdb.KVDBPutCallback) {
	kvdb.Put(key, val, callback)
}

// GetOrPutKVDB 读取指定key所对应的value，如果key所对应的值当前为空，则存入key-value键值对
func GetOrPutKVDB(key string, val string, callback kvdb.KVDBGetOrPutCallback) {
	kvdb.GetOrPut(key, val, callback)
}

// ListGameIDs 获得所有的GameID列表
func ListGameIDs() []GameID {
	return config.GetGameIDs()
}

// AddTimer adds a timer to be executed after specified duration
func AddCallback(d time.Duration, callback func()) {
	timer.AddCallback(d, callback)
}

// AddTimer adds a repeat timer to be executed every specified duration
func AddTimer(d time.Duration, callback func()) {
	timer.AddTimer(d, callback)
}

// Post posts a callback to be executed
// It is almost same as AddCallback(0, callback)
func Post(callback post.PostCallback) {
	post.Post(callback)
}
<commit_msg>goworld_cn文档<commit_after>//GoWorld是一个游戏服务器引擎

package goworld

import (
	"time"

	"github.com/xiaonanln/goTimer"
	"github.com/xiaonanln/goworld/components/game"
	"github.com/xiaonanln/goworld/engine/common"
	"github.com/xiaonanln/goworld/engine/config"
	"github.com/xiaonanln/goworld/engine/entity"
	"github.com/xiaonanln/goworld/engine/gwlog"
	"github.com/xiaonanln/goworld/engine/kvdb"
	"github.com/xiaonanln/goworld/engine/post"
	"github.com/xiaonanln/goworld/engine/service"
	"github.com/xiaonanln/goworld/engine/storage"
)

const (
	// ENTITYID_LENGTH 是EntityID的长度，目前为16
	ENTITYID_LENGTH = common.ENTITYID_LENGTH
)

// GameID 是Game进程的ID。
// GoWorld要求GameID的数值必须是从1~N的连续N个数字，其中N为服务器配置文件中配置的game进程数目。
type GameID = uint16

// GateID 是Gate进程的ID。
// GoWorld要求GateID的数值必须是从1~N的连续N个数字，其中N为服务器配置文件中配置的game进程数目。
type GateID = uint16

// DispatcherID 是Dispatcher进程的ID
// GoWorld要求DispatcherID的数值必须是从1~N的连续N个数字，其中N为服务器配置文件中配置的dispatcher进程数目
type DispatcherID uint16

// EntityID 唯一代表一个Entity。EntityID是一个字符串（string），长度固定（ENTITYID_LENGTH）。
// EntityID是全局唯一的。不同进程上产生的EntityID都是唯一的，不会出现重复。一般来说即使是不用的游戏服务器产生的EntityID也是唯一的。
type EntityID = common.EntityID

// Entity 类型代表游戏服务器中的一个对象。开发者可以使用GoWorld提供的接口进行对象创建、载入。对象载入之后，GoWorld提供定时的对象数据存盘。
// 同一个game进程中的Entity之间可以拿到相互的引用（指针）并直接进行相关的函数调用。不同game进程中的Entity之间可以使用RPC进行相互通信。
type Entity = entity.Entity

// Space 类型代表一个游戏服务器中的一个场景。一个场景中可以包含多个Entity。Space和其中的Entity都存在于一个game进程中。
// Entity可以通过调用EnterSpace函数来切换Space。如果EnterSpace调用所指定的Space在其他game进程上，Entity将被迁移到对应的game进程并添加到Space中。
type Space = entity.Space

// Kind 类型表示Space的种类。开发者在创建Space的时候需要提供Kind参数，从而创建特定Kind的Space。NilSpace的Kind总是为0，并且开发者不能创建Kind=0的Space。
// 开发者可以根据Kind的值来区分不同的场景，具体的区分规则由开发者自己决定。
type Kind = int

// Vector3 是服务端用于存储Entity位置的类型，包含X, Y, Z三个字段。
// GoWorld使用X轴和Z轴坐标进行AOI管理，无视Y轴坐标值。
type Vector3 = entity.Vector3

// Run 开始运行game服务。开发者需要为自己的游戏服务器提供一个main模块和main函数，并在main函数里正确初始化GoWorld服务器并启动服务器。
// 一般来说，开发者需要在main函数中注册相应的Space类型、Service类型、Entity类型，然后调用 goworld.Run() 启动GoWorld服务器即可，可参考：
// https://github.com/xiaonanln/goworld/blob/master/examples/unity_demo/unity_demo.go
func Run() {
	game.Run()
}

// RegisterSpace 注册一个Space对象类型。开发者必须并且只能调用这个接口一次，从而注册特定的Space类型。一个合法的Space类型必须继承goworld.Space类型。
func RegisterSpace(spacePtr entity.ISpace) {
	entity.RegisterSpace(spacePtr)
}

// RegisterEntity 注册一个对象类型到game中。所注册的对象必须是Entity类型的子类（包含一个匿名Entity字段）。
// 使用方法可以参考：https://github.com/xiaonanln/goworld/blob/master/examples/unity_demo/unity_demo.go
func RegisterEntity(typeName string, entityPtr entity.IEntity) *entity.EntityTypeDesc {
	return entity.RegisterEntity(typeName, entityPtr, false)
}

// RegisterService 注册一个Service类型到game中。Service是一种全局唯一的特殊的Entity对象。
// 每个game进程中初始化的时候都应该注册所有的Service。GoWorld服务器会在某一个game进程中自动创建或载入Service对象（取决于Service类型是否是Persistent）。
// 开发者不能手动创建Service对象。
func RegisterService(typeName string, entityPtr entity.IEntity) {
	service.RegisterService(typeName, entityPtr)
}

// CreateSpaceAnywhere 在一个随机选择的game（以后会支持自动负载均衡）上创建一个特定Kind的Space对象。
func CreateSpaceAnywhere(kind Kind) EntityID {
	if kind == 0 {
		gwlog.Panicf("Can not create nil space with kind=0. Game will create 1 nil space automatically.")
	}
	return entity.CreateSpaceSomewhere(0, kind)
}

// CreateSpaceOnGame creates a space with specified kind on the specified game
//
// returns the space EntityID
func CreateSpaceOnGame(gameid uint16, kind int) EntityID {
	return entity.CreateSpaceSomewhere(gameid, kind)
}

// CreateSpaceLocally 在本地game进程上创建一个指定Kind的Space。
func CreateSpaceLocally(kind Kind) *Space {
	if kind == 0 {
		gwlog.Panicf("Can not create nil space with kind=0. Game will create 1 nil space automatically.")
	}
	return entity.CreateSpaceLocally(kind)
}

// CreateEntityLocally 在本地game进程上创建一个指定类型的Entity
func CreateEntityLocally(typeName string) *Entity {
	return entity.CreateEntityLocally(typeName, nil)
}

// CreateEntityAnywhere 在随机选择的game进程上创建一个特定类型的Entity
func CreateEntityAnywhere(typeName string) EntityID {
	return entity.CreateEntitySomewhere(0, typeName)
}

func CreateEntityOnGame(gameid uint16, typeName string) EntityID {
	return entity.CreateEntitySomewhere(gameid, typeName)
}

// LoadEntityAnywhere 在随机选择的game进程上载入指定的Entity。
// GoWorld保证每个Entity最多只会存在于一个game进程，即只有一份实例。
// 如果这个Entity当前已经存在，则GoWorld不会做任何操作。
func LoadEntityAnywhere(typeName string, entityID EntityID) {
	entity.LoadEntityAnywhere(typeName, entityID)
}

// LoadEntityOnGame 在指定的game进程上载入特定的Entity对象。
// 如果这个Entity当前已经存在，则GoWorld不会做任何操作。因此在调用LoadEntityOnGame之后并不能严格保证Entity必然存在于所指定的game进程中。
func LoadEntityOnGame(typeName string, entityID EntityID, gameid GameID) {
	entity.LoadEntityOnGame(typeName, entityID, gameid)
}

// LoadEntityLocally 在当前的game进程中载入特定的Entity对象
// 如果这个Entity当前已经存在，则GoWorld不会做任何操作。因此在调用LoadEntityOnGame之后并不能严格保证Entity必然存在于当前game进程中。
func LoadEntityLocally(typeName string, entityID EntityID) {
	entity.LoadEntityOnGame(typeName, entityID, GetGameID())
}

// ListEntityIDs 获得某个类型的所有Entity对象的EntityID列表
// （这个接口将被弃用）
func ListEntityIDs(typeName string, callback storage.ListCallbackFunc) {
	storage.ListEntityIDs(typeName, callback)
}

// Exists 检查某个特定的Entity是否存在（已创建存盘）
func Exists(typeName string, entityID EntityID, callback storage.ExistsCallbackFunc) {
	storage.Exists(typeName, entityID, callback)
}

// GetEntity 获得当前game进程中的指定EntityID的Entity对象。不存在则返回nil。
func GetEntity(id EntityID) *Entity {
	return entity.GetEntity(id)
}

// GetSpace 获得当前进程中指定EntityID的Space对象。不存在则返回nil。
func GetSpace(id EntityID) *Space {
	return entity.GetSpace(id)
}

// GetGameID 获得当前game进程的GameID
func GetGameID() GameID {
	return game.GetGameID()
}

// MapAttr 创建一个新的空MapAttr对象
func MapAttr() *entity.MapAttr {
	return entity.NewMapAttr()
}

// ListAttr 创建一个新的空ListAttr对象
func ListAttr() *entity.ListAttr {
	return entity.NewListAttr()
}

// Entities 返回所有的Entity对象（通过EntityMap类型返回）
// 此接口将被弃用
func Entities() entity.EntityMap {
	return entity.Entities()
}

// Call 函数调用指定Entity的指定方法，并传递参数。
// 如果指定的Entity在当前game进程中，则会立刻调用其方法。否则将通过RPC发送函数调用和参数到所对应的game进程中。
func Call(id EntityID, method string, args ...interface{}) {
	entity.Call(id, method, args)
}

// CallService 发起一次Service调用。开发者只需要传入指定的Service名字，不需要指知道Service的EntityID或者当前在哪个game进程。
func CallService(serviceName string, method string, args ...interface{}) {
	service.CallService(serviceName, method, args)
}

// GetServiceEntityID 返回Service对象的EntityID。这个函数可以用来确定Service对象是否已经在某个game进程上成功创建或载入。
func GetServiceEntityID(serviceName string) common.EntityID {
	return service.GetServiceEntityID(serviceName)
}

// CallNilSpaces 向所有game进程中的NilSpace发起RPC调用。
// 由于每个game进程中都有一个唯一的NilSpace，因此这个函数想每个game进程都发起了一次函数调用。
func CallNilSpaces(method string, args ...interface{}) {
	entity.CallNilSpaces(method, args, game.GetGameID())
}

// GetNilSpaceID 返回特定game进程中的NilSpace的EntityID。
// GoWorld为每个game进程中的NilSpace使用了固定的EntityID值，例如目前GoWorld实现中在game1上NilSpace的EntityID总是"AAAAAAAAAAAAAAAx"，每次重启服务器都不会变化。
func GetNilSpaceID(gameid GameID) EntityID {
	return entity.GetNilSpaceID(gameid)
}

// GetNilSpace 返回当前game进程总的NilSpace对象
func GetNilSpace() *Space {
	return entity.GetNilSpace()
}

// GetKVDB 获得KVDB中指定key的值
func GetKVDB(key string, callback kvdb.KVDBGetCallback) {
	kvdb.Get(key, callback)
}

// PutKVDB 将制定的key-value对存入到KVDB中
func PutKVDB(key string, val string, callback kvdb.KVDBPutCallback) {
	kvdb.Put(key, val, callback)
}

// GetOrPutKVDB 读取指定key所对应的value，如果key所对应的值当前为空，则存入key-value键值对
func GetOrPutKVDB(key string, val string, callback kvdb.KVDBGetOrPutCallback) {
	kvdb.GetOrPut(key, val, callback)
}

// ListGameIDs 获得所有的GameID列表
func ListGameIDs() []GameID {
	return config.GetGameIDs()
}

// AddTimer adds a timer to be executed after specified duration
func AddCallback(d time.Duration, callback func()) {
	timer.AddCallback(d, callback)
}

// AddTimer adds a repeat timer to be executed every specified duration
func AddTimer(d time.Duration, callback func()) {
	timer.AddTimer(d, callback)
}

// Post posts a callback to be executed
// It is almost same as AddCallback(0, callback)
func Post(callback post.PostCallback) {
	post.Post(callback)
}
<|endoftext|>


<commit_before>// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import "github.com/juju/errors"

// Visitor represents a visitor pattern.
type Visitor interface {
	// VisitBetween visits Between expression.
	VisitBetween(b *Between) (Expression, error)

	// VisitBinaryOperation visits BinaryOperation expression.
	VisitBinaryOperation(o *BinaryOperation) (Expression, error)

	// VisitCall visits Call expression.
	VisitCall(c *Call) (Expression, error)

	// VisitCompareSubQuery visits CompareSubQuery expression.
	VisitCompareSubQuery(cs *CompareSubQuery) (Expression, error)

	// VisitDefault visits Default expression.
	VisitDefault(d *Default) (Expression, error)

	// VisitFunctionCase visits FunctionCase expression.
	VisitFunctionCase(f *FunctionCase) (Expression, error)

	// VisitFunctionCast visits FunctionCast expression.
	VisitFunctionCast(f *FunctionCast) (Expression, error)

	// VisitFunctionConvert visits FunctionConvert expression.
	VisitFunctionConvert(f *FunctionConvert) (Expression, error)

	// VisitFunctionSubstring visits FunctionSubstring expression.
	VisitFunctionSubstring(ss *FunctionSubstring) (Expression, error)

	// VisitExistsSubQuery visits ExistsSubQuery expression.
	VisitExistsSubQuery(es *ExistsSubQuery) (Expression, error)

	// VisitIdent visits Ident expression.
	VisitIdent(i *Ident) (Expression, error)

	// VisitIsNull visits IsNull expression.
	VisitIsNull(is *IsNull) (Expression, error)

	// VisitIsTruth visits IsTruth expression.
	VisitIsTruth(is *IsTruth) (Expression, error)

	// VisitParamMaker visits ParamMarker expression.
	VisitParamMaker(pm *ParamMarker) (Expression, error)

	// VisitPatternIn visits PatternIn expression.
	VisitPatternIn(n *PatternIn) (Expression, error)

	// VisitPatternLike visits PatternLike expression.
	VisitPatternLike(p *PatternLike) (Expression, error)

	// VisitPatternRegexp visits PatternRegexp expression.
	VisitPatternRegexp(p *PatternRegexp) (Expression, error)

	// VisitPExpr visits PExpr expression.
	VisitPExpr(p *PExpr) (Expression, error)

	// VisitPosition visits Position expression.
	VisitPosition(p *Position) (Expression, error)

	// VisitRow visits Row expression.
	VisitRow(r *Row) (Expression, error)

	// VisitSubQuery visits SubQuery expression.
	VisitSubQuery(sq SubQuery) (Expression, error)

	// VisitUnaryOperation visits UnaryOperation expression.
	VisitUnaryOperation(u *UnaryOperation) (Expression, error)

	// VisitValue visits Value expression.
	VisitValue(v Value) (Expression, error)

	// VisitValues visits Values expression.
	VisitValues(v *Values) (Expression, error)

	// VisitVariable visits Variable expression.
	VisitVariable(v *Variable) (Expression, error)

	// VisitWhenClause visits WhenClause expression.
	VisitWhenClause(w *WhenClause) (Expression, error)
}

// BaseVisitor is the base implementation of Visitor.
// It traverse the expression tree and call expression's Accept function.
// It can not be used directly.
// A specific Visitor implementation can embed it in and only implement
// desired methods to do the job.
type BaseVisitor struct {
	V Visitor
}

// VisitBetween implements Visitor interface.
func (bv *BaseVisitor) VisitBetween(b *Between) (Expression, error) {
	var err error
	b.Expr, err = b.Expr.Accept(bv.V)
	if err != nil {
		return b, errors.Trace(err)
	}
	b.Left, err = b.Left.Accept(bv.V)
	if err != nil {
		return b, errors.Trace(err)
	}
	b.Right, err = b.Right.Accept(bv.V)
	if err != nil {
		return b, errors.Trace(err)
	}
	return b, nil
}

// VisitBinaryOperation implements Visitor interface.
func (bv *BaseVisitor) VisitBinaryOperation(o *BinaryOperation) (Expression, error) {
	var err error
	o.L, err = o.L.Accept(bv.V)
	if err != nil {
		return o, errors.Trace(err)
	}
	o.R, err = o.R.Accept(bv.V)
	if err != nil {
		return o, errors.Trace(err)
	}
	return o, nil
}

// VisitCall implements Visitor interface.
func (bv *BaseVisitor) VisitCall(c *Call) (Expression, error) {
	var err error
	for i := range c.Args {
		c.Args[i], err = c.Args[i].Accept(bv.V)
		if err != nil {
			return c, errors.Trace(err)
		}
	}
	return c, nil
}

// VisitCompareSubQuery implements Visitor interface.
func (bv *BaseVisitor) VisitCompareSubQuery(cs *CompareSubQuery) (Expression, error) {
	var err error
	cs.L, err = cs.L.Accept(bv.V)
	if err != nil {
		return cs, errors.Trace(err)
	}
	_, err = cs.R.Accept(bv.V)
	if err != nil {
		return cs, errors.Trace(err)
	}
	return cs, nil
}

// VisitDefault implements Visitor interface.
func (bv *BaseVisitor) VisitDefault(d *Default) (Expression, error) {
	return d, nil
}

// VisitExistsSubQuery implements Visitor interface.
func (bv *BaseVisitor) VisitExistsSubQuery(es *ExistsSubQuery) (Expression, error) {
	var err error
	_, err = es.Sel.Accept(bv.V)
	if err != nil {
		return es, errors.Trace(err)
	}
	return es, nil
}

// VisitFunctionCase implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionCase(f *FunctionCase) (Expression, error) {
	var err error
	f.Value, err = f.Value.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	for i := range f.WhenClauses {
		_, err = f.WhenClauses[i].Accept(bv.V)
		if err != nil {
			return f, errors.Trace(err)
		}
	}
	f.ElseClause, err = f.ElseClause.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	return f, nil
}

//VisitFunctionCast implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionCast(f *FunctionCast) (Expression, error) {
	var err error
	f.Expr, err = f.Expr.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	return f, nil
}

// VisitFunctionConvert implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionConvert(f *FunctionConvert) (Expression, error) {
	var err error
	f.Expr, err = f.Expr.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	return f, nil
}

// VisitFunctionSubstring implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionSubstring(ss *FunctionSubstring) (Expression, error) {
	var err error
	ss.StrExpr, err = ss.StrExpr.Accept(bv.V)
	if err != nil {
		return ss, errors.Trace(err)
	}
	ss.Pos, err = ss.Pos.Accept(bv.V)
	if err != nil {
		return ss, errors.Trace(err)
	}
	ss.Len, err = ss.Len.Accept(bv.V)
	if err != nil {
		return ss, errors.Trace(err)
	}
	return ss, nil
}

// VisitIdent implements Visitor interface.
func (bv *BaseVisitor) VisitIdent(i *Ident) (Expression, error) {
	return i, nil
}

// VisitIsNull implements Visitor interface.
func (bv *BaseVisitor) VisitIsNull(is *IsNull) (Expression, error) {
	var err error
	is.Expr, err = is.Expr.Accept(bv.V)
	if err != nil {
		return is, errors.Trace(err)
	}
	return is, nil
}

// VisitIsTruth implements Visitor interface.
func (bv *BaseVisitor) VisitIsTruth(is *IsTruth) (Expression, error) {
	var err error
	is.Expr, err = is.Expr.Accept(bv.V)
	if err != nil {
		return is, errors.Trace(err)
	}
	return is, nil
}

// VisitParamMaker implements Visitor interface.
func (bv *BaseVisitor) VisitParamMaker(pm *ParamMarker) (Expression, error) {
	if pm.Expr == nil {
		return pm, nil
	}
	var err error
	pm.Expr, err = pm.Expr.Accept(bv.V)
	if err != nil {
		return pm, errors.Trace(err)
	}
	return pm, nil
}

// VisitPatternIn implements Visitor interface.
func (bv *BaseVisitor) VisitPatternIn(n *PatternIn) (Expression, error) {
	var err error
	n.Expr, err = n.Expr.Accept(bv.V)
	if err != nil {
		return n, errors.Trace(err)
	}
	if n.Sel != nil {
		_, err = n.Sel.Accept(bv.V)
		if err != nil {
			return n, errors.Trace(err)
		}
	}
	for i := range n.List {
		n.List[i], err = n.List[i].Accept(bv.V)
		if err != nil {
			return n, errors.Trace(err)
		}
	}
	return n, nil
}

// VisitPatternLike implements Visitor interface.
func (bv *BaseVisitor) VisitPatternLike(p *PatternLike) (Expression, error) {
	var err error
	p.Expr, err = p.Expr.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	p.Pattern, err = p.Pattern.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	return p, nil
}

// VisitPatternRegexp implements Visitor interface.
func (bv *BaseVisitor) VisitPatternRegexp(p *PatternRegexp) (Expression, error) {
	var err error
	p.Expr, err = p.Expr.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	p.Pattern, err = p.Pattern.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	return p, nil
}

// VisitPExpr implements Visitor interface.
func (bv *BaseVisitor) VisitPExpr(p *PExpr) (Expression, error) {
	var err error
	p.Expr, err = p.Expr.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	return p, nil
}

// VisitPosition implements Visitor interface.
func (bv *BaseVisitor) VisitPosition(p *Position) (Expression, error) {
	return p, nil
}

// VisitRow implements Visitor interface.
func (bv *BaseVisitor) VisitRow(r *Row) (Expression, error) {
	var err error
	for i := range r.Values {
		r.Values[i], err = r.Values[i].Accept(bv.V)
		if err != nil {
			return r, errors.Trace(err)
		}
	}
	return r, nil
}

// VisitSubQuery implements Visitor interface.
func (bv *BaseVisitor) VisitSubQuery(sq SubQuery) (Expression, error) {
	return sq, nil
}

// VisitUnaryOperation implements Visitor interface.
func (bv *BaseVisitor) VisitUnaryOperation(u *UnaryOperation) (Expression, error) {
	var err error
	u.V, err = u.V.Accept(bv.V)
	if err != nil {
		return u, errors.Trace(err)
	}
	return u, nil
}

// VisitValue implements Visitor interface.
func (bv *BaseVisitor) VisitValue(v Value) (Expression, error) {
	return v, nil
}

// VisitValues implements Visitor interface.
func (bv *BaseVisitor) VisitValues(v *Values) (Expression, error) {
	return v, nil
}

// VisitVariable implements Visitor interface.
func (bv *BaseVisitor) VisitVariable(v *Variable) (Expression, error) {
	return v, nil
}

// VisitWhenClause implements Visitor interface.
func (bv *BaseVisitor) VisitWhenClause(w *WhenClause) (Expression, error) {
	var err error
	w.Expr, err = w.Expr.Accept(bv.V)
	if err != nil {
		return w, errors.Trace(err)
	}
	w.Result, err = w.Result.Accept(bv.V)
	if err != nil {
		return w, errors.Trace(err)
	}
	return w, nil
}
<commit_msg>expression: address comment.<commit_after>// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package expression

import "github.com/juju/errors"

// Visitor represents a visitor pattern.
type Visitor interface {
	// VisitBetween visits Between expression.
	VisitBetween(b *Between) (Expression, error)

	// VisitBinaryOperation visits BinaryOperation expression.
	VisitBinaryOperation(o *BinaryOperation) (Expression, error)

	// VisitCall visits Call expression.
	VisitCall(c *Call) (Expression, error)

	// VisitCompareSubQuery visits CompareSubQuery expression.
	VisitCompareSubQuery(cs *CompareSubQuery) (Expression, error)

	// VisitDefault visits Default expression.
	VisitDefault(d *Default) (Expression, error)

	// VisitFunctionCase visits FunctionCase expression.
	VisitFunctionCase(f *FunctionCase) (Expression, error)

	// VisitFunctionCast visits FunctionCast expression.
	VisitFunctionCast(f *FunctionCast) (Expression, error)

	// VisitFunctionConvert visits FunctionConvert expression.
	VisitFunctionConvert(f *FunctionConvert) (Expression, error)

	// VisitFunctionSubstring visits FunctionSubstring expression.
	VisitFunctionSubstring(ss *FunctionSubstring) (Expression, error)

	// VisitExistsSubQuery visits ExistsSubQuery expression.
	VisitExistsSubQuery(es *ExistsSubQuery) (Expression, error)

	// VisitIdent visits Ident expression.
	VisitIdent(i *Ident) (Expression, error)

	// VisitIsNull visits IsNull expression.
	VisitIsNull(is *IsNull) (Expression, error)

	// VisitIsTruth visits IsTruth expression.
	VisitIsTruth(is *IsTruth) (Expression, error)

	// VisitParamMaker visits ParamMarker expression.
	VisitParamMaker(pm *ParamMarker) (Expression, error)

	// VisitPatternIn visits PatternIn expression.
	VisitPatternIn(n *PatternIn) (Expression, error)

	// VisitPatternLike visits PatternLike expression.
	VisitPatternLike(p *PatternLike) (Expression, error)

	// VisitPatternRegexp visits PatternRegexp expression.
	VisitPatternRegexp(p *PatternRegexp) (Expression, error)

	// VisitPExpr visits PExpr expression.
	VisitPExpr(p *PExpr) (Expression, error)

	// VisitPosition visits Position expression.
	VisitPosition(p *Position) (Expression, error)

	// VisitRow visits Row expression.
	VisitRow(r *Row) (Expression, error)

	// VisitSubQuery visits SubQuery expression.
	VisitSubQuery(sq SubQuery) (Expression, error)

	// VisitUnaryOperation visits UnaryOperation expression.
	VisitUnaryOperation(u *UnaryOperation) (Expression, error)

	// VisitValue visits Value expression.
	VisitValue(v Value) (Expression, error)

	// VisitValues visits Values expression.
	VisitValues(v *Values) (Expression, error)

	// VisitVariable visits Variable expression.
	VisitVariable(v *Variable) (Expression, error)

	// VisitWhenClause visits WhenClause expression.
	VisitWhenClause(w *WhenClause) (Expression, error)
}

// BaseVisitor is the base implementation of Visitor.
// It traverses the expression tree and call expression's Accept function.
// It can not be used directly.
// A specific Visitor implementation can embed it in and only implements
// desired methods to do the job.
type BaseVisitor struct {
	V Visitor
}

// VisitBetween implements Visitor interface.
func (bv *BaseVisitor) VisitBetween(b *Between) (Expression, error) {
	var err error
	b.Expr, err = b.Expr.Accept(bv.V)
	if err != nil {
		return b, errors.Trace(err)
	}
	b.Left, err = b.Left.Accept(bv.V)
	if err != nil {
		return b, errors.Trace(err)
	}
	b.Right, err = b.Right.Accept(bv.V)
	if err != nil {
		return b, errors.Trace(err)
	}
	return b, nil
}

// VisitBinaryOperation implements Visitor interface.
func (bv *BaseVisitor) VisitBinaryOperation(o *BinaryOperation) (Expression, error) {
	var err error
	o.L, err = o.L.Accept(bv.V)
	if err != nil {
		return o, errors.Trace(err)
	}
	o.R, err = o.R.Accept(bv.V)
	if err != nil {
		return o, errors.Trace(err)
	}
	return o, nil
}

// VisitCall implements Visitor interface.
func (bv *BaseVisitor) VisitCall(c *Call) (Expression, error) {
	var err error
	for i := range c.Args {
		c.Args[i], err = c.Args[i].Accept(bv.V)
		if err != nil {
			return c, errors.Trace(err)
		}
	}
	return c, nil
}

// VisitCompareSubQuery implements Visitor interface.
func (bv *BaseVisitor) VisitCompareSubQuery(cs *CompareSubQuery) (Expression, error) {
	var err error
	cs.L, err = cs.L.Accept(bv.V)
	if err != nil {
		return cs, errors.Trace(err)
	}
	_, err = cs.R.Accept(bv.V)
	if err != nil {
		return cs, errors.Trace(err)
	}
	return cs, nil
}

// VisitDefault implements Visitor interface.
func (bv *BaseVisitor) VisitDefault(d *Default) (Expression, error) {
	return d, nil
}

// VisitExistsSubQuery implements Visitor interface.
func (bv *BaseVisitor) VisitExistsSubQuery(es *ExistsSubQuery) (Expression, error) {
	var err error
	_, err = es.Sel.Accept(bv.V)
	if err != nil {
		return es, errors.Trace(err)
	}
	return es, nil
}

// VisitFunctionCase implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionCase(f *FunctionCase) (Expression, error) {
	var err error
	f.Value, err = f.Value.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	for i := range f.WhenClauses {
		_, err = f.WhenClauses[i].Accept(bv.V)
		if err != nil {
			return f, errors.Trace(err)
		}
	}
	f.ElseClause, err = f.ElseClause.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	return f, nil
}

//VisitFunctionCast implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionCast(f *FunctionCast) (Expression, error) {
	var err error
	f.Expr, err = f.Expr.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	return f, nil
}

// VisitFunctionConvert implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionConvert(f *FunctionConvert) (Expression, error) {
	var err error
	f.Expr, err = f.Expr.Accept(bv.V)
	if err != nil {
		return f, errors.Trace(err)
	}
	return f, nil
}

// VisitFunctionSubstring implements Visitor interface.
func (bv *BaseVisitor) VisitFunctionSubstring(ss *FunctionSubstring) (Expression, error) {
	var err error
	ss.StrExpr, err = ss.StrExpr.Accept(bv.V)
	if err != nil {
		return ss, errors.Trace(err)
	}
	ss.Pos, err = ss.Pos.Accept(bv.V)
	if err != nil {
		return ss, errors.Trace(err)
	}
	ss.Len, err = ss.Len.Accept(bv.V)
	if err != nil {
		return ss, errors.Trace(err)
	}
	return ss, nil
}

// VisitIdent implements Visitor interface.
func (bv *BaseVisitor) VisitIdent(i *Ident) (Expression, error) {
	return i, nil
}

// VisitIsNull implements Visitor interface.
func (bv *BaseVisitor) VisitIsNull(is *IsNull) (Expression, error) {
	var err error
	is.Expr, err = is.Expr.Accept(bv.V)
	if err != nil {
		return is, errors.Trace(err)
	}
	return is, nil
}

// VisitIsTruth implements Visitor interface.
func (bv *BaseVisitor) VisitIsTruth(is *IsTruth) (Expression, error) {
	var err error
	is.Expr, err = is.Expr.Accept(bv.V)
	if err != nil {
		return is, errors.Trace(err)
	}
	return is, nil
}

// VisitParamMaker implements Visitor interface.
func (bv *BaseVisitor) VisitParamMaker(pm *ParamMarker) (Expression, error) {
	if pm.Expr == nil {
		return pm, nil
	}
	var err error
	pm.Expr, err = pm.Expr.Accept(bv.V)
	if err != nil {
		return pm, errors.Trace(err)
	}
	return pm, nil
}

// VisitPatternIn implements Visitor interface.
func (bv *BaseVisitor) VisitPatternIn(n *PatternIn) (Expression, error) {
	var err error
	n.Expr, err = n.Expr.Accept(bv.V)
	if err != nil {
		return n, errors.Trace(err)
	}
	if n.Sel != nil {
		_, err = n.Sel.Accept(bv.V)
		if err != nil {
			return n, errors.Trace(err)
		}
	}
	for i := range n.List {
		n.List[i], err = n.List[i].Accept(bv.V)
		if err != nil {
			return n, errors.Trace(err)
		}
	}
	return n, nil
}

// VisitPatternLike implements Visitor interface.
func (bv *BaseVisitor) VisitPatternLike(p *PatternLike) (Expression, error) {
	var err error
	p.Expr, err = p.Expr.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	p.Pattern, err = p.Pattern.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	return p, nil
}

// VisitPatternRegexp implements Visitor interface.
func (bv *BaseVisitor) VisitPatternRegexp(p *PatternRegexp) (Expression, error) {
	var err error
	p.Expr, err = p.Expr.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	p.Pattern, err = p.Pattern.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	return p, nil
}

// VisitPExpr implements Visitor interface.
func (bv *BaseVisitor) VisitPExpr(p *PExpr) (Expression, error) {
	var err error
	p.Expr, err = p.Expr.Accept(bv.V)
	if err != nil {
		return p, errors.Trace(err)
	}
	return p, nil
}

// VisitPosition implements Visitor interface.
func (bv *BaseVisitor) VisitPosition(p *Position) (Expression, error) {
	return p, nil
}

// VisitRow implements Visitor interface.
func (bv *BaseVisitor) VisitRow(r *Row) (Expression, error) {
	var err error
	for i := range r.Values {
		r.Values[i], err = r.Values[i].Accept(bv.V)
		if err != nil {
			return r, errors.Trace(err)
		}
	}
	return r, nil
}

// VisitSubQuery implements Visitor interface.
func (bv *BaseVisitor) VisitSubQuery(sq SubQuery) (Expression, error) {
	return sq, nil
}

// VisitUnaryOperation implements Visitor interface.
func (bv *BaseVisitor) VisitUnaryOperation(u *UnaryOperation) (Expression, error) {
	var err error
	u.V, err = u.V.Accept(bv.V)
	if err != nil {
		return u, errors.Trace(err)
	}
	return u, nil
}

// VisitValue implements Visitor interface.
func (bv *BaseVisitor) VisitValue(v Value) (Expression, error) {
	return v, nil
}

// VisitValues implements Visitor interface.
func (bv *BaseVisitor) VisitValues(v *Values) (Expression, error) {
	return v, nil
}

// VisitVariable implements Visitor interface.
func (bv *BaseVisitor) VisitVariable(v *Variable) (Expression, error) {
	return v, nil
}

// VisitWhenClause implements Visitor interface.
func (bv *BaseVisitor) VisitWhenClause(w *WhenClause) (Expression, error) {
	var err error
	w.Expr, err = w.Expr.Accept(bv.V)
	if err != nil {
		return w, errors.Trace(err)
	}
	w.Result, err = w.Result.Accept(bv.V)
	if err != nil {
		return w, errors.Trace(err)
	}
	return w, nil
}
<|endoftext|>


<commit_before>package api

import (
	"net/http"

	wkhtmltopdf "github.com/SebastiaanKlippert/go-wkhtmltopdf"

	"strings"

	"encoding/json"
	"os"

	"io/ioutil"

	"bitbucket.org/mundipagg/boletoapi/bank"
	"bitbucket.org/mundipagg/boletoapi/boleto"
	"bitbucket.org/mundipagg/boletoapi/config"
	"bitbucket.org/mundipagg/boletoapi/db"
	"bitbucket.org/mundipagg/boletoapi/log"
	"bitbucket.org/mundipagg/boletoapi/models"
	"bitbucket.org/mundipagg/boletoapi/util"
	gin "gopkg.in/gin-gonic/gin.v1"
)

//Regista um boleto em um determinado banco
func registerBoleto(c *gin.Context) {
	_boleto, _ := c.Get("boleto")
	boleto := _boleto.(models.BoletoRequest)
	bank, err := bank.Get(boleto.BankNumber)
	if checkError(c, err, log.CreateLog()) {
		return
	}
	lg := bank.Log()
	lg.Operation = "RegisterBoleto"
	lg.NossoNumero = boleto.Title.OurNumber
	lg.Recipient = bank.GetBankNumber().BankName()

	repo, err := db.GetDB()
	if checkError(c, err, lg) {
		return
	}
	resp, errR := bank.ProcessBoleto(&boleto)

	if checkError(c, errR, lg) {
		return
	}
	st := http.StatusOK
	if len(resp.Errors) > 0 {
		if resp.StatusCode > 0 {
			st = resp.StatusCode
		} else {
			st = http.StatusBadRequest
		}
	} else {
		boView := models.NewBoletoView(boleto, resp.BarCodeNumber, resp.DigitableLine)
		resp.Links = boView.CreateLinks()
		resp.ID = boView.ID
		errMongo := repo.SaveBoleto(boView)
		if errMongo != nil {
			saveBoletoJSONFile(boView, lg, errMongo)
		}
	}
	c.JSON(st, resp)
	c.Set("boletoResponse", resp)
}

func saveBoletoJSONFile(boView models.BoletoView, lg *log.Log, err error) {
	lg.Warn(err.Error(), "Boleto cannot be saved at Database")
	fd, errOpen := os.Create(config.Get().BoletoJSONFileStore + "/boleto_" + boView.UID + ".json")
	if errOpen != nil {
		lg.Fatal(boView, "[BOLETO_ONLINE_CONTINGENCIA]"+errOpen.Error())
	}
	data, _ := json.Marshal(boView)
	_, errW := fd.Write(data)
	if errW != nil {
		lg.Fatal(boView, "[BOLETO_ONLINE_CONTINGENCIA]"+errW.Error())
	}
	fd.Close()
}

func getBoleto(c *gin.Context) {
	c.Status(200)

	id := c.Query("id")
	format := c.Query("fmt")
	repo, errCon := db.GetDB()
	if checkError(c, errCon, log.CreateLog()) {
		return
	}
	bleto, err := repo.GetBoletoByID(id)
	if err != nil {
		uid := util.Decrypt(id)
		fd, err := os.Open(config.Get().BoletoJSONFileStore + "/boleto_" + uid + ".json")
		if err != nil {
			checkError(c, models.NewHttpNotFound("Boleto não encontrado na base de dados", "MP404"), log.CreateLog())
			return
		}
		data, errR := ioutil.ReadAll(fd)
		if errR != nil {
			checkError(c, models.NewHttpNotFound("Boleto não encontrado na base de dados", "MP404"), log.CreateLog())
			return
		}
		json.Unmarshal(data, &bleto)
		fd.Close()
	}

	s := boleto.HTML(bleto, format)
	if format == "html" {
		c.Header("Content-Type", "text/html; charset=utf-8")
		c.Writer.WriteString(s)
	} else {
		c.Header("Content-Type", "application/pdf")
		buf, _ := toPdf(s)
		c.Writer.Write(buf)
	}

}

func toPdf(page string) ([]byte, error) {
	pdfg, err := wkhtmltopdf.NewPDFGenerator()
	if err != nil {
		return nil, err
	}
	pdfg.Dpi.Set(600)
	pdfg.NoCollate.Set(false)
	pdfg.PageSize.Set(wkhtmltopdf.PageSizeA4)
	pdfg.AddPage(wkhtmltopdf.NewPageReader(strings.NewReader(page)))
	err = pdfg.Create()
	if err != nil {
		return nil, err
	}
	return pdfg.Bytes(), nil
}
<commit_msg>:construction: adiciona metodo get boleto by id<commit_after>package api

import (
	"net/http"

	wkhtmltopdf "github.com/SebastiaanKlippert/go-wkhtmltopdf"

	"strings"

	"encoding/json"
	"os"

	"io/ioutil"

	"bitbucket.org/mundipagg/boletoapi/bank"
	"bitbucket.org/mundipagg/boletoapi/boleto"
	"bitbucket.org/mundipagg/boletoapi/config"
	"bitbucket.org/mundipagg/boletoapi/db"
	"bitbucket.org/mundipagg/boletoapi/log"
	"bitbucket.org/mundipagg/boletoapi/models"
	"bitbucket.org/mundipagg/boletoapi/util"
	gin "gopkg.in/gin-gonic/gin.v1"
)

//Regista um boleto em um determinado banco
func registerBoleto(c *gin.Context) {
	_boleto, _ := c.Get("boleto")
	boleto := _boleto.(models.BoletoRequest)
	bank, err := bank.Get(boleto.BankNumber)
	if checkError(c, err, log.CreateLog()) {
		return
	}
	lg := bank.Log()
	lg.Operation = "RegisterBoleto"
	lg.NossoNumero = boleto.Title.OurNumber
	lg.Recipient = bank.GetBankNumber().BankName()

	repo, err := db.GetDB()
	if checkError(c, err, lg) {
		return
	}
	resp, errR := bank.ProcessBoleto(&boleto)

	if checkError(c, errR, lg) {
		return
	}
	st := http.StatusOK
	if len(resp.Errors) > 0 {
		if resp.StatusCode > 0 {
			st = resp.StatusCode
		} else {
			st = http.StatusBadRequest
		}
	} else {
		boView := models.NewBoletoView(boleto, resp.BarCodeNumber, resp.DigitableLine)
		resp.Links = boView.CreateLinks()
		resp.ID = boView.ID
		errMongo := repo.SaveBoleto(boView)
		if errMongo != nil {
			saveBoletoJSONFile(boView, lg, errMongo)
		}
	}
	c.JSON(st, resp)
	c.Set("boletoResponse", resp)
}

func saveBoletoJSONFile(boView models.BoletoView, lg *log.Log, err error) {
	lg.Warn(err.Error(), "Boleto cannot be saved at Database")
	fd, errOpen := os.Create(config.Get().BoletoJSONFileStore + "/boleto_" + boView.UID + ".json")
	if errOpen != nil {
		lg.Fatal(boView, "[BOLETO_ONLINE_CONTINGENCIA]"+errOpen.Error())
	}
	data, _ := json.Marshal(boView)
	_, errW := fd.Write(data)
	if errW != nil {
		lg.Fatal(boView, "[BOLETO_ONLINE_CONTINGENCIA]"+errW.Error())
	}
	fd.Close()
}

func getBoleto(c *gin.Context) {
	c.Status(200)

	id := c.Query("id")
	format := c.Query("fmt")
	repo, errCon := db.GetDB()
	if checkError(c, errCon, log.CreateLog()) {
		return
	}
	bleto, err := repo.GetBoletoByID(id)
	if err != nil {
		uid := util.Decrypt(id)
		fd, err := os.Open(config.Get().BoletoJSONFileStore + "/boleto_" + uid + ".json")
		if err != nil {
			checkError(c, models.NewHttpNotFound("Boleto não encontrado na base de dados", "MP404"), log.CreateLog())
			return
		}
		data, errR := ioutil.ReadAll(fd)
		if errR != nil {
			checkError(c, models.NewHttpNotFound("Boleto não encontrado na base de dados", "MP404"), log.CreateLog())
			return
		}
		json.Unmarshal(data, &bleto)
		fd.Close()
	}

	s := boleto.HTML(bleto, format)
	if format == "html" {
		c.Header("Content-Type", "text/html; charset=utf-8")
		c.Writer.WriteString(s)
	} else {
		c.Header("Content-Type", "application/pdf")
		buf, _ := toPdf(s)
		c.Writer.Write(buf)
	}

}

func toPdf(page string) ([]byte, error) {
	pdfg, err := wkhtmltopdf.NewPDFGenerator()
	if err != nil {
		return nil, err
	}
	pdfg.Dpi.Set(600)
	pdfg.NoCollate.Set(false)
	pdfg.PageSize.Set(wkhtmltopdf.PageSizeA4)
	pdfg.AddPage(wkhtmltopdf.NewPageReader(strings.NewReader(page)))
	err = pdfg.Create()
	if err != nil {
		return nil, err
	}
	return pdfg.Bytes(), nil
}

func getBoletoByID(c *gin.Context) {
	id := c.Param("id")
	db, errDb := db.GetDB()
	if errDb != nil {
		checkError(c, models.NewInternalServerError("MP500", "Erro interno"), log.CreateLog())
	}
	boleto, err := db.GetBoletoByID(id)
	if err != nil {
		checkError(c, models.NewHttpNotFound("MP404", "Boleto não encontrado"), nil)
		return
	}
	c.JSON(http.StatusOK, boleto)
}
<|endoftext|>


<commit_before>package test

import (
	"errors"

	icd "github.com/dh1tw/goSoundbench/icd"
	"github.com/dh1tw/goSoundbench/sound"
	"github.com/gogo/protobuf/proto"
	"github.com/spf13/viper"
)

// Serialize the results into a protocol buffers byte array
func (STR *SineTestResult) Serialize() ([]byte, error) {
	id := STR.ID

	pbSTR := icd.SineTestResult{}
	pbSTR.Id = &id

	for _, res := range STR.Results {

		pbSTER := icd.SineTestElementResults{}

		for _, ch := range res.Channels {

			pbCH := icd.AudioChannel{}
			var pbAchid icd.ACHID

			if ch.AudioChId == sound.LEFT {
				pbAchid = icd.ACHID_LEFT
			} else if ch.AudioChId == sound.RIGHT {
				pbAchid = icd.ACHID_RIGHT
			} else {
				return []byte{}, errors.New("unknown Audio Channel Id")
			}

			pbCH.Achid = &pbAchid

			for _, tone := range ch.Tones {

				frequency := float32(tone.Frequency)
				amplitude := float32(tone.Amplitude)

				pTone := icd.Tone{
					Frequency: &frequency,
					Amplitude: &amplitude,
				}

				pbCH.Tones = append(pbCH.Tones, &pTone)
			}

			pbSTER.AudioChannels = append(pbSTER.AudioChannels, &pbCH)
		}

		mapping := viper.GetStringMapString("topic-device-mapping")

		if len(mapping) == 0 {
			return nil, errors.New("topic device map is empty; Check config file")
		}

		reverseMap := reverseMap(mapping)

		if _, ok := reverseMap[res.DeviceName]; ok {
			deviceName := mapping[res.DeviceName]
			pbSTER.Channel = &deviceName
		} else {
			return []byte{}, errors.New("could not find device mapping")
		}

		pbSTR.Results = append(pbSTR.Results, &pbSTER)
	}

	pbTR := icd.TestResults{
		SineTestResult: &pbSTR,
	}

	data, err := proto.Marshal(&pbTR)

	if err != nil {
		return nil, err
	}

	return data, nil
}

// reverseMap returns a map with switched keys - values
func reverseMap(m map[string]string) map[string]string {
	n := make(map[string]string)
	for k, v := range m {
		n[v] = k
	}
	return n
}
<commit_msg>Channel Name now correctly resolved<commit_after>package test

import (
	"errors"

	icd "github.com/dh1tw/goSoundbench/icd"
	"github.com/dh1tw/goSoundbench/sound"
	"github.com/gogo/protobuf/proto"
	"github.com/spf13/viper"
)

// Serialize the results into a protocol buffers byte array
func (STR *SineTestResult) Serialize() ([]byte, error) {
	id := STR.ID

	pbSTR := icd.SineTestResult{}
	pbSTR.Id = &id

	for _, res := range STR.Results {

		pbSTER := icd.SineTestElementResults{}

		for _, ch := range res.Channels {

			pbCH := icd.AudioChannel{}
			var pbAchid icd.ACHID

			if ch.AudioChId == sound.LEFT {
				pbAchid = icd.ACHID_LEFT
			} else if ch.AudioChId == sound.RIGHT {
				pbAchid = icd.ACHID_RIGHT
			} else {
				return []byte{}, errors.New("unknown Audio Channel Id")
			}

			pbCH.Achid = &pbAchid

			for _, tone := range ch.Tones {

				frequency := float32(tone.Frequency)
				amplitude := float32(tone.Amplitude)

				pTone := icd.Tone{
					Frequency: &frequency,
					Amplitude: &amplitude,
				}

				pbCH.Tones = append(pbCH.Tones, &pTone)
			}

			pbSTER.AudioChannels = append(pbSTER.AudioChannels, &pbCH)
		}

		mapping := viper.GetStringMapString("topic-device-mapping")

		if len(mapping) == 0 {
			return nil, errors.New("topic device map is empty; Check config file")
		}

		reverseMap := reverseMap(mapping)

		if _, ok := reverseMap[res.DeviceName]; ok {
			deviceName := reverseMap[res.DeviceName]
			pbSTER.Channel = &deviceName
		} else {
			return []byte{}, errors.New("could not find device mapping")
		}

		pbSTR.Results = append(pbSTR.Results, &pbSTER)
	}

	pbTR := icd.TestResults{
		SineTestResult: &pbSTR,
	}

	data, err := proto.Marshal(&pbTR)

	if err != nil {
		return nil, err
	}

	return data, nil
}

// reverseMap returns a map with switched keys - values
func reverseMap(m map[string]string) map[string]string {
	n := make(map[string]string)
	for k, v := range m {
		n[v] = k
	}
	return n
}
<|endoftext|>


<commit_before>//                           _       _
// __      _____  __ ___   ___  __ _| |_ ___
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
//  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
//   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
//
//  Copyright © 2016 - 2019 SeMI Holding B.V. (registered @ Dutch Chamber of Commerce no 75221632). All rights reserved.
//  LICENSE WEAVIATE OPEN SOURCE: https://www.semi.technology/playbook/playbook/contract-weaviate-OSS.html
//  LICENSE WEAVIATE ENTERPRISE: https://www.semi.technology/playbook/contract-weaviate-enterprise.html
//  CONCEPT: Bob van Luijt (@bobvanluijt)
//  CONTACT: hello@semi.technology
//

package classification

import (
	"context"
	"fmt"
	"time"

	"github.com/go-openapi/strfmt"
	uuid "github.com/satori/go.uuid"
	"github.com/semi-technologies/weaviate/adapters/handlers/rest/filterext"
	libfilters "github.com/semi-technologies/weaviate/entities/filters"
	"github.com/semi-technologies/weaviate/entities/models"
	"github.com/semi-technologies/weaviate/entities/schema"
	"github.com/semi-technologies/weaviate/entities/schema/kind"
	"github.com/semi-technologies/weaviate/entities/search"
	schemaUC "github.com/semi-technologies/weaviate/usecases/schema"
	"github.com/semi-technologies/weaviate/usecases/traverser"
	libvectorizer "github.com/semi-technologies/weaviate/usecases/vectorizer"
)

type distancer func(a, b []float32) (float32, error)

type Classifier struct {
	schemaGetter schemaUC.SchemaGetter
	repo         Repo
	vectorRepo   vectorRepo
	authorizer   authorizer
	distancer    distancer
}

type authorizer interface {
	Authorize(principal *models.Principal, verb, resource string) error
}

func New(sg schemaUC.SchemaGetter, cr Repo, vr vectorRepo, authorizer authorizer) *Classifier {
	return &Classifier{
		schemaGetter: sg,
		repo:         cr,
		vectorRepo:   vr,
		authorizer:   authorizer,
		distancer:    libvectorizer.NormalizedDistance,
	}
}

// Repo to manage classification state, should be consistent, not used to store
// acutal data object vectors, see VectorRepo
type Repo interface {
	Put(ctx context.Context, classification models.Classification) error
	Get(ctx context.Context, id strfmt.UUID) (*models.Classification, error)
}

type VectorRepo interface {
	GetUnclassified(ctx context.Context, kind kind.Kind, class string,
		properties []string, filter *libfilters.LocalFilter) ([]search.Result, error)
	AggregateNeighbors(ctx context.Context, vector []float32,
		kind kind.Kind, class string, properties []string, k int,
		filter *libfilters.LocalFilter) ([]NeighborRef, error)
	VectorClassSearch(ctx context.Context, params traverser.GetParams) ([]search.Result, error)
}

type vectorRepo interface {
	VectorRepo
	PutThing(ctx context.Context, thing *models.Thing, vector []float32) error
	PutAction(ctx context.Context, action *models.Action, vector []float32) error
}

// NeighborRef is the result of an aggregation of the ref properties of k neighbors
type NeighborRef struct {
	// Property indicates which property was aggregated
	Property string

	// The beacon of the most common (kNN) reference
	Beacon strfmt.URI

	// Count (n<=k) of number of the winning Beacon
	Count int

	WinningDistance float32
	LosingDistance  *float32
}

type filters struct {
	source      *libfilters.LocalFilter
	target      *libfilters.LocalFilter
	trainingSet *libfilters.LocalFilter
}

func (c *Classifier) Schedule(ctx context.Context, principal *models.Principal, params models.Classification) (*models.Classification, error) {
	err := c.authorizer.Authorize(principal, "create", "classifications/*")
	if err != nil {
		return nil, err
	}

	err = NewValidator(c.schemaGetter, params).Do()
	if err != nil {
		return nil, err
	}

	c.setDefaultValuesForOptionalFields(&params)

	if err := c.assignNewID(&params); err != nil {
		return nil, fmt.Errorf("classification: assign id: %v", err)
	}

	params.Status = models.ClassificationStatusRunning
	params.Meta = &models.ClassificationMeta{
		Started: strfmt.DateTime(time.Now()),
	}

	if err := c.repo.Put(ctx, params); err != nil {
		return nil, fmt.Errorf("classification: put: %v", err)
	}

	// asynchronously trigger the classification
	kind := c.getKind(params)
	filters, err := extractFilters(params)
	if err != nil {
		return nil, err
	}

	go c.run(params, kind, filters)

	return &params, nil
}

func extractFilters(params models.Classification) (filters, error) {
	source, err := filterext.Parse(params.SourceWhere)
	if err != nil {
		return filters{}, fmt.Errorf("field 'sourceWhere': %v", err)
	}

	trainingSet, err := filterext.Parse(params.TrainingSetWhere)
	if err != nil {
		return filters{}, fmt.Errorf("field 'trainingSetWhere': %v", err)
	}

	target, err := filterext.Parse(params.TargetWhere)
	if err != nil {
		return filters{}, fmt.Errorf("field 'targetWhere': %v", err)
	}

	return filters{
		source:      source,
		trainingSet: trainingSet,
		target:      target,
	}, nil
}

func (c *Classifier) getKind(params models.Classification) kind.Kind {
	s := c.schemaGetter.GetSchemaSkipAuth()
	kind, _ := s.GetKindOfClass(schema.ClassName(params.Class))
	// skip nil-check as we have made it past validation
	return kind
}

func (c *Classifier) assignNewID(params *models.Classification) error {
	id, err := uuid.NewV4()
	if err != nil {
		return err
	}

	params.ID = strfmt.UUID(id.String())
	return nil
}

func (c *Classifier) Get(ctx context.Context, principal *models.Principal, id strfmt.UUID) (*models.Classification, error) {
	err := c.authorizer.Authorize(principal, "get", "classifications/*")
	if err != nil {
		return nil, err
	}

	return c.repo.Get(ctx, id)
}

func (c *Classifier) setDefaultValuesForOptionalFields(params *models.Classification) {
	if params.Type == nil {
		defaultType := "knn"
		params.Type = &defaultType
	}

	if params.K == nil {
		defaultK := int32(3)
		params.K = &defaultK
	}

}
<commit_msg>gh-1045 only set defaults for respective types<commit_after>//                           _       _
// __      _____  __ ___   ___  __ _| |_ ___
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \
//  \ V  V /  __/ (_| |\ V /| | (_| | ||  __/
//   \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___|
//
//  Copyright © 2016 - 2019 SeMI Holding B.V. (registered @ Dutch Chamber of Commerce no 75221632). All rights reserved.
//  LICENSE WEAVIATE OPEN SOURCE: https://www.semi.technology/playbook/playbook/contract-weaviate-OSS.html
//  LICENSE WEAVIATE ENTERPRISE: https://www.semi.technology/playbook/contract-weaviate-enterprise.html
//  CONCEPT: Bob van Luijt (@bobvanluijt)
//  CONTACT: hello@semi.technology
//

package classification

import (
	"context"
	"fmt"
	"time"

	"github.com/go-openapi/strfmt"
	uuid "github.com/satori/go.uuid"
	"github.com/semi-technologies/weaviate/adapters/handlers/rest/filterext"
	libfilters "github.com/semi-technologies/weaviate/entities/filters"
	"github.com/semi-technologies/weaviate/entities/models"
	"github.com/semi-technologies/weaviate/entities/schema"
	"github.com/semi-technologies/weaviate/entities/schema/kind"
	"github.com/semi-technologies/weaviate/entities/search"
	schemaUC "github.com/semi-technologies/weaviate/usecases/schema"
	"github.com/semi-technologies/weaviate/usecases/traverser"
	libvectorizer "github.com/semi-technologies/weaviate/usecases/vectorizer"
)

type distancer func(a, b []float32) (float32, error)

type Classifier struct {
	schemaGetter schemaUC.SchemaGetter
	repo         Repo
	vectorRepo   vectorRepo
	authorizer   authorizer
	distancer    distancer
}

type authorizer interface {
	Authorize(principal *models.Principal, verb, resource string) error
}

func New(sg schemaUC.SchemaGetter, cr Repo, vr vectorRepo, authorizer authorizer) *Classifier {
	return &Classifier{
		schemaGetter: sg,
		repo:         cr,
		vectorRepo:   vr,
		authorizer:   authorizer,
		distancer:    libvectorizer.NormalizedDistance,
	}
}

// Repo to manage classification state, should be consistent, not used to store
// acutal data object vectors, see VectorRepo
type Repo interface {
	Put(ctx context.Context, classification models.Classification) error
	Get(ctx context.Context, id strfmt.UUID) (*models.Classification, error)
}

type VectorRepo interface {
	GetUnclassified(ctx context.Context, kind kind.Kind, class string,
		properties []string, filter *libfilters.LocalFilter) ([]search.Result, error)
	AggregateNeighbors(ctx context.Context, vector []float32,
		kind kind.Kind, class string, properties []string, k int,
		filter *libfilters.LocalFilter) ([]NeighborRef, error)
	VectorClassSearch(ctx context.Context, params traverser.GetParams) ([]search.Result, error)
}

type vectorRepo interface {
	VectorRepo
	PutThing(ctx context.Context, thing *models.Thing, vector []float32) error
	PutAction(ctx context.Context, action *models.Action, vector []float32) error
}

// NeighborRef is the result of an aggregation of the ref properties of k neighbors
type NeighborRef struct {
	// Property indicates which property was aggregated
	Property string

	// The beacon of the most common (kNN) reference
	Beacon strfmt.URI

	// Count (n<=k) of number of the winning Beacon
	Count int

	WinningDistance float32
	LosingDistance  *float32
}

type filters struct {
	source      *libfilters.LocalFilter
	target      *libfilters.LocalFilter
	trainingSet *libfilters.LocalFilter
}

func (c *Classifier) Schedule(ctx context.Context, principal *models.Principal, params models.Classification) (*models.Classification, error) {
	err := c.authorizer.Authorize(principal, "create", "classifications/*")
	if err != nil {
		return nil, err
	}

	err = NewValidator(c.schemaGetter, params).Do()
	if err != nil {
		return nil, err
	}

	c.setDefaultValuesForOptionalFields(&params)

	if err := c.assignNewID(&params); err != nil {
		return nil, fmt.Errorf("classification: assign id: %v", err)
	}

	params.Status = models.ClassificationStatusRunning
	params.Meta = &models.ClassificationMeta{
		Started: strfmt.DateTime(time.Now()),
	}

	if err := c.repo.Put(ctx, params); err != nil {
		return nil, fmt.Errorf("classification: put: %v", err)
	}

	// asynchronously trigger the classification
	kind := c.getKind(params)
	filters, err := extractFilters(params)
	if err != nil {
		return nil, err
	}

	go c.run(params, kind, filters)

	return &params, nil
}

func extractFilters(params models.Classification) (filters, error) {
	source, err := filterext.Parse(params.SourceWhere)
	if err != nil {
		return filters{}, fmt.Errorf("field 'sourceWhere': %v", err)
	}

	trainingSet, err := filterext.Parse(params.TrainingSetWhere)
	if err != nil {
		return filters{}, fmt.Errorf("field 'trainingSetWhere': %v", err)
	}

	target, err := filterext.Parse(params.TargetWhere)
	if err != nil {
		return filters{}, fmt.Errorf("field 'targetWhere': %v", err)
	}

	return filters{
		source:      source,
		trainingSet: trainingSet,
		target:      target,
	}, nil
}

func (c *Classifier) getKind(params models.Classification) kind.Kind {
	s := c.schemaGetter.GetSchemaSkipAuth()
	kind, _ := s.GetKindOfClass(schema.ClassName(params.Class))
	// skip nil-check as we have made it past validation
	return kind
}

func (c *Classifier) assignNewID(params *models.Classification) error {
	id, err := uuid.NewV4()
	if err != nil {
		return err
	}

	params.ID = strfmt.UUID(id.String())
	return nil
}

func (c *Classifier) Get(ctx context.Context, principal *models.Principal, id strfmt.UUID) (*models.Classification, error) {
	err := c.authorizer.Authorize(principal, "get", "classifications/*")
	if err != nil {
		return nil, err
	}

	return c.repo.Get(ctx, id)
}

func (c *Classifier) setDefaultValuesForOptionalFields(params *models.Classification) {
	if params.Type == nil {
		defaultType := "knn"
		params.Type = &defaultType
	}

	if *params.Type == "knn" {
		c.setDefaultsForKNN(params)
	}

	if *params.Type == "contextual" {
		c.setDefaultsForContextual(params)
	}

}

func (c *Classifier) setDefaultsForKNN(params *models.Classification) {
	if params.K == nil {
		defaultK := int32(3)
		params.K = &defaultK
	}
}

func (c *Classifier) setDefaultsForContextual(params *models.Classification) {
	// none at the moment
}
<|endoftext|>


<commit_before>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// vespa-logfmt command
// Author: arnej

package main

import (
	"github.com/spf13/cobra"
	"github.com/vespa-engine/vespa/client/go/build"
	"github.com/vespa-engine/vespa/client/go/cmd/logfmt"
)

func NewLogfmtCmd() *cobra.Command {
	var (
		curOptions logfmt.Options = logfmt.NewOptions()
	)
	cmd := &cobra.Command{
		Use:   "vespa-logfmt",
		Short: "convert vespa.log to human-readable format",
		Long: `vespa-logfmt takes input in the internal vespa format
and converts it to something human-readable`,
		Version: build.Version,
		Run: func(cmd *cobra.Command, args []string) {
			logfmt.RunLogfmt(&curOptions, args)
		},
		Args: cobra.MaximumNArgs(1),
	}
	cmd.Flags().VarP(&curOptions.ShowLevels, "level", "l", "turn levels on/off\n")
	cmd.Flags().VarP(&curOptions.ShowFields, "show", "s", "turn fields shown on/off\n")
	cmd.Flags().VarP(&curOptions.ComponentFilter, "component", "c", "select components by regexp")
	cmd.Flags().VarP(&curOptions.MessageFilter, "message", "m", "select messages by regexp")
	cmd.Flags().BoolVarP(&curOptions.OnlyInternal, "internal", "i", false, "select only internal components")
	cmd.Flags().BoolVar(&curOptions.TruncateService, "truncateservice", false, "truncate service name")
	cmd.Flags().BoolVar(&curOptions.TruncateService, "ts", false, "")
	cmd.Flags().BoolVarP(&curOptions.FollowTail, "follow", "f", false, "follow logfile with tail -f")
	cmd.Flags().BoolVarP(&curOptions.DequoteNewlines, "nldequote", "N", false, "dequote newlines embedded in message")
	cmd.Flags().BoolVarP(&curOptions.DequoteNewlines, "dequotenewlines", "n", false, "dequote newlines embedded in message")
	cmd.Flags().BoolVarP(&curOptions.TruncateComponent, "truncatecomponent", "t", false, "truncate component name")
	cmd.Flags().BoolVar(&curOptions.TruncateComponent, "tc", false, "")
	cmd.Flags().StringVarP(&curOptions.OnlyHostname, "host", "H", "", "select only one host")
	cmd.Flags().StringVarP(&curOptions.OnlyPid, "pid", "p", "", "select only one process ID")
	cmd.Flags().StringVarP(&curOptions.OnlyService, "service", "S", "", "select only one service")
	cmd.Flags().MarkHidden("tc")
	cmd.Flags().MarkHidden("ts")
	cmd.Flags().MarkHidden("dequotenewlines")
	return cmd
}
<commit_msg>fix copy-paste bug<commit_after>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
// vespa-logfmt command
// Author: arnej

package main

import (
	"github.com/spf13/cobra"
	"github.com/vespa-engine/vespa/client/go/build"
	"github.com/vespa-engine/vespa/client/go/cmd/logfmt"
)

func NewLogfmtCmd() *cobra.Command {
	var (
		curOptions logfmt.Options = logfmt.NewOptions()
	)
	cmd := &cobra.Command{
		Use:   "vespa-logfmt",
		Short: "convert vespa.log to human-readable format",
		Long: `vespa-logfmt takes input in the internal vespa format
and converts it to something human-readable`,
		Version: build.Version,
		Run: func(cmd *cobra.Command, args []string) {
			logfmt.RunLogfmt(&curOptions, args)
		},
	}
	cmd.Flags().VarP(&curOptions.ShowLevels, "level", "l", "turn levels on/off\n")
	cmd.Flags().VarP(&curOptions.ShowFields, "show", "s", "turn fields shown on/off\n")
	cmd.Flags().VarP(&curOptions.ComponentFilter, "component", "c", "select components by regexp")
	cmd.Flags().VarP(&curOptions.MessageFilter, "message", "m", "select messages by regexp")
	cmd.Flags().BoolVarP(&curOptions.OnlyInternal, "internal", "i", false, "select only internal components")
	cmd.Flags().BoolVar(&curOptions.TruncateService, "truncateservice", false, "truncate service name")
	cmd.Flags().BoolVar(&curOptions.TruncateService, "ts", false, "")
	cmd.Flags().BoolVarP(&curOptions.FollowTail, "follow", "f", false, "follow logfile with tail -f")
	cmd.Flags().BoolVarP(&curOptions.DequoteNewlines, "nldequote", "N", false, "dequote newlines embedded in message")
	cmd.Flags().BoolVarP(&curOptions.DequoteNewlines, "dequotenewlines", "n", false, "dequote newlines embedded in message")
	cmd.Flags().BoolVarP(&curOptions.TruncateComponent, "truncatecomponent", "t", false, "truncate component name")
	cmd.Flags().BoolVar(&curOptions.TruncateComponent, "tc", false, "")
	cmd.Flags().StringVarP(&curOptions.OnlyHostname, "host", "H", "", "select only one host")
	cmd.Flags().StringVarP(&curOptions.OnlyPid, "pid", "p", "", "select only one process ID")
	cmd.Flags().StringVarP(&curOptions.OnlyService, "service", "S", "", "select only one service")
	cmd.Flags().MarkHidden("tc")
	cmd.Flags().MarkHidden("ts")
	cmd.Flags().MarkHidden("dequotenewlines")
	return cmd
}
<|endoftext|>


<commit_before>package command

import (
	"bufio"
	"fmt"
	"log"
	"regexp"
	"strconv"
	"strings"

	"github.com/go-almeria/gitx/api"
	"github.com/go-almeria/gitx/meta"
)

// CountCommand Outputs commit count
type CountCommand struct {
	meta.Meta
}

func (c *CountCommand) Run(args []string) int {
	var all bool

	flags := c.Meta.FlagSet("count", meta.FlagSetDefault)
	flags.BoolVar(&all, "all", false, "")
	flags.Usage = func() { c.Ui.Error(c.Help()) }
	if err := flags.Parse(args); err != nil {
		return 1
	}

	args = flags.Args()
	if len(args) > 1 {
		flags.Usage()
		c.Ui.Error(fmt.Sprintf("\ncount expects at most one argument"))
		return 1
	}

	g := *api.NewGit("shortlog HEAD -n -s")
	if !g.IsRepo() {
		c.Ui.Error("Not a git repository (or any of the parent directories): .git")
		return 1
	}

	if err := g.Run(); err != nil {
		c.Ui.Error(fmt.Sprintf("%s", string(g.Err.Bytes())))
		return 1
	}

	re := regexp.MustCompile(`(\d+)\s+(\S+.*)`)
	scanner := bufio.NewScanner(&g.Out)

	count := 0
	for scanner.Scan() {
		results := re.FindAllStringSubmatch(scanner.Text(), -1)
		userCount, _ := strconv.Atoi(results[0][1])
		count += userCount
		user := results[0][2]
		if all {
			c.Ui.Info(fmt.Sprintf("%s (%d)", user, userCount))
		}
	}

	if err := scanner.Err(); err != nil {
		log.Fatal("--->", err)
	}
	c.Ui.Info(fmt.Sprintf("\ntotal %d", count))

	return 0
}

func (c *CountCommand) Synopsis() string {
	return "Outputs commit counts"
}

func (c *CountCommand) Help() string {
	helpText := `
Usage: gitx count [--all]
`
	return strings.TrimSpace(helpText)
}
<commit_msg>Error redirect<commit_after>package command

import (
	"bufio"
	"fmt"
	"regexp"
	"strconv"
	"strings"

	"github.com/go-almeria/gitx/api"
	"github.com/go-almeria/gitx/meta"
)

// CountCommand Outputs commit count
type CountCommand struct {
	meta.Meta
}

func (c *CountCommand) Run(args []string) int {
	var all bool

	flags := c.Meta.FlagSet("count", meta.FlagSetDefault)
	flags.BoolVar(&all, "all", false, "")
	flags.Usage = func() { c.Ui.Error(c.Help()) }
	if err := flags.Parse(args); err != nil {
		return 1
	}

	args = flags.Args()
	if len(args) > 1 {
		flags.Usage()
		c.Ui.Error(fmt.Sprintf("\ncount expects at most one argument"))
		return 1
	}

	g := *api.NewGit("shortlog HEAD -n -s")
	if !g.IsRepo() {
		c.Ui.Error("Not a git repository (or any of the parent directories): .git")
		return 1
	}

	if err := g.Run(); err != nil {
		c.Ui.Error(fmt.Sprintf("%s", string(g.Err.Bytes())))
		return 1
	}

	re := regexp.MustCompile(`(\d+)\s+(\S+.*)`)
	scanner := bufio.NewScanner(&g.Out)

	count := 0
	for scanner.Scan() {
		results := re.FindAllStringSubmatch(scanner.Text(), -1)
		userCount, _ := strconv.Atoi(results[0][1])
		count += userCount
		user := results[0][2]
		if all {
			c.Ui.Info(fmt.Sprintf("%s (%d)", user, userCount))
		}
	}

	if err := scanner.Err(); err != nil {
		c.Ui.Error(err.Error())
	}

	c.Ui.Info(fmt.Sprintf("\ntotal %d", count))

	return 0
}

func (c *CountCommand) Synopsis() string {
	return "Outputs commit counts"
}

func (c *CountCommand) Help() string {
	helpText := `
Usage: gitx count [--all]
`
	return strings.TrimSpace(helpText)
}
<|endoftext|>