<commit_before>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/
package main

import (
	"flag"
	"fmt"
	stdLog "log"
	"net/http"
	"os"
	"strings"

	_ "github.com/admpub/nging/application/library/sqlite"
	"github.com/webx-top/echo"
	"github.com/webx-top/echo/engine"
	"github.com/webx-top/echo/engine/standard"
	"github.com/webx-top/echo/handler/mvc/events"
	"github.com/webx-top/echo/middleware"
	"github.com/webx-top/echo/middleware/language"
	"github.com/webx-top/echo/middleware/render"
	"github.com/webx-top/echo/middleware/render/driver"
	"github.com/webx-top/echo/middleware/session"

	"github.com/admpub/log"
	"github.com/admpub/nging/application"
	"github.com/admpub/nging/application/library/config"
	"github.com/admpub/nging/application/library/cron"
	"github.com/admpub/nging/application/library/service"
)

var (
	//Version 版本号
	Version = `1.1.2`

	binData    bool
	staticMW   interface{}
	tmplMgr    driver.Manager
	langFSFunc func(dir string) http.FileSystem
)

func main() {
	config.DefaultCLIConfig.InitFlag()
	flag.Parse()

	if binData {
		Version += ` (bindata)`
	}
	config.SetVersion(Version)

	// Service
	if len(os.Args) > 1 && !strings.HasPrefix(os.Args[1], `-`) {
		application.WatchConfig(config.InitConfig, false)
		if err := service.Run(os.Args[1]); err != nil {
			stdLog.Println(err)
		}
		return
	}

	err := config.ParseConfig()
	if err != nil {
		if config.IsInstalled() {
			config.MustOK(err)
		} else {
			log.Error(err)
		}
	}

	if config.DefaultCLIConfig.OnlyRunServer() {
		return
	}

	//Manager
	config.DefaultCLIConfig.RunStartup()

	if config.IsInstalled() {
		// 继续上次任务
		if err := cron.InitJobs(); err != nil {
			log.Error(err)
		}
	}

	e := echo.New()
	if binData {
		e.SetDebug(false)
		log.SetLevel(`Info`)
	} else {
		e.SetDebug(true)
		log.SetLevel(`Debug`)
	}
	e.Use(middleware.Log(), middleware.Recover())
	e.Use(middleware.Gzip(&middleware.GzipConfig{
		Skipper: func(c echo.Context) bool {
			switch c.Request().URL().Path() {
			case `/manage/cmdSend/info`, `/download/progress/info`:
				return true
			}
			return false
		},
	}))
	e.Use(func(h echo.Handler) echo.HandlerFunc {
		return func(c echo.Context) error {
			c.Response().Header().Set(`Server`, `nging/`+Version)
			return h.Handle(c)
		}
	})

	// 注册静态资源文件(网站素材文件)
	e.Use(staticMW)

	// 启用session
	e.Use(session.Middleware(config.SessionOptions))

	// 启用多语言支持
	config.DefaultConfig.Language.SetFSFunc(langFSFunc)
	e.Use(language.New(&config.DefaultConfig.Language).Middleware())

	// 启用Validation
	e.Use(middleware.Validate(echo.NewValidation))

	// 注册模板引擎
	renderOptions := &render.Config{
		TmplDir: `./template`,
		Engine:  `standard`,
		ParseStrings: map[string]string{
			`__PUBLIC__`: `/public`,
			`__ASSETS__`: `/public/assets`,
			`__TMPL__`:   `./template`,
		},
		Reload:     true,
		ErrorPages: config.DefaultConfig.Sys.ErrorPages,
	}
	renderOptions.ApplyTo(e)
	if tmplMgr != nil {
		renderOptions.Renderer().SetManager(tmplMgr)
	}
	events.AddEvent(`clearCache`, func(next func(r bool), args ...interface{}) {
		renderOptions.Renderer().ClearCache()
		next(true)
	})

	application.Initialize(e)
	c := &engine.Config{
		Address:     fmt.Sprintf(`:%v`, config.DefaultCLIConfig.Port),
		TLSAuto:     false,
		TLSCacheDir: config.DefaultConfig.Sys.SSLCacheDir,
		TLSCertFile: config.DefaultConfig.Sys.SSLCertFile,
		TLSKeyFile:  config.DefaultConfig.Sys.SSLKeyFile,
	}
	e.Run(standard.NewWithConfig(c))
}
<commit_msg>v1.1.3<commit_after>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

*/
package main

import (
	"flag"
	"fmt"
	stdLog "log"
	"net/http"
	"os"
	"strings"

	_ "github.com/admpub/nging/application/library/sqlite"
	"github.com/webx-top/echo"
	"github.com/webx-top/echo/engine"
	"github.com/webx-top/echo/engine/standard"
	"github.com/webx-top/echo/handler/mvc/events"
	"github.com/webx-top/echo/middleware"
	"github.com/webx-top/echo/middleware/language"
	"github.com/webx-top/echo/middleware/render"
	"github.com/webx-top/echo/middleware/render/driver"
	"github.com/webx-top/echo/middleware/session"

	"github.com/admpub/log"
	"github.com/admpub/nging/application"
	"github.com/admpub/nging/application/library/config"
	"github.com/admpub/nging/application/library/cron"
	"github.com/admpub/nging/application/library/service"
)

var (
	//Version 版本号
	Version = `1.1.3`

	binData    bool
	staticMW   interface{}
	tmplMgr    driver.Manager
	langFSFunc func(dir string) http.FileSystem
)

func main() {
	config.DefaultCLIConfig.InitFlag()
	flag.Parse()

	if binData {
		Version += ` (bindata)`
	}
	config.SetVersion(Version)

	// Service
	if len(os.Args) > 1 && !strings.HasPrefix(os.Args[1], `-`) {
		application.WatchConfig(config.InitConfig, false)
		if err := service.Run(os.Args[1]); err != nil {
			stdLog.Println(err)
		}
		return
	}

	err := config.ParseConfig()
	if err != nil {
		if config.IsInstalled() {
			config.MustOK(err)
		} else {
			log.Error(err)
		}
	}

	if config.DefaultCLIConfig.OnlyRunServer() {
		return
	}

	//Manager
	config.DefaultCLIConfig.RunStartup()

	if config.IsInstalled() {
		// 继续上次任务
		if err := cron.InitJobs(); err != nil {
			log.Error(err)
		}
	}

	e := echo.New()
	if binData {
		e.SetDebug(false)
		log.SetLevel(`Info`)
	} else {
		e.SetDebug(true)
		log.SetLevel(`Debug`)
	}
	e.Use(middleware.Log(), middleware.Recover())
	e.Use(middleware.Gzip(&middleware.GzipConfig{
		Skipper: func(c echo.Context) bool {
			switch c.Request().URL().Path() {
			case `/manage/cmdSend/info`, `/download/progress/info`:
				return true
			}
			return false
		},
	}))
	e.Use(func(h echo.Handler) echo.HandlerFunc {
		return func(c echo.Context) error {
			c.Response().Header().Set(`Server`, `nging/`+Version)
			return h.Handle(c)
		}
	})

	// 注册静态资源文件(网站素材文件)
	e.Use(staticMW)

	// 启用session
	e.Use(session.Middleware(config.SessionOptions))

	// 启用多语言支持
	config.DefaultConfig.Language.SetFSFunc(langFSFunc)
	e.Use(language.New(&config.DefaultConfig.Language).Middleware())

	// 启用Validation
	e.Use(middleware.Validate(echo.NewValidation))

	// 注册模板引擎
	renderOptions := &render.Config{
		TmplDir: `./template`,
		Engine:  `standard`,
		ParseStrings: map[string]string{
			`__PUBLIC__`: `/public`,
			`__ASSETS__`: `/public/assets`,
			`__TMPL__`:   `./template`,
		},
		Reload:     true,
		ErrorPages: config.DefaultConfig.Sys.ErrorPages,
	}
	renderOptions.ApplyTo(e)
	if tmplMgr != nil {
		renderOptions.Renderer().SetManager(tmplMgr)
	}
	events.AddEvent(`clearCache`, func(next func(r bool), args ...interface{}) {
		renderOptions.Renderer().ClearCache()
		next(true)
	})

	application.Initialize(e)
	c := &engine.Config{
		Address:     fmt.Sprintf(`:%v`, config.DefaultCLIConfig.Port),
		TLSAuto:     false,
		TLSCacheDir: config.DefaultConfig.Sys.SSLCacheDir,
		TLSCertFile: config.DefaultConfig.Sys.SSLCertFile,
		TLSKeyFile:  config.DefaultConfig.Sys.SSLKeyFile,
	}
	e.Run(standard.NewWithConfig(c))
}
<|endoftext|>


<commit_before>//TODO: improve the code

package main

import (
	"fmt"
	"github.com/franleplant/juliaSets/utils"
	"image"
	"image/color"
	"image/draw"
	"math/cmplx"
)

const (
	ER             = 1
	N              = 500
	M              = N
	MIN_x          = float64(-1.0)
	MAX_x          = -MIN_x
	MIN_y          = MIN_x
	MAX_y          = MAX_x
	STEP_x         = (MAX_x - MIN_y) / M
	STEP_y         = (MAX_y - MIN_y) / N
	c              = c7
	c1             = -0.4 + 0.6i //nice
	c2             = -0.285 + 0.1i
	c3             = (1 - 1.618033987) + 0.0i //Golden ratio
	c4             = -0.8 + 0.156i            //nice
	c5             = 0.279 + 0.0i             //really nice
	c6             = 0 + 0i                   //circle
	c7             = -2 + 0i
	MAX_ITERATIONS = 3000
	PHASE          = 150.0
	K_COLOR        = 5.0
)

type CMatrix [N][M]complex128

type fz func(z complex128) complex128

func fz1(z complex128) complex128 {
	return cmplx.Pow(z, 2) + 0.279 + 0.0i
}

var fzi = fz1

var m CMatrix
var z *complex128

func main() {

	var count int
	var r, g, b uint8

	img := image.NewRGBA(image.Rect(0, 0, M, N))

	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			z = &m[i][j]
			*z = complex(MIN_x+float64(j)*STEP_x, MAX_y-float64(i)*STEP_y)
			//fmt.Println(*z)

			for count = 0; count < MAX_ITERATIONS; count++ {
				//*z = cmplx.Pow(*z, 2) + c
				*z = fzi(*z)
				if cmplx.Abs(*z) > ER {
					//fmt.Printf("count %v color %v ", count, (math.Mod(PHASE*float64(count), 255.0))/255.0)
					break
				}
			}

			if count == MAX_ITERATIONS {
				fmt.Println("Max Iterations reached")
			}

			r, g, b = utils.GetColor(count, K_COLOR, PHASE)
			//fmt.Printf("r %v g %v b %v \n", r, g, b)

			draw.Draw(img, image.Rect(j, i, j+1, i+1), &image.Uniform{color.RGBA{r, g, b, 255}}, image.ZP, draw.Src)
		}
	}

	utils.SaveImg(img)
}
<commit_msg>reactoring4...<commit_after>//TODO: improve the code

package main

import (
	"fmt"
	"github.com/franleplant/juliaSets/utils"
	"image"
	"image/color"
	"image/draw"
	"math/cmplx"
)

const (
	ER             = 1
	N              = 500
	M              = N
	MIN_x          = float64(-1.0)
	MAX_x          = -MIN_x
	MIN_y          = MIN_x
	MAX_y          = MAX_x
	STEP_x         = (MAX_x - MIN_y) / M
	STEP_y         = (MAX_y - MIN_y) / N
	c              = c7
	c1             = -0.4 + 0.6i //nice
	c2             = -0.285 + 0.1i
	c3             = (1 - 1.618033987) + 0.0i //Golden ratio
	c4             = -0.8 + 0.156i            //nice
	c5             = 0.279 + 0.0i             //really nice
	c6             = 0 + 0i                   //circle
	c7             = -2 + 0i
	MAX_ITERATIONS = 3000
	PHASE          = 150.0
	K_COLOR        = 5.0
)

type CMatrix [N][M]complex128

type fz func(z complex128) complex128

func fz1(z complex128) complex128 {
	return cmplx.Pow(z, 2) + 0.279 + 0.0i
}

var fzi = fz1

var m CMatrix
var z *complex128

func escapeTime() {

	var count int
	var r, g, b uint8

	img := image.NewRGBA(image.Rect(0, 0, M, N))

	for i := 0; i < N; i++ {
		for j := 0; j < M; j++ {
			z = &m[i][j]
			*z = complex(MIN_x+float64(j)*STEP_x, MAX_y-float64(i)*STEP_y)
			//fmt.Println(*z)

			for count = 0; count < MAX_ITERATIONS; count++ {
				//*z = cmplx.Pow(*z, 2) + c
				*z = fzi(*z)
				if cmplx.Abs(*z) > ER {
					//fmt.Printf("count %v color %v ", count, (math.Mod(PHASE*float64(count), 255.0))/255.0)
					break
				}
			}

			if count == MAX_ITERATIONS {
				fmt.Println("Max Iterations reached")
			}

			r, g, b = utils.GetColor(count, K_COLOR, PHASE)
			//fmt.Printf("r %v g %v b %v \n", r, g, b)

			draw.Draw(img, image.Rect(j, i, j+1, i+1), &image.Uniform{color.RGBA{r, g, b, 255}}, image.ZP, draw.Src)
		}
	}

	utils.SaveImg(img)
}

func main() {

	escapeTime()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"net/http"

	"github.com/gorilla/csrf"
	"github.com/qor/qor-example/config"
	"github.com/qor/qor-example/config/admin"
	"github.com/qor/qor-example/config/api"
	_ "github.com/qor/qor-example/config/i18n"
	"github.com/qor/qor-example/config/routes"
	_ "github.com/qor/qor-example/db/migrations"
)

func main() {
	mux := http.NewServeMux()
	mux.Handle("/", routes.Router())
	admin.Admin.MountTo("/admin", mux)
	admin.Widgets.WidgetSettingResource.IndexAttrs("Name")

	api.API.MountTo("/api", mux)
	admin.Filebox.MountTo("/downloads", mux)

	for _, path := range []string{"system", "javascripts", "stylesheets", "images"} {
		mux.Handle(fmt.Sprintf("/%s/", path), http.FileServer(http.Dir("public")))
	}

	fmt.Printf("Listening on: %v\n", config.Config.Port)
	handler := csrf.Protect([]byte("3693f371bf91487c99286a777811bd4e"), csrf.Secure(false))(mux)
	if err := http.ListenAndServe(fmt.Sprintf(":%d", config.Config.Port), handler); err != nil {
		panic(err)
	}
}
<commit_msg>skip csrf check for backend<commit_after>package main

import (
	"fmt"
	"net/http"
	"strings"

	"github.com/gorilla/csrf"
	"github.com/qor/qor-example/config"
	"github.com/qor/qor-example/config/admin"
	"github.com/qor/qor-example/config/api"
	_ "github.com/qor/qor-example/config/i18n"
	"github.com/qor/qor-example/config/routes"
	_ "github.com/qor/qor-example/db/migrations"
)

func main() {
	mux := http.NewServeMux()
	mux.Handle("/", routes.Router())
	admin.Admin.MountTo("/admin", mux)
	admin.Widgets.WidgetSettingResource.IndexAttrs("Name")

	api.API.MountTo("/api", mux)
	admin.Filebox.MountTo("/downloads", mux)

	for _, path := range []string{"system", "javascripts", "stylesheets", "images"} {
		mux.Handle(fmt.Sprintf("/%s/", path), http.FileServer(http.Dir("public")))
	}

	fmt.Printf("Listening on: %v\n", config.Config.Port)
	skipCheck := func(h http.Handler) http.Handler {
		fn := func(w http.ResponseWriter, r *http.Request) {
			if !strings.HasPrefix(r.URL.Path, "/auth") {
				r = csrf.UnsafeSkipCheck(r)
			}
			h.ServeHTTP(w, r)
		}
		return http.HandlerFunc(fn)
	}
	handler := csrf.Protect([]byte("3693f371bf91487c99286a777811bd4e"), csrf.Secure(false))(mux)
	if err := http.ListenAndServe(fmt.Sprintf(":%d", config.Config.Port), skipCheck(handler)); err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path"
	"sync"

	"github.com/fatih/color"
)

const (
	windowsExtension = ".exe"
	buildPath        = "dist"
)

var (
	project string
	pwd     string

	currentOS             string
	currentArchchitecture string

	architectures = []string{"amd64", "386"}
	systems       = []string{"darwin", "linux", "windows"}

	// user specified system to target
	target string
)

func init() {
	// Record the environment variables before proceeding
	getFromEnvironement()

	// Split and store paths for later use
	currentPath, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	pwd, project = path.Split(currentPath)
}

func main() {
	flag.StringVar(&target, "for", "", "builder -for linux")
	flag.Parse()

	// only pass in current target
	if target != "" && isSupported(target) {
		systems = []string{target}
	}

	clearBuilds()

	color.Green("%s", fmt.Sprintf("Starting build in:\n%s%s", pwd, project))

	var wg sync.WaitGroup
	for _, targetSystem := range systems {
		for _, targetArch := range architectures {
			wg.Add(1)
			go performBuild(&wg, targetSystem, targetArch)
			wg.Wait()
		}
	}
	// reset the environment before exiting
	setEnvironement(currentOS, currentArchchitecture)

	notice := color.GreenString("Done!\nYou will your build under the '%s' folder", buildPath)
	fmt.Println(notice)
}

func isSupported(target string) bool {
	for _, sys := range systems {
		if target == sys {
			return true
		}
	}
	return false
}

// clearBuilds removes the old builds before starting a new one
func clearBuilds() {
	_, err := os.Stat(buildPath)
	if err != nil {
		return
	}

	fmt.Print("Clearing old builds...")

	err = os.RemoveAll(buildPath)
	if err != nil {
		panic(err)
	}

	fmt.Print(" Success.\n")
}

func performBuild(wg *sync.WaitGroup, o, a string) {
	defer wg.Done()

	platform := fmt.Sprintf("%s_%s", o, a)
	folderPath := fmt.Sprintf("%s/%s", buildPath, platform)

	fmt.Println(fmt.Sprintf("Building %s for %s", project, platform))

	err := os.MkdirAll(folderPath, 0755)
	if err != nil {
		fmt.Println("Error creating directories: ", err)
		return
	}

	// Set the environment to the currently targeted build
	setEnvironement(o, a)

	err = executeGoBuild()
	if err != nil {
		fmt.Println("Error running build command", err)
		fmt.Println("Make sure you are running this tool where your main.go is located!")
		return
	}

	// I could use os.Rename, but linking and removing after is safer...
	if o == "windows" {
		filename := fmt.Sprintf("%s%s", project, windowsExtension)
		os.Link(filename, fmt.Sprintf("./%s/%s/%s%s", buildPath, platform, project, windowsExtension))
		os.Remove(filename)
	} else {
		os.Link(project, fmt.Sprintf("./%s/%s/%s", buildPath, platform, project))
		os.Remove(project)
	}
}

func getFromEnvironement() {
	currentOS = os.Getenv("GOOS")
	currentArchchitecture = os.Getenv("GOARCH")
}

func setEnvironement(system, architecture string) {
	os.Setenv("GOOS", system)
	os.Setenv("GOARCH", architecture)
}

func executeGoBuild() error {
	cmd := exec.Command("go", "build")
	err := cmd.Run()
	return err
}
<commit_msg>Fix unchecked errors<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path"
	"sync"

	"github.com/fatih/color"
)

const (
	windowsExtension = ".exe"
	buildPath        = "dist"
)

var (
	project string
	pwd     string

	currentOS             string
	currentArchchitecture string

	architectures = []string{"amd64", "386"}
	systems       = []string{"darwin", "linux", "windows"}

	// user specified system to target
	target string
)

func init() {
	// Record the environment variables before proceeding
	getFromEnvironement()

	// Split and store paths for later use
	currentPath, err := os.Getwd()
	if err != nil {
		panic(err)
	}

	pwd, project = path.Split(currentPath)
}

func main() {
	flag.StringVar(&target, "for", "", "builder -for linux")
	flag.Parse()

	// only pass in current target
	if target != "" && isSupported(target) {
		systems = []string{target}
	}

	clearBuilds()

	color.Green("%s", fmt.Sprintf("Starting build in:\n%s%s", pwd, project))

	var wg sync.WaitGroup
	for _, targetSystem := range systems {
		for _, targetArch := range architectures {
			wg.Add(1)
			go performBuild(&wg, targetSystem, targetArch)
			wg.Wait()
		}
	}
	// reset the environment before exiting
	setEnvironement(currentOS, currentArchchitecture)

	notice := color.GreenString("Done!\nYou will your build under the '%s' folder", buildPath)
	fmt.Println(notice)
}

func isSupported(target string) bool {
	for _, sys := range systems {
		if target == sys {
			return true
		}
	}
	return false
}

// clearBuilds removes the old builds before starting a new one
func clearBuilds() {
	_, err := os.Stat(buildPath)
	if err != nil {
		return
	}

	fmt.Print("Clearing old builds...")

	err = os.RemoveAll(buildPath)
	if err != nil {
		panic(err)
	}

	fmt.Print(" Success.\n")
}

func performBuild(wg *sync.WaitGroup, o, a string) {
	defer wg.Done()

	platform := fmt.Sprintf("%s_%s", o, a)
	folderPath := fmt.Sprintf("%s/%s", buildPath, platform)

	fmt.Println(fmt.Sprintf("Building %s for %s", project, platform))

	err := os.MkdirAll(folderPath, 0755)
	if err != nil {
		fmt.Println("Error creating directories: ", err)
		return
	}

	// Set the environment to the currently targeted build
	setEnvironement(o, a)

	err = executeGoBuild()
	if err != nil {
		fmt.Println("Error running build command", err)
		fmt.Println("Make sure you are running this tool where your main.go is located!")
		return
	}

	// I could use os.Rename, but linking and removing after is safer...
	if o == "windows" {
		filename := fmt.Sprintf("%s%s", project, windowsExtension)
		if err := os.Link(filename, fmt.Sprintf("./%s/%s/%s%s", buildPath, platform, project, windowsExtension)); err != nil {
			log.Println("Error moving file:", filename)
		}
		if err := os.Remove(filename); err != nil {
			log.Println("Error removing file:", filename)
		}
	} else {
		if err := os.Link(project, fmt.Sprintf("./%s/%s/%s", buildPath, platform, project)); err != nil {
			log.Println("Error moving file:", project)
		}
		if err := os.Remove(project); err != nil {
			log.Println("Error removing file:", project)
		}
	}
}

func getFromEnvironement() {
	currentOS = os.Getenv("GOOS")
	currentArchchitecture = os.Getenv("GOARCH")
}

func setEnvironement(system, architecture string) {
	if err := os.Setenv("GOOS", system); err != nil {
		log.Fatalln("Could not sset GOOS environment variable")
	}
	if err := os.Setenv("GOARCH", architecture); err != nil {
		log.Fatalln("Could not set GOARCH environment variable")
	}
}

func executeGoBuild() error {
	cmd := exec.Command("go", "build")
	err := cmd.Run()
	return err
}
<|endoftext|>


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

package main

import (
	"fmt"
	zmq "github.com/pebbe/zmq4"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"
)

const (
	BCAST_INGRESS_PORT = "GL_BCAST_INGRESS_PORT"
	BCAST_EGRESS_PORT  = "GL_BCAST_EGRESS_PORT"
	RR1_INGRESS_PORT   = "GL_RR1_INGRESS_PORT"
	RR1_EGRESS_PORT    = "GL_RR1_EGRESS_PORT"
	RR2_INGRESS_PORT   = "GL_RR2_INGRESS_PORT"
	RR2_EGRESS_PORT    = "GL_RR2_EGRESS_PORT"
)

func main() {
	env := getenv(BCAST_INGRESS_PORT)
	bcast_ingress_port := asPort(env)
	env = getenv(BCAST_EGRESS_PORT)
	bcast_egress_port := asPort(env)
	env = getenv(RR1_INGRESS_PORT)
	rr1_ingress_port := asPort(env)
	env = getenv(RR1_EGRESS_PORT)
	rr1_egress_port := asPort(env)
	env = getenv(RR2_INGRESS_PORT)
	rr2_ingress_port := asPort(env)
	env = getenv(RR2_EGRESS_PORT)
	rr2_egress_port := asPort(env)

	pprint("starting")

	// CREATE EACH SOCKET...
	sub_ingress := newSocket(zmq.SUB)
	sub_ingress.SetSubscribe("")
	defer sub_ingress.Close()
	pub_egress := newSocket(zmq.PUB)
	pub_egress.SetLinger(1)
	defer pub_egress.Close()

	rr1_ingress := newSocket(zmq.ROUTER)
	defer rr1_ingress.Close()
	rr1_egress := newSocket(zmq.DEALER)
	defer rr1_egress.Close()
	rr2_ingress := newSocket(zmq.ROUTER)
	defer rr2_ingress.Close()
	rr2_egress := newSocket(zmq.DEALER)
	defer rr2_egress.Close()

	// ... AND BIND
	bind(sub_ingress, "tcp", "0.0.0.0", bcast_ingress_port)
	bind(pub_egress, "tcp", "0.0.0.0", bcast_egress_port)
	bind(rr1_ingress, "tcp", "0.0.0.0", rr1_ingress_port)
	bind(rr1_egress, "tcp", "0.0.0.0", rr1_egress_port)
	bind(rr2_ingress, "tcp", "0.0.0.0", rr2_ingress_port)
	bind(rr2_egress, "tcp", "0.0.0.0", rr2_egress_port)

	poller := zmq.NewPoller()
	poller.Add(sub_ingress, zmq.POLLIN)
	poller.Add(rr1_ingress, zmq.POLLIN)
	poller.Add(rr2_ingress, zmq.POLLIN)
	poller.Add(rr1_egress, zmq.POLLIN)
	poller.Add(rr2_egress, zmq.POLLIN)

	pprint("greenline alive")
	sigchan := make(chan os.Signal, 1)
	signal.Notify(sigchan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	go func() {
		for sig := range sigchan {
			switch sig {
			case syscall.SIGTERM:
				die("received SIGTERM")
			case syscall.SIGINT:
				die("received SIGINT")
			case syscall.SIGQUIT:
				die("received SIGQUIT")
			}
		}
	}()

	pprint("greenline ready")
	for {
		sockets, _ := poller.Poll(-1)
		for _, socket := range sockets {
			switch s := socket.Socket; s {
			case sub_ingress:
				pprint("processing broadcast message")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("broadcast more: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("broadcast recv more: %s", err.Error())
					}
					if more {
						pub_egress.Send(msg, zmq.SNDMORE)
					} else {
						pub_egress.Send(msg, 0)
						break
					}
				}
			case rr1_ingress:
				pprint("processing rr1 request")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr1 ingress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr1 ingress recv more: %s", err.Error())
					}
					if more {
						rr1_egress.Send(msg, zmq.SNDMORE)
					} else {
						rr1_egress.Send(msg, 0)
						break
					}
				}
			case rr2_ingress:
				pprint("processing rr2 request")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr2 ingress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr2 ingress recv more: %s", err.Error())
					}
					if more {
						rr2_egress.Send(msg, zmq.SNDMORE)
					} else {
						rr2_egress.Send(msg, 0)
						break
					}
				}
			case rr1_egress:
				pprint("processing rr1 response")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr1 egress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr1 egress recv more: %s", err.Error())
					}
					if more {
						rr1_ingress.Send(msg, zmq.SNDMORE)
					} else {
						rr1_ingress.Send(msg, 0)
						break
					}
				}
			case rr2_egress:
				pprint("processing rr2 response")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr2 egress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr2 egress recv more: %s", err.Error())
					}
					if more {
						rr2_ingress.Send(msg, zmq.SNDMORE)
					} else {
						rr2_ingress.Send(msg, 0)
						break
					}
				}
			}
		}
	}
}

func getenv(env string) string {
	_env := os.Getenv(env)
	if len(_env) == 0 {
		die("no " + env + " is set")
	}
	return _env
}

func asPort(env string) (port int) {
	port, err := strconv.Atoi(env)
	if err != nil {
		die("invalid port: %s", env)
	} else if port < 1 || port > 65535 {
		die("invalid port: %s", env)
	}
	return
}

func newSocket(ztype zmq.Type) (socket *zmq.Socket) {
	socket, err := zmq.NewSocket(ztype)
	if err != nil {
		die("failed creating socket type %d: %s", ztype, err.Error())
	}
	return
}

func bind(socket *zmq.Socket, transport string, address string, port int) {
	endpoint := fmt.Sprintf("%s://%s:%d", transport, address, port)
	out("Binding socket %d... ", port)
	err := socket.Bind(endpoint)
	if err != nil {
		die("failed binding %s: %s", endpoint, err.Error())
	}
	fmt.Println("done.")
}

func makeMsg(msg string, args ...interface{}) string {
	const layout = "%d%02d%02d-%02d-%02d-%02d greenline[%d]: %s"
	now := time.Now()
	year := now.Year()
	month := now.Month()
	day := now.Day()
	hour := now.Hour()
	minute := now.Minute()
	seconds := now.Second()
	pid := os.Getpid()
	arg := fmt.Sprintf(msg, args...)
	ret := fmt.Sprintf(layout, year, month, day, hour, minute, seconds, pid, arg)
	return ret
}

func pprint(msg string, args ...interface{}) {
	msg = makeMsg(msg, args...)
	fmt.Fprintf(os.Stdout, msg+"\n")
}

func out(msg string, args ...interface{}) {
	msg = makeMsg(msg, args...)
	fmt.Fprintf(os.Stdout, msg)
	os.Stdout.Sync()
}

func die(msg string, args ...interface{}) {
	msg = makeMsg(msg, args...)
	fmt.Fprintf(os.Stderr, msg+"\n")
	os.Exit(1)
}
<commit_msg>log and exit with 0 code for INT,TERM,QUIT signals<commit_after>// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//
// See http://formwork-io.github.io/ for more.

package main

import (
	"fmt"
	zmq "github.com/pebbe/zmq4"
	"os"
	"os/signal"
	"strconv"
	"syscall"
	"time"
)

const (
	BCAST_INGRESS_PORT = "GL_BCAST_INGRESS_PORT"
	BCAST_EGRESS_PORT  = "GL_BCAST_EGRESS_PORT"
	RR1_INGRESS_PORT   = "GL_RR1_INGRESS_PORT"
	RR1_EGRESS_PORT    = "GL_RR1_EGRESS_PORT"
	RR2_INGRESS_PORT   = "GL_RR2_INGRESS_PORT"
	RR2_EGRESS_PORT    = "GL_RR2_EGRESS_PORT"
)

func main() {
	env := getenv(BCAST_INGRESS_PORT)
	bcast_ingress_port := asPort(env)
	env = getenv(BCAST_EGRESS_PORT)
	bcast_egress_port := asPort(env)
	env = getenv(RR1_INGRESS_PORT)
	rr1_ingress_port := asPort(env)
	env = getenv(RR1_EGRESS_PORT)
	rr1_egress_port := asPort(env)
	env = getenv(RR2_INGRESS_PORT)
	rr2_ingress_port := asPort(env)
	env = getenv(RR2_EGRESS_PORT)
	rr2_egress_port := asPort(env)

	pprint("starting")

	// CREATE EACH SOCKET...
	sub_ingress := newSocket(zmq.SUB)
	sub_ingress.SetSubscribe("")
	defer sub_ingress.Close()
	pub_egress := newSocket(zmq.PUB)
	pub_egress.SetLinger(1)
	defer pub_egress.Close()

	rr1_ingress := newSocket(zmq.ROUTER)
	defer rr1_ingress.Close()
	rr1_egress := newSocket(zmq.DEALER)
	defer rr1_egress.Close()
	rr2_ingress := newSocket(zmq.ROUTER)
	defer rr2_ingress.Close()
	rr2_egress := newSocket(zmq.DEALER)
	defer rr2_egress.Close()

	// ... AND BIND
	bind(sub_ingress, "tcp", "0.0.0.0", bcast_ingress_port)
	bind(pub_egress, "tcp", "0.0.0.0", bcast_egress_port)
	bind(rr1_ingress, "tcp", "0.0.0.0", rr1_ingress_port)
	bind(rr1_egress, "tcp", "0.0.0.0", rr1_egress_port)
	bind(rr2_ingress, "tcp", "0.0.0.0", rr2_ingress_port)
	bind(rr2_egress, "tcp", "0.0.0.0", rr2_egress_port)

	poller := zmq.NewPoller()
	poller.Add(sub_ingress, zmq.POLLIN)
	poller.Add(rr1_ingress, zmq.POLLIN)
	poller.Add(rr2_ingress, zmq.POLLIN)
	poller.Add(rr1_egress, zmq.POLLIN)
	poller.Add(rr2_egress, zmq.POLLIN)

	pprint("greenline alive")
	exitchan := make(chan os.Signal, 0)
	signal.Notify(exitchan, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
	go func() {
		sig := <-exitchan
		out("received %s signal, exiting.\n", sig.String())
		os.Exit(0)
	}()

	pprint("greenline ready")
	for {
		sockets, _ := poller.Poll(-1)
		for _, socket := range sockets {
			switch s := socket.Socket; s {
			case sub_ingress:
				pprint("processing broadcast message")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("broadcast more: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("broadcast recv more: %s", err.Error())
					}
					if more {
						pub_egress.Send(msg, zmq.SNDMORE)
					} else {
						pub_egress.Send(msg, 0)
						break
					}
				}
			case rr1_ingress:
				pprint("processing rr1 request")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr1 ingress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr1 ingress recv more: %s", err.Error())
					}
					if more {
						rr1_egress.Send(msg, zmq.SNDMORE)
					} else {
						rr1_egress.Send(msg, 0)
						break
					}
				}
			case rr2_ingress:
				pprint("processing rr2 request")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr2 ingress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr2 ingress recv more: %s", err.Error())
					}
					if more {
						rr2_egress.Send(msg, zmq.SNDMORE)
					} else {
						rr2_egress.Send(msg, 0)
						break
					}
				}
			case rr1_egress:
				pprint("processing rr1 response")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr1 egress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr1 egress recv more: %s", err.Error())
					}
					if more {
						rr1_ingress.Send(msg, zmq.SNDMORE)
					} else {
						rr1_ingress.Send(msg, 0)
						break
					}
				}
			case rr2_egress:
				pprint("processing rr2 response")
				for {
					msg, err := s.Recv(0)
					if err != nil {
						die("rr2 egress: %s", err.Error())
					}
					more, err := s.GetRcvmore()
					if err != nil {
						die("rr2 egress recv more: %s", err.Error())
					}
					if more {
						rr2_ingress.Send(msg, zmq.SNDMORE)
					} else {
						rr2_ingress.Send(msg, 0)
						break
					}
				}
			}
		}
	}
}

func getenv(env string) string {
	_env := os.Getenv(env)
	if len(_env) == 0 {
		die("no " + env + " is set")
	}
	return _env
}

func asPort(env string) (port int) {
	port, err := strconv.Atoi(env)
	if err != nil {
		die("invalid port: %s", env)
	} else if port < 1 || port > 65535 {
		die("invalid port: %s", env)
	}
	return
}

func newSocket(ztype zmq.Type) (socket *zmq.Socket) {
	socket, err := zmq.NewSocket(ztype)
	if err != nil {
		die("failed creating socket type %d: %s", ztype, err.Error())
	}
	return
}

func bind(socket *zmq.Socket, transport string, address string, port int) {
	endpoint := fmt.Sprintf("%s://%s:%d", transport, address, port)
	out("Binding socket %d... ", port)
	err := socket.Bind(endpoint)
	if err != nil {
		die("failed binding %s: %s", endpoint, err.Error())
	}
	fmt.Println("done.")
}

func makeMsg(msg string, args ...interface{}) string {
	const layout = "%d%02d%02d-%02d-%02d-%02d greenline[%d]: %s"
	now := time.Now()
	year := now.Year()
	month := now.Month()
	day := now.Day()
	hour := now.Hour()
	minute := now.Minute()
	seconds := now.Second()
	pid := os.Getpid()
	arg := fmt.Sprintf(msg, args...)
	ret := fmt.Sprintf(layout, year, month, day, hour, minute, seconds, pid, arg)
	return ret
}

func pprint(msg string, args ...interface{}) {
	msg = makeMsg(msg, args...)
	fmt.Fprintf(os.Stdout, msg+"\n")
}

func out(msg string, args ...interface{}) {
	msg = makeMsg(msg, args...)
	fmt.Fprintf(os.Stdout, msg)
	os.Stdout.Sync()
}

func die(msg string, args ...interface{}) {
	msg = makeMsg(msg, args...)
	fmt.Fprintf(os.Stderr, msg+"\n")
	os.Exit(1)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"

	"github.com/CotaPreco/Horus/command"
	"github.com/CotaPreco/Horus/receiver/udp"
	"github.com/CotaPreco/Horus/util"
	"github.com/CotaPreco/Horus/ws"
	wsc "github.com/CotaPreco/Horus/ws/command"
	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		// @link https://godoc.org/github.com/gorilla/websocket#hdr-Origin_Considerations
		return true
	},
}

func main() {
	flag.Usage = func() {
		flag.CommandLine.SetOutput(os.Stdout)

		fmt.Fprint(os.Stdout, "Usage: horus [OPTIONS] :-)\n\n")

		flag.PrintDefaults()

		os.Exit(0)
	}

	// --
	udpHost := flag.String("receiver-udp-host", "0.0.0.0", "Defines the host IP for `UdpReceiver`")
	udpPort := flag.Int("receiver-udp-port", 7600, "Defines which port `UdpReceiver` will be listening")

	wsHost := flag.String("ws-host", "0.0.0.0", "Where websocket will be available?")
	wsPort := flag.Int("ws-port", 8000, "And in which port people will connect?")

	flag.Parse()
	// --

	bus := command.NewGenericCommandBus()
	hub := ws.NewTaggedConnectionHub()

	bus.PushHandler(hub)
	bus.PushHandler(wsc.NewARTagCommandRedispatcher(bus))

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		conn, err := upgrader.Upgrade(w, r, nil)

		defer conn.Close()

		if err != nil {
			if _, ok := err.(websocket.HandshakeError); !ok {
				util.Invariant(
					err == nil,
					"...`%s` on attempt to upgrade/handshake connection",
					err,
				)
			}
		}

		hub.Subscribe(conn)

		for {
			messageType, message, err := conn.ReadMessage()

			if err != nil {
				hub.Unsubscribe(conn)
				conn.Close()
				return
			}

			// util.Invariant(
			// 	err == nil,
			// 	"... `%s` on `ReadMessage`",
			// 	err,
			// )

			if messageType == websocket.TextMessage {
				bus.Dispatch(wsc.NewSimpleTextCommand(string(message), conn))
			}
		}
	})

	// ---
	receiver := udp.NewUdpReceiver(*udpHost, *udpPort, new(udp.NullByteReceiveStrategy))
	receiver.Attach(hub)

	go receiver.Receive()
	// ---

	err := http.ListenAndServe(
		fmt.Sprintf("%s:%d", *wsHost, *wsPort),
		nil,
	)

	util.Invariant(
		err == nil,
		"...unexpected `%s` (ListenAndServe)",
		err,
	)
}
<commit_msg>Defaults to `UDP_RECEIVER_HOST`, `UDP_RECEIVER_PORT`, `WS_HOST`, `WS_PORT` (refs #3)<commit_after>package main

import (
	"flag"
	"fmt"
	"net/http"
	"os"
	"strconv"

	"github.com/CotaPreco/Horus/command"
	"github.com/CotaPreco/Horus/receiver/udp"
	"github.com/CotaPreco/Horus/util"
	"github.com/CotaPreco/Horus/ws"
	wsc "github.com/CotaPreco/Horus/ws/command"
	"github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{
	ReadBufferSize:  1024,
	WriteBufferSize: 1024,
	CheckOrigin: func(r *http.Request) bool {
		// @link https://godoc.org/github.com/gorilla/websocket#hdr-Origin_Considerations
		return true
	},
}

func main() {
	flag.Usage = func() {
		flag.CommandLine.SetOutput(os.Stdout)

		fmt.Fprint(os.Stdout, "Usage: horus [OPTIONS] :-)\n\n")

		flag.PrintDefaults()

		os.Exit(0)
	}

	// --
	udpHost := flag.String(
		"receiver-udp-host",
		util.EnvOrDefault("UDP_RECEIVER_HOST", "0.0.0.0"),
		"Defines the host IP for `UdpReceiver`",
	)

	udpReceiverPort, _ := strconv.Atoi(util.EnvOrDefault("UDP_RECEIVER_PORT", "7600"))

	udpPort := flag.Int(
		"receiver-udp-port",
		udpReceiverPort,
		"Defines which port `UdpReceiver` will be listening",
	)

	wsHost := flag.String(
		"ws-host",
		util.EnvOrDefault("WS_HOST", "0.0.0.0"),
		"Where websocket will be available?",
	)

	wsDefaultPort, _ := strconv.Atoi(util.EnvOrDefault("WS_PORT", "8000"))

	wsPort := flag.Int(
		"ws-port",
		wsDefaultPort,
		"And in which port people will connect?",
	)

	flag.Parse()
	// --

	bus := command.NewGenericCommandBus()
	hub := ws.NewTaggedConnectionHub()

	bus.PushHandler(hub)
	bus.PushHandler(wsc.NewARTagCommandRedispatcher(bus))

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		conn, err := upgrader.Upgrade(w, r, nil)

		defer conn.Close()

		if err != nil {
			if _, ok := err.(websocket.HandshakeError); !ok {
				util.Invariant(
					err == nil,
					"...`%s` on attempt to upgrade/handshake connection",
					err,
				)
			}
		}

		hub.Subscribe(conn)

		for {
			messageType, message, err := conn.ReadMessage()

			if err != nil {
				hub.Unsubscribe(conn)
				conn.Close()
				return
			}

			// util.Invariant(
			// 	err == nil,
			// 	"... `%s` on `ReadMessage`",
			// 	err,
			// )

			if messageType == websocket.TextMessage {
				bus.Dispatch(wsc.NewSimpleTextCommand(string(message), conn))
			}
		}
	})

	// ---
	receiver := udp.NewUdpReceiver(*udpHost, *udpPort, new(udp.NullByteReceiveStrategy))
	receiver.Attach(hub)

	go receiver.Receive()
	// ---

	err := http.ListenAndServe(
		fmt.Sprintf("%s:%d", *wsHost, *wsPort),
		nil,
	)

	util.Invariant(
		err == nil,
		"...unexpected `%s` (ListenAndServe)",
		err,
	)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/szeliga/goray/math"
)

func main() {
	fmt.Println(math.Vector{X: 1., Y: 1., Z: 1.})
}
<commit_msg>Fix import in main.go<commit_after>package main

import (
	"fmt"

	"github.com/szeliga/goray/core"
)

func main() {
	fmt.Println(core.Vector{X: 1., Y: 1., Z: 1.})
}
<|endoftext|>


<commit_before>package main

import (
	"bc"
	"storage"
)

func main() {

	storage.Init()
	bc.Sync()
	go bc.Init()
	bc.InitSystem()
}<commit_msg>Adapted import full path<commit_after>package main

import (
	"github.com/lisgie/bazo_miner/bc"
	"github.com/lisgie/bazo_miner/storage"
)

func main() {

	storage.Init()
	bc.Sync()
	go bc.Init()
	bc.InitSystem()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
	"sync"

	"github.com/google/go-github/github"
	flags "github.com/jessevdk/go-flags"
	"github.com/martinp/ghm/git"
	gh "github.com/martinp/ghm/github"
)

type CLI struct {
	GitPath     string `short:"g" long:"git" description:"Path to git executable" value-name:"PATH" default:"git"`
	Quiet       bool   `short:"q" long:"quiet" description:"Only print errors"`
	Dryrun      bool   `short:"n" long:"dryrun" description:"Print commands that would be run and exit"`
	Protocol    string `short:"p" long:"protocol" description:"Use the given protocol when mirroring" choice:"ssh" choice:"https" choice:"git" default:"ssh"`
	SkipFork    bool   `short:"s" long:"skip-fork" description:"Skip forked repositories"`
	Concurrency int    `short:"c" long:"concurrency" description:"Mirror COUNT repositories concurrently" value-name:"COUNT" default:"1"`
	Args        struct {
		Username string `description:"GitHub username" positional-arg-name:"github-user"`
		Path     string `description:"Path where repositories should be mirrored" positional-arg-name:"path"`
	} `positional-args:"yes" required:"yes"`
	mu sync.Mutex
}

func (c *CLI) run(cmd *exec.Cmd) error {
	if c.Dryrun {
		// Prevent overlapping output
		c.mu.Lock()
		defer c.mu.Unlock()
		fmt.Println(strings.Join(cmd.Args, " "))
		return nil
	}
	if err := cmd.Run(); err != nil {
		return err
	}
	return nil
}

func (c *CLI) sync(g *git.Git, r *github.Repository) error {
	repoURL, err := gh.CloneURL(c.Protocol, r)
	if err != nil {
		return err
	}
	localDir := git.LocalDir(c.Args.Path, *r.Name)
	syncCmd := g.Sync(repoURL, localDir)
	if err := c.run(syncCmd); err != nil {
		return err
	}
	return nil
}

func (c *CLI) syncAll(g *git.Git, repos []*github.Repository) {
	sem := make(chan bool, c.Concurrency)
	for _, r := range repos {
		if c.SkipFork && *r.Fork {
			continue
		}
		sem <- true
		go func(r *github.Repository) {
			defer func() { <-sem }()
			if err := c.sync(g, r); err != nil {
				log.Fatal(err)
			}
		}(r)
	}
	// Wait for remaining goroutines to finish
	for i := 0; i < cap(sem); i++ {
		sem <- true
	}
}

func main() {
	var cli CLI
	_, err := flags.ParseArgs(&cli, os.Args[1:])
	if err != nil {
		os.Exit(1)
	}

	if cli.Concurrency < 1 {
		fmt.Fprintln(os.Stderr, "concurrency level must be >= 1")
		os.Exit(1)
	}

	gh := gh.New()
	repos, err := gh.ListAllRepositories(cli.Args.Username)
	if err != nil {
		log.Fatal(err)
	}

	g, err := git.New(cli.GitPath, !cli.Quiet)
	if err != nil {
		log.Fatal(err)
	}

	cli.syncAll(g, repos)
}
<commit_msg>Update import paths<commit_after>package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"strings"
	"sync"

	"github.com/google/go-github/github"
	flags "github.com/jessevdk/go-flags"
	"github.com/mpolden/ghm/git"
	gh "github.com/mpolden/ghm/github"
)

type CLI struct {
	GitPath     string `short:"g" long:"git" description:"Path to git executable" value-name:"PATH" default:"git"`
	Quiet       bool   `short:"q" long:"quiet" description:"Only print errors"`
	Dryrun      bool   `short:"n" long:"dryrun" description:"Print commands that would be run and exit"`
	Protocol    string `short:"p" long:"protocol" description:"Use the given protocol when mirroring" choice:"ssh" choice:"https" choice:"git" default:"ssh"`
	SkipFork    bool   `short:"s" long:"skip-fork" description:"Skip forked repositories"`
	Concurrency int    `short:"c" long:"concurrency" description:"Mirror COUNT repositories concurrently" value-name:"COUNT" default:"1"`
	Args        struct {
		Username string `description:"GitHub username" positional-arg-name:"github-user"`
		Path     string `description:"Path where repositories should be mirrored" positional-arg-name:"path"`
	} `positional-args:"yes" required:"yes"`
	mu sync.Mutex
}

func (c *CLI) run(cmd *exec.Cmd) error {
	if c.Dryrun {
		// Prevent overlapping output
		c.mu.Lock()
		defer c.mu.Unlock()
		fmt.Println(strings.Join(cmd.Args, " "))
		return nil
	}
	if err := cmd.Run(); err != nil {
		return err
	}
	return nil
}

func (c *CLI) sync(g *git.Git, r *github.Repository) error {
	repoURL, err := gh.CloneURL(c.Protocol, r)
	if err != nil {
		return err
	}
	localDir := git.LocalDir(c.Args.Path, *r.Name)
	syncCmd := g.Sync(repoURL, localDir)
	if err := c.run(syncCmd); err != nil {
		return err
	}
	return nil
}

func (c *CLI) syncAll(g *git.Git, repos []*github.Repository) {
	sem := make(chan bool, c.Concurrency)
	for _, r := range repos {
		if c.SkipFork && *r.Fork {
			continue
		}
		sem <- true
		go func(r *github.Repository) {
			defer func() { <-sem }()
			if err := c.sync(g, r); err != nil {
				log.Fatal(err)
			}
		}(r)
	}
	// Wait for remaining goroutines to finish
	for i := 0; i < cap(sem); i++ {
		sem <- true
	}
}

func main() {
	var cli CLI
	_, err := flags.ParseArgs(&cli, os.Args[1:])
	if err != nil {
		os.Exit(1)
	}

	if cli.Concurrency < 1 {
		fmt.Fprintln(os.Stderr, "concurrency level must be >= 1")
		os.Exit(1)
	}

	gh := gh.New()
	repos, err := gh.ListAllRepositories(cli.Args.Username)
	if err != nil {
		log.Fatal(err)
	}

	g, err := git.New(cli.GitPath, !cli.Quiet)
	if err != nil {
		log.Fatal(err)
	}

	cli.syncAll(g, repos)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/aws/aws-sdk-go/service/cloudwatch"
	"github.com/y13i/metrin/lib"

	"github.com/urfave/cli"
)

const (
	defaultStartTime = -300
	defaultEndTime   = 0
	defaultPeriod    = 60
)

func main() {
	app := cli.NewApp()

	app.Name = "metrin"
	app.Usage = "Very simple CloudWatch CLI for Zabbix/Nagios/Sensu/Mackerel/etc."
	app.Version = "0.0.5"
	app.EnableBashCompletion = true

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "namespace, n",
			Usage: "CloudWatch namespace. e.g. 'AWS/EC2'",
		},

		cli.StringFlag{
			Name:  "metric-name, m",
			Usage: "CloudWatch metric name. e.g. 'CPUUtilization'",
		},

		cli.Int64Flag{
			Name:  "start-time, S",
			Value: defaultStartTime,
			Usage: "start time as unix timestamp, relative from now if 0 or negative value given",
		},

		cli.Int64Flag{
			Name:  "end-time, E",
			Value: defaultEndTime,
			Usage: "end time as unix timestamp, relative from now if 0 or negative value given",
		},

		cli.Int64Flag{
			Name:  "period, p",
			Usage: "CloudWatch metric statistic period.",
			Value: defaultPeriod,
		},

		cli.StringFlag{
			Name:  "unit, u",
			Usage: "CloudWatch metric statistic unit. e.g. 'Percent'",
		},

		cli.StringSliceFlag{
			Name:  "statistic, s",
			Usage: "CloudWatch metrics statistic. e.g. 'Average'",
		},

		cli.StringSliceFlag{
			Name:  "extended-statistic, e",
			Usage: "CloudWatch extended metrics statistic. e.g. 'p99.5'",
		},

		cli.StringSliceFlag{
			Name:  "dimension, d",
			Usage: "CloudWatch dimension. `DIM_KEY:DIM_VALUE` e.g. 'InstanceId:i-12345678'",
		},

		cli.StringFlag{
			Name:  "region, r",
			Usage: "AWS region. e.g. 'us-west-2'",
		},

		cli.StringFlag{
			Name:  "profile, P",
			Usage: "AWS profile name. e.g. 'myprofile'",
		},

		cli.StringFlag{
			Name:  "access-key-id, a",
			Usage: "AWS access key id. e.g. 'AKIAIOSFODNN7EXAMPLE'",
		},

		cli.StringFlag{
			Name:  "secret-access-key, A",
			Usage: "AWS secret access key. e.g. 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'",
		},

		cli.Float64Flag{
			Name:  "value-when-no-datapoint, W",
			Usage: "use this value when no datapoint fetched",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:  "check",
			Usage: "perform check and exit with status codes (0: OK, 1: WARNING, 2: CRITICAL, 3: UNKNOWN)",

			Flags: []cli.Flag{
				cli.Float64Flag{
					Name:  "critical-gt",
					Usage: "exit as critical (code 2) if latest metric value is greater than the value",
				},

				cli.Float64Flag{
					Name:  "critical-lt",
					Usage: "exit as critical (code 2) if latest metric value is less than the value",
				},

				cli.Float64Flag{
					Name:  "critical-gte",
					Usage: "exit as critical (code 2) if latest metric value is greater than or equal to the value",
				},

				cli.Float64Flag{
					Name:  "critical-lte",
					Usage: "exit as critical (code 2) if latest metric value is less than or equal to the value",
				},

				cli.Float64Flag{
					Name:  "warning-gt",
					Usage: "exit as warning (code 1) if latest metric value is greater than the value",
				},

				cli.Float64Flag{
					Name:  "warning-lt",
					Usage: "exit as warning (code 1) if latest metric value is less than the value",
				},

				cli.Float64Flag{
					Name:  "warning-gte",
					Usage: "exit as warning (code 1) if latest metric value is greater than or equal to the value",
				},

				cli.Float64Flag{
					Name:  "warning-lte",
					Usage: "exit as warning (code 1) if latest metric value is less than or equal to the value",
				},
			},

			Action: func(ctx *cli.Context) error {
				setAwsEnv(ctx)
				params := getParams(ctx)
				response := metrin.GetMetricStatistics(params)

				thresholds := metrin.CheckThresholds{
					CriticalGtPresent:  ctx.IsSet("critical-gt"),
					CriticalLtPresent:  ctx.IsSet("critical-lt"),
					CriticalGtePresent: ctx.IsSet("critical-gte"),
					CriticalLtePresent: ctx.IsSet("critical-lte"),
					WarningGtPresent:   ctx.IsSet("warning-gt"),
					WarningLtPresent:   ctx.IsSet("warning-lt"),
					WarningGtePresent:  ctx.IsSet("warning-gte"),
					WarningLtePresent:  ctx.IsSet("warning-lte"),
					CriticalGtValue:    ctx.Float64("critical-gt"),
					CriticalLtValue:    ctx.Float64("critical-lt"),
					CriticalGteValue:   ctx.Float64("critical-gte"),
					CriticalLteValue:   ctx.Float64("critical-lte"),
					WarningGtValue:     ctx.Float64("warning-gt"),
					WarningLtValue:     ctx.Float64("warning-lt"),
					WarningGteValue:    ctx.Float64("warning-gte"),
					WarningLteValue:    ctx.Float64("warning-lte"),
				}

				checkOutput := metrin.Check(metrin.CheckInput{
					Thresholds:         thresholds,
					Datapoints:         response.Datapoints,
					Statistics:         ctx.GlobalStringSlice("statistic"),
					ExtendedStatistics: ctx.GlobalStringSlice("extended-statistic"),
					UseDefaultValue:    ctx.GlobalIsSet("value-when-no-datapoint"),
					DefaultValue:       ctx.GlobalFloat64("value-when-no-datapoint"),
				})

				fmt.Println(strings.Join(checkOutput.Messages, ", "))
				fmt.Println("Params:", params)
				os.Exit(checkOutput.ExitCode)

				return nil
			},
		},

		{
			Name:  "print",
			Usage: "Prints GetMetricStatistics response with given format template",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "template, t",
					Usage: "output format template (using 'text/template' package. see https://golang.org/pkg/text/template/)",
					Value: "CloudWatch.{{(index .Params.Dimensions 0).Name}}.{{(index .Params.Dimensions 0).Value}}.{{.Params.MetricName}}.{{index .Params.Statistics 0}}\t{{getvalue .Datapoint .Params 0 | deref | printf \"%f\"}}\t{{.Datapoint.Timestamp | unixtime}}",
				},

				cli.BoolFlag{
					Name:  "last-value-only",
					Usage: "if true, print last datapoint value only",
				},
			},

			Action: func(ctx *cli.Context) error {
				setAwsEnv(ctx)
				params := getParams(ctx)
				response := metrin.GetMetricStatistics(params)

				var datapoints []*cloudwatch.Datapoint

				if ctx.Bool("last-value-only") {
					datapoints = []*cloudwatch.Datapoint{
						metrin.GetLastDatapoint(response.Datapoints, ctx.GlobalIsSet("value-when-no-datapoint"), ctx.GlobalFloat64("value-when-no-datapoint")),
					}
				} else {
					datapoints = response.Datapoints
				}

				outputStrings := metrin.BuildPrintStrings(metrin.BuildPrintStringInput{
					Params:         params,
					Datapoints:     datapoints,
					TemplateString: ctx.String("template"),
				})

				fmt.Println(strings.Join(outputStrings, "\n"))

				return nil
			},
		},

		{
			Name:  "debug",
			Usage: "Prints GetMetricStatistics params and response",

			Action: func(ctx *cli.Context) error {
				setAwsEnv(ctx)
				params := getParams(ctx)
				fmt.Println("Params:", params)

				response := metrin.GetMetricStatistics(params)
				fmt.Println("Response:", response)

				return nil
			},
		},
	}

	app.Run(os.Args)
}

func getParams(ctx *cli.Context) *cloudwatch.GetMetricStatisticsInput {
	return metrin.BuildParams(metrin.BuildParamsInput{
		Namespace:          ctx.GlobalString("namespace"),
		MetricName:         ctx.GlobalString("metric-name"),
		StartTime:          ctx.GlobalInt64("start-time"),
		EndTime:            ctx.GlobalInt64("end-time"),
		Period:             ctx.GlobalInt64("period"),
		Unit:               ctx.GlobalString("unit"),
		Statistics:         ctx.GlobalStringSlice("statistic"),
		ExtendedStatistics: ctx.GlobalStringSlice("extended-statistic"),
		Dimensions:         ctx.GlobalStringSlice("dimension"),
	})
}

func setAwsEnv(ctx *cli.Context) {
	if ctx.GlobalIsSet("region") {
		os.Setenv("AWS_REGION", ctx.GlobalString("region"))
	}

	if ctx.GlobalIsSet("profile") {
		os.Setenv("AWS_PROFILE", ctx.GlobalString("profile"))
	}

	if ctx.GlobalIsSet("access-key-id") {
		os.Setenv("AWS_ACCESS_KEY_ID", ctx.GlobalString("access-key-id"))
	}

	if ctx.GlobalIsSet("secret-access-key") {
		os.Setenv("AWS_SECRET_ACCESS_KEY", ctx.GlobalString("secret-access-key"))
	}
}
<commit_msg>fix version<commit_after>package main

import (
	"fmt"
	"os"
	"strings"

	"github.com/aws/aws-sdk-go/service/cloudwatch"
	"github.com/y13i/metrin/lib"

	"github.com/urfave/cli"
)

const (
	defaultStartTime = -300
	defaultEndTime   = 0
	defaultPeriod    = 60
)

func main() {
	app := cli.NewApp()

	app.Name = "metrin"
	app.Usage = "Very simple CloudWatch CLI for Zabbix/Nagios/Sensu/Mackerel/etc."
	app.Version = "0.0.6"
	app.EnableBashCompletion = true

	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:  "namespace, n",
			Usage: "CloudWatch namespace. e.g. 'AWS/EC2'",
		},

		cli.StringFlag{
			Name:  "metric-name, m",
			Usage: "CloudWatch metric name. e.g. 'CPUUtilization'",
		},

		cli.Int64Flag{
			Name:  "start-time, S",
			Value: defaultStartTime,
			Usage: "start time as unix timestamp, relative from now if 0 or negative value given",
		},

		cli.Int64Flag{
			Name:  "end-time, E",
			Value: defaultEndTime,
			Usage: "end time as unix timestamp, relative from now if 0 or negative value given",
		},

		cli.Int64Flag{
			Name:  "period, p",
			Usage: "CloudWatch metric statistic period.",
			Value: defaultPeriod,
		},

		cli.StringFlag{
			Name:  "unit, u",
			Usage: "CloudWatch metric statistic unit. e.g. 'Percent'",
		},

		cli.StringSliceFlag{
			Name:  "statistic, s",
			Usage: "CloudWatch metrics statistic. e.g. 'Average'",
		},

		cli.StringSliceFlag{
			Name:  "extended-statistic, e",
			Usage: "CloudWatch extended metrics statistic. e.g. 'p99.5'",
		},

		cli.StringSliceFlag{
			Name:  "dimension, d",
			Usage: "CloudWatch dimension. `DIM_KEY:DIM_VALUE` e.g. 'InstanceId:i-12345678'",
		},

		cli.StringFlag{
			Name:  "region, r",
			Usage: "AWS region. e.g. 'us-west-2'",
		},

		cli.StringFlag{
			Name:  "profile, P",
			Usage: "AWS profile name. e.g. 'myprofile'",
		},

		cli.StringFlag{
			Name:  "access-key-id, a",
			Usage: "AWS access key id. e.g. 'AKIAIOSFODNN7EXAMPLE'",
		},

		cli.StringFlag{
			Name:  "secret-access-key, A",
			Usage: "AWS secret access key. e.g. 'wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY'",
		},

		cli.Float64Flag{
			Name:  "value-when-no-datapoint, W",
			Usage: "use this value when no datapoint fetched",
		},
	}

	app.Commands = []cli.Command{
		{
			Name:  "check",
			Usage: "perform check and exit with status codes (0: OK, 1: WARNING, 2: CRITICAL, 3: UNKNOWN)",

			Flags: []cli.Flag{
				cli.Float64Flag{
					Name:  "critical-gt",
					Usage: "exit as critical (code 2) if latest metric value is greater than the value",
				},

				cli.Float64Flag{
					Name:  "critical-lt",
					Usage: "exit as critical (code 2) if latest metric value is less than the value",
				},

				cli.Float64Flag{
					Name:  "critical-gte",
					Usage: "exit as critical (code 2) if latest metric value is greater than or equal to the value",
				},

				cli.Float64Flag{
					Name:  "critical-lte",
					Usage: "exit as critical (code 2) if latest metric value is less than or equal to the value",
				},

				cli.Float64Flag{
					Name:  "warning-gt",
					Usage: "exit as warning (code 1) if latest metric value is greater than the value",
				},

				cli.Float64Flag{
					Name:  "warning-lt",
					Usage: "exit as warning (code 1) if latest metric value is less than the value",
				},

				cli.Float64Flag{
					Name:  "warning-gte",
					Usage: "exit as warning (code 1) if latest metric value is greater than or equal to the value",
				},

				cli.Float64Flag{
					Name:  "warning-lte",
					Usage: "exit as warning (code 1) if latest metric value is less than or equal to the value",
				},
			},

			Action: func(ctx *cli.Context) error {
				setAwsEnv(ctx)
				params := getParams(ctx)
				response := metrin.GetMetricStatistics(params)

				thresholds := metrin.CheckThresholds{
					CriticalGtPresent:  ctx.IsSet("critical-gt"),
					CriticalLtPresent:  ctx.IsSet("critical-lt"),
					CriticalGtePresent: ctx.IsSet("critical-gte"),
					CriticalLtePresent: ctx.IsSet("critical-lte"),
					WarningGtPresent:   ctx.IsSet("warning-gt"),
					WarningLtPresent:   ctx.IsSet("warning-lt"),
					WarningGtePresent:  ctx.IsSet("warning-gte"),
					WarningLtePresent:  ctx.IsSet("warning-lte"),
					CriticalGtValue:    ctx.Float64("critical-gt"),
					CriticalLtValue:    ctx.Float64("critical-lt"),
					CriticalGteValue:   ctx.Float64("critical-gte"),
					CriticalLteValue:   ctx.Float64("critical-lte"),
					WarningGtValue:     ctx.Float64("warning-gt"),
					WarningLtValue:     ctx.Float64("warning-lt"),
					WarningGteValue:    ctx.Float64("warning-gte"),
					WarningLteValue:    ctx.Float64("warning-lte"),
				}

				checkOutput := metrin.Check(metrin.CheckInput{
					Thresholds:         thresholds,
					Datapoints:         response.Datapoints,
					Statistics:         ctx.GlobalStringSlice("statistic"),
					ExtendedStatistics: ctx.GlobalStringSlice("extended-statistic"),
					UseDefaultValue:    ctx.GlobalIsSet("value-when-no-datapoint"),
					DefaultValue:       ctx.GlobalFloat64("value-when-no-datapoint"),
				})

				fmt.Println(strings.Join(checkOutput.Messages, ", "))
				fmt.Println("Params:", params)
				os.Exit(checkOutput.ExitCode)

				return nil
			},
		},

		{
			Name:  "print",
			Usage: "Prints GetMetricStatistics response with given format template",

			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "template, t",
					Usage: "output format template (using 'text/template' package. see https://golang.org/pkg/text/template/)",
					Value: "CloudWatch.{{(index .Params.Dimensions 0).Name}}.{{(index .Params.Dimensions 0).Value}}.{{.Params.MetricName}}.{{index .Params.Statistics 0}}\t{{getvalue .Datapoint .Params 0 | deref | printf \"%f\"}}\t{{.Datapoint.Timestamp | unixtime}}",
				},

				cli.BoolFlag{
					Name:  "last-value-only",
					Usage: "if true, print last datapoint value only",
				},
			},

			Action: func(ctx *cli.Context) error {
				setAwsEnv(ctx)
				params := getParams(ctx)
				response := metrin.GetMetricStatistics(params)

				var datapoints []*cloudwatch.Datapoint

				if ctx.Bool("last-value-only") {
					datapoints = []*cloudwatch.Datapoint{
						metrin.GetLastDatapoint(response.Datapoints, ctx.GlobalIsSet("value-when-no-datapoint"), ctx.GlobalFloat64("value-when-no-datapoint")),
					}
				} else {
					datapoints = response.Datapoints
				}

				outputStrings := metrin.BuildPrintStrings(metrin.BuildPrintStringInput{
					Params:         params,
					Datapoints:     datapoints,
					TemplateString: ctx.String("template"),
				})

				fmt.Println(strings.Join(outputStrings, "\n"))

				return nil
			},
		},

		{
			Name:  "debug",
			Usage: "Prints GetMetricStatistics params and response",

			Action: func(ctx *cli.Context) error {
				setAwsEnv(ctx)
				params := getParams(ctx)
				fmt.Println("Params:", params)

				response := metrin.GetMetricStatistics(params)
				fmt.Println("Response:", response)

				return nil
			},
		},
	}

	app.Run(os.Args)
}

func getParams(ctx *cli.Context) *cloudwatch.GetMetricStatisticsInput {
	return metrin.BuildParams(metrin.BuildParamsInput{
		Namespace:          ctx.GlobalString("namespace"),
		MetricName:         ctx.GlobalString("metric-name"),
		StartTime:          ctx.GlobalInt64("start-time"),
		EndTime:            ctx.GlobalInt64("end-time"),
		Period:             ctx.GlobalInt64("period"),
		Unit:               ctx.GlobalString("unit"),
		Statistics:         ctx.GlobalStringSlice("statistic"),
		ExtendedStatistics: ctx.GlobalStringSlice("extended-statistic"),
		Dimensions:         ctx.GlobalStringSlice("dimension"),
	})
}

func setAwsEnv(ctx *cli.Context) {
	if ctx.GlobalIsSet("region") {
		os.Setenv("AWS_REGION", ctx.GlobalString("region"))
	}

	if ctx.GlobalIsSet("profile") {
		os.Setenv("AWS_PROFILE", ctx.GlobalString("profile"))
	}

	if ctx.GlobalIsSet("access-key-id") {
		os.Setenv("AWS_ACCESS_KEY_ID", ctx.GlobalString("access-key-id"))
	}

	if ctx.GlobalIsSet("secret-access-key") {
		os.Setenv("AWS_SECRET_ACCESS_KEY", ctx.GlobalString("secret-access-key"))
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/kkserver/kk-job/job"
	"github.com/kkserver/kk-lib/kk"
	"log"
	"os"
	"os/exec"
	"runtime/debug"
	"strconv"
	"time"
)

func help() {
	fmt.Println("kk-job-slave <name> <127.0.0.1:8700> <kk.job.> <token> <workdir> <processCount>")
}

func request(sendRequest func(message *kk.Message, timeout time.Duration) *kk.Message, to string, timeout time.Duration, data interface{}, result interface{}) error {

	log.Printf("[REQUEST] %s ...\n", to)

	var b, _ = json.Marshal(data)
	var v = kk.Message{"REQUEST", "", to, "text/json", b}
	var r = sendRequest(&v, timeout)

	log.Printf("[REQUEST] %s %s\n", to, r.String())

	if r == nil {
		return errors.New(fmt.Sprintf("TO: %s fail", to))
	}

	if r.Method != "REQUEST" {
		return errors.New(fmt.Sprintf("TO: %s %s", to, r.String()))
	}

	if r.Type == "text/json" || r.Type == "application/json" {
		return json.Unmarshal(r.Content, result)
	}

	return nil
}

func createJSONFile(data interface{}, path string) error {

	os.Remove(path)

	fd, err := os.Create(path)

	if err != nil {
		return err
	}

	defer fd.Close()

	os.Chmod(path, 0777)

	b, err := json.Marshal(data)

	if err == nil {

		var n = 0

		for n != len(b) {

			n, err := fd.Write(b)

			if err != nil {
				log.Println("[FAIL] " + err.Error())
				return err
			}

			if n != len(b) {
				b = b[n:]
			} else {
				break
			}
		}
	} else {
		log.Println("[FAIL] " + err.Error())
	}

	return nil
}

func createTextFile(text string, path string) error {

	os.Remove(path)

	fd, err := os.Create(path)

	if err != nil {
		return err
	}

	os.Chmod(path, 0777)

	defer fd.Close()

	b := []byte(text)

	var n = 0

	for n != len(b) {

		n, err := fd.Write(b)

		if err != nil {
			return err
		}

		if n != len(b) {
			b = b[n:]
		} else {
			break
		}
	}

	return nil
}

func createShellFile(options map[string]interface{}, path string, cmd string) error {

	os.Remove(path)

	fd, err := os.Create(path)

	if err != nil {
		return err
	}

	os.Chmod(path, 0777)

	defer fd.Close()

	fd.WriteString("#/bin/sh\n\n")

	for key, value := range options {
		var option, ok = value.(map[string]interface{})
		if ok {
			v, ok := option["value"]
			if ok {
				b, _ := json.Marshal(v)
				fmt.Fprintf(fd, "export %s=%s\n", key, string(b))
			}

		}
	}

	fd.WriteString("\n\n")

	fd.WriteString(cmd)

	fd.WriteString("\n")

	return nil
}

func writeLogFile(tag string, log string, path string) error {

	fd, err := os.OpenFile(path, os.O_APPEND, os.ModePerm)

	if err != nil {

		fd, err = os.Create(path)

		if err != nil {
			return err
		}

		os.Chmod(path, 0777)

	}

	defer fd.Close()

	fd.WriteString(fmt.Sprintf("[%s][%s] %s", tag, time.Now().String(), log))

	return nil
}

type LogWriter struct {
	fd          *os.File
	tag         string
	token       string
	jobId       int64
	version     int
	baseURL     string
	sendRequest func(message *kk.Message, timeout time.Duration) *kk.Message
	line        *bytes.Buffer
}

func NewLogWriter(path string, tag string, token string, jobId int64, version int, baseURL string, sendRequest func(message *kk.Message, timeout time.Duration) *kk.Message) (log *LogWriter, err error) {
	var v = LogWriter{}
	var e error = nil

	v.fd, e = os.OpenFile(path, os.O_APPEND, 0)

	if e != nil {

		v.fd, e = os.Create(path)

		if e != nil {
			return nil, e
		}

		os.Chmod(path, 0777)

	}

	v.tag = tag
	v.token = token
	v.jobId = jobId
	v.version = version
	v.baseURL = baseURL
	v.sendRequest = sendRequest
	v.line = bytes.NewBuffer(nil)

	return &v, nil
}

func (L *LogWriter) Close() error {
	return L.fd.Close()
}

func (L *LogWriter) Write(p []byte) (n int, err error) {

	for _, c := range p {
		if c == '\n' {
			var r = job.JobVersionLogTaskResult{}
			request(L.sendRequest, L.baseURL+"job/slave/log", time.Second, map[string]interface{}{
				"token":   L.token,
				"jobId":   fmt.Sprintf("%d", L.jobId),
				"version": fmt.Sprintf("%d", L.version),
				"tag":     L.tag,
				"log":     L.line.String()}, &r)
			L.line.Reset()
		} else {
			L.line.WriteByte(c)
		}
	}

	return L.fd.Write(p)
}

func main() {

	log.SetFlags(log.Llongfile | log.LstdFlags)

	var args = os.Args
	var name string = ""
	var address string = ""
	var baseURL string = ""
	var token string = ""
	var workdir string = ""
	var processCount int = 10

	if len(args) > 6 {
		name = args[1]
		address = args[2]
		baseURL = args[3]
		token = args[4]
		workdir = args[5]
		processCount, _ = strconv.Atoi(args[6])
	} else {
		help()
		return
	}

	var sendRequest, _ = kk.TCPClientRequestConnect(name, address, map[string]interface{}{"exclusive": true})

	var process map[string]*kk.Dispatch = map[string]*kk.Dispatch{}
	var online func() = nil

	online = func() {

		var result = job.JobSlaveOnlineTaskResult{}

		var err = request(sendRequest, baseURL+"job/slave/online", time.Second, map[string]interface{}{"token": token}, &result)

		if err != nil {
			log.Println(err)
		} else if result.Errno == 0 {
			createJSONFile(result.Slave, workdir+"/job/slave.json")
		} else {
			log.Println(result.Errmsg)
		}

		kk.GetDispatchMain().AsyncDelay(func() {

			go online()

		}, time.Second*6)

	}

	var jobProcess func() = nil

	jobProcess = func() {

		var result = job.JobSlaveProcessTaskResult{}

		var err = request(sendRequest, baseURL+"job/slave/process", time.Second, map[string]interface{}{"token": token}, &result)

		if err != nil {

			log.Println(err)

			kk.GetDispatchMain().AsyncDelay(func() {
				go jobProcess()
			}, time.Second*6)

		} else if result.Errno == 0 {

			if result.Version != nil {

				var name = fmt.Sprintf("%s/job/%d_%d/", workdir, result.Version.JobId, result.Version.Version)

				_, err := os.Stat(name)

				if err != nil {

					var p = kk.NewDispatch()

					process[name] = p

					var exit = func() {

						kk.GetDispatchMain().Async(func() {

							p.Break()

							delete(process, name)

							kk.GetDispatchMain().AsyncDelay(func() {
								go jobProcess()
							}, time.Second*6)

						})

					}

					var fail = func(err error) {

						log.Println("[FAIL] " + err.Error())

						debug.PrintStack()

						createTextFile(err.Error(), name+"fail")

						var fail = job.JobVersionFailTaskResult{}

						request(sendRequest, baseURL+"job/slave/fail", time.Second, map[string]interface{}{
							"token":      token,
							"jobId":      fmt.Sprintf("%d", result.Version.JobId),
							"version":    fmt.Sprintf("%d", result.Version.Version),
							"statusText": err.Error()}, &fail)

						exit()

					}

					p.Async(func() {

						err := os.Mkdir(name, 0777)

						if err != nil {
							fail(err)
							return
						}

						err = createJSONFile(result.Job, name+"job.json")

						if err != nil {
							fail(err)
							return
						}

						err = createJSONFile(result.Slave, name+"slave.json")

						if err != nil {
							fail(err)
							return
						}

						err = createJSONFile(result.Version, name+"version.json")

						if err != nil {
							fail(err)
							return
						}

						var options = map[string]interface{}{}

						if result.Job.Options != "" {
							json.Unmarshal([]byte(result.Job.Options), &options)
						}

						if result.Version.Options != "" {

							var opts = map[string]interface{}{}

							json.Unmarshal([]byte(result.Job.Options), &opts)

							for key, value := range opts {
								opt, ok := options[key]
								if ok {
									m, ok := opt.(map[string]interface{})
									if ok {
										m[key] = value
									}
								}
							}
						}

						err = createShellFile(options, name+"run.sh", workdir+"/run.sh")

						if err != nil {
							fail(err)
							return
						}

						cmd := exec.Command("/bin/sh", "-c", name+"run.sh")

						cmd.Dir = name

						stdout, err := NewLogWriter(name+"info.log", "INFO", token, result.Version.JobId, result.Version.Version, baseURL, sendRequest)

						cmd.Stderr = stdout
						cmd.Stdout = stdout

						defer stdout.Close()

						err = cmd.Start()

						if err != nil {
							fail(err)
							return
						}

						err = cmd.Wait()

						if err != nil {
							log.Println(workdir + "/run.sh")
							fail(err)
							return
						}

						var r = job.JobVersionOKTaskResult{}

						request(sendRequest, baseURL+"job/slave/ok", time.Second, map[string]interface{}{
							"token":   token,
							"jobId":   fmt.Sprintf("%d", result.Version.JobId),
							"version": fmt.Sprintf("%d", result.Version.Version)}, &r)

						writeLogFile("INFO", "EXIT", name+"info.log")

						exit()
					})

					kk.GetDispatchMain().Async(func() {

						if len(process) < processCount {
							go jobProcess()
						}

					})

					return
				}

				var fail = job.JobVersionFailTaskResult{}

				request(sendRequest, baseURL+"job/slave/fail", time.Second, map[string]interface{}{
					"token":   token,
					"jobId":   fmt.Sprintf("%d", result.Version.JobId),
					"version": fmt.Sprintf("%d", result.Version.Version)}, &fail)

				log.Printf("[FAIL] jobId:%d version:%d %s\n", result.Version.JobId, result.Version.Version)

				kk.GetDispatchMain().AsyncDelay(func() {
					go jobProcess()
				}, time.Second*6)

			} else {
				kk.GetDispatchMain().AsyncDelay(func() {
					go jobProcess()
				}, time.Second*6)
			}

		} else {

			log.Println(result.Errmsg)

			kk.GetDispatchMain().AsyncDelay(func() {
				go jobProcess()
			}, time.Second*6)
		}
	}

	kk.GetDispatchMain().AsyncDelay(func() {

		go func() {

			var result = job.JobSlaveLoginTask{}

			var err = request(sendRequest, baseURL+"job/slave/login", time.Second, map[string]interface{}{"token": token}, &result)

			if err != nil {

				log.Println("[FAIL] " + err.Error())

				kk.GetDispatchMain().Break()

				return
			}

			go online()

			go jobProcess()

		}()

	}, time.Second)

	kk.DispatchMain()

	for _, v := range process {
		v.Break()
	}

	log.Println("[EXIT]")

}
<commit_msg>update<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/kkserver/kk-job/job"
	"github.com/kkserver/kk-lib/kk"
	"log"
	"os"
	"os/exec"
	"runtime/debug"
	"strconv"
	"time"
)

func help() {
	fmt.Println("kk-job-slave <name> <127.0.0.1:8700> <kk.job.> <token> <workdir> <processCount>")
}

func request(sendRequest func(message *kk.Message, timeout time.Duration) *kk.Message, to string, timeout time.Duration, data interface{}, result interface{}) error {

	log.Printf("[REQUEST] %s ...\n", to)

	var b, _ = json.Marshal(data)
	var v = kk.Message{"REQUEST", "", to, "text/json", b}
	var r = sendRequest(&v, timeout)

	log.Printf("[REQUEST] %s %s\n", to, r.String())

	if r == nil {
		return errors.New(fmt.Sprintf("TO: %s fail", to))
	}

	if r.Method != "REQUEST" {
		return errors.New(fmt.Sprintf("TO: %s %s", to, r.String()))
	}

	if r.Type == "text/json" || r.Type == "application/json" {
		return json.Unmarshal(r.Content, result)
	}

	return nil
}

func createJSONFile(data interface{}, path string) error {

	os.Remove(path)

	fd, err := os.Create(path)

	if err != nil {
		return err
	}

	defer fd.Close()

	os.Chmod(path, 0777)

	b, err := json.Marshal(data)

	if err == nil {

		var n = 0

		for n != len(b) {

			n, err := fd.Write(b)

			if err != nil {
				log.Println("[FAIL] " + err.Error())
				return err
			}

			if n != len(b) {
				b = b[n:]
			} else {
				break
			}
		}
	} else {
		log.Println("[FAIL] " + err.Error())
	}

	return nil
}

func createTextFile(text string, path string) error {

	os.Remove(path)

	fd, err := os.Create(path)

	if err != nil {
		return err
	}

	os.Chmod(path, 0777)

	defer fd.Close()

	b := []byte(text)

	var n = 0

	for n != len(b) {

		n, err := fd.Write(b)

		if err != nil {
			return err
		}

		if n != len(b) {
			b = b[n:]
		} else {
			break
		}
	}

	return nil
}

func createShellFile(options map[string]interface{}, path string, cmd string) error {

	os.Remove(path)

	fd, err := os.Create(path)

	if err != nil {
		return err
	}

	os.Chmod(path, 0777)

	defer fd.Close()

	fd.WriteString("#/bin/bash\n\n")

	for key, value := range options {
		var option, ok = value.(map[string]interface{})
		if ok {
			v, ok := option["value"]
			if ok {
				b, _ := json.Marshal(v)
				fmt.Fprintf(fd, "export %s=%s\n", key, string(b))
			}

		}
	}

	fd.WriteString("\n\n")

	fd.WriteString(cmd)

	fd.WriteString("\n")

	return nil
}

func writeLogFile(tag string, log string, path string) error {

	fd, err := os.OpenFile(path, os.O_APPEND, os.ModePerm)

	if err != nil {

		fd, err = os.Create(path)

		if err != nil {
			return err
		}

		os.Chmod(path, 0777)

	}

	defer fd.Close()

	fd.WriteString(fmt.Sprintf("[%s][%s] %s", tag, time.Now().String(), log))

	return nil
}

type LogWriter struct {
	fd          *os.File
	tag         string
	token       string
	jobId       int64
	version     int
	baseURL     string
	sendRequest func(message *kk.Message, timeout time.Duration) *kk.Message
	line        *bytes.Buffer
}

func NewLogWriter(path string, tag string, token string, jobId int64, version int, baseURL string, sendRequest func(message *kk.Message, timeout time.Duration) *kk.Message) (log *LogWriter, err error) {
	var v = LogWriter{}
	var e error = nil

	v.fd, e = os.OpenFile(path, os.O_APPEND, 0)

	if e != nil {

		v.fd, e = os.Create(path)

		if e != nil {
			return nil, e
		}

		os.Chmod(path, 0777)

	}

	v.tag = tag
	v.token = token
	v.jobId = jobId
	v.version = version
	v.baseURL = baseURL
	v.sendRequest = sendRequest
	v.line = bytes.NewBuffer(nil)

	return &v, nil
}

func (L *LogWriter) Close() error {
	return L.fd.Close()
}

func (L *LogWriter) Write(p []byte) (n int, err error) {

	for _, c := range p {
		if c == '\n' {
			var r = job.JobVersionLogTaskResult{}
			request(L.sendRequest, L.baseURL+"job/slave/log", time.Second, map[string]interface{}{
				"token":   L.token,
				"jobId":   fmt.Sprintf("%d", L.jobId),
				"version": fmt.Sprintf("%d", L.version),
				"tag":     L.tag,
				"log":     L.line.String()}, &r)
			L.line.Reset()
		} else {
			L.line.WriteByte(c)
		}
	}

	return L.fd.Write(p)
}

func main() {

	log.SetFlags(log.Llongfile | log.LstdFlags)

	var args = os.Args
	var name string = ""
	var address string = ""
	var baseURL string = ""
	var token string = ""
	var workdir string = ""
	var processCount int = 10

	if len(args) > 6 {
		name = args[1]
		address = args[2]
		baseURL = args[3]
		token = args[4]
		workdir = args[5]
		processCount, _ = strconv.Atoi(args[6])
	} else {
		help()
		return
	}

	var sendRequest, _ = kk.TCPClientRequestConnect(name, address, map[string]interface{}{"exclusive": true})

	var process map[string]*kk.Dispatch = map[string]*kk.Dispatch{}
	var online func() = nil

	online = func() {

		var result = job.JobSlaveOnlineTaskResult{}

		var err = request(sendRequest, baseURL+"job/slave/online", time.Second, map[string]interface{}{"token": token}, &result)

		if err != nil {
			log.Println(err)
		} else if result.Errno == 0 {
			createJSONFile(result.Slave, workdir+"/job/slave.json")
		} else {
			log.Println(result.Errmsg)
		}

		kk.GetDispatchMain().AsyncDelay(func() {

			go online()

		}, time.Second*6)

	}

	var jobProcess func() = nil

	jobProcess = func() {

		var result = job.JobSlaveProcessTaskResult{}

		var err = request(sendRequest, baseURL+"job/slave/process", time.Second, map[string]interface{}{"token": token}, &result)

		if err != nil {

			log.Println(err)

			kk.GetDispatchMain().AsyncDelay(func() {
				go jobProcess()
			}, time.Second*6)

		} else if result.Errno == 0 {

			if result.Version != nil {

				var name = fmt.Sprintf("%s/job/%d_%d/", workdir, result.Version.JobId, result.Version.Version)

				_, err := os.Stat(name)

				if err != nil {

					var p = kk.NewDispatch()

					process[name] = p

					var exit = func() {

						kk.GetDispatchMain().Async(func() {

							p.Break()

							delete(process, name)

							kk.GetDispatchMain().AsyncDelay(func() {
								go jobProcess()
							}, time.Second*6)

						})

					}

					var fail = func(err error) {

						log.Println("[FAIL] " + err.Error())

						debug.PrintStack()

						createTextFile(err.Error(), name+"fail")

						var fail = job.JobVersionFailTaskResult{}

						request(sendRequest, baseURL+"job/slave/fail", time.Second, map[string]interface{}{
							"token":      token,
							"jobId":      fmt.Sprintf("%d", result.Version.JobId),
							"version":    fmt.Sprintf("%d", result.Version.Version),
							"statusText": err.Error()}, &fail)

						exit()

					}

					p.Async(func() {

						err := os.Mkdir(name, 0777)

						if err != nil {
							fail(err)
							return
						}

						err = createJSONFile(result.Job, name+"job.json")

						if err != nil {
							fail(err)
							return
						}

						err = createJSONFile(result.Slave, name+"slave.json")

						if err != nil {
							fail(err)
							return
						}

						err = createJSONFile(result.Version, name+"version.json")

						if err != nil {
							fail(err)
							return
						}

						var options = map[string]interface{}{}

						if result.Job.Options != "" {
							json.Unmarshal([]byte(result.Job.Options), &options)
						}

						if result.Version.Options != "" {

							var opts = map[string]interface{}{}

							json.Unmarshal([]byte(result.Job.Options), &opts)

							for key, value := range opts {
								opt, ok := options[key]
								if ok {
									m, ok := opt.(map[string]interface{})
									if ok {
										m[key] = value
									}
								}
							}
						}

						err = createShellFile(options, name+"run.sh", workdir+"/run.sh")

						if err != nil {
							fail(err)
							return
						}

						cmd := exec.Command("/bin/sh", "-c", name+"run.sh")

						cmd.Dir = name

						stdout, err := NewLogWriter(name+"info.log", "INFO", token, result.Version.JobId, result.Version.Version, baseURL, sendRequest)

						cmd.Stderr = stdout
						cmd.Stdout = stdout

						defer stdout.Close()

						err = cmd.Start()

						if err != nil {
							fail(err)
							return
						}

						err = cmd.Wait()

						if err != nil {
							log.Println(workdir + "/run.sh")
							fail(err)
							return
						}

						var r = job.JobVersionOKTaskResult{}

						request(sendRequest, baseURL+"job/slave/ok", time.Second, map[string]interface{}{
							"token":   token,
							"jobId":   fmt.Sprintf("%d", result.Version.JobId),
							"version": fmt.Sprintf("%d", result.Version.Version)}, &r)

						writeLogFile("INFO", "EXIT", name+"info.log")

						exit()
					})

					kk.GetDispatchMain().Async(func() {

						if len(process) < processCount {
							go jobProcess()
						}

					})

					return
				}

				var fail = job.JobVersionFailTaskResult{}

				request(sendRequest, baseURL+"job/slave/fail", time.Second, map[string]interface{}{
					"token":   token,
					"jobId":   fmt.Sprintf("%d", result.Version.JobId),
					"version": fmt.Sprintf("%d", result.Version.Version)}, &fail)

				log.Printf("[FAIL] jobId:%d version:%d %s\n", result.Version.JobId, result.Version.Version)

				kk.GetDispatchMain().AsyncDelay(func() {
					go jobProcess()
				}, time.Second*6)

			} else {
				kk.GetDispatchMain().AsyncDelay(func() {
					go jobProcess()
				}, time.Second*6)
			}

		} else {

			log.Println(result.Errmsg)

			kk.GetDispatchMain().AsyncDelay(func() {
				go jobProcess()
			}, time.Second*6)
		}
	}

	kk.GetDispatchMain().AsyncDelay(func() {

		go func() {

			var result = job.JobSlaveLoginTask{}

			var err = request(sendRequest, baseURL+"job/slave/login", time.Second, map[string]interface{}{"token": token}, &result)

			if err != nil {

				log.Println("[FAIL] " + err.Error())

				kk.GetDispatchMain().Break()

				return
			}

			go online()

			go jobProcess()

		}()

	}, time.Second)

	kk.DispatchMain()

	for _, v := range process {
		v.Break()
	}

	log.Println("[EXIT]")

}
<|endoftext|>


<commit_before>package datasync

import (
	"github.com/golang/protobuf/proto"
)

// ChangeEvent is used as the data type for the change channel
// (see the VPP Standard Plugins API). A data change event contains
// a key identifying where the change happened and two values for
// data stored under that key: the value *before* the change (previous
// value) and the value *after* the change (current value).
type ChangeEvent interface {
	CallbackResult

	ProtoWatchResp
}

// ResyncEvent is used as the data type for the resync channel
// (see the ifplugin API)
type ResyncEvent interface {
	CallbackResult

	GetValues() map[ /*keyPrefix*/ string]KeyValIterator
}

// CallbackResult can be used by an event receiver to indicate to the event producer
// whether an operation was successful (error is nil) or unsuccessful (error is
// not nil)
//
// DoneMethod is reused later. There are at least two implementations DoneChannel, DoneCallback
type CallbackResult interface {
	// Done allows plugins that are processing data change/resync to send feedback
	// If there was no error the Done(nil) needs to be called. Use the noError=nil
	// definition for better readability, for example:
	//     Done(noError).
	Done(error)
}

// ProtoWatchResp contains changed value
type ProtoWatchResp interface {
	ChangeValue
	WithKey
	WithPrevValue
}

// ChangeValue represents single propagated change.
type ChangeValue interface {
	LazyValueWithRev
	WithChangeType
}

// LazyValueWithRev defines value that is unmarshalled into proto message on demand with a revision.
// The reason for defining interface with only one method is primary to unify interfaces in this package
type LazyValueWithRev interface {
	LazyValue
	WithRevision
}

// WithKey is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithKey interface {
	// GetKey returns the key of the pair
	GetKey() string
}

// WithKey is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithChangeType interface {
	GetChangeType() PutDel
}

// WithRevision is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithRevision interface {
	// GetRevision gets revision of current value
	GetRevision() (rev int64)
}

// WithPrevValue is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithPrevValue interface {
	// GetPrevValue gets previous value in the data change event.
	// The caller must provide an address of a proto message buffer
	// for each value.
	// returns:
	// - prevValueExist flag is set to 'true' if prevValue was filled
	// - error if value argument can not be properly filled
	GetPrevValue(prevValue proto.Message) (prevValueExist bool, err error)
}

// LazyValue defines value that is unmarshalled into proto message on demand.
// The reason for defining interface with only one method is primary to unify interfaces in this package
type LazyValue interface {
	// GetValue gets the current in the data change event.
	// The caller must provide an address of a proto message buffer
	// for each value.
	// returns:
	// - revision associated with the latest change in the key-value pair
	// - error if value argument can not be properly filled
	GetValue(value proto.Message) error
}
<commit_msg> ODPM-361 fix golint WithChangeType comment<commit_after>package datasync

import (
	"github.com/golang/protobuf/proto"
)

// ChangeEvent is used as the data type for the change channel
// (see the VPP Standard Plugins API). A data change event contains
// a key identifying where the change happened and two values for
// data stored under that key: the value *before* the change (previous
// value) and the value *after* the change (current value).
type ChangeEvent interface {
	CallbackResult

	ProtoWatchResp
}

// ResyncEvent is used as the data type for the resync channel
// (see the ifplugin API)
type ResyncEvent interface {
	CallbackResult

	GetValues() map[ /*keyPrefix*/ string]KeyValIterator
}

// CallbackResult can be used by an event receiver to indicate to the event producer
// whether an operation was successful (error is nil) or unsuccessful (error is
// not nil)
//
// DoneMethod is reused later. There are at least two implementations DoneChannel, DoneCallback
type CallbackResult interface {
	// Done allows plugins that are processing data change/resync to send feedback
	// If there was no error the Done(nil) needs to be called. Use the noError=nil
	// definition for better readability, for example:
	//     Done(noError).
	Done(error)
}

// ProtoWatchResp contains changed value
type ProtoWatchResp interface {
	ChangeValue
	WithKey
	WithPrevValue
}

// ChangeValue represents single propagated change.
type ChangeValue interface {
	LazyValueWithRev
	WithChangeType
}

// LazyValueWithRev defines value that is unmarshalled into proto message on demand with a revision.
// The reason for defining interface with only one method is primary to unify interfaces in this package
type LazyValueWithRev interface {
	LazyValue
	WithRevision
}

// WithKey is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithKey interface {
	// GetKey returns the key of the pair
	GetKey() string
}

// WithChangeType is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithChangeType interface {
	GetChangeType() PutDel
}

// WithRevision is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithRevision interface {
	// GetRevision gets revision of current value
	GetRevision() (rev int64)
}

// WithPrevValue is a helper interface which intent is to ensure that same
// method declaration is used in different interfaces (composition of interfaces)
type WithPrevValue interface {
	// GetPrevValue gets previous value in the data change event.
	// The caller must provide an address of a proto message buffer
	// for each value.
	// returns:
	// - prevValueExist flag is set to 'true' if prevValue was filled
	// - error if value argument can not be properly filled
	GetPrevValue(prevValue proto.Message) (prevValueExist bool, err error)
}

// LazyValue defines value that is unmarshalled into proto message on demand.
// The reason for defining interface with only one method is primary to unify interfaces in this package
type LazyValue interface {
	// GetValue gets the current in the data change event.
	// The caller must provide an address of a proto message buffer
	// for each value.
	// returns:
	// - revision associated with the latest change in the key-value pair
	// - error if value argument can not be properly filled
	GetValue(value proto.Message) error
}
<|endoftext|>