0

Constraint.validate() event thread bug

asked 2010-01-27 13:05:08 +0800

dastultz gravatar image dastultz
797 9

Hello,

I have an "EventThreadListener" that implements EventThreadCleanup, EventThreadSuspend, EventThreadInit, EventThreadResume. EventThreadCleanup.cleanup() and EventThreadSuspend.beforeSuspend() release a database connection that is on a ThreadLocal variable. I have a Textbox with a Constraint added to it. Constraint.validate(...) gets a database connection and runs a query. The connection is not being released, which is to say the cleanup routine is not being called on the thread that is active during Constraint.validate(...). I've added debugging to my EventThreadListener. When I enter something in the textbox and trigger the validation routine I get this in the log:

DEBUG 01/27 13:25:23 : EventThreadInit.prepare() - on http-8080-2
DEBUG 01/27 13:25:23 : EventThreadInit.init() - on Thread-33
DEBUG 01/27 13:25:23 : EventThreadCleanup.cleanup() - on Thread-33
DEBUG 01/27 13:25:23 : EventThreadCleanup.complete() - on http-8080-2
DEBUG 01/27 13:25:23 : EventThreadInit.prepare() - on http-8080-2
DEBUG 01/27 13:25:23 : EventThreadInit.init() - on Thread-33
DEBUG 01/27 13:25:23 : EventThreadCleanup.cleanup() - on Thread-33
DEBUG 01/27 13:25:23 : EventThreadCleanup.complete() - on http-8080-2
DEBUG 01/27 13:25:23 : Constraint.validate() on http-8080-2

The event threads usually have a name like "Thread-##". Here is appears Constraint.validate() is being run on the http request thread rather than an event thread. This looks like a bug to me. (It also looks odd that Constraint.validate() is called after completion of the event thread.) Is this expected behavior? Should I also be cleaning up my database connection on EventThreadCleanup.complete() since this appears to run on the http request thread?

/Daryl

delete flag offensive retag edit

16 Replies

Sort by ยป oldest newest

answered 2010-03-12 02:06:31 +0800

tmillsclare gravatar image tmillsclare
799 2 5 30

Hey Daryl,

Good to know that you have found this condition. I am pleased it was all sorted.

The validate is run on the HTTP thread as it is received as an HTTP request, if you ever want to cleanup on the HTTP thread you can so with ExecutionCleanup.cleanup().

Thanks,
Tim

link publish delete flag offensive edit

answered 2010-03-09 14:01:40 +0800

dastultz gravatar image dastultz
797 9

Tim,

I've discovered a severe race condition in my handling of database connections. Fixing the condition makes this problem go away, so it appears it's my fault, which is fine since I could fix it pretty quickly. While I still think Constraint.validate() should run on an event thread, it really doesn't matter from a practical standpoint.

Anyway, I did learn from you about ExecutionCleanup.cleanup(), so do appreciate your attention.

Thanks.

/Daryl

link publish delete flag offensive edit

answered 2010-03-08 08:52:37 +0800

dastultz gravatar image dastultz
797 9

ExecutionCleanup.cleanup() runs only on the HTTP thread, therefore it doesn't clean up my connections acquired in events. Can we go back to the original message? Constraint.validate() is being run on the http request thread rather than an event thread. Why is that? If Constraint.validate() ran on an event thread, I don't think I'd have any problem. Are you sure it's supposed to run on the HTTP thread?

/Daryl

link publish delete flag offensive edit

answered 2010-03-07 21:56:22 +0800

tmillsclare gravatar image tmillsclare
799 2 5 30

Hey Daryl,

>You should only cleanup in ... ExecutionCleanup.cleanup()

Are you saying I don't need the other 3? ExecutionCleanup.cleanup() is always called after all the others?

Yes, you should not need the other 3, ExecutionCleanup should suffice!

Please let me if it works!

Thanks,
Tim

link publish delete flag offensive edit

answered 2010-03-04 10:39:05 +0800

dastultz gravatar image dastultz
797 9

ConnectionResource.cleanUp() is the method that does the actual cleanup. It is called from

EventThreadCleanup.cleanup()
ExecutionCleanup.cleanup()
EventThreadCleanup.complete()
EventThreadSuspend.beforeSuspend()

>You should only cleanup in ... ExecutionCleanup.cleanup()

Are you saying I don't need the other 3? ExecutionCleanup.cleanup() is always called after all the others?

>A very simple way to solve your problem is to turn the event thread off. If you are not using modal dialogs it is the best solution.

Ah, but I am using modal dialogs. While it may solve the problem, it's a workaround rather than a fix. If the problem is my code I'm happy to fix it, but I should not have to work around it if the problem is in Zk. I'm not convinced the problem is mine yet.

Thanks for sticking with me on this.

/Daryl

link publish delete flag offensive edit

answered 2010-03-03 20:27:33 +0800

tmillsclare gravatar image tmillsclare
799 2 5 30

Hey Daryl,

Why are you cleaning up in

DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - removing from Thread-33
and
DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - removing from http-8080-1?

You should only cleanup in DEBUG 03/01 12:49:06 : ExecutionCleanup.cleanup() - on http-8080-1 and that should solve your problem.


A very simple way to solve your problem is to turn the event thread off. If you are not using modal dialogs it is the best solution.

link publish delete flag offensive edit

answered 2010-03-01 12:12:08 +0800

dastultz gravatar image dastultz
797 9

I've done as you say, and if I simply TAB off the textbox it works as expected and I get this logging:

DEBUG 03/01 12:51:36 : Constraint.validate() on http-8080-1
DEBUG 03/01 12:51:36 : ConnectionResource.get() conn ...Connection@392cf455 on http-8080-1
DEBUG 03/01 12:51:36 : Constraint.validate() got connection ...Connection@392cf455
DEBUG 03/01 12:51:36 : Constraint.validate() exiting
DEBUG 03/01 12:51:36 : ExecutionCleanup.cleanup() - on http-8080-1
DEBUG 03/01 12:51:36 : ConnectionResource.cleanUp() - connectionRetrieved = true
DEBUG 03/01 12:51:36 : ConnectionResource.cleanUp() - removing from http-8080-1

The second line shows the connection being retrieved. The second to last shows that the ThreadLocal variable knows the connection was retrieved and it is closed (not shown). But if instead of TABBING off the field, I click the Save button, I get a different set of log entries and it fails:

DEBUG 03/01 12:49:06 : Constraint.validate() on http-8080-1
DEBUG 03/01 12:49:06 : ConnectionResource.get() conn ...Connection@393d701a on http-8080-1
DEBUG 03/01 12:49:06 : Constraint.validate() got connection ...Connection@393d701a
DEBUG 03/01 12:49:06 : Constraint.validate() exiting
DEBUG 03/01 12:49:06 : EventThreadInit.prepare() - on http-8080-1

DEBUG 03/01 12:49:06 : EventThreadInit.init() - on Thread-33
DEBUG 03/01 12:49:06 : EventThreadCleanup.cleanup() - on Thread-33
DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - connectionRetrieved = true
DEBUG 03/01 12:49:06 : ConnectionResource.get() conn ...Connection@5a3bb53f on Thread-33
DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - removing from Thread-33

DEBUG 03/01 12:49:06 : EventThreadCleanup.complete() - on http-8080-1
DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - connectionRetrieved = false
DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - removing from http-8080-1

DEBUG 03/01 12:49:06 : ExecutionCleanup.cleanup() - on http-8080-1
DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - connectionRetrieved = false
DEBUG 03/01 12:49:06 : ConnectionResource.cleanUp() - removing from http-8080-1

Again, the second line shows the connection being retrieved and the constraint runs. Then Thread-33 is spun up presumably to handle the Save click. On the third line of the "second paragraph" it appears as though Thread-33 has retrieved a connection, though there is no corresponding retrieval line. I then expected the third line of the third paragraph to show that the connection had been retrieved on http-8080-1, but it doesn't show this. It appears as though the state of my ThreadLocal jumped from one thread to the other. Since it doesn't think the connection was ever retrieved, it doesn't try to close it.

Do you have any insight as to what may be going on here?

Thanks.

/Daryl

link publish delete flag offensive edit

answered 2010-02-22 19:34:54 +0800

tmillsclare gravatar image tmillsclare
799 2 5 30

Hey Daryl,

Here are some steps:

1. Implement the interface ExecutionCleanup. Let's name the implementing class "CycleCleanup"
2. Get your db connection in the Validate routine and make sure the data is valid
3. In CycleCleanup's clean up routine implement your cleanup code, checking to see whether the db connection is active and if it is release the resource

This should now work.

link publish delete flag offensive edit

answered 2010-02-12 08:15:49 +0800

dastultz gravatar image dastultz
797 9

Well, I thought that would work, but it doesn't. Here's my current log of happenings:

DEBUG 02/12 09:11:00 : EventThreadInit.prepare() - on http-8080-4
DEBUG 02/12 09:11:00 : EventThreadInit.init() - on Thread-65
DEBUG 02/12 09:11:00 : EventThreadCleanup.cleanup() - on Thread-65
DEBUG 02/12 09:11:00 : EventThreadCleanup.complete() - on http-8080-4
DEBUG 02/12 09:11:00 : EventThreadInit.prepare() - on http-8080-4
DEBUG 02/12 09:11:00 : EventThreadInit.init() - on Thread-65
DEBUG 02/12 09:11:00 : EventThreadCleanup.cleanup() - on Thread-65
DEBUG 02/12 09:11:00 : EventThreadCleanup.complete() - on http-8080-4
DEBUG 02/12 09:11:00 : Constraint.validate() on http-8080-4

EventThreadCleanup.complete() is called BEFORE Constraint.validate(), thus missing the opportunity to close the database connection. This certainly has to be a bug as EventThreadCleanup can't do what it's supposed to be able to do. Unless there's another interface I could implement to clean up the main thread after Constraint.validate()?

/Daryl

link publish delete flag offensive edit

answered 2010-02-09 07:31:30 +0800

dastultz gravatar image dastultz
797 9

> The original received validate command is HTTP then the processing is done in the EventThread.

Ok, I'll add cleanup code to EventThreadCleanup.complete(), thanks.

/Daryl

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-01-27 13:05:08 +0800

Seen: 816 times

Last updated: Mar 12 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More