EventStore-Client-Go icon indicating copy to clipboard operation
EventStore-Client-Go copied to clipboard

bug: AppendEvents does not persist Metadata if more than one event is provided.

Open seanppayne opened this issue 1 year ago • 5 comments

I make the following function call in my codebase

_, err = e.client.AppendToStream(
    ctx,
    streamID,
    appendOptions,
    esdbEvents...,
)

When esdbEvents contains more than one event, anything I put in the metadata field of the EventData is not persisted to the DB (not visible in UI, not accessible when reading stream).

When esdbEvents contains only one event, the metadata is persisted as expected.

My metadata

metadata := UserMetadata{
	CausedBy:  event.UUID().String(),
	ReceiptNo: event.ReceiptNumber(),
	ReqId:     event.RequestId(),
	TermId:    event.TerminalId(),
	DealNo:    event.DealNumber(),
}

I am wondering is this a bug or is this intended behavior?

seanppayne avatar Apr 16 '24 22:04 seanppayne

Hey @seanppayne ,

I need you to share exactly how you wrote your metadata. I don't need to see the data of course but I need to ascertain you use the API correctly first.

YoEight avatar Apr 17 '24 03:04 YoEight

Sure thing, I create the events/metadata as follows:

metadata := UserMetadata{
	CausedBy:  event.UUID().String(),
	ReceiptNo: event.ReceiptNumber(),
	ReqId:     event.RequestId(),
	TermId:    event.TerminalId(),
	DealNo:    event.DealNumber(),
}

metadataBytes, err := json.Marshal(metadata)
	
if err != nil {
	return esdbEvents, fmt.Errorf("error occurred while marshalling metadata EventType: %s Err: %v", event.EventType(), err)
}

esdbEvents[i] = esdb.EventData{
	ContentType: esdb.ContentTypeJson,
	EventType:   event.EventType(),
	Data:        eventBytes,
	EventID:     event.UUID(),
	Metadata:    metadataBytes,
}

seanppayne avatar Apr 17 '24 06:04 seanppayne

You confirm that all the events you write have their metadata set to UserMetada of yours?

YoEight avatar Apr 17 '24 18:04 YoEight

@YoEight Yes, here is a screenshot. This is when only one event is provided. If there is more than one event these fields do not show up.

Screenshot 2024-04-18 at 14 40 25

seanppayne avatar Apr 18 '24 05:04 seanppayne

Hey @seanppayne,

I wrote an unit test to try to reproduce your issue. Unfortunately, it's still working as expected:

func eventMetadataOperation(db *esdb.Client) TestCall {
	return func(t *testing.T) {
		streamID := NAME_GENERATOR.Generate()
		ctx, cancel := context.WithTimeout(context.Background(), time.Duration(5)*time.Second)
		defer cancel()

		var events []esdb.EventData

		type data struct {
			Baz int
		}

		type meta struct {
			Zaz int
		}

		for i := 0; i < 3; i++ {
			data, _ := json.Marshal(data{
				Baz: i,
			})

			meta, _ := json.Marshal(meta{
				Zaz: i,
			})

			events = append(events, esdb.EventData{
				EventID:     uuid.New(),
				EventType:   "event-tested",
				ContentType: esdb.ContentTypeJson,
				Data:        data,
				Metadata:    meta,
			})
		}

		_, err := db.AppendToStream(ctx, streamID, esdb.AppendToStreamOptions{}, events...)
		assert.Nil(t, err)

		ctx, cancel = context.WithTimeout(context.Background(), time.Duration(5)*time.Second)
		defer cancel()

		stream, err := db.ReadStream(ctx, streamID, esdb.ReadStreamOptions{
			From:      esdb.Start{},
			Direction: esdb.Forwards,
		}, 128)

		defer stream.Close()

		assert.Nil(t, err)

		for i := 0; i < 3; i++ {
			event, err := stream.Recv()
			assert.Nil(t, err)

			var data data
			err = json.Unmarshal(event.OriginalEvent().Data, &data)
			assert.Nil(t, err)

			var meta meta
			err = json.Unmarshal(event.OriginalEvent().UserMetadata, &meta)
			assert.Nil(t, err)

			assert.Equal(t, i, data.Baz)
			assert.Equal(t, i, meta.Zaz)
		}
	}

Is that snippet close to your code? If not, could you tell me what should I change?

YoEight avatar Apr 19 '24 02:04 YoEight

@YoEight I apologize for the delayed response, but I was unable to reproduce the behavior after returning to this, so I am not sure what happened. I have to chalk it up to user error on my part.

Thank you for taking the time to write this test.

seanppayne avatar May 15 '24 02:05 seanppayne