Switch branches/tags
Nothing to show
Clone or download
Latest commit bde4cbc Mar 20, 2017
Permalink
Failed to load latest commit information.
LICENSE update Nov 16, 2016
README.md upd Mar 21, 2017
gophers.jpg header Jan 22, 2016
tips32.md update Mar 22, 2016
tips64.md upd Jan 20, 2017

README.md

header

Golang short tips & tricks

This list of short golang code tips & tricks will help keep collected knowledge in one place.

Support the project

Send some ether 0x30FD8822D15081F3c98e6A37264F8dF37a2EB416

Tips list

#70 - distributed protocols

2017-03-15 by @beyondns

Distributed protocol can be divided into two parts: serve incommin' requests (passive), make outgoin' requests (active)

#69 - sql more productive

2017-03-06 by @beyondns

#68 - go1.8 features

2017-02-17 by @beyondns

package main

import (
	"log"
	"io"
	"os"
	"os/signal"
	"net/http"
	"context"
	"golang.org/x/net/http2"
)

type handl struct{}

func (*handl) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	log.Printf("%v",r.URL)
	io.WriteString(w, "Hello")
		if p, ok := w.(http.Pusher); ok {
			p.Push("/static/1.jpg", nil)
		}	
}
func main() {
	quit := make(chan os.Signal)
	signal.Notify(quit, os.Interrupt)

	srv := &http.Server{Addr: ":8080", Handler: &handl{}}

	go func() {
		<-quit
		err := srv.Shutdown(context.Background())
		if err != nil {
			log.Fatal(err)
		}
	}()

	http2.ConfigureServer(srv, nil)

// openssl req -x509 -newkey rsa:2048 -nodes -keyout srv.key -out srv.cert -days 365
	err := srv.ListenAndServeTLS("srv.cert", "srv.key")
	if err != nil {
		log.Fatal(err)
	}

}
// js client
var http2 = require('http2');

http2.globalAgent = new http2.Agent({
  rejectUnauthorized: false
});

var request = http2.get('https://localhost:8080/');

request.on('response', function(response) {
  response.pipe(process.stdout);
});

request.on('push', function(pushRequest) {
  console.log('Receiving pushed resource: ' + pushRequest.url);
  pushRequest.on('response', function(pushResponse) {
    console.dir('Receiving pushed response: ' + pushResponse);
  });
});

#67 - microservices

2017-01-31 by @beyondns

It's an approach to handle complexity

#66 - json rpc over any transport

2017-01-31 by @beyondns

package main

import (
	"encoding/json"
	"errors"
	"fmt"	
	"log"
)

const transpostJSON = `
{
"version": "0.1", 
"id": "1234567", 
"method": "transpost", 
"params": {
	"data":{
		"timestamp":"2017-01-20T15:50:41.163Z"
	},
	"hash":"acfd55c995be410bbda4ee78f921608db42b3c10a5f44a1a5d15b1c0a7138e0e",
	"signs": [
  	{
   		"pub": "03ab4b14fe08f81e56af1d731f6c22c0a860c2c3c9c7b91d9c190aa602cf97f668",
   		"sign": "bfb7fc15f336b802310d9c38288ecacc0c5fadda31a564c120e63e6ee5a4d8ae5beaaeae75007d1fac97e77520087f86823f98a25b2f3be51eac47fec862c2ee",
   		"date": "2017-01-31T18:38:24.057Z"
  	}
 	]
}
}
`

type (

	RemoteRequest struct {
		Version string          `json:"version"`
		Id      string          `json:"id,omitempty"`
		Method  string          `json:"method"`
		Params  json.RawMessage `json:"params,omitempty"`
	}

	Transaction struct {
		Data  TransData `json:"data"`
		Hash  string       `json:"hash"`
		Signs []TransSign     `json:"signs"`
	}
	TransData struct {
		Timestamp string `json:"timestamp"`
	}
	TransSign struct {
		Pub  string `json:"pub"`
		Sign string `json:"sign"`
		Date string `json:"date"`
	}

	RemoteResponse struct {
		Version string `json:"version"`
		Id      string `json:"id,omitempty"`
		Status  string `json:"status"`
	}
)


func processTransPost(data []byte) ([]byte, error) {
	tx:=&Transaction{}
	err := json.Unmarshal(data, tx)
	if err != nil {
		log.Printf("json.Unmarshal %v", err)
		return nil, err
	}
	log.Printf("tx:%v",tx)
	return []byte(`{"status":"ok"}`), nil
}

func processTransVerify(data []byte) ([]byte, error) {
	return nil, errors.New("processTransVerify not implemented")
}

func processHeartBeat(data []byte) ([]byte, error) {
	return nil, errors.New("processHeartBeat not implemented")
}

func processRemote(data []byte) ([]byte, error) {
	req := &RemoteRequest{}
	err := json.Unmarshal(data, req)
	if err != nil {
		log.Printf("json.Unmarshal %v", err)
		return nil, err
	}
	switch req.Method {
	case "transpost":
		return processTransPost(req.Params)
	case "transverify":
		return processTransVerify(req.Params)
	case "heartbeat":
		return processHeartBeat(req.Params)
	}

	return nil, errors.New(fmt.Sprintf("unknown method %s", req.Method))
}

func main() {

	bin, err := processRemote([]byte(transpostJSON))
	if err != nil {
		log.Fatal(err)
	}

	log.Printf(string(bin))
}

#65 - grpc

2017-01-26 by @beyondns

syntax = "proto3";

package remote;

service Inter {
  rpc HandShake (HandShakeData) returns (HandShakeResult) {}
}

message HandShakeData {
  int32 no = 1;
  string query = 2;
}

message HandShakeResult {
  int32 no = 1;
  string res = 2;
}
package main

import (
	"flag"
	"log"
	"net"
	"strings"

	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
	pb "./remote"
)

// go get google.golang.org/grpc
// go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
// protoc -I ./remote/ ./remote/rem.proto  --go_out=plugins=grpc:remote

type server struct{
	host *string
}

func (s *server) HandShake(ctx context.Context, in *pb.HandShakeData) (*pb.HandShakeResult, error) {
	log.Printf("HandShake %v", in)
	res := &pb.HandShakeResult{
		Res: fmt.Sprintf("Response from %s to query %s" + s.host,in.Query),
	}
	return res, nil
}

// ./node -host 127.0.0.1:50051
// ./node -host 127.0.0.1:50052

func main() {
	host := flag.String("host", "127.0.0.1:50051", "host host:port")
	nodes := flag.String("nodes", "127.0.0.1:50051,127.0.0.1:50052,127.0.0.1:50053",
		"[host:port,host:port,...]")

	flag.Parse()

	go func() {
		lis, err := net.Listen("tcp", *host)
		if err != nil {
			log.Fatalf("failed to listen: %v", err)
		}
		s := grpc.NewServer()
		pb.RegisterInterServer(s, &server{host:host})
		reflection.Register(s)
		log.Printf("Serve...")
		if err := s.Serve(lis); err != nil {
			log.Fatalf("failed to serve: %v", err)
		}
	}()

	for _, n := range strings.Split(*nodes, ",") {
		if n != *host {
			go func(n string) {

				conn, err := grpc.Dial(n, grpc.WithInsecure())
				if err != nil {
					log.Printf("did not connect:%s %v", n, err)
					return
				}
				defer conn.Close()
				c := pb.NewInterClient(conn)

				r, err := c.HandShake(context.Background(), 
					&pb.HandShakeData{No: 1, Query: "hello"})
				if err != nil {
					log.Printf("could not HandShake: %v", err)
					return
				}
				log.Printf("HandShake:%s %s", n, r.Res)

			}(n)
		}
	}

	select {}
}

#64 - go vs rust

2017-01-20 by @beyondns

gotips#32..#63
gotips #0..#31

General Golang links

Inspired by

License

CC0