[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Gnumed-devel] low Performance
From: |
sjtan |
Subject: |
Re: [Gnumed-devel] low Performance |
Date: |
Sun, 06 Jun 2004 23:08:26 +1000 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040113 |
Sun, 6 Jun 2004 11:30:04 +1000
Horst Herb wrote:
This is what we have asynchronous backend communication for.
1.) a complex / time consuming query is initiated asynchronously on the server
To do things asynchronously, the coding style for data access might have
to be changed
to a listener request/ event driven style.
e.g. instead of
1.
data = businessObject.getData(id )
self.mapToGui(data)
it might be something like
def __init()__:
gmDispatcher.connect( businessObjectReceivedData,
self.specificResponseRouting)
...
...( start request here)
self.mapHandling[id] = self._specificResponse
businessObject.requestData(id)
self.guiMessageMonitor(id, "waiting for XXXdata %d" % id)
...
def specificResponseRouting( self, id):
func = self.mapHandling.get(id, None)
if func:
func(id)
del self.mapHandling[id]
else:
businessObject.notifyErrorNoReceiver(id)
self.guiMessageMonitorAppend(id, "response received:
Error no handler")
Meanwhile
... businessObject starts off a separate thread, obtains a connection,
calls the sql selects, formats the rows,
stores the data by id, and then calls
gmDispatcher.send(businessObjectReceivedData, id).
alternatively, businessObject requestData () puts the request on a
Queue object, and unblocks its consumer thread
waiting for a non-empty queue. The single consumer thread services the
request with a single connection, then
calls gmDispatcher.send( .., id) , and then looks for more items on the
queue to service with its single connections, or blocks.
... in response to gmDispatcher.send( businessObjectReceivedData, id).
def _specificResponse(self, id):
data = businessObject.receiveData(id)
self.mapToGui(data)
self.guiMessageMonitorAppend(id, " response received.")
That's just trying to keep to a single thread within the presentation code .
Alternatively, a multiple threads possible scheme, which keeps some of
the synchronous business object call style , could be:
1. above, could be done theoretically without using the dispatcher,
within a separate thread, and businessObject.getData() would be
blocking and internally deal with
re-entrant calls, or create a separate businessObject on a per thread
basis, and use ConnectionPool to queue businessObject
requests for connections, blocking the thread when none available
( using threading .Condition. wait() /notify(), or Queue objects
get/put, or BoundedSemaphore.acquire / release ) ,
as well as self.mapToGui() calling wxInvokeLater( ) to synchronise
with the gui main thread.
In practice , though, we'd probably be spending a lot of time trying to
debug forever blocked threads , etc..