Correct use in multithreaded env


#1

Hi

I have a .net core app, that is deployed to an azure web app instance. We use a standalone Realm as database. Every night we do some maintenance on the server, which means that a lot of request a thrown at this app via REST. Approx 4000 records will be deleted and following that 4000 object will be created again. Each one as a result of a call to the Web Api.

But as my understanding on the Web Api, all these requests is done via a threadpool. And the code handling this is like this

	public static void AddJob(SyncJob so, IHubContext<SyncHub> hContext)
	{
		hubContext = hContext;

		var realm = RealmHelper.GetDefaultRealm();

		// if request is from api token that is not in syncserver, throw away
		if(realm.All<ApiToken>().Where(o => o.token.Equals(so.api_token)).Count() == 0)
			return;

		// add to queue
		so.created = DateTime.Now;
		jobsQueue.Enqueue(so);

		Logger.Debug("Added new SyncJob: " + so.ToString());

		return;
	}

My realm file ends up with a filesize of 1.4G and normally its around 10M. Could the problem be, that I’m not disposing my connections to the realm instance or how come it gets so large in size? Eventually my app crashes, because it runs out of memory with the “CreateMapViewOfFile FromApp() failed” error.

I know about the “ShouldCompactOnLaunch” callback, but dont see any real usage for this, as this problem happends during use.

I’m I missing some disposing or “close” for each thread connecting to the instance or should I be doing something ala

		using (var realm = RealmHelper.GetDefaultRealm())
		{
			// do stuff
		}

Please help, any advice would be highly appreciated.

Cheers,
Kent Fonager


#2

Yes, for threadpool threads, you need to dispose of the Realm instance as soon as you’re done with it.


#3

Thanks for your reply. After spending a lot of time, making sure all instances of the realm was proper cleaned up, it now looks and works as expected!

Btw. Do you recommend incapsulating realm work with “using(var realm = …)” or plain object creation and realm.Dispose() at the end?


#4

I’d recommend using-s as these will dispose of the Realm even if an unhandled exception is thrown. Unless you have some very convoluted code path, I can see no reason not to wrap things in a using :slight_smile:


#5

Okay, I get it … but how would you then return a given set of object from your realm in ei. a kind of “Repository” class?

	public static IQueryable<FerryRoute> GetAllFerryRoutes()
	{
		using (var realm = RealmHelper.GetDefaultRealm())
		{
			return realm.All<FerryRoute>();
		}
	}

I guess this would return “invalid” objects, as the realm is automatically disposed, correct ?

What is best practice for implemeting this?

Cheers,
Kent


#6

You’re right. Generally, I don’t think Realm is a very good fit for the repository pattern precisely because Realm objects are tied to the database, whereas a typical repository implementation would not care about what happens to these objects after they’re returned. I imagine you can design some super magical reference counting wrappers that keep track of the objects returned by the repository and automatically dispose Realms, but I feel this would be an extreme cognitive overhead over simply using Realm directly.


#7

I totally agree with you! Thanks for quick reply, I’ll try to figure something out :slight_smile:

Have a wonderfull weekend in sunny Copenhagen :sunny: