Nathan Smith sent me some good questions on CFThread. I've broken up his email and bit and have commented with my opinions. I'd like to know what others think as well. CFThread is brand new to the language. Just like we are still debating the best way to use CFCs, I think we have a long road ahead of us deciding what is 'best practices' for this feature. Anyway - Nathan's email:
In your blog posts, you mostly are using it to send some time-intensive tasks away from the page thread(user). This is done to return "control" to the user faster and make the application appear to run faster.
Actually that isn't always true. You can fire off threads and not wait for them to return. This does then result in the user getting a result a lot quicker. (Which you can kind of do in older versions of ColdFusion with the CFFLUSH tag.) You may choose though to wait for your threads to finish. This is done with the JOIN action:
<cfthread join="list of threads" action="join">
Most of the examples I have seen so far use cfthread to enclose some simple, operation or a single tag. Is it safe to enclose large blocks of code inside a thread?
Well I think the answer here is "it depends." I don't think there is any simple answer as to how much code should be inside a cfthread. I'd probably try to keep it small just because there is less chance to screw up (more on that later).
I have an application that is basically two parts - interface and core. At one point I do a cfexecute on the core, while the user waits. could I put a cfthread around this type of thing to protect the user from breaking their core-requests and processes? How do I know if all the stuff happening in the core will be "thread-safe"?
Ah and here is where things can get nasty. Let's assume that when a user requests foo.cfm, you fire off a thread and then tell the user 'your process is running.' If the user reloads, what should happen? Should the process run again? If not - then you need some way to track the thread. You can use the Application scope. Before the process runs, check for Application.ImDoingX. If true, then don't run the thread again. Inside your thread you need to set ImDoingX back to false when done. Problem is though - what happens if the process dies and never sets it to false? You may want to also record when the process began and do some kind of sanity check. If it has been running for 30 minutes then you may want to just assume it died.
This kind of goes back to what I alluded to earlier about less of a chance of screw up. It is very easy to "miss" errors in threads. If you wait for threads to join, you can check the status to see if something went wrong. If you don't wait for the threads to end, then you need another method. Again - the application scope may help you here. You can wrap the code in the thread with a try/catch, and have the catch set a "status" message saying that the process died.
I have coldfusion standard which limits the number of threads to 10. If I have a process that can run from n-100 threads but usually averages 7-10 is it still beneficial to put the threads in?
Sure. If your code needs more than 10, than the other ones will just wait. You probably want to monitor/log your code a bit and see how well it runs. See for example how often you go over 10.
How about inter-thread communication. Can I have a page show the status of other threads by having them send info back to the page thread. Say the % of completion for 3 different queues or something like that?
Yes you can - again though you need to use the Application scope (or session/server) to store the status messages. I can probably whip up a small demo of this later today.
If I can leave off with a few bits of advice (and probably repeating myself a bit here):
- Definitely be sure you notice errors in the threads. If you don't join, then be sure to log/update Application scope so that you know an exception occurred in thread. This has bitten me in the rear before.
- Definitely monitor how often your threads fire, how many, etc. Because things get "hidden" with threads, it's easy to overload/abuse/go crazy with how many are running. The server does put a limit on the total # of threads, but try to keep a handle on what you are doing.
- All in all - just tread carefully.
Archived Comments
I'd add to your advice list. Watch scoping. I'd say that scoping issues are more likely to turn up in CFthread usage than in Functions. Be sure to var scope any variables created just for the thread process.
Var scoping doesn't make sense here. When you are inside a cfthread, you have your own local scope. It is different from the global Variables scope. Each thread has his own local socpe.
<cfthread> may also be used when no users or browsers are involved at all. We have a process that runs through a data set and performs various actions based on that data. In some cases, certain data needs some correction which prevents processing this time around. Rather than hold up that whole process while some data fix is performed on that record, we just fire of a separate thread to have it fixed, but rather than wait, the main process keeps going. That allows the main process to keep on trucking. Next time around, the data record we had fixed previously is not all good, and the main process picks it up and finished whatever it was doing.
So threading behavior need not be used solely to improve the perception of page request speed to a human user.
True, it does implicitly set any created variables in the local scope. But I would still recommend explicitly var scoping these variables. It keeps you consistent with how you have to write functions. Plus I've seen issues with threads that are reminiscent of issues I've seen in functions that are not properly scoped.
This doc talks about the nature of the implicit thread local scope:
http://livedocs.adobe.com/c...
Terrance- Right - I'll concede that point.
Thanks for taking the time to write more about threads. I wonder if it would be valuable to create a library and/or framework for using threads. It is hard to articulate because programming threads are a new paradigm for a lot of us. Perhaps something like fusebox for threads with a way to do interthread communication and trap errors and manage joins.
I'm excited about this new capability, but I'm having trouble remembering all the places I wanted to use it in the past.
"With great power comes great responsibility"?
Mark Mandel has an interesting blog post on using child threads in threads and accessing the java.lang.thread
http://compoundtheory.com/?...
Unles I'm mistaken, it also looks like if you reference the java object you could solve the issue of page reloads spawning another thread that may still be active.
If you refer to the facing thread docs it has a few good methods that seem like they'd take care of the job:
http://java.sun.com/j2se/1....
It may be a newbie question. Does a CFTHREAD generates another concurrent request?
If so, If I have a request being executed once. Wouldn't CFTHREAD consume more server resources?
It could make difference in pics moments.
Ray, just to clarify the use of Application scope:
you're specifically talking about single users processing, say, one row in a database, yes? eg: a school admin system where multiple admin staff could edit student records ... but only one *should* at any one time?
so, if you don't need to tie specific application processing to a unique user request, tracking via session scope (for that users processing) is the go? (unique processing per user)
what if session scope isn't available?
What I'm getting at is webserver control of ensuring threads are not erroniously re-run vs trying to control this on the client end. Perhaps even a Flex front-end.
@barry.b: I'm not 100% sure I get you - but yes, if the Process was for a single user, then the session scope would make sense. If the Process is meant to be for the entire App, I'd use the Application scpe.
If the session scope is not available, then make it available. ;)
@ronan: I'm not entirely sure - sorry.
You can use this http://www.cfchris.com/cfch... page as a refernce also. It seems that many are asking questions and there are pretty few sites/ blog that answer these kind of questions. This domain has its subjects more for the developers and not that much on the beginner. I think a FAQ would be useful on any site. I wanted to lauch such thing on my http://www.jmihai.ro/blog, but I lack the time these days as there are always more important things to do :-) . Hoping you can give me a hand and post few interesting questions and answers.
Are <cfthread />'s safe to use inside singleton instantiated objects?