Jeroen T. Vermeulen wrote:
> On Sun, August 12, 2007 14:39, Bart Samwel wrote:
>
>> ...but generally intended to be a precise one if the user doesn't
>> manually cancel what he's waiting for. So timeouts are generally not the
>> thing. Think of loading web pages: there's a network timeout of several
>> minutes, but there's also a "stop" button. I would be very annoyed if I
>> would replace this with only a timeout, but not with only a stop button.
>
> But if there's an application running behind the web page, and a query
> inside that application is taking too long, then at some point the
> application must conclude that:
>
> 1. The user isn't going to get an answer in reasonable time, and it may be
> better to tell him "no can do" than to keep him waiting.
>
> 2. There may be something seriously wrong with the query, or with system
> load, and the application had better abort the query to protect itself.
>
> The user is likely at some point to move on to something else anyway, and
> it doesn't make much sense to continue processing. Worst case, the user
> has already tried to reload the page a few times and you may have several
> instances of the problem query running at the same time.
Ahhh, I wasn't considering the web application case. I was only
considering the desktop application case, in which case there's no
reloading and TCP timeouts to consider.
>> And consider "real-time monitoring" software, e.g. something displaying
>> a graph. If the data doesn't get there on time for a once-a-second graph
>> update, should the query be cancelled? No: otherwise it probably won't
>> get there on time *every* second.
>
> Yes, if the job can't make its real-time constraint, it should be
> canceled. If the application consistently can't make its time goals, then
> it must cope or die. Otherwise you're talking about "fast enough," not
> realtime.
True. "Real-time monitoring" is a misnomer, I should have said something
like "live monitoring".
>>> And of course there's the matter of transactions. Do you abort the
>>> transaction (if any)?
>> Treat it the same as a statement failure. I don't know how pqxx behaves
>> in this respect: if statement failure only rolls back the statement
>> itself, then it should do that. If statement failure aborts an entire
>> transaction, then it should do that.
>
> That is determined in the back-end, not in the client library: a failed
> statement aborts the transaction if one was ongoing.
Then that's what it should do!
>>> What if you're not currently executing any queries
>>> so that the cancel is a no-op from the database's perspective? Do you
>>> abort, throw, ignore?
>> I can give you a definite answer to that one. You ignore. Quite simply
>> put: as a programmer you can never make sure that the database is busy
>> and then cancel in the safe knowledge that the database will not *just*
>> have finished what it was doing. So if you throw/abort, you basically
>> force all users of cancel() to try/catch around it. Worse: if they only
>> cancel long-running queries, they may not ever find out you're throwing
>> on this condition until production time (because they didn't encounter
>> the race condition in testing, it being unlikely when long queries are
>> involved).
>
> I'm inclined to agree, but I appreciate the opportunity to discuss it.
> Any multi-transaction database application should be prepared to catch and
> handle errors while executing database statements. The cancel is not very
> different from, say, a resource error or deadlock there.
Well, yeah. But it's the *scope* of the try/catch that differs from
normal exceptions. For instance, there's something like:
try
{
// ... whole chunk of code ...
foo();
// ... whole chunk of code ...
}
catch (std::exception const&)
{
// ...
}
This is the normal thing -- do error reporting, aborting an entire chunk
of work and doing some cleanup. But if foo() is a cancel statement, and
I want the behaviour "I want this canceled if it is running", I might
need to add another try/catch *just around the call to foo()*.
Another reason not to throw an exception: it's not an exceptional
situation. It's to be expected that the statement may have just finished
when the cancellation is requested.
> It's also similar in that, if we ignore cancels that don't come during
> database statements, the exception typically won't show up during testing
> and exploration.
Yes. But I'd hate to add exceptions for expectable situations just to
make people aware that they should add exception handlers. At least find
a proper excuse to throw an exception once in a while. :-)
> In fact I wonder whether it may make sense to have two versions of cancel:
> a "cancel current statement" that only aborts a statement if one is
> ongoing, and a "cancel and die." The latter would guarantee that the
> ongoing transaction would abort and accept no further statements,
> regardless of what it was doing at the time. That could be a useful way
> for a multithreaded application to "reach out and touch" a thread that was
> doing stuff that's no longer appreciated. The application could implement
> that as well, of course, but if it means many programmers re-writing the
> same code, we might as well have it in the library.
A very interesting concept, and very useful, I think! Definitely worth
considering.
> One problem is, all this asynchronous stuff requires locking. We don't do
> that right now, and it's a pretty big step to take.
True, that may take up a lot more work...
Cheers,
Bart
_______________________________________________
Libpqxx-general mailing list
[email protected]
http://gborg.postgresql.org/mailman/listinfo/libpqxx-general