Hi mark and others,
I was just thinking about it again, and i realized object/query
caching would be exactly a thing best solved with AOP.
So i had a look at this article:
http://cdscott.blogspot.com/2005/10/coldspring-aop-tutorial-part-one.html
Which is a coldspring AOP tutorial. And i thought, maybe the best way
to solve the whole caching problem the easiest way is like this.
For now, i think the gateway classes would be the ones benefitting the
most from caching as they return a lot of data, the record methods
probably rarely need to be cached, or never (correct me if im wrong).
We cant really use coldspring to do our aop. So, we need to do AOP in
the ReactorFactory.createGateway.
We would need a class, actually just one class, that has one method
that would look something like this:
<cffunction name="before" access="public" returntype="any">
<cfargument name="method" type="coldspring.aop.Method" required="true" />
<cfargument name="args" type="struct" required="true" /> <-------
These args are the key in whatever cache solution used.
<cfargument name="target" type="any" required="true" />
</cfloop>
This method has to be executed on every method call in any gateway
object, or maybe better: any method that returns a query.
If i have time i will try to rip things out of coldspring to make this
happen, or maybe even use complete cfc's from coldspring if thats
possible. The good thing about this solution would be that even custom
methods in the xxxmssql.cfc's will be cached.
It might be pretty difficult to get this done, but very unobtrusive,
the whole reactor library will stay the same, except for the one
reactorfactory.createGateway method.
The key in whatever cache solution we use, would be derived from the
set of arguments and values.
So if all argument-values are the same, we can decide to return a
cached query and not execute the normal method.
On top of this, this before method (or whatever name used), can write
up an xml file, for every method (and even possible argument values),
a default cache timeout is added (default would be 0). It can write
this up when gateway methods are called, which would mean you would
have to first execute methods to have a complete xml file. Another
option would be to write one up straightaway by parsing all gateway
cfc's, which would require extra code.
Now we can completely optimize the cache timeouts per method per
gateway and even per argument values. With this xml file you can
basically 'tune' your application, i think its even nicer that the
cfquery cache tags... which are not central, and you forget about
them. Caching is something that should be configured centrally if you
ask me, as its an aspect problem.
Another solution would be to add a custom reactortimeout attribute to
gateway methods, like <function name="getAll" reactortimeout="20" ....
But the disadvantage of this is that you can not do this with cfc's
in the project directory of reactor.
One 'but' is, if certain methods are not determenistic (e.g. do not
make the same query with the same arguments because they use variables
from other places/cfc's), the caching will mess things up. I have to
think about this better, a solution would be to just keep the
timeout's of these methods 0. It should not happen in to much cases
anyway.
The before method now has all information, a key, a timeout. Reactor
now just needs a general interface cfc that specifies an interface for
a cache solution. Whatever caching solution (implementing this
interface) can now be injected with coldspring using the
reactor.config.Config cfc, which would have to be modified for this.
What do you think about this solution? Is this worthy an RFC ?
greets,
Klaas-Jan