Compound Theory

v2.0

Categories

  1. Transfer
  2. ColdFusion
  3. JRuby
  4. Java
  5. ColdSpring
  6. Squabble
  7. JavaLoader
  8. ColdDoc
  9. 2ddu
  10. AsyncHTTP
  11. OO Analysis and Design
  12. Flex
  13. Railo
  14. XML / XSL
  15. Hibernate
  16. ColdFusion Builder
  17. Fall
  18. Ubuntu
  19. XHTML / CSS
  20. Eclipse
  21. Git
  22. Oracle Database
  23. Usability / UI Design
  24. webDU
  25. cf.Objective()
  26. LWJGL
  27. cf.Objective(ANZ)
  28. Captcha
  29. MAX
  30. Melbourne CFUG
  31. Martial Arts
  32. Random Things
  33. Conduit

Recent Posts

Projects

Recent Comments

23 October 2008 04:23 AM 7 Comments

Adobe eSeminar tomorrow: Transfer ORM Caching Mechanics

Just a reminder that I'm doing an Adobe eSeminar tomorrow at 2pm on Transfer Caching Mechanisms

One of the most powerful features of Transfer is its highly configurable, in-built caching layer that allows for significant performance gains for a given application when configured correctly.

During this eSeminar we'll discuss caching concepts such as 'caching algorithms' and 'memory sensitive caching', so that as a Transfer Developer, you'll have a better understanding of the intricacies of Transfer.

Click here to register

Click here for World Times

20 October 2008 09:45 AM 3 Comments

Managing Selfish Threads in ColdFusion

As per usual, this is something that came out of my work with Transfer, but is something that applies to any ColdFusion application that exists.

So in the context of ColdFusion, what exactly are we referring to when we say Thread?  Generally the first thing we think of is <cfthread>, which executes some code on its own given Thread.  But, we should also remember that the original page that was executing, is its own Thread as well.  If we run a scheduled task, that is also it's own Thread.

Wikipedia defines a Thread very well:

"A thread in computer science is short for a thread of execution. Threads are a way for a program to split itself into two or more simultaneously (or pseudo-simultaneously) running tasks..."

So when looking at Threads, we can consider:

To be its own Thread, because, it is!

So what defines a Selfish Thread?

A Selfish Thread is a thread that takes up almost all of the CPU's processing, without allowing any other Thread to be able to utilise the CPU at all.

Some code like this, would be a good example of a Thread being selfish -

<cfscript>
    for(counter = 1; counter <= 10000; counter++)
    {
       writeOutPut(counter & "<br/>");

    }
</cfscript>

It's a very tight loop, and there is no waiting, or pausing, or 'room' for any other processing to do anything else while this loop processes.

Now it should be noted, that a Selfish Thread may not necessarily be a bad thing.  In many instances, we want this loop to completed, without waiting for any other Thread to interrupt it.  But in cases when Thread execution can go on for a long time, this can be highly disruptive to an application, as nothing else can be done during that time.

The common CF solution I often see for this, is the scheduled task that runs at 3:00am, so that it doesn't bother any of the users.  This can work perfectly well for many applications, but what if your application is 24 hours? Or is something that has to run every hour, what do you do then?

Before we get into this too much, I want to make note of something - managing Threads is bit black magic, and a bit trial and error.  Since Threads are managed differently per OS, and there are differences per JVM, some of these techniques will work, and some will not, so make sure you test everything thoroughly so you know that it is affective for your OS and JVM configuration.

The other thing to note, is that any Thread that is running, is an actual instance of th Java object java.lang.Thread.  If at any point and time we want access to the actual Thread object that the given process is running we can run:

currentThread = createObject("java", "java.lang.Thread").currentThread();

Will return a reference to the currently executing Thread object, which will be very handy as we move along.

The first thing we should look at, is <cfthread>.  CFThread has a 'priority' attribute that can be set to 'HIGH', 'NORMAL' or 'LOW', which should  control the level of priority that a Thread has.  For example, a HIGH priority thread should have processing precedence over a LOW priority thread.

For example:

<cfthread action="run" name="foo1" priority="LOW">
<!--- do some processing --->
</cfthread>


In reality, I've not seen this actually do much (in my tests), and it does not seem to actually effect a Thread's Thread.getPriority(), which we will talk about later.  That being said, there may be some other mechanism under the hood, and its not going to hurt anything if you choose to use it.

From here, we can look at setting a Threads priority, which can be applied to any CF based Thread (i.e. pages, scheduled tasks, cfthread etc).  A Threads priority goes from 1 to 10, where 1 is the lowest priority, and 10 is the highest.  5 is usually considered 'Normal'.

In theory, a lower priority Thread should give way to a high priority Thread whenever the higher priority Thread requires CPU processing time.  As stated earlier, depending onJVM and OS, this may, or may not happen.

To set the Thread's priority, all you need to do is grab the current thread, like we did above and call:

currentThread.setPriority(2); //set it to a lower priority.
//do some processing...

Since ColdFusion tends to pool Thread (i.e. stores them for reuse), we should reset the Thread's priority after we are done with it, so that it doesn't stay that when it gets used to execute another piece of code. e.g.

priority = currentThread.getPriority();

currentThread.setPriority(2); //set it to a lower priority.

//do some expensive, long running processing...

currentThread.setPriority(priority); //reset it

This way, when the Thread get re-used, the Priority is not set to something that is inappropriate for the processing it is doing.

There are also mechanisms in Java that allow you tell the JVM when a good time is for the current thread to yield to other threads that need to do some processing.

This simply hints to the JVM that 'hey! now would be a really good time for me to pause for a second, if you wanted to do something else'.  The JVM can totally ignore this if it chooses, and depending on OS and JVM, it may well do.

To do this, we call the static method yield(), on java.lang.Thread, like so:

createObject("java", "java.lang.Thread").yield();

So we can now take our very selfish loop above, and do something similar to:

<cfscript>
    for(counter = 1; counter <= 10000; counter++)
    {
       writeOutPut(counter & "<br/>");
       createObject("java", "java.lang.Thread").yield(); //here is a good place to pause
    }
</cfscript>


This is actually a very poor use of yield(), simply because in a display, we would never want the server to pause when displaying some data, but it displays how it works reasonably well.

The interesting thing is, yield() automatically resolves what the current thread it is processing on, and works that way, rather than the setPriority() method we saw above, which required us to use a specific Thread.

Quite probably the least useful, but the most consistent way of managing selfish threads, is by putting the thread to sleep, which will allow other Threads access to the CPU while that thread is asleep.

This is the least useful, as no matter what, the Thread will pause.  Nothing else may be happening on the server, but the Thread will pause anyway, which can mean wasted cycles for whatever it is you are doing.

That being said, this will always work, no matter what JVM or OS you are on, so there is a trade off.

There are three ways we can make the current thread sleep in ColdFusion,

In cfscript:

<cfscript>
    sleep(1000);
</cfscript>


via a Tag

<cfthread action="sleep" duration="1000" />

And via Java,

currentThread = createObject("java", "java.lang.Thread").currentThread();
currentThread.sleep(1000);

Either way, in the above example, the current thread will pause for 1000 milliseconds.

In a real world example, there is no reason we can't combine these techniques.  If we had some processing we wanted to happen asynchronously, but we knew it was going to take a while to complete, we could do something like the following:

<cfthread action="run" name="foo1" priority="LOW">
    c
urrentThread = createObject("java", "java.lang.Thread").currentThread();

    priority = currentThread.getPriority();

    currentThread.setPriority(3); //set it to a lower priority.

    for(counter = 1; counter <= 10000; counter++)
    {
       doSomethingExpensive();
       createObject("java", "java.lang.Thread").yield(); //could pause here
    }

    currentThread.setPriority(priority); //reset it
</cfthread>


Which gives us multiple ways in which to tell Java to make sure that other Threads are able to access the CPU.

Next time you are looking at a long running, expensive process, you now have multiple options about how you want to manage it.

17 October 2008 06:17 AM 2 Comments

Transfer 1.1 Final Released

After a few minor delays, Transfer 1.1 Final is ready for final release.

A few bugs and fixes occured during the release candidate period, so make sure you upgrade to the final release if you are running the release candidate.

For those of you not familiar with the new features of 1.1, some of the highlights of 1.1 are:

Huge Performance Enhancements!

During Testing (on my machine), a 500 Object load has been reduced from an average of 8 seconds down to an average of 6 seconds.   This is a speed increase of around 25%!.  I've even seen Object loads of 500 objects as small at 2 seconds.

Even for the performance alone, it is worth upgrading!

Transfer Object Proxies

This of this like Lazy Loading, but on steroids!

With a simple new setting 'proxied' on onetomany, manytoone and manytomany elements like so:

<onetomany lazy="true" proxied="true">
...
<onetomany>

Objects in the collection will be loaded as Proxies of the real object, and their underlying data will be loaded on an individual basis upon request.

A very handy feature when dealing with large collections.

New Discard Algorithm

Before, if you had a configuration when A -manytoone->B, and B was discarded from the cache, both A and B would have been discarded.

Now in the new algorithm, if B gets discarded, A simply unloads its many to one, and stays resident in the cache.  This ensures there is less unnecessary too-and-fro between the database and Transfer's cache.

Cache Monitoring and Reporting

While there is a new CachMonitor component that allows you to get fine grained reporting on what the cache is doing, to get a re-built cache report, it is as simple as:

<cfimport prefix="report" taglib="/transfer/tags/reports">
<---  Basic Report --->
<report:cacheReport monitor="#application.transferFactory.getTransfer().getCacheMonitor()#">

<---  Detailed Report --->
<report:cacheReport monitor="#application.transferFactory.getTransfer().getCacheMonitor()#" mode="detail" chartsize="300">

TQL Custom Tags

Big thanks to Elliot Sprehn for contributing these TQL custom tags, that make it super easy to do TQL queries, in a <cfquery> style!

For example:

<cfimport prefix="t" taglib="/transfer/tags">

<---  Do list operations --->
<t:query name="result" transfer="#getTransfer()#">
        select
                u.firstName, u.lastName
        from
                user.User as u
        where
                u.email like <t:queryparam value="%example.com" type="string">
</t:query>

<---  Do read operations --->
<---  Get a single record as a TransferObject --->
<t:query name="user" action="read" class="user.User" transfer="#getTransfer()#">
        from
                user.User as u
        where
                u.email = <t:queryparam value="user@foo.com" type="string">
</t:query>

Lots of bug fixes

The usual slew of bug fixes, improvements, and other various adjustments.

If you want more information on what got included in this release, and why to upgrade, I would highly recommend the 'What's new in Transfer 1.0 (and 1.1) ' presentation recordings, and also make sure you check out the Release Notes .

Transfer 1.1 download .

13 October 2008 08:27 AM 0 Comments

Transfer Survey, now open!

I've put together a short Google Forms survey on Transfer to get some consolidated feedback from the community at large on what people are doing with Transfer, what features they want in the future, and what can be done to improve it overall.

It isn't limited to just people who are using Transfer.  If you are not, I also want to hear your reasons why, as hopefully it is something that can be improved upon in the future.

It shouldn't take you much longer than around fifteen minutes to complete, and I would really appreciate the feedback.

Transfer Survey

 

08 October 2008 10:11 AM 2 Comments

Melbourne CFUG - 16th of October

All,

This Month's CFUG is lined up!

Location:
NGA.net, Level 2, 17 Raglan St, South Melbourne
Map: http://link.toolbot.com/google.com/73016

When:
16th of October, Meeting starts at 7:00, so get there before hand (doors
open at 6:30).

Agenda:
Recorded Presentation by Dan Wilson

Refactoring in ColdFusion

If you would like to know how to migrate an existing procedurally programmed application into an object oriented one, grab a chair and sit for a while. We'll discuss some sensible guidelines designed to help you make incremental changes towards OO nirvana. We'll also look at lots of code samples, we all like code samples, right?

If you are going to attend, please RSVP to mark (dot) mandel (at) gmail.com.

Only those that RSVP are eligible for the door prizes, so make sure you apply!

See the CFUG Melbourne Calendar at:
http://www.cfcentral.com.au/Events/index.cfm

Or add to your Google Calendar - search for 'CFUG Melbourne'.

As per usual, we'll grab pizza during the evening, so we have
something to scoff down!

Look forward to seeing you all there.
04 October 2008 12:10 PM 0 Comments

Not been blogging much, where have I been?

I came to the realisation the other day, that my blog has really become almost totally announcement based.  A series of presentation announcements, eSeminars, ColdFusion User Groups, Code Releases and various other 'hey! this is what is going on' posts.

It used to be chock full of weird and interesting things you could do with ColdFusion, and combining with the Java layer that sits underneath it to do even weirder and even more interesting things with that.  Sadly, I've been super busy over the past <insert long time frame>, and I've let things slip.

That being said, I plan on returning to the original theme of this blog, and start publishing some of the new things I've found out about ColdFusion, and what can be done with it.  I've got some interesting ideas on article on ColdFusion and Threading, and also some more on onMissingMethod and method injection and manipulation, so be prepared!

So what has kept me so busy? Quite a lot actually. In no particular order...

Consulting full time.
This has been one of the biggest changes, and adjustments for me to make over the past 6 months or so.  That being said, it is going very well, and I am keeping myself very busy (Almost too busy!).  I love working from home, and love the flexibility working for myself gives me.

I also find it is a really rewarding experience. Working for yourself challenges you in a variety of ways, as you only have yourself to rely on, and you are solely responsible to make it or break it.

While mostly I've been doing Transfer related work, I've also been doing some mentoring and memory leak analysis, all of which have been really interesting.  Coming from a background in which I have tended to work on single projects for months/years at a time, having a variety of undertakings going at once is a nice change.

Speaking at webDU
I didn't even blog about this, which was very remiss of me!  But I went to webDU, which was great fun.  I gave a presentation on TQL, and although I had some projector issues, it seemed to go quite well.

Writing Transfer code
I also got very busy writing Transfer 1.2 in my spare (?) time.  I'm really getting excited about Transfer all over again, and I think I have some really interesting ideas for the future. The next version is almost mapped out in my head... but I will wait until after the Transfer Survey before setting it in stone.

Writing DevNet Frameworks Article
Writing articles always take far longer than you expect them to, but when they finally get published, it feels really great.  From the feedback I've received the Introduction to ColdFusion Frameworks has been well received, and given some people new to frameworks some perspective over the landscape.

Something Super Cool Special
Been spending some time doing something really, really cool, but I can't really talk about it yet...

Don't you hate it when people say that? ;o)

Technical Editing for FAQU
I've also started technical editing for the Fusion Authority Quarterly Update, which one was one of those random opportunities that show up during a conversation I was having with Judith Dinowitz.  Editing other people's articles in an interesting endeavour, but (I find) much easier than writing them in the first place ;o)

Went on Holiday
I actually hadn't had a proper holiday in several years, and it has made a huge difference!  Taking a solid break for a few weeks has meant I've come back with a new passion for writing code, and a variety of other things in my life.  I always forget how much change a holiday can bring.
So that's my life at the moment in a nut shell.  Figured I would let people know what was going on.

An introduction to ColdFusion frameworks - now on Adobe Devnet!

I'm feeling pretty excited, because my first article for Adobe DevNet has finally been published.

An introduction to ColdFusion frameworks

It covers the differences between Model-View-Controller, Dependency Injection, and Persistence frameworks, and also gives a general overview of some of the most popular offerings that are available in ColdFusion right now.

There was a bit of a rush towards the end, and some pieces of it are not as perfect as I would have liked, but I hope that it serves as a way for people to enter into the ColdFusion framework world, gives them enough information so that they understand the differences between framework types, and also allow them to make an informed decision on which one to use based on their personal preferences and needs.