Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async Object Mapping #10

Open
DrewRidley opened this issue Oct 15, 2020 · 5 comments
Open

Async Object Mapping #10

DrewRidley opened this issue Oct 15, 2020 · 5 comments

Comments

@DrewRidley
Copy link

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.

@mlockett42
Copy link
Owner

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?

@DrewRidley
Copy link
Author

@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).

@mlockett42
Copy link
Owner

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.

@mookid8000
Copy link
Contributor

@mlockett42 sorry, don't have an opinion on this 😐

@mlockett42
Copy link
Owner

Going to work on another feature in LiteDb.Async before coming back to this one

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants