lookup_peer.go
package nsqd
import (
"encoding/binary"
"fmt"
"io"
"net"
"time"
"github.com/nsqio/go-nsq"
)
// lookupPeer is a low-level type for connecting/reading/writing to nsqlookupd
//
// A lookupPeer instance is designed to connect lazily to nsqlookupd and reconnect
// gracefully (i.e. it is all handled by the library). Clients can simply use the
// Command interface to perform a round-trip.
type lookupPeer struct {
l Logger
addr string
conn net.Conn
state int32
connectCallback func(*lookupPeer)
maxBodySize int64
Info peerInfo
}
// peerInfo contains metadata for a lookupPeer instance (and is JSON marshalable)
type peerInfo struct {
TCPPort int `json:"tcp_port"`
HTTPPort int `json:"http_port"`
Version string `json:"version"`
BroadcastAddress string `json:"broadcast_address"`
}
// newLookupPeer creates a new lookupPeer instance connecting to the supplied address.
//
// The supplied connectCallback will be called *every* time the instance connects.
func newLookupPeer(addr string, maxBodySize int64, l Logger, connectCallback func(*lookupPeer)) *lookupPeer {
return &lookupPeer{
l: l,
addr: addr,
state: stateDisconnected,
maxBodySize: maxBodySize,
connectCallback: connectCallback,
}
}
// Connect will Dial the specified address, with timeouts
func (lp *lookupPeer) Connect() error {
lp.l.Output(2, fmt.Sprintf("LOOKUP connecting to %s", lp.addr))
conn, err := net.DialTimeout("tcp", lp.addr, time.Second)
if err != nil {
return err
}
lp.conn = conn
return nil
}
// String returns the specified address
func (lp *lookupPeer) String() string {
return lp.addr
}
// Read implements the io.Reader interface, adding deadlines
func (lp *lookupPeer) Read(data []byte) (int, error) {
lp.conn.SetReadDeadline(time.Now().Add(time.Second))
return lp.conn.Read(data)
}
// Write implements the io.Writer interface, adding deadlines
func (lp *lookupPeer) Write(data []byte) (int, error) {
lp.conn.SetWriteDeadline(time.Now().Add(time.Second))
return lp.conn.Write(data)
}
// Close implements the io.Closer interface
func (lp *lookupPeer) Close() error {
lp.state = stateDisconnected
if lp.conn != nil {
return lp.conn.Close()
}
return nil
}
// Command performs a round-trip for the specified Command.
//
// It will lazily connect to nsqlookupd and gracefully handle
// reconnecting in the event of a failure.
//
// It returns the response from nsqlookupd as []byte
func (lp *lookupPeer) Command(cmd *nsq.Command) ([]byte, error) {
initialState := lp.state
if lp.state != stateConnected {
err := lp.Connect()
if err != nil {
return nil, err
}
lp.state = stateConnected
lp.Write(nsq.MagicV1)
if initialState == stateDisconnected {
lp.connectCallback(lp)
}
}
if cmd == nil {
return nil, nil
}
_, err := cmd.WriteTo(lp)
if err != nil {
lp.Close()
return nil, err
}
resp, err := readResponseBounded(lp, lp.maxBodySize)
if err != nil {
lp.Close()
return nil, err
}
return resp, nil
}
func readResponseBounded(r io.Reader, limit int64) ([]byte, error) {
var msgSize int32
// message size
err := binary.Read(r, binary.BigEndian, &msgSize)
if err != nil {
return nil, err
}
if int64(msgSize) > limit {
return nil, fmt.Errorf("response body size (%d) is greater than limit (%d)",
msgSize, limit)
}
// message binary data
buf := make([]byte, msgSize)
_, err = io.ReadFull(r, buf)
if err != nil {
return nil, err
}
return buf, nil
}
lookup_peer.go的更多相关文章
随机推荐
- 我的sql数据库存储过程分页- -
以前用到数据库存储过程分页的时候都是用 not in 但是最近工作的时候,随着数据库记录的不断增大,发现not in的效率 真的不行 虽然都设置了索引,但是当记录达到10w的时候就发现不行了,都是需要 ...
- Oracle面试过程中常见的二十个问题
1.冷备份和热备份的不同点以及各自的优点 解答:热备份针对归档模式的数据库,在数据库仍旧处于工作状态时进行备份.而冷备份指在数据库关闭后,进行备份,适用于所有模式的数据库.热备份的优点在于当备份时, ...
- VS2017安装包不占用C盘空间的方法,亲试
问题:普通VS2017的安装方式,不论是在线安装还是下载的离线安装包,都会在安装过程中将安装包保存在C:\ProgramData\Microsoft\VisualStudio\Packages文件夹下 ...
- 使用swagger管理接口
swagger 配置 1.pom 增加jar包依赖 <dependency> <groupId>io.springfox</groupId> <artifac ...
- GitHub awesome Resource
各种Awesome技术资源的资源聚合: https://github.com/sindresorhus/awesome Contents Platforms Programming Languages ...
- 当今商业中使用的三种十分重要的IT应用系统
本文为读书笔记,其中内容摘自<信息时代的管理信息系统>第八版第二章 当今商业中使用的三种十分重要的IT应用系统: 供应链管理(SCM) 客户关系管理(CRM) 电子协同(e-collabo ...
- clear read-only status问题的解决
IDEA系工具可能会报出的错误. 解决方法见官方文档吧:Changing Read-Only Status of Files : https://www.jetbrains.com/help/ide ...
- hadoop环境运行程序出现 Retrying connect to server 问题
程序运行时出现如下问题: 从网上查资料,有说重启format的..有说/etc/hosts出问题的... 反正都试了一遍..还是有这个问题 后来看日志,发现问题是访问服务器9001端口访问不到..开始 ...
- 纯CSS炫酷的3D旋转
<html><head><meta charset="utf-8"><title>纯CSS炫酷的3D旋转</title> ...
- Pygame常用方法
'''import pygame# 初始化pygame库,让计算机硬件准备pygame.init()# ----------窗口相关操作-----------# 创建窗口window = pygame ...