package nsqd

import (
    "bytes"
    "encoding/binary"
    "fmt"
    "io"
    "time"
)

const (
    MsgIDLength       = 16
    minValidMsgLength = MsgIDLength + 8 + 2 // Timestamp + Attempts
)

type MessageID [MsgIDLength]byte

type Message struct {
    ID        MessageID
    Body      []byte
    Timestamp int64
    Attempts  uint16

    // for in-flight handling
    deliveryTS time.Time
    clientID   int64
    pri        int64
    index      int
    deferred   time.Duration
}

func NewMessage(id MessageID, body []byte) *Message {
    return &Message{
        ID:        id,
        Body:      body,
        Timestamp: time.Now().UnixNano(),
    }
}

func (m *Message) WriteTo(w io.Writer) (int64, error) {
    var buf [10]byte
    var total int64

    binary.BigEndian.PutUint64(buf[:8], uint64(m.Timestamp))
    binary.BigEndian.PutUint16(buf[8:10], uint16(m.Attempts))

    n, err := w.Write(buf[:])
    total += int64(n)
    if err != nil {
        return total, err
    }

    n, err = w.Write(m.ID[:])
    total += int64(n)
    if err != nil {
        return total, err
    }

    n, err = w.Write(m.Body)
    total += int64(n)
    if err != nil {
        return total, err
    }

    return total, nil
}

// decodeMessage deserializes data (as []byte) and creates a new Message
// message format:
// [x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x][x]...
// |       (int64)        ||    ||      (hex string encoded in ASCII)           || (binary)
// |       8-byte         ||    ||                 16-byte                      || N-byte
// ------------------------------------------------------------------------------------------...
//   nanosecond timestamp    ^^                   message ID                       message body
//                        (uint16)
//                         2-byte
//                        attempts
func decodeMessage(b []byte) (*Message, error) {
    var msg Message

    if len(b) < minValidMsgLength {
        return nil, fmt.Errorf("invalid message buffer size (%d)", len(b))
    }

    msg.Timestamp = int64(binary.BigEndian.Uint64(b[:8]))
    msg.Attempts = binary.BigEndian.Uint16(b[8:10])
    copy(msg.ID[:], b[10:10+MsgIDLength])
    msg.Body = b[10+MsgIDLength:]

    return &msg, nil
}

func writeMessageToBackend(buf *bytes.Buffer, msg *Message, bq BackendQueue) error {
    buf.Reset()
    _, err := msg.WriteTo(buf)
    if err != nil {
        return err
    }
    return bq.Put(buf.Bytes())
}

message.go的更多相关文章

  1. Eclipse 4.2 failed to start after TEE is installed

    ---------------  VM Arguments---------------  jvm_args: -Dosgi.requiredJavaVersion=1.6 -Dhelp.lucene ...

  2. ABP文档 - Javascript Api - Message

    本节内容: 显示信息 确认 Message API给用户显示一个信息,或从用户那里获取一个确认信息. Message API默认使用sweetalert实现,为使sweetalert正常工作,你应该包 ...

  3. 代码的坏味道(20)——过度耦合的消息链(Message Chains)

    坏味道--过度耦合的消息链(Message Chains) 特征 消息链的形式类似于:obj.getA().getB().getC(). 问题原因 如果你看到用户向一个对象请求另一个对象,然后再向后者 ...

  4. java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INSTANCE

    Android发出HTTP请求时出现了这个错误: java.lang.NoSuchFieldError: org.apache.http.message.BasicLineFormatter.INST ...

  5. POJ2774 Long Long Message [后缀数组]

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 29277   Accepted: 11 ...

  6. Android消息处理机制(Handler、Looper、MessageQueue与Message)

    Android是消息驱动的,实现消息驱动有几个要素: 消息的表示:Message 消息队列:MessageQueue 消息循环,用于循环取出消息进行处理:Looper 消息处理,消息循环从消息队列中取 ...

  7. Logstash时区、时间转换,message重组

    适用场景 获取日志本身时间 日志时间转Unix时间 重组message 示例日志: hellow@,@world@,@2011-11-01 18:46:43 logstash 配置文件: input{ ...

  8. Kafka消息时间戳(kafka message timestamp)

    最近碰到了消息时间戳的问题,于是花了一些功夫研究了一下,特此记录一下.   Kafka消息的时间戳 在消息中增加了一个时间戳字段和时间戳类型.目前支持的时间戳类型有两种: CreateTime 和 L ...

  9. infopath发布的提示“无法解析SOAP消息”(The SOAP message cannot be parsed)问题解决方案

    最近发现一个列表数据过大,每次发布infopath表单提示如下错误: 后来发现一个infopath表单通过list.asmx and Formsservice.asmx来进行发布的. This err ...

  10. 阶段一:用Handler和Message实现计时效果及其中一些疑问

    “阶段一”是指我第一次系统地学习Android开发.这主要是对我的学习过程作个记录. 本来是打算继续做天气预报的优化的,但因为某些原因,我要先把之前做的小应用优化一下.所以今天就插播一下用Handle ...

随机推荐

  1. 棋盘的完美覆盖问题,c++代码实现

    #include "stdafx.h" #include<iostream> #include<iomanip> using namespace std; ...

  2. spring boot + jersey工程由jar包转为war包在tomcat中启动报错问题

    第一步: 在maven下,将Spring Boot工程由jar转换为war包启动,很简单,将pom.xml文件中的packaging改为war <packaging>war</pac ...

  3. node_acl 路径通配

    最近做一个基于nodejs的权限管理,查阅了一两天,发现大致是这样的: passportjs node-oauth rbac node_acl express_acl connect-roles 需求 ...

  4. IT轮子系列(五)——MVC API 文件上传,总有一款是你需要的

    前言 在对外提供的接口时,也常常需要提供上传文件的.在这篇文章中会描述三种上传方式. 1.第一款,通过Base64字符上传——PostFromBase64Str 首先,定义上传数据模型.对于模型的定义 ...

  5. getElementById 用法的一个技巧

    假设实现把 TextBox1 的字符实时的拷贝到 TextBox2 中,代码如下: <Script language="Javascript">         fun ...

  6. 使用lombok的@Data @NoArgsConstructor @AllArgsConstructor @EqualsAndHashCode注解,编译时报错 找不到符号

    使用lombok添加@AllArgsConstructor后报错"错误:找不到符号 符号: 问题:未启用lombok注解 解决: settings->build->compile ...

  7. Java Selenium 定位元素 实现的一个注册功能

    import java.util.List; import java.util.concurrent.TimeUnit; import org.openqa.selenium.Alert; impor ...

  8. POP3和imap

    POP3 POP3是Post Office Protocol 3的简称,即邮局协议的第3个版本,是TCP/IP协议族中的一员(默认端口是110).本协议主要用于支持使用客户端远程管理在服务器上的电子邮 ...

  9. visio2010去除直线交叉处的歪曲

    Visio画图时,两根直线交叉时,总是默认会出现一个跨线的标志,在2007前的版本,可以通过以下方式解决: 选中线条,然后菜单的格式->行为->连接线->跨线->添加-> ...

  10. hadoop 2.x安装:完全分布式安装

    1. 安装环境 本文使用三台CentOS6.4虚拟机模拟完全分布式环境.前五个过程和hadoop1.x安装相同 1.1. 安装环境 项目 参数 主操作系统 Windows 10 64 bit,8GB内 ...