Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 10 of 12 total
Thread Aborting Queries
Tue, Feb 19 2008 4:54 AMPermanent Link

"Amir"
Hi Guys,

We have several threads running, querying a single database.
Some of the threads need to abort (user refreshes the screen during query,
need to restart a query, etc...)

To achieve this we are using TDBISAMQuery.OnQueryProgress event, (see
below).
We inspect a global variable saying if the thread needs to abort, and set
"Abort" variable to true.
To make sure the query is stopped, we set the "Active" state to false as
well.

I have a feeling we do something wrong,
especially due to the fact that it sometimes take ages for the query to
stop.
Ideas?

The code:
============
Procedure TmyDB.MyDBQueryProgress(Sender: TObject; PercentDone: Word; var
Abort: Boolean);
begin
  Abort := ApplicationClosing;

  if Sender is TDBISAMQuery then
     case (Sender AS TDBISAMQuery).Tag of
          2: Abort := StatusThreadBreak;  // From Status thread
          3: Abort := AlertThreadBreak;    // From Alerts thread
     end;

    if Abort then
       (Sender AS TDBISAMQuery).Active := false;

    Application.ProcessMessages;
end;

============

Thanks
Amir

Tue, Feb 19 2008 8:18 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

Amir


What do you have your progress steps set to, and are these long queries? You only have the option of aborting at each progress step so if its a long one, even if its set to 100 steps it can take some time.

Roy Lambert
Tue, Feb 19 2008 9:23 AMPermanent Link

amir netiv
Hello Roy,

> Amir
>
> What do you have your progress steps set to, and are these long
> queries? You only have the option of aborting at each progress step so
> if its a long one, even if its set to 100 steps it can take some time.
>
> Roy Lambert
>

Thanks Roy

it is indeed set to 100,
yet, even if i put a breakpoint on this function,
it takes a long time until i see the first progress call, after the query
has started.
(it almost seems as if the query had not yet started) Frown

Alternatively,
Can you think of a way to - "brutally" abort all queries in a session,
without interrupting other sessions in their activity?

i have no problem killing the entire thread, owning a
TDBISAMDatabase and a TDBISAMSession of its own.

the major problem we're dealing with,
is that we sometimes cannot close a thread or even the entire application,
gracefully.

Tue, Feb 19 2008 10:54 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate Team Elevate

amir

>it is indeed set to 100,
>yet, even if i put a breakpoint on this function,
>it takes a long time until i see the first progress call, after the query
>has started.
>(it almost seems as if the query had not yet started) Frown

Yes - that is a "feature" of DBISAM. Tim did explain once what was happening but I can't remember Smiley

>Alternatively,
>Can you think of a way to - "brutally" abort all queries in a session,
>without interrupting other sessions in their activity?

Unfortunately no. I've often wanted this myself, other people have asked on the CodeGear ng's and I've never seen an answer.

Roy Lambert
Tue, Feb 19 2008 11:29 AMPermanent Link

amir netiv
Hello Roy,

> amir
>
>> it is indeed set to 100,
>> yet, even if i put a breakpoint on this function,
>> it takes a long time until i see the first progress call, after the
>> query
>> has started.
>> (it almost seems as if the query had not yet started) Frown
> Yes - that is a "feature" of DBISAM. Tim did explain once what was
> happening but I can't remember Smiley
>
>> Alternatively,
>> Can you think of a way to - "brutally" abort all queries in a
>> session,
>> without interrupting other sessions in their activity?
> Unfortunately no. I've often wanted this myself, other people have
> asked on the CodeGear ng's and I've never seen an answer.
>
> Roy Lambert
>

Thanks for your input.

i have managed to resolve some of this:
the query did not start as another session was in the midst of a:

  StartTransaction
     ...
     loop of activity
     ...
  commit

that takes a LOT of time.
Once i divided it into shorter transactions, the DB is released and it runs
much better!

Still,
if someone would miraculously find a way to gracefully shut down a DB with
all open queries,
i will be more than grateful Smile
Tue, Feb 19 2008 3:58 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Amir,

<< Still, if someone would miraculously find a way to gracefully shut down a
DB with all open queries, i will be more than grateful Smile>>

Most queries should shut down fairly gracefully, since DBISAM does know when
the server is shutting down and when they should abort.

--
Tim Young
Elevate Software
www.elevatesoft.com

Tue, Feb 19 2008 4:51 PMPermanent Link

"Lucian Radulescu"
> i have no problem killing the entire thread, owning a TDBISAMDatabase
> and a TDBISAMSession of its own.
>
> the major problem we're dealing with,
> is that we sometimes cannot close a thread or even the entire
> application, gracefully.

It is because you don't actually call TerminateThread. I have this code
in an application that never gave my any problems:

 procedure KIA( Thread: TThreadCustomWorker );
 var
   bOk: Boolean;
 begin
   bOk := TRUE;
   try
     try
       TerminateThread( Thread.Handle, 0 );
       // it is not threadsafe to referenciate Thread.Handle,
       // but we believe this thread hung ...
     except
       bOk := FALSE; // if there is an exception, most likely thread
freed itself
     end;
   finally
     if bOk then     // ... most likely thread freed itself
     begin
       if ENABLE_CHILD_REGISTERING then
         LogDT( Format( '%s %.4x - %s', [id_KIA, Thread.ThreadID,
Thread.ThreadName] ) );

       Thread.LogDT( {Log_ThreadTerminated}id_TERMINATED );
       Thread.Unregistered := True;
       Thread.Free;
     end;
   end;
 end;

(My worker threads have always FreeOnTerminate true and that's why I
only free the thread object if TerminateThread fails, so there's no
memory leak above).

So, when you actually do get to free the thread with a call to Free,
you handle there all the exceptions coming from DBISAM and that's it.

regards,
Lucian
Wed, Feb 20 2008 3:09 AMPermanent Link

amir netiv
Hello Tim Young [Elevate Software],

> Amir,
>
> << Still, if someone would miraculously find a way to gracefully shut
> down a DB with all open queries, i will be more than grateful Smile>>
>
> Most queries should shut down fairly gracefully, since DBISAM does
> know when the server is shutting down and when they should abort.
>

We suffer from issues with closing queries (including freeing cached queries
and so),
while closing the application.

For some reason when closing the database, it thinks some queries are still
alive though they were already freed,
and after the application terminates we get a "Runtime error 216", that we
cannot suppress (bad reflection on our users) Frown

My issue in starting this news thread was that
we sometimes need to close down a session (in one thread),
while leaving other sessions active (in other threads),
but since some queries fail to abort (waiting for something), or take too
long to stop,
the thread needs to be freed (including its database session) more brutally
(FreeAndNil).

In doing so, we may leave things "hanging",
and the database trips an error (mentioned above) on final closing of the
application.

The main question is therefore focused on:
Is there a way to shutdown gracefully, without getting an error on the screen?

(even though we might have some in-the-wild pointers somewhere).

i know this sounds dirty, but the application is rather chaotic, lots of
threads, and unexpected events from the user and the network, and even with
best practice, there is sometimes no work around to aggressive termination
of threads (we also watchdog the threads to make sure none is in deadlock
state, and free them if needed), i wish there was another way to do it Smile

Thanks

Wed, Feb 20 2008 4:12 PMPermanent Link

Tim Young [Elevate Software]

Elevate Software, Inc.

Avatar

Email timyoung@elevatesoft.com

Amir,

<< For some reason when closing the database, it thinks some queries are
still alive though they were already freed,
and after the application terminates we get a "Runtime error 216", that we
cannot suppress (bad reflection on our users) Frown>>

This sounds like you're not respecting the rules regarding multi-threading
with DBISAM.  Are you re-using query objects among multiple threads ?

--
Tim Young
Elevate Software
www.elevatesoft.com

Thu, Feb 21 2008 2:36 AMPermanent Link

amir netiv
Thanks Tim,

> Amir,
>
> << For some reason when closing the database, it thinks some queries
> are
> still alive though they were already freed,
> and after the application terminates we get a "Runtime error 216",
> that we
> cannot suppress (bad reflection on our users) Frown>>
> This sounds like you're not respecting the rules regarding
> multi-threading with DBISAM.  Are you re-using query objects among
> multiple threads ?
>

No,
Each thread has its own database component (instance), with its own cache
and query objects.

in the mean time to hide error messages on closing, i have entered the source
code and added multiple "try ecxtps" statements (
this should be extensivly implementes in my opinion in all code), over the
closing steps of TDBISAMEngine.FreeInstance.

i will see if this improves the closing and let you know.

i would suggest adding to the "wish list" a "Hide All Errors" feature, for
reckless users like us, that still need their application to close greacefully
Smile

Thanks

Page 1 of 2Next Page »
Jump to Page:  1 2
Image