Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service Fabric Actors - save state to database

I'm working on a sample Service Fabric project, where I have to maintain a shopping list. For this I have a ShoppingList actor, which is identifiable by a specific id. It stores the current list content in its state using StateManager. All works fine.

However, in parallel I'd like to maintain the shopping list content in a sql database. In particular:

  • store all add/remove item request for future analysis (ML)
  • on first actor initialization load list content from db (e.g. after cluster has been re-created)

What is the best approach to achieve that? Create a custom StateProvider (how? can't find examples)? Or maybe have another service/actor for handling all db operations (possibly using queues and reminders)?

All examples seem to completely rely on default StateManager, with no data persistence to external storage, so I'm not sure what's the best practice.

like image 340
filip Avatar asked Jul 15 '16 11:07

filip


1 Answers

The best way will be to have a separate entity responsible for storing data to DB. And actor will just send an event (not implying SF events) with some data about performed operation, and another entity will catch it and perform the rest of the work.

But of course you can implement this thing in actor itself, but it will bring two possible issues:

  • Actor will be not able to process other requests if there will be some issues with DB or connectivity between actor and DB or if there will be high loading of DB itself and it will process requests slowly. The actor would have to wait till transferring to DB successfully completes.
  • Possible overloading of DB with many single connections from many actors instead of one or several connection from another entity and batch insertion.

So, your final solution will depend on workload of your system. But definitely you will need a reliable queue to safely store data in DB if value of such data is too high to afford a loss.

Also, I think you could use default state manager to store logs and information about transactions before it will be transferred to DB and remove from service's state after transaction completes. There is no need to have permanent storage of such data in services.

And another things to take into consideration — reading from DB. Probably, if you have relationship database and will update with new records only one table + if there will be huge amount of actors that will query such data on activation, you will have performance degradation as this table will be locked for reading or writing if you will not configure it to behave differently. So, probably, you will need caching system to read data for actors activation — depends on your workload.

And about implementing your custom State Manager: take a look at this example. Basically, all you need to do is to implement IReliableStateManagerReplica interface and pass it to StatefullService constructor.

like image 54
cassandrad Avatar answered Nov 03 '22 22:11

cassandrad