In-memory database accessible via AppDomain boundary

I wonder if there is an in-memory database implementation where the same in-memory database instance can be used for multiple applications.

Motivation. Like many people, we have integration tests for our client / server application. There are several test modes: from the most difficult - a real life scenario, where the client, server and database are located on different machines, to the lightest, where both the client and the server are just two AppDomains in the same process and the database is sqlite file on the same computer.

Naturally, the lightest script is the fastest and developers usually use it, and the heaviest script is on our CI server in every build.

My goal is to speed up a lightweight scenario using an in-memory database.

Problem. Ok, so sqlite has an in-memory database option, but a database like this:

  • is deleted after the connection with it is closed.
  • cannot have two open connections, new connections open another instance of the database.

Unfortunately, I need two - one for the test middleware that runs on the client side of the AppDomain and one for the DAL on the server side.

I understand the rationale behind how sqlite in-memory database works. I am also aware of the difficulties involved in having an in-memory database shared between two applications. How can a memory buffer be swapped between two AppDomains without going back to memory mapped files (and I don't want to deal with any filesystem API)?

The only effective solution I see is that the two AppDomains share an unmanaged memory buffer where the buffer handle will be passed from one application to the other. But are there implementations built into the database that support this setup?

(An inefficient solution would be to transfer the entire database from one AppDomain to another and then back again).

Perhaps I am completely wrong in my analysis, and there may be simple solutions that I am missing. Anyway, I would like to know if anyone faced the same problem and how they solved it.

PS

I would really like to avoid any File APIs like memory mapped files.

+2


source to share


2 answers


I have three solutions that come to mind, but they all require some configuration. They all require you to create a third AppDomain, where the in-memory database is in the s syntax, and to code a class with a well-defined interface to that database.

The first solution is to just call the code through AppDomains. The objects you go through must be "Remotable" which can be tricky to customize. (Derive from MarshalByRefObject, etc.) Not only that any objects you pass to or from AppDomains need to be serializable. He can, but sometimes it is not very good.

The second solution is to use remote access. This is old technology now, but it still works. It basically makes out the above call via AppDomains. I won't say more about it here, I'm almost embarrassed to pick it up.



The third solution is to use WCF and namedPipeBinding, which are fast. Both ends of a WCF call can be in the same application and in different application domains. A side effect of coding it is that you can later unmount the in-memory database for a fully functional device and change the binding to work over an intranet or the Internet.

The third solution is the one I am currently using for a project similar to what you are describing. Our goal was to isolate the database so that we can try out nHibernate without "contaminating" the rest of the layers.

+1


source


I don't know of any such database.

But it is interesting to think about what form such a database might have. If we view the application domain as a lightweight process, then we can view cross-domain speech (serialization) as message passing. We can then define a simple messaging protocol that allows clients to send requests and receive results in response.



  • Your database should be running in its own application domain
  • Each client must run in its own application domain
  • Standard serialization between application domains should be used to return query results. The easiest way to do this is to encapsulate the queries in your own classes, which are executed on build. This way you can use AppDomain.CreateInstance .
  • Your database should be able to handle requests from any thread.

I don't think this is a great idea. There are too many details about how domain applications work and interact to get 100% rights.

0


source







All Articles