Re: One question about setting query timeout.

From: Dave Cramer <pg(at)fastcrypt(dot)com>
To: zhangyuanchao <zhangyuanchao(at)highgo(dot)com(dot)cn>
Cc: List <pgsql-jdbc(at)postgresql(dot)org>
Subject: Re: One question about setting query timeout.
Date: 2014-02-18 12:00:28
Message-ID: CADK3HHKB6vxBP7OMfk=u69-s3hz-Xw1PP547pRUsfJQqTULtQA@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-jdbc

Why would you not just call purge on the cancelTimer ?

Dave Cramer

dave.cramer(at)credativ(dot)ca
http://www.credativ.ca

On Tue, Feb 18, 2014 at 3:30 AM, zhangyuanchao
<zhangyuanchao(at)highgo(dot)com(dot)cn>wrote:

> On 02/17/2014 09:08 PM, Dave Cramer wrote:
>
> Hi,
>
> There were some fixes put into the latest version can you check out the
> snapshot here ?
>
>
> https://oss.sonatype.org/content/repositories/snapshots/org/postgresql/postgresql/
>
> Dave Cramer
>
> dave.cramer(at)credativ(dot)ca
> http://www.credativ.ca
>
>
> On Tue, Feb 11, 2014 at 2:01 AM, zhangyuanchao <
> zhangyuanchao(at)highgo(dot)com(dot)cn> wrote:
>
>> On 02/10/2014 07:18 PM, Dave Cramer wrote:
>>
>> I think this is a known issues. What version of the driver are you using ?
>>
>> Dave Cramer
>>
>> dave.cramer(at)credativ(dot)ca
>> http://www.credativ.ca
>>
>>
>> On Sun, Feb 9, 2014 at 10:46 PM, zhangyuanchao <
>> zhangyuanchao(at)highgo(dot)com(dot)cn> wrote:
>>
>>> Hi,
>>> I have a question about setting query timeout by jdbc.
>>> When tested my application with Tomcat7.0 and loadrunner,my tomcat's
>>> configure file is like this:
>>> <Resource ......
>>> jdbcInterceptors="QueryTimeoutInterceptor(queryTimeout=600)"
>>> ....../>.
>>> After setting like above ,tomcat will call the jdbc's
>>> setQueryTimeout function and set the query timeout to 600seconds for each
>>> statement.
>>> Next,i start my test with 150 concurrency.After about 10 minutes
>>> later,i found the response time was much longer than before.At that
>>> moment,i found there were a lot of statement object in the heap memory of
>>> the JVM.And the JVM's gc could not clean these objects,because they were referenced
>>> by the TimerTask.So i read the source code of the jdbc and Timer class,i
>>> found the mainloop function of the Timer calss can cause the
>>> problem.This is the code of mainloop function in Timer class and i think
>>> the red colour text is that what cause the problem:
>>>
>>> private void mainLoop() {
>>> while (true) {
>>> try {
>>> TimerTask task;
>>> boolean taskFired;
>>> synchronized(queue) {
>>> // Wait for queue to become non-empty
>>> while (queue.isEmpty() && newTasksMayBeScheduled)
>>> queue.wait();
>>> if (queue.isEmpty())
>>> break; // Queue is empty and will forever
>>> remain; die
>>>
>>> // Queue nonempty; look at first evt and do the
>>> right thing
>>> long currentTime, executionTime;
>>> task = queue.getMin();fixes
>>>
>>> synchronized(task.lock) {
>>> if (task.state == TimerTask.CANCELLED) {
>>> queue.removeMin();
>>> continue; // No action required, poll queue
>>> again
>>> }
>>> currentTime = System.currentTimeMillis();
>>> executionTime = task.nextExecutionTime;
>>> if (taskFired = (executionTime<=currentTime)) {
>>> if (task.period == 0) { // Non-repeating,
>>> remove
>>> queue.removeMin();
>>> task.state = TimerTask.EXECUTED;
>>> } else { // Repeating task, reschedule
>>> queue.rescheduleMin(
>>> task.period<0 ? currentTime -
>>> task.period
>>> : executionTime +
>>> task.period);
>>> }
>>> }
>>> }
>>> if (!taskFired) // Task hasn't yet fired; wait
>>> queue.wait(executionTime - currentTime);
>>> }
>>> if (taskFired) // Task fired; run it, holding no locks
>>> task.run();
>>> } catch(InterruptedException e) {
>>> }
>>> }
>>> }
>>> }
>>> So,i want to ask if there is any solution for this problem.
>>> Thanks very much.
>>>
>>>
>>>
>>
>> Hi Dave,
>> Thanks for your response.
>> The version of driver that i am using is 9.3-1100(the latest
>> version).And i searched some similar problem in the mail list,but i did
>> not get it.I think the reason is : when an statement has been execute
>> finished successfully and the statement cancel the timertask,but the
>> timertask is still in Timer's queue.So the statement is always referenced
>> by the Timer class and it can not be cleaned.
>> Let me look at the mainloop function of Timer class.The part that is
>> marked red colour can cause the mainloop stop,so the canceled timetask can
>> not be removed from the queue.If i set the query timeout to 600 seconds,the
>> mainloop will wait for about ten minutes.In the ten minutes,there will be
>> more an more statement in the JVM heap.
>> I think this is what cause the problem,but i don't have some good
>> idea to solve it.Do you have some solution?Thanks a lot.
>>
>
> Hi,
> I checked out the snapshot you sent to me.And i download this
>
> https://oss.sonatype.org/content/repositories/snapshots/org/postgresql/postgresql/9.3-1101-jdbc4-SNAPSHOT/postgresql-9.3-1101-jdbc4-20140214.105528-4.jarand test my application , i got the same problem.I look at the fixes that
> was put into the latest version,i think that can not solve my issue.I think
> you may not understand my question.
> I have a solution like this,
> adding a function into Driver.java.in:
> public static Timer getCancelTimer()
> {
> return cancelTimer;
> }
> and modifing the killTimer() function AbstractJdbc2Statement.java:
> private synchronized void killTimer()
> {
> if ( cancelTimer != null )
> {
> cancelTimer.cancel();
> Driver.getCancelTimer().purge();
> cancelTimer = null;
> }
>
> }
> After modifing like above, i solved the problem.But i don't know if the
> solution is good.
> Thank you.
>

In response to

Responses

Browse pgsql-jdbc by date

  From Date Subject
Next Message dmp 2014-02-18 22:16:45 pgJdbc to JDBC Transfers
Previous Message zhangyuanchao 2014-02-18 08:30:07 Re: One question about setting query timeout.