Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Actor based database accessor

Solved!
Go to solution

Hi Experts,

 

I cannot wrap my head around this: I would like to create a re-usable, actor-based wrapper to abstract queries to a database. So "some" application should be able to start this actor - best as a singleton instance - and make queries via pre-defined methods/messages.

 

So I need some architecture to send a "query this or that" message which fetches data from the DB and sends data back to the calling code. I read  couple of thread discussing "request-reply" patterns, but I don't get my foot on the ground there. Could anyone help me with a code example showing this kind of use case - could be reading a file or so as well.

0 Kudos
Message 1 of 9
(1,054 Views)

Actors are  for asynchronous things. What you are describing is synchronous.  I wouldn't use an Actor for that.

 

If you are determined to go down that road, there is a Request and Wait for Reply message that ships with LabVIEW but is not part of the Actor lvlib. Look around in vi.lib and you'll find it. 

 

Using that Request and Wait for Reply occassionally (for a few messages for an Actor) is totally fine (you do have to be aware and careful about deadlocks) despite what the purists will tell you. However if you find that every message your Actor processes is a request and wait for reply, then you don't really have an async process, so why are you wasting your time and polluting your code by making it an Actor?

 

 

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
Message 2 of 9
(1,052 Views)

Mostly I agree with Sam.

 

What you seem to want is a reference to a database that your root actor creates and then sends to all the other actors that want it. Just be very careful that your database doesn't turn into a backdoor communications path between actors (i.e., one actor writes to table X, another actor reads table X). Each table (or set of tables) should be accessed by one and only one actor. There are some API wrapping tricks you could do to ensure that: have root create the raw "I can do any SQL query" reference, but instead of sharing the raw reference to all nested actors, wrap it in an object that can only do limited queries, and send different limited objects to different nested actors.

 

(The reason for not letting multiple actors talk to the same tables is that you blow away all the correctness guarantees for state and lifetime management that the Actor Framework provides. If you choose to go that route, beware the dragons.)

Message 3 of 9
(1,049 Views)
Solution
Accepted by topic author wgeithner

Databases are well-established technology that support multiple clients and have things like parallel reads and writes.  Routing everything through a singleton actor will only degrade capability, as well as being a lot of work.  Just use a simple LVClass as a wrapper about a Database Connection, and have multiple connections.

 

Message 4 of 9
(1,036 Views)

Taggart, drjdpowell, and I are all in agreement. You probably do not want an actor for your database layer. 🙂

Message 5 of 9
(1,020 Views)

@drjdpowell wrote:

Databases are well-established technology that support multiple clients and have things like parallel reads and writes.  Routing everything through a singleton actor will only degrade capability, as well as being a lot of work.  Just use a simple LVClass as a wrapper about a Database Connection, and have multiple connections.

 


This.

 

I have been very successful doing what drjdpowell suggests here.  Moreover, the API of the class wrapper should reflect the needs of the application, NOT the design of the database, as this supports changing the database structure, or even the database product, as the needs of the project progress.  (It also facilitates unit testing.)  Because it's a simple class, it can be request-reply.

 

Different parts of your application will touch the database in different ways.  Have different API classes for each.  Resist the urge to have a "universal" interface class, as that will just cause your database schema to leak out into the larger application, which is highly undesirable.  (Like fire, a database is a good servant but a terrible master - not abstracting/encapsulating it away leads to much future pain.)

 

Call these APIS from your actors when those actors need data.  If they need to share that data out, you can use regular (not reply) messaging.  If you need to support multiple requesters, have the requester send its enqueuer (possibly wrapped in a protection proxy) along with the request.  Reply messages should be used sparingly (if at all), and this is NOT an instance where one is required.

Message 6 of 9
(1,019 Views)

@drjdpowell wrote:

Databases are well-established technology that support multiple clients and have things like parallel reads and writes.  Routing everything through a singleton actor will only degrade capability, as well as being a lot of work.  Just use a simple LVClass as a wrapper about a Database Connection, and have multiple connections.

 


This combined with Allen's answer is exactly what you need.

Sam Taggart
CLA, CPI, CTD, LabVIEW Champion
DQMH Trusted Advisor
Read about my thoughts on Software Development at sasworkshops.com/blog
GCentral
0 Kudos
Message 7 of 9
(999 Views)

@AristosQueue (NI) wrote:

Just be very careful that your database doesn't turn into a backdoor communications path between actors (i.e., one actor writes to table X, another actor reads table X). Each table (or set of tables) should be accessed by one and only one actor.


Minor aside: I find many database actors often work best by making the database the frontdoor, if not sole, communication path.   If Actor A writes new data to the db, and Actor B displays data from the db for the User, then the sole communication between them should be new data in the db.  Any messaging between A and B is actually the problematic backdoor.  Done right, and Actor B can be built into a separate "Viewer" application.

0 Kudos
Message 8 of 9
(941 Views)

drjdpowell wrote:

> I find many database actors often work best by...

 

As a whole independent actor tree, yes, your suggestion is great. As a shortcut across an actor tree, no. It introduces all the race conditions, etc, that the tree is meant to prevent.

0 Kudos
Message 9 of 9
(934 Views)