Need some details for contribution
kunjee17 opened this issue · comments
Hi @Dzoukr
It would be great if you can provide some details around the contribution. I ll start with few questions.
- What is getting store? From the code I figure it out that Stream type and EventRead is getting stored. But I am not sure if anything I missed.
- When we are creating EventRead
createdUtc
is based on event or stream's createUtc. - Is any validation I need to take care of ? I got one validation about expected position but is there any other validation is there?
- Is there any coding guideline for adding support of another data store ?
Hi @kunjee17,
thanks for creating new storage provider for CosmoStore!
To your questions:
When we are creating EventRead createdUtc is based on event or stream's createUtc.
CreatedUtc
value is created when stored EventWrite
. The value for Stream metadata can differ (only in miliseconds, most likely), because it is meant to be timestamp of metadata stored, but that is ok. In other words - CreatedUtc
on EventRead and CreatedUtc
on Metadata can be different.
Is any validation I need to take care of ? I got one validation about expected position but is there any other validation is there?
The only validation now is for expected position.
Is there any coding guideline for adding support of another data store
Just follow what you found in existing implemenation, but I will not be heavily strict. I think the "usual F# code" looks more less the same.
What is getting store? From the code I figure it out that Stream type and EventRead is getting stored. But I am not sure if anything I missed.
Sorry, I don't get the question. Can you please elaborate on this?
Thanks again!
Hi, @Dzoukr
I was trying to ask which details we are storing in persistence storage. From code I could make out that EventRead and Stream model are getting stored.
Stream model will be updated every time event happens.
Hope I am right?
Yeah, you are right. Stream metadata keeps the info about whole stream (last updated, last position, etc...). Don't forget that is necessary to have storing both in some kind of transaction - if updating metadata fails, no event is appended in vice versa.
Hi, @Dzoukr
I am able to create most of the function. But couldn't get the JToken part. Why specifically JToken is used. Litedb is failing because it can't de-serialized JToken. As JToken is not having any public constructor.
How, you are serializing / de - serializing them?
I have made following changes to file and remove JToken as input. All test are passing for litedb
namespace CosmoStore
open System
open System.Threading.Tasks
open Newtonsoft.Json.Linq
type ExpectedPosition =
| Any
| NoStream
| Exact of int64
type EventsReadRange =
| AllEvents
| FromPosition of int64
| ToPosition of int64
| PositionRange of fromPosition:int64 * toPosition:int64
type StreamsReadFilter =
| AllStreams
| StartsWith of string
| EndsWith of string
| Contains of string
[<CLIMutable>]
type EventRead<'a,'b> = {
Id : Guid
CorrelationId : Guid option
CausationId : Guid option
StreamId : string
Position: int64
Name : string
Data : 'a
Metadata : 'b option
CreatedUtc : DateTime
}
type EventWrite<'a, 'b> = {
Id : Guid
CorrelationId : Guid option
CausationId : Guid option
Name : string
Data : 'a
Metadata : 'b option
}
[<CLIMutable>]
type Stream = {
Id : string
LastPosition : int64
LastUpdatedUtc: DateTime
}
type EventStore<'a,'b> = {
AppendEvent : string -> ExpectedPosition -> EventWrite<'a,'b> -> Task<EventRead<'a,'b>>
AppendEvents : string -> ExpectedPosition -> EventWrite<'a,'b> list -> Task<EventRead<'a,'b> list>
GetEvent : string -> int64 -> Task<EventRead<'a,'b>>
GetEvents : string -> EventsReadRange -> Task<EventRead<'a,'b> list>
GetEventsByCorrelationId : Guid -> Task<EventRead<'a,'b> list>
GetStreams : StreamsReadFilter -> Task<Stream list>
GetStream : string -> Task<Stream>
EventAppended : IObservable<EventRead<'a,'b>>
}
Above is surely a breaking changes. So, I don't know if that works out or not. Please have a look.
I also like to ask that common functions like (mapping, validation) should be moved to core so it can easily be used in all implementation?
Hi @kunjee17,
thanks for questions:
Why specifically JToken is used. Litedb is failing because it can't de-serialized JToken.
Historically it is used because Newtonsoft.Json is "industry standard for JSON on .NET" + is internally used for Cosmos DB.
I would rather avoid breaking changes (version 2 is still too young). I am not LiteDb expert, but there must be way how to store json data.
Maybe... you can map it to your internal structure?
[<CLIMutable>]
type EventRead = {
Id : Guid
CorrelationId : Guid option
CausationId : Guid option
StreamId : string
Position: int64
Name : string
Data : BsonDocument
Metadata : BsonDocument option
CreatedUtc : DateTime
}
And then create JToken from BsonDocument on mapping?
Let me know, please.
I will give it a try. Litedb is storing kind of json format only. And as JToken is not having default constructor it is giving issue while de serialization . I will still give one more try to by pass it.
You did more than good 😂 so I am closing this one now.