Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Periodically update entities from multiple threads in EF

I have the following scenario:

I have a Database storing Jobs which are catched and processed by a server. The database is accessed via Entity Framework.

The server processes the jobs in parallel using multiple threads. For this I have one thread which periodically checks for new Jobs in the database and Distributes them to worker threads.

My problem now is that my Entities have a Progress property which should be updated by the worker threads and periodically written to the database.

The worker threads update the property quite often (many times per second), but for my requirements it's enough if the database is updated every few seconds and I don't want to make to many unnecessary updates to the database.

So far my solution is to have the worker threads write the progress to the Entity directly and have the thread which checks for updates also issue these changes to the database.

My question here is: Is this thread safe from the EF point of view. Can I update properties of an Entity from one thread and write the changes to the Database on another thread? Do I need any case of locking? Keep in mind that I use the DataContext only in one thread (add least explicitly since I don't know what EF does internally when I update an (Non-POCO) entity.

Another requirement now is that I need to load additional data from the database in the worker processes. I assume I have to use separate DataContexts for this and I don't really like having to manage entities from two separate data contexts in the same thread.

Do you have any advice how to structure this in a nice way?

Since every worker is only updating the status for one Job-Entity, one idea was to expose the progress as a property in the worker-threads class which is fetched by the main thread which would then update the entities and issue the update to the database. But I still need the original Job-Entity in the worker thread to read configuration data and if I reattach it to the DataContext of the worker thread I cannot use the Entity anymore in the main thread. I want to avoid loading the same entity 2 times if it's not really necessary...

Is it possible to duplicate an Entity automatically, to use it in 2 separate DataContexts?

Thanks for any ideas!

like image 842
aKzenT Avatar asked Nov 14 '22 01:11

aKzenT


1 Answers

At the end I made the following decision:

My main class / main thread reads the jobs from the database and distributes them to various worker threads. For each job there is a corresponding Job-Executor whose .Execute() method is run by the worker thread.

By convention, the Executor-classes read all necessary configuration data from the Job-Entity when it's constructed and isn't allowed to touch it anymore during the execution period. Since construction of the Executor class is done from the main thread, there is no multi threaded access here.

Changing state, like the progress of a Job is exposed via properties on the executor class and periodically synched to the entities/database from the main thread.

The worker threads also have their own DataContext to load additional data when necessary.

All other multi-thread access to DataContext is synchronized with locks.

like image 51
aKzenT Avatar answered Nov 16 '22 23:11

aKzenT