/// <summary> /// Fetches raw events along with their deserialized EventDocument-derived instances when possible, returning an enumerable of /// (raw, doc, error) tuples /// </summary> /// <param name="consumer">Event consumer implementation</param> /// <param name="route">Queue designator</param> /// <param name="partition">Logical partition to fetch from <see cref="IEventConsumer.PartitionCount"/></param> /// <param name="checkpoint">A point in time as of which to fetch</param> /// <param name="skip">Number of events to skip in the beginning</param> /// <param name="count">Number of events to fetch</param> /// <param name="lossMode">Data loss tolerance</param> /// <returns> /// A tuple of `raw` event representation, its converted EventDocument-derived instance `doc`, and an error (if any) which surfaced /// during event doc deserialization attempt, thus `doc` and `err` are mutually exclusive /// </returns> public static async Task <IEnumerable <(Event raw, EventDocument doc, Exception err)> > FetchEventDocsAsync(this IEventConsumer consumer, Route route, int partition, ulong checkpoint, int skip, int count, DataLossMode lossMode = DataLossMode.Default) { var got = await consumer.NonNull(nameof(consumer)) .FetchAsync(route, partition, checkpoint, skip, count, lossMode); using (var ms = new IO.BufferSegmentReadingStream()) { return(got.Select(e => { EventDocument doc = null; Exception error = null; try { if (e.ContentType == CONTENT_TYPE_JSON_DOC && e.Content != null) { ms.UnsafeBindBuffer(e.Content, 0, e.Content.Length); var map = JsonReader.DeserializeDataObject(ms, EVENT_JSON_ENCODING, true) as JsonDataMap; doc = JsonReader.ToDoc <EventDocument>(map, fromUI: false); } } catch (Exception err) { error = err; } return (raw: e, doc: doc, err: error); }).ToArray()); } }