github.com/nsqio/nsq@v1.3.0/nsqd/message.go (about) 1 package nsqd 2 3 import ( 4 "encoding/binary" 5 "fmt" 6 "io" 7 "time" 8 ) 9 10 const ( 11 MsgIDLength = 16 12 minValidMsgLength = MsgIDLength + 8 + 2 // Timestamp + Attempts 13 ) 14 15 type MessageID [MsgIDLength]byte 16 17 type Message struct { 18 ID MessageID 19 Body []byte 20 Timestamp int64 21 Attempts uint16 22 23 // for in-flight handling 24 deliveryTS time.Time 25 clientID int64 26 pri int64 27 index int 28 deferred time.Duration 29 } 30 31 func NewMessage(id MessageID, body []byte) *Message { 32 return &Message{ 33 ID: id, 34 Body: body, 35 Timestamp: time.Now().UnixNano(), 36 } 37 } 38 39 func (m *Message) WriteTo(w io.Writer) (int64, error) { 40 var buf [10]byte 41 var total int64 42 43 binary.BigEndian.PutUint64(buf[:8], uint64(m.Timestamp)) 44 binary.BigEndian.PutUint16(buf[8:10], uint16(m.Attempts)) 45 46 n, err := w.Write(buf[:]) 47 total += int64(n) 48 if err != nil { 49 return total, err 50 } 51 52 n, err = w.Write(m.ID[:]) 53 total += int64(n) 54 if err != nil { 55 return total, err 56 } 57 58 n, err = w.Write(m.Body) 59 total += int64(n) 60 if err != nil { 61 return total, err 62 } 63 64 return total, nil 65 } 66 67 // decodeMessage deserializes data (as []byte) and creates a new Message 68 // 69 // [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]... 70 // | (int64) || || (hex string encoded in ASCII) || (binary) 71 // | 8-byte || || 16-byte || N-byte 72 // ------------------------------------------------------------------------------------------... 73 // nanosecond timestamp ^^ message ID message body 74 // (uint16) 75 // 2-byte 76 // attempts 77 func decodeMessage(b []byte) (*Message, error) { 78 var msg Message 79 80 if len(b) < minValidMsgLength { 81 return nil, fmt.Errorf("invalid message buffer size (%d)", len(b)) 82 } 83 84 msg.Timestamp = int64(binary.BigEndian.Uint64(b[:8])) 85 msg.Attempts = binary.BigEndian.Uint16(b[8:10]) 86 copy(msg.ID[:], b[10:10+MsgIDLength]) 87 msg.Body = b[10+MsgIDLength:] 88 89 return &msg, nil 90 } 91 92 func writeMessageToBackend(msg *Message, bq BackendQueue) error { 93 buf := bufferPoolGet() 94 defer bufferPoolPut(buf) 95 _, err := msg.WriteTo(buf) 96 if err != nil { 97 return err 98 } 99 return bq.Put(buf.Bytes()) 100 }