in reply to [solved] Long-running DB query makes Tk application unresponsive

keep the execute() from blocking is to spawn a thread that handles it, and not update the widget until the thread returns. This approach seems to require quite a bit of shared memory magic, since the thread will have to get me an AoA with the results (or be aware of the Columns widget in order to populate it, depending)

Just brainstorming..... but you should be able to work out a way of getting the data back from the thread, without it totally finishing. Maybe the way the SQL works, it has to be that way, but the thread could set a shared flag when it knows one portion of the data is retreived, and you could setup a timer in the main Tk thread to repeatedly check the flag, and do what is neccesary to read the completed section. Maybe if you thought about it, you could figure out a method for the thread to detect when a column is ready to be populated, then have it set the shared flag, and put the column number( or whatever) in another shared variable. Then as the Tk loop goes through it's wait-timer, it will process that column as it detects it is ready. That way, you will see the columns fill as they are individually finished. Just setup a shared array @columns_finished. Have the thread push finished columns into @columns_finished, and have a Tk timer, watch for and shift off of @columns_finished and send it to the Columns widget.

P.S. If this script is more than a "1-shot deal", you should make your thread reusable, instead of launching multiple async threads.


I'm not really a human, but I play one on earth. flash japh
  • Comment on Re: Long-running DB query makes Tk application unresponsive

Replies are listed 'Best First'.
Re^2: Long-running DB query makes Tk application unresponsive
by radiantmatrix (Parson) on Oct 14, 2005 at 17:43 UTC

    Hm, my communication skills are letting me down again. The retrieval of the rows is not slow. The end result set is only about 10-15 rows on average, but the gymnastics to get them in SQL is terribly complex. I had our DBA guys optimize the SQL, but even so it takes several minutes just to *start* returning rows, even in SQL*PLUS, for example.

    As to making a reusable thread, I've lately been toying with the idea of having a long-running process act as some kind of IPC server, and having the GUI just be a client of that. The client might look something like:

    $res = $srvr->ask($SQL,@params); if ($res == SRVR_ACK && SRVR_WAIT) { # set up something to check back for results later } else { # deal with the results }

    I think that's kinda-sorta what you're talking about, but I just can't seem to wrap my head around this, so I might be wrong. Thoughts?

    <-radiant.matrix->
    A collection of thoughts and links from the minds of geeks
    The Code that can be seen is not the true Code
    "In any sufficiently large group of people, most are idiots" - Kaa's Law
      As far as making a reusable thread, see ztk-BBC-World-News-Rss-TickerTape and look at the sub work. It is a sleeping thread, which gets turned on by the shared variable $shash{'go'} and is killed by $shash{'die'}. So you can create the thread, (or a couple of them), wake them with a go=1, and let them do whatever you want. When done, set go=0. The sleep 1 gives a very efficient sleep, but you can remove the 1 second lagtime, by using a smaller sleep time with something like "select,undef,undef,undef,100" for a 100 microsecond delay.

      I'm not really a human, but I play one on earth. flash japh