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. 恶补web之二:css知识(1)

    css指层叠样式表(Cascading Style Sheets)     样式定义如何显示html元素,样式通常存储在样式表里.把样式添加到html4.0中,是为了解决内容与表现分离的问题.外部样式 ...

  2. 【大前端攻城狮之路】JavaScript函数式编程

    转眼之间已入五月,自己毕业也马上有三年了.大学计算机系的同学大多都在北京混迹,大家为了升职加薪,娶媳妇买房,熬夜加班跟上线,出差pk脑残客户.同学聚会时有不少兄弟已经体重飙升,开始关注13号地铁线上铺 ...

  3. sort list(给链表排序)

    Sort a linked list in O(n log n) time using constant space complexity. 题目要求使用O(nlogn)时间复杂度,可以考虑使用归并排 ...

  4. 微信小程序中自定义函数的学习使用

    新手,最近在给学校搞个党费计算器.需要自己定义函数来实现某个功能. 1.无参函数: 函数都是写在js文件里面的. Page({ data:{ income1:'0', }, cal:function( ...

  5. for循环之后的return

    <C++primer>第五版中文版,201页: 在含有return语句的循环后面应该也有一条return语句,如果没有的话该程序就是错误的. 前几天编写一个函数,for循环查找某个值,找到 ...

  6. 帧同步(LockStep)该如何反外挂

    在中国的游戏环境下,反挂已经成为了游戏开发的重中之重,甚至能决定一款游戏的生死,吃鸡就是一个典型的案例.目前参与了了一款动作射击的MOBA类游戏的开发,同步方案上选择了帧同步技术(LockStep而非 ...

  7. 利用Python进行数据分析——pandas入门

    利用Python进行数据分析--pandas入门 基于NumPy建立的 from pandas importSeries,DataFrame,import pandas as pd 一.两种数据结构 ...

  8. Node六-模块化

    Node实现CommonJS规范 -因此node可以使用模块化的方式组织代码结构 简单命令行加减运算 -代码 命令行执行 V8对es6的支持 -直接支持:const.模版字符串等. -严格模式支持:l ...

  9. Oracle入门《Oracle介绍》第一章1-3 Oracle 逻辑组件

    一.数据库的逻辑结构是从逻辑的角度分析数据库的组成.Oracle 的逻辑组件包括: 1.表空间 表空间是数据库中最大的逻辑单位,一个 Oracle 数据库至少包含一个表空间,就是名为SYSTEM的系统 ...

  10. Linux的一些问题

    2. VMware11安装deepin15 实现文件共享和屏幕分辨率放大 要点:安装 open-vm-tools open-vm-tools-desktop open-vm-tools-dkms  这 ...