Asynchronous Database Access: Difference between revisions

Jump to navigation Jump to search
Content deleted Content added
imported>Hendrik Brummermann
No edit summary
imported>Hendrik Brummermann
No edit summary
 
(29 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{Navigation for Marauroa Top|Internals}}
{{Navigation for Marauroa Top|Internals}}
{{Navigation for Marauroa Developers}}
{{Navigation for Marauroa Developers}}


{{Future Concept}}




Line 15: Line 12:
== Kinds of database operations ==
== Kinds of database operations ==


Most of the database operations in marauroa are write only, making it easy to put them into a queue for asynchronous processing. Read operations are more difficult to handle because the data returned by them is needed. That is obvious the reason why it is read in the first place.
Most of the database operations in marauroa are write only, making it easy to put them into a queue for asynchronous processing. Read operations are more difficult to handle because the data returned by them is needed. That is obviously the reason why it is read in the first place.


There are three kinds of read operations:
There are three kinds of read operations:
Line 44: Line 41:




== Implementation ==
== Some quick ideas on how to ==


Note: This sections needs more thinking.


There should be a DatabaseOperationQueue, which is singleton and has a background thread to execute enqueued DatabaseOperations. DatabaseOperation is an interface that specifies an execute()-method, that handles the database operation by invoking the DAO-classes. It is called from the background thread of DatabaseOperationQueue.
Marauroa has a DBCommandQueue, which is singleton and has a background thread to execute enqueued DBCommands. DBCommand is an interface that specifies an execute()-method, that processed the database request by invoking the DAO-classes. It is called from the background thread of DBCommandQueue.


The following example for a simple write operation assumes that GameEvent implements/extends DatabaseOperation:
The following example for a simple write operation assumes that GameEvent implements/extends DBCommand:


DatabaseOperationQueue.get().enqueue(
DBCommandQueue.get().enqueue(
new GameEvent(attacker.getName(),
new GameEvent(attacker.getName(),
"attack", target.getName());
"attack", target.getName());
Line 61: Line 55:
Since we ignore 1) for now, this leaves us with 2): We need a way to receive the data produced by an read operation:
Since we ignore 1) for now, this leaves us with 2): We need a way to receive the data produced by an read operation:


UUID uuid = DatabaseOperationQueue.get().enqueueAndNotify(
UUID uuid = DBCommandQueue.get().enqueueAndAwaitResult(
this, new GetCharacterList(username));
this, new GetCharacterList(username));


The DatabaseOperationQueue will process the GetCharacterList at some future time in the background thread. It will then put the GetCharacterList which now contains the results from the database in a second queue ("waiting to be fetched by program"). Here comes the tricky part: We need a way to notify the program in the thread that requested the operation about the results. The easiest way is to remember the requesting thread by Thread.getCurrentThread() and provide a List<DatabaseOperation>
The DBCommandQueue will process the GetCharacterList at some future time in the background thread. It will then put the GetCharacterList which now contains the results from the database in a second queue ("waiting to be fetched by program"). Here comes the tricky part: We need a way to notify the program in the thread that requested the operation about the results. The easiest way is to remember the requesting thread by Thread.getCurrentThread() and provide a List<DBCommand>
getResults() method, which fetches all results of Operations enqueue by the current thread.
getResults() method, which fetches all results of Commands enqueued by the current thread.


We have to decide here whether we want an interrupt or polling based approach: An interrupt based approach would then distribute the results to various program parts of the current thread using an interface DatabaseOperationResultReceiver<T extends DatabaseOperation>, which is implemented by those classes who requested the data. A polling based
We had to decide here whether we wanted an ''interrupt'' or ''polling'' based approach: An interrupt based approach would then distribute the results to various program parts of the current thread using an interface DBCommandResultReceiver<T extends DBCommand>, which is implemented by those classes who requested the data. We chose a a polling based
approach would result in the program parts to look for specific results. So the program part that sends the character list back to the client would call:
approach. Here, the program parts look for specific results. The program part that sends the character list back to the client calls:
List<GetCharacterList> DatabaseOperationQueue.get().getResults(this).
List<GetCharacterList> DBCommandQueue.get().getResults(this).




[[Category:Marauroa]]
[[Category:Marauroa]]
{{#breadcrumbs: [[Marauroa]] | [[Navigation for Marauroa Developers|Internals]] | [[Marauroa Roadmap|Roadmap]] | [[Asynchronous Database Access]] }}