AsyncFileAppender fails within a spawned thread

I'm writing an asynchronous event interceptor and running into an
issue with the asynchronous file logging appender in Logbox. The
problem, fundamentally, is that the AsyncLogFileAppender uses cfthread
to spawn the log write action but you can't run cfthread from within
cfthread, so if you main application logic uses cfthread, any logging
will end up throwing an error trying to nest cfthread tags.

I'm unsure what the best way to solve the issue is. I was thinking
about dynamically rewriting the log appenders to use the general
FileAppender if the Root Logger uses an asynchronous log appender and
then dynamically swapping it back at the end of my interceptor but
that seems like quite the hack.

Perhaps a better method would be to wrap a try/catch around the call
to cfthread in AsyncFileAppender.cfc and if it throws an error about
nested cfthread calls, revert it to a normal, non-threaded, call to
append(attributes.entry). This would keep the performance gains for
existing applications while also making the built-in logging work for
applications using cfthread themselves.

Cheers,
Judah

How to tell if code is being run inside a CFTHREAD taghttp://www.compoundtheory.com/?action=displayPost&ID=251

Does that work?

?

That's nice Mark, I really didn't think there was any way to tell if
you were instead a cfthread spawned execution path or not. It is up to
Luis, of course, to decide whether or not he wants to implement that
sort of check with the Asynchronous Log File Appender or not, but I
think it is an excellent idea and I'll implement it locally while we
wait to hear what Luis thinks.

Cheers,
Judah

Hmm...alas, it looks like Railo doesn't return the same value for the
thread group that Adobe does. In fact, it returns a blank string. I'll
submit that as a feature request to Railo so there is compatibility
but I guess that's what we get for relying upon an undocumented
feature.

I guess I'll either go back to using try/catch or else come up with
some other way to distinguish between normal page threads and cfthread
spawned threads.

Cheers,
Judah

Opened up a JIRA ticket on this issue for Railo, fyi

https://jira.jboss.org/jira/browse/RAILO-527

Judah

I think Mark’s solution works well for Adobe cf only, as blue dragon also has a different thread group. So we are at an impass of how to tackle this.

Any ideas on how to do this without writing three implementations per server? Which I would prefer not to do.

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

I’m sure an ‘OR’ statement in the thread group name would would work?

Possibly something as sophisticated as ListFindNoCase().

Crazy I know ;o)

As long as there IS a name, it can be searched for.

  • ducks and runs *

Mark

LOL!! I love your ** comments.

Ok, we need railo is empty, adobe is “cfthread” any open blue dragon peeps out there can collaborate on this really quickly?

Anyways, going to ticket this out.

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

I’m a cheeky bugger I know ;o)

An interesting check could be to see what Railo uses for a Thread name for their General purpose web request threads, as if you are in there, you know you aren’t in a cfthread.

Just an alternative approach.

Mark

The main thread name seems to be of the form
HTTP-*portnumber*-*increment* so when I looked at it earlier today it
was HTTP-8080-2 on the built-in Tomcat webserver.

I'm going to run some more tests tomorrow. It occurred to me that I
should go look at Railo's internal code. I know that the thread being
spawned by a thread is not a Java limitation, so it must be a check
that Railo/ACF is doing. Therefore we should be able to do the same
check ourselves.

Judah

I agree,

Please investigate and we can add it to the core and prepare a logbox 1.1 release.

Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Here are the results of my investigation so far on Railo 3.1.2, CF 8
and CF 9. I don't have OpenBD installed on this box, so I'll ask
someone else to investigate that.

Basic test code:

<cfoutput>
#createObject("java","java.lang.Thread").currentThread().getThreadGroup().getName()#
</cfoutput>

<cfthread action="run" name="mythread">
  <cfscript>
        var Thread = createObject("java","java.lang.Thread");
    </cfscript>
  <cffile action="write" file="C:\threadname.txt"
output="#Thread.currentThread().getThreadGroup().getName()#">
</cfthread>

Results in

Railo: same name for both the page thread and the spawned thread (both
called "main")
CF 8: "jrpp" for page thread and "cfthread" for spawned thread
CF 9 (built in webserver): "web" for page thread and "cfthread" for
spawned thread.

I did find a way with Railo, however, to tell if you are in a cfthread
or not. Railo has a function called hasFamily() of off
GetPageContext() So in Railo, the following code:

<cfdump var="#GetPageContext().hasFamily()#">

<cfthread action="run" name="mythread">
  <cfset ThreadHasFamily = GetPageContext().hasFamily() />
  <cffile action="write" file="C:\threadinfo.txt" output="#ThreadHasFamily#">
</cfthread>

results in "False" on the main page thread and "True" inside the
spawned thread. I could not find a comparable function in ACF after
poking around their implementation of GetPageContext()

So thus far it looks like the best way to check is to check the Thread
Group name for ACF and to check GetPageContext.hasFamily() for Railo.

Not terribly clean or consistent, alas, but the best I can do so far.

Cheers,
Judah

Ok I think I can add this to the coldbox main utility class and just
reuse. The only test needed would be open blue dragon

This has been added yesterday to the core and also to logbox. Nice little tool to find if you are in a thread in any CFMLEngine.
Luis F. Majano
President
Ortus Solutions, Corp

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com