• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

go 安全通道(缓存器)缓存池 io.Reader error类

原作者: [db:作者] 来自: [db:来源] 收藏 邀请
  •  向一个已经关闭的通道发送值和关闭一个已经关闭的通道,

都会引发运行时候的恐慌,缓冲器就是解决这个问题诞生的。
Put 方法先检查缓冲器实例是否关闭,并且保证只有在检查结果是否的时候
进行存入。,在Close 方法中仅在当前缓冲器实例未关闭的情况下
进行关闭操作

package buffer

import (
	"sync"
	"sync/atomic"
)

import (
	"fmt"
	"gopcp.v2/chapter6/webcrawler/toolkit/buffer"
	"sync"
)

/***
向一个已经关闭的通道发送值和关闭一个已经关闭的通道,
都会引发运行时候的恐慌,缓冲器就是解决这个问题诞生的。
Put 方法先检查缓冲器实例是否关闭,并且保证只有在检查结果是否的时候
进行存入。,在Close 方法中仅在当前缓冲器实例未关闭的情况下
进行关闭操作
 */
// Buffer 代表FIFO的缓冲器的接口类型。
type Buffer interface {
	// Cap 用于获取本缓冲器的容量。
	Cap() uint32
	// Len 用于获取本缓冲器中的数据数量。
	Len() uint32
	// Put 用于向缓冲器放入数据。
	// 注意!本方法应该是非阻塞的。
	// 若缓冲器已关闭则会直接返回非nil的错误值。
	Put(datum interface{}) (bool, error)
	// Get 用于从缓冲器获取器。
	// 注意!本方法应该是非阻塞的。
	// 若缓冲器已关闭则会直接返回非nil的错误值。
	Get() (interface{}, error)
	// Close 用于关闭缓冲器。
	// 若缓冲器之前已关闭则返回false,否则返回true。
	Close() bool
	// Closed 用于判断缓冲器是否已关闭。
	Closed() bool
}

type myBuffer struct {
	//ch 代表采访数据的通道
	ch chan interface{}
	//closed 代表缓冲器的关闭状态
	closed uint32
	//closingLock 代表为了消除因关闭缓冲器而产生的竟态条件的读写锁
	closingLock sync.RWMutex
}

func NewBuffer(size uint32)(Buffer, error){
	if size==0 {
		errMsg := fmt.Sprintf(" illegal size for buffer:%d",size)
		return nil, error.NewIllegalParameterError(errMsg)
	}

	return &myBuffer{
		ch : make(chan interface{},size),
	},nil
}

func (buf *myBuffer) Cap() uint32 {
	return uint32(cap(buf.ch))
}

func (buf *myBuffer) Len() uint32 {
	return uint32(len(buf.ch))
}

func (buf *myBuffer) Put (datum interface{}) (ok bool,err error){
		buf.closingLock.RLock()
		defer buf.closingLock.Unlock()

		if buf.Closed() {
			return false,ErrClosedBuffer
		}

		select {
		case buf.ch <- datum:
			ok = true
		default:
			ok = false
		}

		return
}

func (buf *myBuffer) Get() (interface{}, error) {
	select {
	case datum, ok := <-buf.ch:
		if !ok {
			return nil, ErrClosedBuffer
		}
		return datum, nil
	default:
		return nil, nil
	}
}

func (buf *myBuffer)Close() bool {
	if atomic.CompareAndSwapUint32(&buf.closed,0,1){
		buf.closingLock.Lock()
		close(buf.ch)
		buf.closingLock.Unlock()
		return true
	}

	return false
}
  • io.Reader 

io.Reader 实现类型:bytes.Reader  bufio.Reader  ,这类读取器只能够读取他们底层的一遍数据,当读完数据后,他们的Read 方法总会把io.EOF 变量的值做为错误值返回。net/http 中的 http.Reaponse 类型的body 就是 io.Readcloser接口类型的,io.Readcloser的类型声明嵌入了io.Reader,前者只比后者多一个Close的方法。   

  • 错误类
package errors

import (
	"bytes"
	"fmt"
	"strings"
)

type ErrorType string

const (
	// ERROR_TYPE_DOWNLOADER 代表下载器错误。
	ERROR_TYPE_DOWNLOADER ErrorType = "downloader error"
	// ERROR_TYPE_ANALYZER 代表分析器错误。
	ERROR_TYPE_ANALYZER ErrorType = "analyzer error"
	// ERROR_TYPE_PIPELINE 代表条目处理管道错误。
	ERROR_TYPE_PIPELINE ErrorType = "pipeline error"
	// ERROR_TYPE_SCHEDULER 代表调度器错误。
	ERROR_TYPE_SCHEDULER ErrorType = "scheduler error"
)

type CrawlerError interface {
	Type() ErrorType
	error() string
}

type myCrawlerError struct{
	errType ErrorType
	errMsg  string
	fullErrMsg string
}

// NewCrawlerError 用于创建一个新的爬虫错误值。
func NewCrawlerError(errType ErrorType, errMsg string) CrawlerError {
	return &myCrawlerError{
		errType: errType,
		errMsg:  strings.TrimSpace(errMsg),
	}
}

// NewCrawlerErrorBy 用于根据给定的错误值创建一个新的爬虫错误值。
func NewCrawlerErrorBy(errType ErrorType, err error) CrawlerError {
	return NewCrawlerError(errType, err.Error())
}

func (ce *myCrawlerError) Type() ErrorType {
	return ce.errType
}

func (ce *myCrawlerError) Error() string {
	if ce.fullErrMsg == "" {
		ce.genFullErrMsg()
	}
	return ce.fullErrMsg
}

func (ce *myCrawlerError) getFullErrMsg() {
	var buffer bytes.Buffer

	buffer.WriteString("crawler error:")
	if ce.errType!="" {
		buffer.WriteString(string(ce.errType))
		buffer.WriteString(":")
	}

	buffer.WriteString(ce.errMsg)
	ce.fullErrMsg =fmt.Sprintf("%s",buffer.String())
	return
}

// IllegalParameterError 代表非法的参数的错误类型。
type IllegalParameterError struct {
	msg string
}

// NewIllegalParameterError 会创建一个IllegalParameterError类型的实例。
func NewIllegalParameterError(errMsg string) IllegalParameterError {
	return IllegalParameterError{
		msg: fmt.Sprintf("illegal parameter: %s",
			strings.TrimSpace(errMsg)),
	}
}

func (ipe IllegalParameterError) Error() string {
	return ipe.msg
}

 

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
Super Head Go-puzzle of colors Technical support发布时间:2022-07-10
下一篇:
freetype-go学习发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap