Copy link to clipboard
Copied
I have a series of CFC methods which call each other (using cfinvoke) to determine the inventory of an item, and down in the lowest level of the calls, I'm making a Java Socket() call to my ERP server to get real-time inventory (and then that value is bubbled up and used through the calling CFCs to determine what message to display on our site. The issue I'm trying to deal with is how to gracefully recognize when there's no response from the ERP server and give up within 3 seconds. So ideally, I'd like to add some sort of timeout to either the method that makes the socket call itself, or the method that calls that method.
The socket class that I'm using has an internal connection timeout of 5 seconds, although it doesn't seem to really follow that. If I point it at a non-responsive address, it seems to take over a minute to give up and timeout. So I don't trust that setting, even if I wanted to recompile the class to receive the timeout as a parm. Here's the basic Java code used to create the socket connection:
Socket socket = new Socket();
try {
socket.connect(new InetSocketAddress(host, Integer.parseInt(port)), 1000);
socket.setSoTimeout(5000);
}
I tried adding <cfsetting requesttimeout="3"> to the method that makes the socket call based on some other posts I'd found, but it has no effect. I also tried making the final cfinvoke call as a webservice with the timeout parameter set, but again, it doesn't timeout.
Anybody have any other suggestions? Would love a CFTIMEOUT tag.
One could try this sort of thing, perhaps:
<cfthread action="run" name="t1">
<cfset cfthread.t1.done = false>
<!--- slow operation here --->
<cfset cfthread.t1.done = true>
</cfthread>
<cfthread action="join" name="t1" timeout="3000" />
<cfif not cfthread.t1.done>
<cfthread action="terminate" name="t1" />
</cfif>
--
Adam
Copy link to clipboard
Copied
The first thing I would try is to use the cfsetting tag for the entire cfc, not just one function.
Copy link to clipboard
Copied
Similar idea
<cftry>
<cfthread action="run" name="t1">
<!--- slow operation here --->
</cfthread>
<cfthread action="join" name="t1" timeout="3000" />
<cfif not (t1.status is "COMPLETED" or t1.status is "TERMINATED")>
<cfthread action="terminate" name="t1" />
<cfthrow type="thread_t1_terminated">
</cfif>
<cfcatch type=thread_t1_terminated">
<!--- handle t1's termination --->
</cfcatch>
</cftry>
Copy link to clipboard
Copied
One could try this sort of thing, perhaps:
<cfthread action="run" name="t1">
<cfset cfthread.t1.done = false>
<!--- slow operation here --->
<cfset cfthread.t1.done = true>
</cfthread>
<cfthread action="join" name="t1" timeout="3000" />
<cfif not cfthread.t1.done>
<cfthread action="terminate" name="t1" />
</cfif>
--
Adam
Copy link to clipboard
Copied
Great suggestion, seems to work like a charm. I'll need to test it a bit to see if I need to allow more cfthreads to handle heavy volume. And there's a bit of scope gymnastics required when you're calling a cfthread within a cfc to make sure all the appropriate variables are accessible, but all in all, very slick solution, thanks very much!