views:

723

answers:

4

I have a Flex application that calls a function which searches a large document collection. Depending on the search term, the user may want to stop the request from flex.

I’d like to not only stop the flex application from expecting the request, but also stop the CFC request. Is this possible? What’s the best approach for doing this?

A: 

You can programmatically end requests with either <cfabort/> or <cfsetting requesttimeout="0"/> - but that's on the CF server side of things, which I don't think is what you're asking?

Ending it remotely... well, if you have FusionReactor it might be possible to contact that using Flex and have it interrupt the request for you. (You can certainly try to end requests within FusionReactor, but whether or not Flex can actually ask FR to stop it... you'd have to ask that on the FR mailing list if there's a way to do that.)


Possibly an alternative solution is to try and architect the search so that it works over multiple requests, but how feasible that is will depend on exactly what you're searching.

Peter Boughton
+1  A: 

If you are using ColdFusion 8 you can make use of the <cfthread> tag. You can spawn the search process off on its own thread and then use the remote call to terminate the search thread as needed.

Dan Cramer
Threads work within a request, rather than across multiple requests?
Peter Boughton
+6  A: 

I don't think there is a direct way to stop a page call externally. According to the docs, only the thread itself and it's parent can abort a given thread.

However, you could set a flag for a given thread in a shared scope.

Let's say you call a method that starts some background processing. It generates a unique thread ID and returns it to the caller. The thread looks for a flag in (for example) the application scope that tells it to stop. It checks at each substep of the background process. It could abort at any point that flag is thrown.

To throw the flag, add an abort method that takes the name of the thread that is to be aborted, along with sufficient security to make sure a 3rd party can't just start killing off threads.

Ben Doom
+2  A: 

To add onto Ben Doom's answer, I'm including some example code of a way this can be accomplished. There are multiple approaches and ways of names, organizing and calling the code below, but hopefully it is helpful.

At some point during request start, store information about the process in shared scope and return an ID to the client. Here are example functions that could be used on page or remote requests.

<cffunction name="createProcess" output="false">
  <cfset var id = createUUID()>
  <cfset application.processInfo[id] = {
    progress = 0,
    kill = false
  }>
  <cfreturn id />
</cffunction>

Client can then check progress by polling server, or submit request to kill process

<cffunction name="getProcessProgress" output="false">
  <cfargument name="processID" required="true">
  <cfreturn application.processInfo[arguments.processID].progress />
</cffunction>

<cffunction name="killProcess" output="false">
  <cfargument name="processID" required="true">
  <cfset application.processInfo[arguments.processID].kill = true />
</cffunction>

The actual server-side process in question can then hit a function, for example during a loop, to check whether it should abort processing and cleanup any work as appropriate.

<cffunction name="shouldKillProcess" output="false">
  <cfargument name="processID" required="true">
  <cfreturn application.processInfo[arguments.processID].kill />
</cffunction>
Dan Roberts