go code 锦集

code

好的代码忍不住想记2笔。重点拿来即用

  1. 服务管理。服务启动按此套路来,初始化,启动,停止的轮廓感特强,借鉴nsqd。
package main

import (
	"github.com/judwhite/go-svc/svc"
	"github.com/rs/zerolog/log"
	"sync"
)

type program struct {
	once sync.Once
}
//服务未开始需要准备的工作
func (p *program) Init(env svc.Environment) error {
	return nil
}

//服务启动的业务代码入口
func (p *program) Start() error {
	return nil
}

//当你的服务进程被kill pid 的时候会触动Stop方法执行,stop执行完毕进程退出(当然kill -9 pid是不行的)
func (p *program) Stop() error {
    //once是避免多次kill发送过来停止信号
	p.once.Do(func() {
		
	})
	return nil
}



func main() {
	prg := &program{}
	if err := svc.Run(prg); err != nil {
	}
}

  1. 并发型却相互依赖goroutinu。任意一个协程error了,外围便知,亮点的code结构上干净利落的解耦,却又能轻易做到紧密通讯。nsqd使用此设计 控制http,tcp,https等服务启动到停止的生命周期。
package main

import (
	"sync"
)

type WaitGroupWrapper struct {
	sync.WaitGroup
}

func (w *WaitGroupWrapper) Wrap(cb func()) {
	w.Add(1)
	go func() {
		cb()
		w.Done()
	}()
}

func main(){
    w := WaitGroupWrapper{}
	exitCh := make(chan error)
	var once sync.Once
	exitFunc := func(err error) {
		once.Do(func() {
			if err != nil {
			   fmt.Println("自定义打印日志")
			}
			exitCh <- err
		})
	}
	//TCPServer,TCPServer(),HttpServer() 假装是一个个协程相互独立并行却同时正常才行的协程
	// 当然TCPServer,HttpServer需要保证 能被通讯到
	w.waitGroup.Wrap(func() {
		exitFunc(TCPServer())
	})

	w.waitGroup.Wrap(func() {
		exitFunc(HttpServer())
	})
	err := <-exitCh
	fmt.Println("err到说明存在服务err了,在此开始你的err错误处理逻辑,保证业务代码从上而下顺流而下")
	return
}

  1. 协程编排。让你能轻松设计出系列串行goroutinue,和并行goroutinue,其表现规则在代码结构层也清晰易懂,有异常捕获。

package main

import (
	"errors"
	"fmt"
	"runtime"
	"sync"
)



func try(fn func(), cleaner func()) (err error) {
	if cleaner != nil {
		defer cleaner()
	}
	defer func() {
		_, file, line, _ := runtime.Caller(2)
		if rErr := recover(); rErr != nil {
			if _, ok := rErr.(error); ok {
				err = errors.New(fmt.Sprintf("%s:%d,err:%v", file, line,rErr.(error)))
			} else {
				err = fmt.Errorf("%+v", rErr)
			}
		}
	}()

	fn()

	return nil
}


// Parallel 并发执行
func Parallel(fns ...func()) func() {
	var wg sync.WaitGroup
	return func() {
		wg.Add(len(fns))
		for _, fn := range fns {
			go try(fn, wg.Done)
		}
		wg.Wait()
	}
}

// Serial 串行
func Serial(fns ...func()) func() {
	return func() {
		for _, fn := range fns {
			fn()
		}
	}
}



func main() {


	serial1 := func() {
		fmt.Println("我是串行协程1")
	}

	parallels := Parallel(
		func(){
			fmt.Println("我是并行协程1,我得等到 serial1 里面的串行协程执行完毕后才能执行")
		},
		func(){
			fmt.Println("我是并行协程2,我得等到 serial1 里面的串行协程执行完毕后才能执行")
		},
	)

	serial4 := func() {
		fmt.Println("我是串行协程4,我得等到 Parallel 里面的2并发协程都执行完毕才能开始")
	}

	run :=Serial(serial1,parallels,serial4)
    //开跑
	run()
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值