Open DrewRidley opened 4 years ago
It is possible I think I saw your question on the main LiteDb project. Do you have an example of the code you want to implement?
Like an example of how you do it now in the synchronous way and how you would like to do it in Async?
@mlockett42 heres a good example,
BsonMapper.Global.RegisterType<Uri> ( serialize: (uri) => uri.FromBsonSync(uri), deserialize: (bson) => Uri.ToBsonSync(bson) );
The proposed solution would involve something like the following.
BsonMapper.Global.RegisterType<Uri> ( serialize: async (uri) => await uri.FromBsonAsyncSync(uri), deserialize: async (bson) => await Uri.ToBsonAsyncSync(bson) );
Obviously the Uri class doesn't require any asynchronous context, but I can name a few objects that require specifically asynchronous construction. Async constructors dont exist, but many asyncronous libraries do not allow you to construct objects without an asynchronous context (or the threat of blocking lots of things that shouldn't be blocked). Supporting asyncronous callbacks going forwards would improve compatibility (at least until litedb officially supports async).
I have had a look at this. This is how I think it works from a couple of hours of reading the code. Seems pretty complex to implement but may be possible. The BsonMapper appears to mostly be used internally. It gets used in when transforming POCO to/from writing (via insert or update or toenmumerable). The second more complex use is when something like a where function is called with a Linq expression the BsonMapper transforms the Linq expression in a BsonExpression this where the complexity comes from. The Where function just stores the queries and applies the BsonMapper when they are evalulated. The BSonMapper class itself is pretty complex it doesn't appear that we can just subclass it override a few methods and make it work. We basically need to copy the code and add an async option. In the LiteDatabaseAsync and LiteCollectionAsync classes we need to detect whether the user has set up an Async mapper and change behaviour if they are using the Async mapper and call that to map things before submitting the query to the background thread. To do this when the user called the where function with a Linq Expression as a parameter LiteDb.Async needs to call the Async mapper to transform the Expression into a BsonExpression before passing it on whatever is going to execute it in the background thread.
The only use case I can think up for this is the user wants look up the mapped value in a large database that requires IO. Then one special case needs to be considered we need to deal with what happens if the async mapper function then calls back into the same LiteDatabaseAsync instance. If the async calls to the map functions are called in the background thread they will deadlock the library (because it won't be able to top anything off the internal queue, but it won't be able to read the next item off the queue until the ansync mapper returns.
Seems complicated- well the existing mapper looks complicated.
@mookid8000 has be doing some work on this library. I would like to get his input on this.
@mlockett42 sorry, don't have an opinion on this 😐
Going to work on another feature in LiteDb.Async before coming back to this one
Is there any way this library can be extended to support asynchronous calls in a custom object mapper? if there is, that would be greatly appreciated if it could be added! I would be happy to contribute if needed.