Skip to content

Commit

Permalink
Add msgpack bytes write method to serializer.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidlion committed Oct 30, 2024
1 parent 5ce36b0 commit 40d4ded
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 8 deletions.
39 changes: 33 additions & 6 deletions ir/serializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
// so will result in a memory leak.
type Serializer interface {
SerializeLogEvent(logEvent ffi.LogEvent) (BufView, error)
SerializeMsgPackBytes(msgPackBytes []byte) (BufView, error)
Close() error
}

Expand Down Expand Up @@ -95,6 +96,16 @@ func (serializer *eightByteSerializer) SerializeLogEvent(
return serializeLogEvent(serializer, LogEvent)
}

// SerializeMsgPackBytes attempts to serialize the log event, event, into a eight
// byte encoded CLP IR byte stream. On error returns:
// - nil BufView
// - [IrError] based on the failure of the Cgo call
func (serializer *eightByteSerializer) SerializeMsgPackBytes(
msgPackBytes []byte,
) (BufView, error) {
return serializeMsgPackBytes(serializer, msgPackBytes)
}

// Create a distinct type so we know the type of the underlying serializer, but allows the use of
// the same methods.
type fourByteSerializer struct {
Expand All @@ -121,29 +132,45 @@ func (serializer *fourByteSerializer) SerializeLogEvent(
return serializeLogEvent(serializer, logEvent)
}

// SerializeMsgPackBytes attempts to serialize the log event, event, into a four
// byte encoded CLP IR byte stream. On error returns:
// - nil BufView
// - [IrError] based on the failure of the Cgo call
func (serializer *fourByteSerializer) SerializeMsgPackBytes(
msgPackBytes []byte,
) (BufView, error) {
return serializeMsgPackBytes(serializer, msgPackBytes)
}

func serializeLogEvent(
serializer Serializer,
logEvent ffi.LogEvent,
) (BufView, error) {
var irView C.ByteSpan
var err error

msgpackBytes, err := msgpack.Marshal(&logEvent)
msgPackBytes, err := msgpack.Marshal(&logEvent)
if err != nil {
return nil, err
}
return serializeMsgPackBytes(serializer, msgPackBytes)
}

func serializeMsgPackBytes(
serializer Serializer,
msgPackBytes []byte,
) (BufView, error) {
var irView C.ByteSpan
var err error

switch irs := serializer.(type) {
case *eightByteSerializer:
err = IrError(C.ir_serializer_eight_byte_serialize_log_event(
irs.cptr,
newCByteSpan(msgpackBytes),
newCByteSpan(msgPackBytes),
&irView,
))
case *fourByteSerializer:
err = IrError(C.ir_serializer_four_byte_serialize_log_event(
irs.cptr,
newCByteSpan(msgpackBytes),
newCByteSpan(msgPackBytes),
&irView,
))
}
Expand Down
24 changes: 23 additions & 1 deletion ir/writer.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (writer *Writer) Reset() {
// - success: number of bytes written, nil
// - error: number of bytes written (can be 0), error propagated from
// [SerializeLogEvent] or [bytes.Buffer.Write]
func (writer *Writer) Write(logEvent ffi.LogEvent) (int, error) {
func (writer *Writer) WriteLogEvent(logEvent ffi.LogEvent) (int, error) {
irView, err := writer.SerializeLogEvent(logEvent)
if nil != err {
return 0, err
Expand All @@ -113,6 +113,28 @@ func (writer *Writer) Write(logEvent ffi.LogEvent) (int, error) {
return n, nil
}

// Write uses [SerializeLogEvent] to serialize the provided log event to CLP IR
// and then stores it in the internal buffer. Returns:
// - success: number of bytes written, nil
// - error: number of bytes written (can be 0), error propagated from
// [SerializeLogEvent] or [bytes.Buffer.Write]
func (writer *Writer) WriteMsgPackBytes(msgPackBytes []byte) (int, error) {
irView, err := writer.SerializeMsgPackBytes(msgPackBytes)
if nil != err {
return 0, err
}
// bytes.Buffer.Write will always return nil for err (https://pkg.go.dev/bytes#Buffer.Write)
// However, err is still propagated to correctly alert the user in case this ever changes. If
// Write can fail in the future, we should either:
// 1. fix the issue and retry the write
// 2. store irView and provide a retry API (allowing the user to fix the issue and retry)
n, err := writer.buf.Write(irView)
if nil != err {
return n, err
}
return n, nil
}

// WriteTo writes data to w until the buffer is drained or an error occurs. If
// no error occurs the buffer is reset. On an error the user is expected to use
// [writer.Bytes] and [writer.Reset] to manually handle the buffer's contents before
Expand Down
2 changes: 1 addition & 1 deletion ir/writeread_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func testWriteReadLogMessages(
"LogMessage": msg,
"Timestamp": time.Now().UnixMilli(),
}
_, err := irWriter.Write(event)
_, err := irWriter.WriteLogEvent(event)
if nil != err {
t.Fatalf("ir.Writer.Write failed: %v", err)
}
Expand Down
Binary file modified lib/libclp_ffi_linux_amd64.a
Binary file not shown.

0 comments on commit 40d4ded

Please sign in to comment.