Skip to content

vs4vijay/vizix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

63 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

vizix

Release Go Report Card Maintainability

Getting Started

go get github.com/vs4vijay/vizix

OR (Via Homebrew)

brew install vs4vijay/vizix/vizix

OF (Via Installer Script)

curl -fsSL https://raw.githubusercontent.com/vs4vijay/vizix/vizix/scripts/install.sh | bash

Development

go run main.go

Guidelines


Commands

~/go/bin/cobra init --pkg-name github.com/vs4vijay/vizix

go mod init github.com/vs4vijay/vizix

go build

~/go/bin/cobra add list

createCmd.MarkFlagRequired("secret")

Logging

log.SetFormatter(&log.TextFormatter{ForceColors: true})
log.SetOutput(colorable.NewColorableStdout())
  • Log Verbosity: cmd.PersistentFlags().CountVarP(&verbosity, "verbosity", "v", "set verbosity")

Linting

  • gofmt
  • goimports
  • golint
  • go vet

Makefile

tools:
	go get golang.org/x/tools/cmd/goimports
	go get github.com/kisielk/errcheck
	go get github.com/golang/lint/golint
	go get github.com/axw/gocov/gocov
	go get github.com/matm/gocov-html
	go get github.com/tools/godep
	go get github.com/mitchellh/gox

- `make test-lint`: runs linter/style checks
- `make test-unit`: runs basic unit tests
- `make test`: runs all of the above

I/O

s := bufio.Scanner(os.Stdin)
s.Scan()

// OR

scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
  break
}
if err := scanner.Err(); err != nil {
  panic(err)
}

// OR

serverData, err := bufio.NewReader(connection).ReadString('\n')

JSON / Marshalling / Un-marshalling

// Marshalling 1
j, err := json.Marshal(p)

// Marshalling 2
json.NewEncoder(writer).Encode(todos)

// Un-marshalling 1
body := make(map[string]interface{})
bodyBytes, _ := ioutil.ReadAll(request.Body)
err := json.Unmarshal(bodyBytes, &body)

// Un-marshalling 2
body := make(map[string]interface{})
err := json.NewDecoder(request.Body).Decode(&body)

// Make HTTP Call

payloadBytes, err := json.Marshal(payload)
if err != nil {
    return nil, err
}

client = &http.Client{
	Timeout: 10 * time.Second,
}
request, err := http.NewRequest(method, url, bytes.NewBuffer(payloadBytes))

request.Header.Add(echo.HeaderContentType, echo.MIMEApplicationJSON)
request.Header.Add("Authorization", "Bearer " + apiKey)
response, err := client.Do(request)
if err != nil {
    return nil, err
}

defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
    return nil, err
}

string(body)

// Convert Payload - I
values := map[string]string{"username": username, "password": password}
dataBytes, _ := json.Marshal(values)
resp, err := http.Post(authAuthenticatorUrl, "application/json", bytes.NewBuffer(dataBytes))

// Convert Payload - II, Mainly for Streaming
buf := new(bytes.Buffer)
json.NewEncoder(buf).Encode(body)
resp, err := http.Post(authAuthenticatorUrl, "application/json", buf)


// Ready Body
body, err := ioutil.ReadAll(resp.Body)

// Read Body to Object
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)

Channels

bye := make(chan os.Signal, 1)
signal.Notify(bye, os.Interrupt, syscall.SIGTERM)
<-bye

WaitGroups

var wg sync.WaitGroup

wg.Add(1)
wg.Done()

wg.Wait()

Signals

  • signal.Notify(s1, syscall.SIGWINCH)
  • signal.Ignore(syscall.SIGINT)
  • signal.Stop(s1)
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)

signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

go func() {
    sig := <-sigs
    fmt.Println(sig)
    done <- true
}()

fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")

Timers and Tickers

// Timer
timer := time.NewTimer(2 * time.Second)
<-timer.C
fmt.Println("Timer 1 fired")


// Ticker
ticker := time.NewTicker(2 * time.Second)
done := make(chan bool)

go func() {
    for {
        select {
        case <-done:
            return
        case t := <-ticker.C:
            fmt.Println("Tick at", t)
        }
    }
}()

time.Sleep(10 * time.Second)
ticker.Stop()
done <- true
fmt.Println("Ticker stopped")

Context

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
OR
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()

// Example 2

ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)

go func() {
    s := bufio.Scanner(os.Stdin)
    s.Scan()
    cancel()
}()

// Example 3
time.AfterFunc(time.Second, cancel)

// OR
ctx := context.Background()
ctx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel() // "deadline exceeded", but "cancel()" will cancel

// viz
func viz(ctx context.Context, d time.Duration, msg string) {
    select {
    case <- time.After(d):
        fmt.Println(msg)
    case <- ctx.Done()
        fmt.Errorf(ctx.Err())
    }
}

Mutex

var mutex *sync.Mutex

users.mutex.Lock()
defer users.mutex.Unlock()
append(users, user)

Testing

  • Table Testing

System Exec

binary, lookErr := exec.LookPath("ls")

// Spawing
out, err := exec.Command("ls").Output()


// Using Syscall
args := []string{"ls", "-a", "-l", "-h"}
env := os.Environ()
execErr := syscall.Exec(binary, args, env)

OS Detection:

  • runtime.GOOS == "windows"

APIs

  • net/http - Native Implementation
  • chi - lightweight, compatible net.Http
  • mux -
  • gin -
  • iris -
  • echo -
  • beego

Using net/http:

// Option-I:

func someFunc(w http.ResponseWriter, r *http.Request) {
    w.write([]byte("Hey"))
    // fmt.Fprintln(w, "Hey")
}

http.HandleFunc("/", someFunc)
http.ListenAndServe(address, nil)

// Option-II:

http.Handle("/", server)
http.ListenAndServe(address, nil)
  • server should have Handler interface, which should have ServeHTTP method

Using Mux:

router := mux.NewRouter()
router.HandleFunc("/", Index)
http.ListenAndServe(address, router)
  • To get params - mux.Vars(request)

Graceful Shutdown

// Trap sigterm or interrupt to gracefully shutdown the server
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt)
signal.Notify(sigChan, os.Kill)

// Block until a signal is received.
sig := <-sigChan
logger.Printf("Got signal: %v, shutting down the server\n", sig)

// gracefully shutdown the server, waiting max 30 seconds for current operations to complete
ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)
srv.Shutdown(ctx)

// OR

quit := make(chan os.Signal)
signal.Notify(quit, os.Interrupt)
<-quit

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
if err := e.Shutdown(ctx); err != nil {
		e.Logger.Fatal(err)
	}
}

Bash:

yell() { echo "FAILED> $*" >&2; }
die() { yell "$*"; exit 1; }
try() { "$@" || die "failed executing: $*"; }
log() { echo "--> $*"; }

Dockerization:

docker build -t vs4vijay/vizix .
docker run vs4vijay/vizix
  • Cleanup:
docker container prune
docker image prune
docker network prune
docker volume prune
  • List Dangling Images: docker images -f dangling=true
    • docker rmi $(docker images --filter "dangling=true" -q --no-trunc)
  • Remove Volumes of Dangling Images: docker volume rm $(docker volume ls -qf dangling=true)
  • Remove Containers: docker rm $(docker ps -qa --no-trunc --filter "status=exited")
  • Remove Everything: docker system prune -a --volumes
  • Kill All Running Containers: docker kill $(docker ps -q)

Build Binary

  • Build Tags: // +build pro
  • go build -tags pro

Distribute Binaries

  • Manual Build
GOOS=darwin GOARCH=amd64 go build
GOOS=linux GOARCH=amd64 go build
GOOS=windows GOARCH=386 go build
  • Git tags

    • Create Tag: git tag -a v0.0.0 -m "Initial release"
    • Push Tag: git push origin v0.0.0
    • Delete Tag: git push origin :v0.0.1
  • Go Releaser

    • brew install goreleaser/tap/goreleaser
    • goreleaser init
    • Test: goreleaser --snapshot --skip-publish --rm-dist
    • Release: goreleaser --rm-dist
    • CI/CD with Github Actions:
name: Release

on:
  push:
    tags:
      - "v*.*.*"

jobs:
  goreleaser:
    runs-on: ubuntu-latest
    steps:
      -
        name: Checkout
        uses: actions/checkout@v2
      -
        name: Unshallow
        run: git fetch --prune --unshallow
      -
        name: Set up Go
        uses: actions/setup-go@v1
        with:
          go-version: 1.14.x
      -
        name: GoReleaser Action
        uses: goreleaser/goreleaser-action@v1.3.1
        with:
          version: latest
          args: release --rm-dist
        env:
          GITHUB_TOKEN: ${{ secrets.GORELEASER_TOKEN }}
brew install vizix
brew info vizix
brew reinstall vizix --force
brew update
brew upgrade vizix

Deployment


Badges

  • Release - ![Release](https://github.com/vs4vijay/vizix/workflows/Release/badge.svg)

3rd Party Integrations


Git Hooks

git config core.hooksPath .
  • commit - go mod tidy

Microservice Toolkits


Development Notes


GO111MODULE=on
GOPROXY=https://gocenter.io
CGO_ENABLED=0

GOARCH=wasm GOOS=js go build -o app.wasm

wget: wget -q -O - https://raw.githubusercontent.com/rancher/k3d/master/install.sh | TAG=v1.3.4 bash
curl: curl -s https://raw.githubusercontent.com/rancher/k3d/master/install.sh | TAG=v1.3.4 bash

curl -sfL https://get.k3s.io | sh -

go get github.com/labstack/echo/v4