More efficient contexts

114 views
Skip to first unread message

Bruce Kirkpatrick

unread,
Nov 22, 2011, 6:02:30 PM11/22/11
to Railo
Currently using railo , tomcat 7, apache, mod_jk.

I wish the railo development team could figure out how to merge the
web-inf folders so that they have less duplication.

It really doesn't make any sense for scripts in a CFML mapping to be
recompiled individually for every context. Can't you throw those
files in a global class folder without breaking sandbox
functionality? I have around 300-400 scripts * 110 contexts. That
is about 1gb of extra storage and up to 40,000 files that causes
wasteful I/O lookups for every site plus wasteful or more tedious
backups. This gets worse with every web site I add. Even if I had
many different apps, I'm sure I'd still have a shared library. It
doesn't make sense to duplicate frameworks/libraries files to every
client.

Not having a jrun-style connector forces me to rewrite my app to use
reverse proxy and rewrite all my url routing. I was able to get one
of the sites working like this today. I have to spend another 10+
hours modifying the rewrite rules for all the web sites. I'm using
the catch-all localhost context to host all sites in the future.

I don't know how coldfusion enterprise contexts work, but if it is
duplicating class compilation as well, then it is far too inefficient
as well.

I'm also curious why the templates aren't fully cached by the second
request. I almost always have to make 3 requests before seeing the
fully cached performance.

Railo tries to be the faster engine, and I think the above would help
that cause.

My sites use 99.9% the same source code between them. So in my case
using multiple contexts doesn't make sense.

If mod_cfml or any other superior connector can also handle this
issue, that would be excellent.

I've been reprogramming my app to work in one context and its a lot of
work. The proxy rewrite rules especially.

Jordan Michaels

unread,
Nov 22, 2011, 6:25:19 PM11/22/11
to ra...@googlegroups.com
mod_cfml will add your contexts automatically so you don't have to edit
the Tomcat server.xml file for each new site. Right now it works
alongside the connector (mod_jk, mod_proxy, or mod_proxy_ajp), but I'm
currently working on a module that will make it all-inclusive. It
performed it's first working proxy request just a few moments ago. =)
So... progress is being made there.

For the context duplication issue, you can suggest features a variety of
ways to the Railo dev team. Planning has started for Railo 5 and 6 so
now is a really good time to submit ideas like this! Maybe better
context control or increased support for common-class installs could be
a feature in a future version?

Warm Regards,
Jordan Michaels

Peter Boughton

unread,
Nov 22, 2011, 7:06:13 PM11/22/11
to ra...@googlegroups.com
If you are on Linux, you could perhaps replace the common stuff with symlinks?

I think they would still appear as multiple distinct files to
Java/Railo, but it would probably still help to cut down that 1GB of
space quite a bit.

> My sites use 99.9% the same source code between them.  So in my case
> using multiple contexts doesn't make sense.

Well you're not *required* to use individual contexts - if you were
able to make the settings and source 100% the same for all sites then
you can simply point all the Tomcat's server.xml Host records at the
same context - the one context per host/domain is a convention not a
requirement.

Bruce Kirkpatrick

unread,
Nov 22, 2011, 8:21:35 PM11/22/11
to Railo
Yes, I have the one context thing working as follows:

This is context root:
/home/vhosts/

apache is separate virtualhosts like normal.

each virtualhost is like this:
/home/vhosts/domain1.com/public_html/
/home/vhosts/domain2.com/public_html/

I use mod_proxy_ajp with mod_rewrite so i can have redirects before
tomcat takes over.

RewriteRule ^/script.cfm$ ajp://%{HTTP_HOST}:8009/domain1.com/public_html/script.cfm
[L,P,QSA]

And I had to replace every CGI.SCRIPT_NAME variable in my application
with a custom variable that rewrites the path so my urls continue
working correctly. I'll have to update every site as well since the
skin templates often use this variable too.

It is time consuming to rewrite all the url rewrites due to the
verbose proxy syntax. R=301 redirects don't use proxy, so that makes
it less find/replace friendly.

My complaint is that multiple contexts needs to be rewritten either in
Tomcat or in Railo. It wastes too many resources. Every context is
2mb to 10mb of ram depending on how much a compiled class takes in
memory when cached. I don't know why simple directory security should
require wasting hundreds of mb of ram and storage. Perhaps there is
a security risk having the actual java classes under the public web
root as well. I don't know if it is possible for a hacker to replace
those with their own malicious java code. ACF had all this in a non-
public directory. I think the web-inf files & connector issues with
Railo are the biggest faults. Everything else is quite good. If you
made a mistake with setting up a new context, tomcat isn't able to
recognize deleting and adding it again unless you restart. I've done
this a few times by forgetting to give the new files apache
permissions and then had to restart tomcat. Restarting tomcat is very
painful. I have about 1000 failed requests and it takes over 4
minutes for everything to start responding normally again on a new
sandy bridge cpu. in my test environment, i just enable the contexts
i'm using because startup is even worse in a virtual machine. Soon,
I'll have just one context, but this is not a very good situation for
new railo users and I'd like it to be successful software so i leave
my feedback and do the workaround to move on.

The system should cache 1 file per unique path.
i.e. this file should be compiled to a global folder
/home/vhosts/domain1.com/public_html/script.cfm

example of global location
/opt/railo/tomcat/webapps/ROOT/web-inf/railo/cfclasses/global/
script.class
some kind of name hashing / tracking of compiled scripts in memory i
assume to sort out the uniqueness. I believe ACF just replaces
slashes with dollar sign to retain the full path.

However, it is better if only the mapping feature had a global class
cache. It doesn't need to work for everything. Obviously if you are
using a mapping, the sandbox is going to have to allow access to it
anyway probably so there is no security issue here I believe.

Todd Rafferty

unread,
Nov 22, 2011, 9:12:03 PM11/22/11
to ra...@googlegroups.com
I'll take the security of Railo's context any day over the opinion you expressed here. :)
--
~Todd Rafferty
Volunteer
Community Manager
Railo Server - Open Source
----

Peter Boughton

unread,
Nov 22, 2011, 9:25:56 PM11/22/11
to ra...@googlegroups.com
Bruce wrote:
> It is time consuming to rewrite all the url rewrites due to the
> verbose proxy syntax. R=301 redirects don't use proxy, so that makes
> it less find/replace friendly.

Then write a script to generate your configuration files for you!

It basically only takes cfloop and an array of host names.


> The system should cache 1 file per unique path.
> i.e. this file should be compiled to a global folder
> /home/vhosts/domain1.com/public_html/script.cfm

If you have a single context, each file in that context will be
compiled once, and stored in a location within that context.

Storing outside the context makes no sense - it's not how Tomcat/JEE
is designed to work.

You seem to be asking the Railo team to re-define the way JEE works
for your particular use-case, except you don't appear to *need*
multiple contexts in the first place.

Michael Offner

unread,
Nov 23, 2011, 3:04:15 AM11/23/11
to ra...@googlegroups.com
Hi Bruce

First of all, ACF (standard setting) has only ONE web-context for all web-sites and because of that you have only one WEB-INF folder.
BUT every cfml file is compiled in a single class file like in Railo as well, because all class files are in a single folder (extremely slow in Windows)! No merging of any kind here.

What you can do, compile your shared library to a .ra file (can be done in detail view of the mapping in admin). then define a mapping in server admin that use this ra file.

/micha

btw: we are working on reducing the memory footprint used for loaded classes in Railo Appollo (4.0)



2011/11/23 Bruce Kirkpatrick <skyf...@gmail.com>

Bruce Kirkpatrick

unread,
Nov 23, 2011, 10:20:30 PM11/23/11
to Railo
I think I made the wrong assumption about what a context is.  It seems
that railo deploys complete copies of itself in the web-inf folder for
each context.   Not just my scripts and settings, but the entire
application / cfml engine.  The overhead to do this is more then I
previous thought probably and this would be why Todd thinks I don't
make any sense.

I appreciate Michael's recommendation and this will be appropriate for
better performance after I rewrite some of how my code generation
works. That was the most relevant response that can help. I do
believe that the ra file would still be duplicated between all the
contexts, which would still waste memory.

We can stop discussing this further however because I've decided that
I'm not going to use multiple contexts at all based on performance &
available ram being more important to me. I'm not going to use apache
or mod_rewrite anymore. I will probably experiment with other java
servers to see what exists for doing url rewrites, good extension
api, lightweight / efficient. I might write my own extension to the
java server to handle url routing instead of relying on these other
ones which may be less efficient. From what I've read, regular
expressions are up to 10 times slower, even though this might just be
1 millisecond in additional processing for your request. Even 1
millisecond can add up.

On Nov 23, 3:04 am, Michael Offner <mich...@getrailo.com> wrote:
> Hi Bruce
>
> First of all, ACF (standard setting) has only ONE web-context for all
> web-sites and because of that you have only one WEB-INF folder.
> BUT every cfml file is compiled in a single class file like in Railo as
> well, because all class files are in a single folder (extremely slow in
> Windows)! No merging of any kind here.
>
> What you can do, compile your shared library to a .ra file (can be done in
> detail view of the mapping in admin). then define a mapping in server admin
> that use this ra file.
>
> /micha
>
> btw: we are working on reducing the memory footprint used for loaded
> classes in Railo Appollo (4.0)
>

> 2011/11/23 Bruce Kirkpatrick <skyfl...@gmail.com>

Bruce Kirkpatrick

unread,
Nov 23, 2011, 10:31:43 PM11/23/11
to Railo
Without knowing how java / railo function inside, my concept of
reducing memory usage could be compared to how some backup solutions
handle redundant information.

If large blocks of data between physical machines are the same, they
can store all of that information just once and reference it instead.

If you could write a java application that does some kind of checksum
comparison of new classes as they load and compare it with existing
loaded / classes and also found this to be faster after building it,
that could be more efficient and save cpu cycles / memory. But this
is totally a general idea with no understanding of what you have to
deal with in the existing code.

Thanks!

Bruce Kirkpatrick

unread,
Nov 23, 2011, 10:39:00 PM11/23/11
to Railo
Google also uses this approach to compress data within BigTable
according to their freely available published document explaining it.
They claim web pages compress to 90% smaller 5-6 times faster then
gzip due to all the shared navigation between pages. They really have
some clever ideas in that paper which can be generally applied to
other computing problems.

Sean Corfield

unread,
Nov 23, 2011, 11:31:25 PM11/23/11
to Railo
On Nov 23, 7:20 pm, Bruce Kirkpatrick <skyfl...@gmail.com> wrote:
> I think I made the wrong assumption about what a context is.  It seems
> that railo deploys complete copies of itself in the web-inf folder for
> each context.

I think the root of the problem is that you have a lot of assumptions
about Railo that aren't accurate - because you're not familiar with
how normal Java web applications behave. I've seen quite a few CFers,
whose only exposure to anything vaguely like a Java application server
is thru Adobe ColdFusion, have similar misconceptions about Java web
applications.

ACF provides no isolation between applications because it subverts
Java's web application infrastructure. As Micha notes, it provides a
single web context and lets you execute CFML code "anywhere". That's
why sandboxing is an "Enterprise" feature and is clunky and mostly
doesn't work properly (it's gotten better over the years). It's why
ACF still isn't a very good solution for shared hosting. It's partly
why shared hosting companies are giving up on ColdFusion.

Railo, on the other hand, has complete Java-based sandboxing built-in
for free - because it follows the Java web application model.

The standard installer uses the common class path / multi-web approach
where the Railo JARs are added to the base Java application server and
the basics of an independent Java web application is laid down in each
web context - so there are complete, separate, sandboxed Java web
applications. That's how Java web applications work. Railo shares a
lot of Java infrastructure between these web contexts by having its
core loaded into the common class loader.

I generally use the WAR deployment. That's a complete, separate
installation of Railo in each web context - no shared JARs. I do that
because I also have web contexts that are Java applications that don't
include Railo. In the grand scale of Java web applications, the
overhead of a complete instance of Railo in each web context is pretty
minimal - despite what you may think.

At World Singles, we mix CFML and Clojure. We use Clojure for a custom
log4j appender which has to be compiled to bytecode (normally Clojure,
like CFML, is deployed as source code). Because each web context has
its own class loader, we have to create a JAR from compiled Clojure
code and put it on the classpath of _each_ web application. The reason
for that is that a class loaded in one class loader is not considered
"the same" as the same class loaded into another class loader - so you
can't have a log4j appender in the common class loader that is used by
the web class loaders.

> We can stop discussing this further however because I've decided that
> I'm not going to use multiple contexts at all based on performance &
> available ram being more important to me.

Certainly moving everything into a single web context will use less
memory overall, especially if you have a lot of CFML applications and
they don't need to be sandboxed (in the Java sense).

Take a look at Jetty if you want a very lightweight Java server. Jetty
is designed to be small enough to be embedded in applications - that's
how the Cedar Stack on Heroku works, for example, and in the Clojure
world it's typically how people development web applications (with
frameworks such as Ring, Noir, Compojure and FW/1), even if they might
deploy to another Java application server.

> From what I've read, regular
> expressions are up to 10 times slower, even though this might just be
> 1 millisecond in additional processing for your request.

FWIW, macromedia.com had thousands of regex-based rewrite rules in
place - in Apache - and served many millions of page views a day. You
might be spending a lot of time optimizing something that isn't even a
real world problem...

Sean

Denny

unread,
Nov 23, 2011, 11:46:08 PM11/23/11
to ra...@googlegroups.com
On 11/23/11 8:20 PM, Bruce Kirkpatrick wrote:
> I think I made the wrong assumption about what a context is. It seems
> that railo deploys complete copies of itself in the web-inf folder for
> each context. Not just my scripts and settings, but the entire
> application / cfml engine. The overhead to do this is more then I
> previous thought probably and this would be why Todd thinks I don't
> make any sense.
...

Unless you are deploying stand-alone WARs for each project (which it
doesn't sound like you are), you'll notice that the .jar files are only
in the server context, and that the web contexts do not have them.

If you're seeing something different, there's something else going on.

What are you seeing duplicated? Are there .jar files in all of your
WEB-INF/lib directories?

> We can stop discussing this further however because I've decided that
> I'm not going to use multiple contexts at all based on performance &
> available ram being more important to me. I'm not going to use apache
> or mod_rewrite anymore. I will probably experiment with other java
> servers to see what exists for doing url rewrites, good extension
> api, lightweight / efficient. I might write my own extension to the
> java server to handle url routing instead of relying on these other
> ones which may be less efficient. From what I've read, regular
> expressions are up to 10 times slower, even though this might just be
> 1 millisecond in additional processing for your request. Even 1
> millisecond can add up.

Everything is a trade-off. Separate contexts are more secure, but
consume more memory. Separate *instances* are more bulletproof (bad
code will only take down one site, vs. all of them), but require more
resources, and are generally more complicated (using multiple ports, or
virtual IP addresses, etc.).

You're not going to find a java solution for rewrites that is faster
than Apache. Plus, a webserver in front of the appserver will take a
load off the appserver. The webserver is generally better at serving
static resources, and has more sophisticated caching for serving static
resources, and is more secure than exposing an appserver. Apache has
been *battle* tested far more than any other webserver in existence, I'd
wager.

Plus, apache has built-in load balancing and failover solutions, which
allow you to have setups where if your main appserver falls down, a
backup one can take over seamlessly. Lovely stuff- gets you close to
five 9s, and doesn't cost an arm and a leg or require big iron.

FWIW, it sounds like separate contexts for your generated sites *is*
overkill. You're learning some hard lessons that I too beat my head
against (while cursing previous-me for not thinking about the future a
bit more). I learned not to rely on things that are out of my control,
like cgi variables, and to give apps a "home", vs. "/", etc..

We can do some stuff to make transition easier (using a "/" mapping, for
instance), but ultimately we have to adjust our coding practices to
account for the "long tail" of development.

It's generally easier in the long run to do things that are a little
hard in the short term, if that makes sense. :)

:Denny

--
Railo Technologies: getrailo.com Professional Open Source
Skype: valliantster (505)510.1336 de...@getrailo.com
GnuPG-FP: DDEB 16E1 EF43 DCFD 0AEE 5CD0 964B B7B0 1C22 CB62

Bruce Kirkpatrick

unread,
Nov 24, 2011, 12:16:38 PM11/24/11
to Railo
Comparing how macromedia or adobe uses coldfusion to how a single
developer shop like me that uses coldfusion is quite different.   If I
save $100/month, that is huge - direct profit.   It is just "spare
change" to an enterprise.  They'll throw away thousands in a single
meeting that probably achieves nothing. They have to deal with
teaching a team of people how to do what the expert vision wants plus
the cost of doing business itself.  Their software gets bulkier and
more demanding each year at a higher price.  They don't think like a
small business.
Shaving off milliseconds is the real joy of the work.  I've been doing
CFML for 8 years and I'm at the limits of what you can do with it and
it is boring to stay where you are, just churning out the same work.
 Making subtle improvements is what I need to be happy.  I don't care
about getting rich or scaling out to having a store-front with 30
staff.  I pay my contractors 90% or more of the income and let them
develop their own business and schedule themselves however they want.
 I just want to make cool code.
I think Denny and Michael made recommendations that are helpful and it
seems they are more technical experts with a diverse range of
experience.   I guess you'll just have to remember that I'm one person
with no corporate experience and I self-fund my work through word of
mouth and free SEO.   Coldfusion might be used in the enterprise more
frequently since individual developers like me tend to use PHP or
other crap like .NET.  I just happened to work at a company that had
built most things in Coldfusion and I inherited the framework I wrote,
otherwise I'd be another php guy.   I find CFML's shared memory scopes
to be the strongest benefit of it over php.  I tested php's equivalent
features to be slower then current version of railo and I was done
with that debate.
However, I do plan on writing parts in C/C++ to go faster by wasting
less memory / cpu cycles and hopefully railo will keep improving as
well.  I feel CFML is not able to be optimized at a certain point
since it is a dynamic language and I don't understand how the java
code gets put together or how to write java.  What I learn in C, can
often be applied back to CFML or the database though.  I recently
realized that making copies of database tables with a different
clustered index can eliminate the need for sorting since they are
already presorted and denormalized.  I figured out how to do that by
accident by thinking of how I'd achieve this app in C and this made
those queries 10 times faster with far less work.  I was able to
reduce my CFML framework overhead from 60ms to as little as 3ms in the
last few months through programming changes only based on my knowledge
of what the fastest CFML language features are.   No user would care
about 53ms, but the difference in scalability is tremendous in
artificial tests (1000 concurrency, no problem, whereas the previous
version would stall for minutes on garbage collection and disk i/o)
and this will surely reduce my need to waste money on additional
hardware later.
I typically can migrate servers every 1-2 years at the same cost and
never need additional hardware.  It was a scary idea to have to buy a
new coldfusion license for each server.  If I wanted to do clustering
with Railo, I can now, which is something that is easy to forget until
you need it.  I'll surely prefer optimizing one server to its limit
before going to a clustered setup due to its complexity and overhead.
 I currently spend $300 per month for a dedicated 1 intel e3-1230 cpu,
8gb ram,  raid 1 7200rpm sas drive.  This cheap system achieves
average page load performance of 50ms to 200ms once the common data is
cached.  Most pages are searching a database of 10,000 to 150,000 real
estate listings and do multiple dynamic ajax / iframe requests.  If I
add an SSD drive, startup and app updates will be more tolerable.  My
server is currently only 15% loaded on average too.  I don't have a
performance / cost problem right now.  I'm just trying to program it
to be able to handle 300 similar sites now instead of 100 on the same
hardware.   When I launch a free trial and cheap template based
system, I will need that extra growth capacity faster since currently
I charge $1000+ for new custom sites, but that may be $50 per month in
a few months so sign-ups will be easier.  Perhaps understanding my
goals, you can see my logic that multiple contexts are not appropriate
for this. I want each new site to be 100% profit, and not require an
excessive amount of extra resources.
My whole company can operate including my living expenses for just
under $1000 USD per month.  I live in Florida, USA.  With my low
overhead, I'm able to focus on writing new code and pass on the
savings to my customers.  I'm doing about 80% of my work for free in
order to focus on having a superior real estate web design
subscription service rather then service individual customers.  I can
afford to spend a day debating which technique is 10% faster because
my time is free.  My in town competitor spends $2000 to $3,000 per
month in hosting to serve less capacity then I do with $300.  This
happens because the management doesn't know programming and is at the
mercy of the staff.  There is waste all throughout their organization
and they have to charge 3 times as much as me and often lose money
even with that.  It feels good knowing that your customer is not
having to pay for your inefficiencies and I strive to go without the
vices of traditional companies.

Sean Corfield

unread,
Nov 24, 2011, 7:21:59 PM11/24/11
to Railo
On Nov 24, 9:16 am, Bruce Kirkpatrick <skyfl...@gmail.com> wrote:
> I find CFML's shared memory scopes
> to be the strongest benefit of it over php.  I tested php's equivalent
> features to be slower then current version of railo and I was done
> with that debate.

Indeed. I was a user of both Fusebox for PHP and Mach-II for PHP and
the lack of shared scopes made those frameworks extremely sub-optimal
on PHP, compared to CFML.

> I feel CFML is not able to be optimized at a certain point
> since it is a dynamic language and I don't understand how the java
> code gets put together or how to write java.

Micha has made Railo a lot faster than ACF by keeping the underlying
translation of CFML closer to Java (in terms of how numeric types are
handled and how components map to classes, amongst many other things).
More could probably be done but staying compatible with ACF would
suffer I suspect. At World Singles, we are using Clojure - also a
dynamic scripting language - for performance-critical pieces of our
application, alongside CFML, because Clojure is designed to get Java
performance (numerics are primitive types, for example) while still
remaining idiomatic. We're finding Railo + Clojure to be a great
combination (ACF doesn't work so well with Clojure because of how it
deals with numeric types, e.g., an array of numbers is exactly that in
Railo but it is an array of strings in ACF that get converted on
demand to numbers... which Clojure doesn't like).

> I'm just trying to program it
> to be able to handle 300 similar sites now instead of 100 on the same
> hardware.   When I launch a free trial and cheap template based
> system, I will need that extra growth capacity faster since currently
> I charge $1000+ for new custom sites, but that may be $50 per month in
> a few months so sign-ups will be easier.  Perhaps understanding my
> goals, you can see my logic that multiple contexts are not appropriate
> for this.

Definitely. At Broadchoice and at World Singles, we have large multi-
tenant applications: a single codebase in a single context serving
many similar sites. At Broadchoice, it was a hosted CMS with many
different customers, each have many different hosted web sites. One
application, one context, one database. At World Singles, we have
about fifty dating sites. We're migrating from a legacy codebase to a
new platform, but each is one application, one context, one database**
and many sites. **Actually we're using both MySQL and MongoDB so it's
technically two databases but our CRUD abstraction makes it look like
a single datastore.

Sean

Bruce Kirkpatrick

unread,
Nov 29, 2011, 11:33:37 PM11/29/11
to Railo
Let me start by saying Railo is awesome, thanks.

I must still complain that multiple contexts are super inefficient and
should not be the default way for new railo installations or there
should be a way to disable it with a magic connector, etc.

I just finished migrating all my sites to a single context. (It used
to be 110 contexts - one for each web site). And like I said above,
there were over 40,000 java classes instead of the 450 like ACF
usually had for my application. Mappings should not be getting
compiled separately for every site.

The memory usage of JVM went from 2.4gb to 982mb immediately. I
didn't even lower the JVM settings. This is much more in line with
ACF memory usage. A HUGE IMPROVEMENT.

According to top in linux, my average I/O wait is about 1/3 as much
now.

Railo now also doesn't have any trouble caching all of the templates
and keeping all the sites fast at once now. Most pages are fully
cached and nearly the same speed as making a railo archive.

Clearly there is a lot more then a "modest" difference between single
and multiple context. Pretty much however big your WEB-INF folder is
without the logs is it how much ram you'll use on each context. It
is not just a matter of wasting ram though. It affects the entire
system's performance and causes extra garbage collection and very slow
startup time. Minutes compared to seconds. Because classes only
inspect/compile once now, the whole app is running smooth in about
40-50 seconds even in a tiny virtual machine.

I also had numerous issues with the server scope that go away when I
don't use it (in multiple contexts). I don't think server scope is
safe between contexts because there are known issues with the current
stable release of railo. I think my stability will be rock solid now
that I don't have these bugs and I have a healthy amount of ram for
the other processes. Railo was running out of memory before and
crashing every few days, but now I can give it more then it needs.

Anyone doing many hosts with the same source library would be wasting
enormous amount of resources with multiple contexts, I.E. Every site
running on one <Host> tag in tomcat is the better way to go.

I also put all my rewrite rules in httpd.conf and use mod_proxy_ajp
now, and that seems better then mod_jk / .htaccess like I was doing.

I still plan on using railo archives later and automate the deployment/
recompilation hopefully. It took about 30 hours to modify my app to
be able to simulate ACF standard behavior. Plus I made mistakes / had
downtime, etc Kind of tricky to implement mod_proxy on every site
you've done in the last 8 years when you are doing lots of url
rewriting like I do. I hope that the team considers making it easier
for other people's sake and to make better security use less resources.

Bruce Kirkpatrick

unread,
Nov 30, 2011, 12:16:07 AM11/30/11
to Railo
I believe locks on server scope actually lock each context separately
or synchronize them separately. They might even have separate copies
of the server scope memory?

I wanted to mention that my process that updates the server scope was
taking 16 seconds with multiple contexts and now it takes just 2
seconds. During these server scope locks, users would have to wait
the 16 seconds to be able to see the page. That is also a bad thing
about multiple contexts.

The server admin pages also update much faster without multiple
contexts.

Denny

unread,
Nov 30, 2011, 1:11:54 AM11/30/11
to ra...@googlegroups.com
On 11/29/11 9:33 PM, Bruce Kirkpatrick wrote:
> Let me start by saying Railo is awesome, thanks.

Thank you for the detailed account of your experiences!

> I must still complain that multiple contexts are super inefficient and
> should not be the default way for new railo installations or there
> should be a way to disable it with a magic connector, etc.

I think the magic connector (hehe) will ease some things.

As for defaults, well... one man's awesome setup is another man's, um,
not so awesome setup. :)

If you *don't* have a shared code base, separate contexts offer much to
be desired.

If you are using a single codebase, separate contexts can still be
swell, but in a different sense- you could have separate contexts for
your codebase (vs. separate contexts for the output, as it were, of your
codebase-- the "generated" sites -- 2 or 3 vs. 40).

Sometimes you'd want separate contexts for security, logging, and other
isolation-ish reasons, even with the same code. There's a lot of variables.

...


> usually had for my application. Mappings should not be getting
> compiled separately for every site.

I might want to run one version of a 3rd party library on one and a
different version of that same library on another.

Caching is one of the two hard things in computing (naming stuff and
off-by-one errors are the other). ;)

...


> I also had numerous issues with the server scope that go away when I
> don't use it (in multiple contexts). I don't think server scope is
> safe between contexts because there are known issues with the current
> stable release of railo. I think my stability will be rock solid now
> that I don't have these bugs and I have a healthy amount of ram for
> the other processes. Railo was running out of memory before and
> crashing every few days, but now I can give it more then it needs.

It sounds like the server scope is doing what it's supposed to do. It
is per context.


This all basically relates to a shift in thinking. What ACF does by
default, is use a single context for everything.

Once you start needing multiple instances, or separation of stuff, you
have to configure bootstrap settings and whatnot. Oh, JRun- I remember
thee! Clustering was harder, etc.. And don't get me started on running
other JEE apps! Oy!

I don't know how they're going to handle things with the shift to
Tomcat, but I'm glad they are switching. :)

> Anyone doing many hosts with the same source library would be wasting
> enormous amount of resources with multiple contexts, I.E. Every site
> running on one <Host> tag in tomcat is the better way to go.

To quote Sean "it depends". :)

What is best varies widely from use case to use case.

...


> rewriting like I do. I hope that the team considers making it easier
> for other people's sake and to make better security use less resources.

We are constantly trying to make things easier and optimized! :)

I'd like to take a second and thank our *awesome* community for all it
does as well. I feel blessed to be a part of all this.

Keep us posted, and again, thanks for the involvement!

Bruce Kirkpatrick

unread,
Nov 30, 2011, 4:38:00 AM11/30/11
to Railo
Look at it only from a performance point of view where the same
features are retained.

Are you sure the "java context" is the level of security that is
needed to do directory protection of CFML I/O tags and functions which
are a layer on top of java? The other security features are just
toggling features on/off, which you'd just have to generate an error
if the internal data is not allowing access to that. I've been using
coldfusion for 8 years and I can't think of a reason when I would use
the security provided except in shared hosting, but I don't understand
how the method used is required for that.

simple example:

function fileopenwrapper(myfilepath){
if(isSafeLocation(myfilepath)){
return fileopen(myfilepath,"r");
}else{
// throw security error
}
}

Does it need to be more complex then that inside Railo? I could make
wrapper functions for all coldfusion I/O features and implement this
myself to secure I/O between my sites in one context and hide all my
source inside compiled archives and a different path using mod_proxy
so that co-workers only see static files. If you truly are sharing
the system with strangers like shared hosting, then you want it to be
a language feature like multiple contexts. In shared hosting, you'd
want it to be efficient as possible since having a bunch of amateur
developers on 1 box is a performance nightmare already. Wasting a ton
of ram would make it very expensive to host each developer. If the
cost gets too close to $50+ USD range, then people would be moving to
VPS servers or better at that point where security is mostly
irrelevant again.

My impression from the docs and administrator is that <cfexecute> and
Java I/O are not protected at all by the sandbox feature, so I don't
understand why this heavyweight approach is used. It says: "Allowing
access to Java methods and properties might be a potential security
risk.". It is probably too much work to figure out how to wrap every
java feature ever made with sandbox security, so that's fine. That's
why something like suphp exists for php. They can't fix crap, so they
put a layer around it. I have a feeling that you guys are able to
change anything in Railo because you don't have a million other people
making extensions and forking the source code probably as bad as php
does.

One thing that would be a cool feature here is if you let me replace
existing coldfusion functions with my own version that calls the
native version or possibly even something in a different language like
Java or a remote call. This would let me emulate new validation /
error and security features without having to control the source code
written by developers and make them learn all my function names. This
would save you from having to rewrite the security contexts, because I
could manage it myself by having a thin layer around the entire
language using CFML. I could even choose to disable coldfusion
language features that are slow / inappropriate, etc in a much more
detailed fashion then what the contexts allow - educate programmers to
use the faster way. Like structkeyexists is faster then isdefined.
If they type isdefined('request.myvar'), i could slap them and ask
them to type it the fast way. This could help code quality.

I've nearly replaced every function in CFML with my own over time, but
like I said other people have to learn that and it's not documented
the same. I do this to avoid having to go in and out of cfscript and
achieve a million other things. You really don't want to have the
same required arguments and errors always. I even rewrite ACF's
errors into human readable ideas when they don't make much sense.
Some of the missing "#" errors were insane in the past, so I detected
that and say "There is probably a missing # or closing tag somewhere."
to reduce the time spent guessing what the error means.

I've pretty much written my own language on top of coldfusion
already. But it would be cool to be able to change it using CFML.
Like custom tags that replace the original language. Does that exist?

Currently i prepend a z to everything to identify my code, but it
would be nice if other people could copy and paste existing code and
have it act differently. A new hire is not going to have the
experience to write from their own mind in a new language and no one
knows CFML typically.

Michael Offner

unread,
Nov 30, 2011, 5:53:11 AM11/30/11
to ra...@googlegroups.com
after your first mail i was thinking if Railo could detect if a class was already loaded in a other or the same context with the same signature (md5 hash for example) and then only load once. 
if we do so railo would even detect if 2 cfml files have the same content even the names are different and load only once.
feel free to open a ticket for this.

for the rest please see my answers in text.

/micha

2011/11/30 Bruce Kirkpatrick <skyf...@gmail.com>

Look at it only from a performance point of view where the same
features are retained.
from day one when we have started writing Railo the idea was to share resources between contextes when possible and not share when it makes no sense or it is not possible.
Every time we do a new feature the question is, can this be loaded in server context (global) or web context.
The cfml engine is loaded only once, this means the complete functionality is only once in memory.
the only thing splitted for every context is the "ConfigWeb" object (http://www.getrailo.org/javadoc/railo/runtime/config/ConfigWeb.html), every context has its own ConfigWeb Object.
This Object include for example all mappings of a context, i have to say every cfml template is loaded from a mapping even you have not defined a mapping in the admin, there is always a default mapping.
you see this was our main goal from day one, but of course we always can improve, just name it what you think railo does wrong and we will address. 



Are you sure the "java context" is the level of security that is
needed to do directory protection of CFML I/O tags and functions which
are a layer on top of java?  The other security features are just
toggling features on/off, which you'd just have to generate an error
if the internal data is not allowing access to that.   I've been using
coldfusion for 8 years and I can't think of a reason when I would use
the security provided except in shared hosting, but I don't understand
how the method used is required for that.

simple example:

function fileopenwrapper(myfilepath){
if(isSafeLocation(myfilepath)){
  return fileopen(myfilepath,"r");
}else{
  // throw security error
}
}
you have to secure on java level because you can do always something like:createObject("java","java.io:File").init(...)
...
btw: java direct invocation can be disabled in Railo admin but not ACF.

The FS is just one point of many, for example in ACF it is very easy to access/modify/delete ANY datasource defined on the server or any shared scope defined i any context or ... (i can make you a long list about this)
Give me access to a single site in a shared ACF hosting and i will kill you all running sites independent of the setting in your admin! 

 

Does it need to be more complex then that inside Railo?  I could make
wrapper functions for all coldfusion I/O features and implement this
myself to secure I/O between my sites in one context and hide all my
source inside compiled archives and a different path using mod_proxy
so that co-workers only see static files.   If you truly are sharing
the system with strangers like shared hosting, then you want it to be
a language feature like multiple contexts.  In shared hosting, you'd
want it to be efficient as possible since having a bunch of amateur
developers on 1 box is a performance nightmare already.  Wasting a ton
of ram would make it very expensive to host each developer.  If the
cost gets too close to $50+ USD range, then people would be moving to
VPS servers or better at that point where security is mostly
irrelevant again.
and because of that Railo shares as much resources possible between contexts and make it possible to restrict possibility as much as possible. we are definitely on the same site here!

 

My impression from the docs and administrator is that  <cfexecute> and
Java I/O are not protected at all by the sandbox feature, so I don't
understand why this heavyweight approach is used.
what heavy approach, not sharing mappings? of course railo allows to disable cfexecute and restrict file access.

 
  It says: "Allowing
access to Java methods and properties might be a potential security
risk.".
that can be disabled (only) in Railo.
 
It is probably too much work to figure out how to wrap every
java feature ever made with sandbox security, so that's fine.  That's
why something like suphp exists for php.  They can't fix crap, so they
put a layer around it.   I have a feeling that you guys are able to
change anything in Railo because you don't have a million other people
making extensions and forking the source code probably as bad as php
does.

One thing that would be a cool feature here is if you let me replace
existing coldfusion functions with my own version that calls the
native version or possibly even something in a different language like
Java or a remote call.
you can replace existing Build in Tags and functions very simple in Railo by putting your implementation to "railo/library/" in  server context (for all webs) or in web context (for only the current context). This replacement can be written in cfml or Java. Of course you can also extend with new functions/tags.
 
  This would let me emulate new validation /
error and security features without having to control the source code
written by developers and make them learn all my function names.  This
would save you from having to rewrite the security contexts, because I
could manage it myself by having a thin layer around the entire
language using CFML.
I'm Sorry to say that, but i think you have no idea how Railo is working internally, because this makes no sense at all, this is not how Railo is working or how you solve problems.

 
 I could even choose to disable coldfusion
language features that are slow / inappropriate,
we had discussions about this in past, the only thing you can do, is to remove the 3-party libraries not used, for example removing all Lucene libraries when you are not using cfsearch, but this cannot be done by Railo, because this libraries are controlled by the servlet engine not Railo.
Only disabling the feature in the engine makes no difference on memory usage/performance.
have in mind that Railo is not a interpreter, Railo is a runtime compiler. things are loaded when needed, but jar files are loaded when they exist in lib dir.

 
etc in a much more
detailed fashion then what the contexts allow - educate programmers to
use the faster way.   Like structkeyexists is faster then isdefined.
If they type  isdefined('request.myvar'),  i could slap them and ask
them to type it the fast way.  This could help code quality.

the Railo Compiler detects this constellation and translate it at compile time.
Because of that there is no difference between  structkeyexists and isdefined in this case performance wise ;-)
we try to improve many things like this on compile level, when possible.
railo for example translate this:
<cfargument name="peter" type="boolean" default="true">
<cfparam name="susi" default="true" type="boolean">
to
<cfargument name="peter" type="boolean" default="#true#">
<cfparam name="susi" default="#true#" type="boolean">
this is used 1000times in every app!
Railo also analyse code and for example outputs in debug if a column of a query never was used. because many users still do SQL like "select * from test" and then only use 1 column of 10 (this is new to 3.3.1.005).

any idea here is welcome!


I've nearly replaced every function in CFML with my own over time, but
like I said other people have to learn that and it's not documented
the same.   I do this to avoid having to go in and out of cfscript and
achieve a million other things.    You really don't want to have the
same required arguments and errors always.   I even rewrite ACF's
errors into human readable ideas when they don't make much sense.
Some of the missing "#" errors were insane in the past, so I detected
that and say "There is probably a missing # or closing tag somewhere."
to reduce the time spent guessing what the error means.
we are more than open to any input here!
 

I've pretty much written my own language on top of coldfusion
already.  But it would be cool to be able to change it using CFML.
Like custom tags that replace the original language.  Does that exist?
of course (see above) and in Railo custom tags can be written as cfm or cfc


Currently i prepend a z to everything to identify my code, but it
would be nice if other people could copy and paste existing code and
have it act differently.  
with railo you can define a extension (provided by a webservice) that can be easily installed in Railo admin and this extension can include your custom tags and functions deployed as "Build in tags".
 
A new hire is not going to have the
experience to write from their own mind in a new language and no one
knows CFML typically.

if you deploy a function/tag to the library directory it is also listed in the tag/function reference in admin with your documentation (defined with "hint").



 

Bruce Kirkpatrick

unread,
Nov 30, 2011, 8:46:41 PM11/30/11
to Railo
Thank you for replying. Some of that is very interesting. You are
trying to do some of the things I've been working on it seems. I have
an ORM and skin system in CFML that is going to do what you said about
changing * to be only the fields because I wrote an HTML parser and my
skin tags are html comments and html 5 "data-" attributes.

normal custom tags end up like this <cf_file> I was asking to be
able to do a wrapper for <cffile> that retains the same name.
And more importantly, to be able to override the cfscript functions
too. Like filecopy().
It appears php has "runkit" extension that can rename existing
functions if you enable the option.
For example, i'd rename native <cffile> to be <railo_cffile> and then
i'd rename my function from <cf_file> to <cffile> and my <cf_file>
would call <railo_cffile> optionally.
Or a configuration file that lets you define such mappings. This
would minimize how much it impacts how railo operates.

I think there is value in analyzing CFML for quality concerns in an
automatic way in development mode. Doing things like static
analysis / code coverage and performance analysis might be possible
without even running the code, but maybe some of the problems are only
obvious when it is running. Like letting people select 1 million
database records could be prevented in one step by overriding cfquery
to always have a limit of something more reasonable. Part of what
they do in some other systems is try to standardize the way people
program. It seems like facebook tried to do this with thrift by using
data types that convert well between the languages. Maybe there is a
set of coldfusion features that I want to just deny my staff from
using without impacting the entire railo community, which is why I
came up with this idea of having a server option to configure the
built-in language features. For example, there is no benefit to let
someone use a proprietary function that is only going to work on ACF
if you are trying to do a framework that is multi-engine compatible.
It doesn't have to be removed from memory, just inaccessible with the
normal name.


I thought of a few more feature requests that could improve CFML. A
mix of front-end and back-end ideas.

1.
a set of tags that does lightweight javascript json persistence
between the server and client-side with ajax. Perhaps the front-end
could use something like persistjs, which uses the new HTML 5 storage
when available, otherwise flash. Javascript would send a delta of
only the changed data in json format to the server and then server
would be able to do partial/full reloads on startup. Perhaps it even
allows offline users to do work and later authenticate with the server
and persist the data. There would need to be conflict resolution
system client/server and flexible persistence methods such as ORM,
datasource, session, external KV cache stores. Plus a way to add
filters that handle security / override values before it gets stored
in the database. Similar to what some of the Flash components do.
Imagine a CMS where they have all the site content offline and then
publish it later when back online. This is more common in modern
mobile devices / games at the moment.

2.
Add NEW non-blocking I/O functions for all features that currently
block. I'm not entirely sure if it is possible to have callback
functions and a system that tracks if there are incomplete events. An
event gateway is like a whole new request. Coming up with language
features that allow true javascript callback style behavior would be
awesome. Node.js attempts to do what I am saying. Facebook's Tornado
is one as well. Perhaps it is possible to set the java thread in a
poll/epoll system state so the CFM/CFC comes back to life and handles
the other actions asyncronously without high cpu spinning. For
example, an unbuffered query in PHP is exactly twice as fast due to
copying about half the memory. ACF seems to do a full download of the
data before giving it to you because of how JDBC works maybe. This
causes a query that returns 100mb to be dangerous for system stability
potentially. I know for sure ACF was very bad with this and I don't
think you are able to optimize cfquery the way it works right now
because you'd have to wait until the data is accessed before running
it and you'd have to know everywhere it is used in the whole app,
impossible. Someone needs to rewrite the JDBC driver to be
asynchronous. An incomplete project exists for mysql.
http://code.google.com/p/async-mysql-connector/ I don't know if that
would work with Railo. CFQUERY, CFHTTP, CFFTP, CFPOP, etc. I know
I can use <cfthread> to fake it, but that is not the same because it
makes a single huge buffer instead of letting me control the buffer
size in small chunks or rows/lines, etc. For this reason, I used
underlying java I/O or php in the past, but it was difficult to use
Java in ACF at least. It seems like I have to use a different
language to get the fast Async I/O performance.

3.
Maybe it would help to add some static typing features to CFML or more
control of how references/pointer work like php has. I'm aware that
complex values pass by reference instead of copy. It might be useful
if the above async I/O system returned complex values because you
wouldn't want it to be copying a string multiple times since the whole
point is for it to be more efficient. Perhaps this is why <cfhttp>
writes data to cfhttp.filecontent because making 2 copies would make
it even more wasteful and its easier to use structs because of the
CFML legacy. You could let us specify a struct variable name to store
the results in, but you still need a function that lets use check to
see the task is complete without having to block on a thread join.
And if there was a true event system, then you could avoid having to
even check. Coldfusion has been a very procedural language so far. I
found a lot of speed with cfthread on certain things and a epoll/poll
feature set with closer to static performance would be awesome.

4.
I think it would be helpful to have some functions to measure the size
of coldfusion complex data types during runtime. We already have
gettickcount() for speed tests, we need a way to measure memory.
analyzing a heap dump is not super easy for me even though I did get
eclipse mat to work. One of the hardest things to know is how much
memory different CFML approaches use in the middle of a request
because garbage collection is so random, you can't measure the
difference of heap state and get an accurate number. I often find the
best performance comes from copying less memory and hopefully using I/
O that is closer to the cpu cache. One of the most obvious examples
is string concatenation vs arrayappend. Appending strings with & on
ACF was extremely slow in a tight loop due to the full memory copies,
so I write everything to use arrays and then arraytolist at the end.
If I knew one of my components was 50mb or the local scope was getting
huge, I might reorganize that to be more efficient. It seems a bit
easier to measure memory usage with php. These features should
probably only work during debugging to avoid overhead, perhaps a
cfsetting or application setting to turn it on / off - like
this.trackMemoryStatistics="true".

5.
A built in way of detect static file changes and handling versioning /
url rewriting automatically. I often find it annoying to have to
rename css / js files to get the browser to update the cache. You
often want to have caching store files permanently if possible but you
have to design the whole app to use this method and it takes more
time. I'm making the new framework able to handle this by storing
changes to the filesystem in the database and incrementing a version
number which the app will output and I'll cache this information to
shared memory to prevent constant disk I/O overhead. I'm also using
the same system to compile HTML skins into CFML code because I made a
template language. A rewrite rule that maps the fake version url to
the static file minimizes the overhead. For example /versions/3/
stylesheets/style.css could map to /stylesheets/style.css CFML
would assist with this by having tags for stylesheets, javascript and
images that generate the appropriate HTML.

Todd Rafferty

unread,
Nov 30, 2011, 8:50:04 PM11/30/11
to ra...@googlegroups.com
Hey Bruce? We have a feature system:  http://railo.uservoice.com/forums/21016-general

Bruce Kirkpatrick

unread,
Dec 1, 2011, 12:53:28 AM12/1/11
to Railo
ok, using it now. Kind of scary the top requests are 2 years old. I
must increase my patience levels and focus on my app. The stability
of the server is always #1 priority. Railo doesn't have to be a swiss
army knife, but some things are better done at the lower levels.

On Nov 30, 8:50 pm, Todd Rafferty <t...@getrailo.org> wrote:
> Hey Bruce? We have a feature system:http://railo.uservoice.com/forums/21016-general
>

> ~Todd Rafferty*
> Volunteer** *Community Manager

Mark Drew

unread,
Dec 1, 2011, 3:04:49 AM12/1/11
to ra...@googlegroups.com
And they are both planned (and in progress actually)

MD
Sent from one of my many iDevices

Michael Offner

unread,
Dec 1, 2011, 3:33:49 AM12/1/11
to ra...@googlegroups.com
see my comments in text

/micha

2011/12/1 Bruce Kirkpatrick <skyf...@gmail.com>

Thank you for replying.  Some of that is very interesting.  You are
trying to do some of the things I've been working on it seems.  I have
an ORM and skin system in CFML that is going to do what you said about
changing * to be only the fields because I wrote an HTML parser and my
skin tags are html comments and html 5 "data-" attributes.

normal custom tags end up like this <cf_file>   I was asking to be
able to do a wrapper for <cffile> that retains the same name.
And more importantly, to be able to override the cfscript functions
too.  Like filecopy().
copy a file named file.cfc or file.cfm to library/tag and you overwrite the existing cffile.
copy a file named filecopy.cfm to library/function to overwrite the existing filecopy.
but have in mind that the railo tags not only support the local filesystem.

 
It appears php has "runkit" extension that can rename existing
functions if you enable the option.
For example, i'd rename native <cffile> to be <railo_cffile>  and then
i'd rename my function from <cf_file> to <cffile> and my <cf_file>
would call <railo_cffile> optionally.
all core tags are defined in a single .tld file and all functions in a single .fld

like written before you can overwrite this tags by adding you own cfml based tags, but you can also overwrite by adding your own .tld/.fld to library/tld and library/fld directory. i have attached a example that makes the current cffile tag available the following way
<railo:file action="read" ...>



Or a configuration file that lets you define such mappings.  This
would minimize how much it impacts how railo operates.

I think there is value in analyzing CFML for quality concerns in an
automatic way in development mode.  Doing things like static
analysis / code coverage and performance analysis might be possible
without even running the code, but maybe some of the problems are only
obvious when it is running.  Like letting people select 1 million
database records could be prevented in one step by overriding cfquery
to always have a limit of something more reasonable.
we had discussion about things like this, also restrict cfloop for example to avoid infiniti loops but we have nothing implemented at the moment, this is still a option for us. we also rewriting the current query implementation atm to hold connection to the datasource that railo only read in data when needed.
sounds very intressting 

2.
Add NEW non-blocking I/O functions for all features that currently
block.  I'm not entirely sure if it is possible to have callback
functions and a system that tracks if there are incomplete events. An
event gateway is like a whole new request.  Coming up with language
features that allow true javascript callback style behavior would be
awesome.  Node.js attempts to do what I am saying.  Facebook's Tornado
is one as well.  Perhaps it is possible to set the java thread in a
poll/epoll system state so the CFM/CFC comes back to life and handles
the other actions asyncronously without high cpu spinning.    For
example, an unbuffered query in PHP is exactly twice as fast due to
copying about half the memory.  ACF seems to do a full download of the
data before giving it to you because of how JDBC works maybe.  This
causes a query that returns 100mb to be dangerous for system stability
potentially.  I know for sure ACF was very bad with this and I don't
think you are able to optimize cfquery the way it works right now
because you'd have to wait until the data is accessed before running
it and you'd have to know everywhere it is used in the whole app,
impossible.  
read above, we are working exactly on this ;-)
 
Someone needs to rewrite the JDBC driver to be
asynchronous.  An incomplete project exists for mysql.
http://code.google.com/p/async-mysql-connector/   I don't know if that
would work with Railo.    CFQUERY, CFHTTP, CFFTP, CFPOP, etc.  I know
I can use <cfthread> to fake it, but that is not the same because it
makes a single huge buffer instead of letting me control the buffer
size in small chunks or rows/lines, etc.  For this reason, I used
underlying java I/O or php in the past, but it was difficult to use
Java in ACF at least.  It seems like I have to use a different
language to get the fast Async I/O performance.
we had discussion about this in the team, first we will add the possibility for eventhandlers to certain tags or in the application.cfc
example:
index.cfm:
<cfmail eventHandler="my.app.Mail">
---
Application.cfc:
this.mail.eventhandler="my.app.Mail";
---
Mail.cfc:
component {
function onError(...){...}
function onBeforeExecution(...){...}
...
}
----
then we discussed if we should add a "async" attribute to certain tags. i was against it because i think you can use cfthread for this.
the only thin i support is something like this:
<cffunction async="true">
but this discussion is still open

 

3.
Maybe it would help to add some static typing features to CFML or more
control of how references/pointer work like php has.  I'm aware that
complex values pass by reference instead of copy.
nope, complex types are never passed by value (cloned).
ACF does this with arrays but railo dont.
 
 It might be useful
if the above async I/O system returned complex values because you
wouldn't want it to be copying a string multiple times since the whole
point is for it to be more efficient.  
this is a common misunderstanding of string i have read a lot of times.
first of all we have to find the right naming, Railo is nothing else than a java bytecode compiler and all your code executed is java bytecode. in Java complex values (reference types) can only be passed by reference, the only way to "pass by value" is to clone the object before passing, what ACF does for arrays. the question is what objects are cloned before or after passing.
the answer for Railo is none.
the string is "passed by reference" (not cloned), there is no need to do so, because the java.lang.String class is read only, there is no way to change the inner state of  Object based on this class, because of that there is no need to clone a instance of String. same for all classes extending java.lang.Number or java.lang.Boolean.


 
Perhaps this is why <cfhttp>
writes data to cfhttp.filecontent because making 2 copies would make
it even more wasteful and its easier to use structs because of the
CFML legacy.  You could let us specify a struct variable name to store
the results in, but you still need a function that lets use check to
see the task is complete without having to block on a thread join.
see eventhandler above
 
And if there was a true event system, then you could avoid having to
even check.  Coldfusion has been a very procedural language so far.  I
found a lot of speed with cfthread on certain things and a epoll/poll
feature set with closer to static performance would be awesome.

4.
I think it would be helpful to have some functions to measure the size
of coldfusion complex data types during runtime.  We already have
gettickcount() for speed tests,  we need a way to measure memory.
analyzing a heap dump is not super easy for me even though I did get
eclipse mat to work.  
there is a experimentell function called "sizeOf" in Railo, but this function is not really working accurate atm.
we are working on a "Monitor" plugin for Railo that shows you how many elements are in all your shared scopes (server,application,session) in all your contexts.

 
One of the hardest things to know is how much
memory different CFML approaches use in the middle of a request
because garbage collection is so random, you can't measure the
difference of heap state and get an accurate number.  I often find the
best performance comes from copying less memory and hopefully using I/
O that is closer to the cpu cache.  One of the most obvious examples
is string concatenation vs arrayappend.  Appending strings with & on
ACF was extremely slow in a tight loop due to the full memory copies,
this is because the string class is read only, Railo always has to do new strings. you can also use StringBuffer or StringBuilder. we are thinking about making railo smarter in this case, if there is a string concatination railo does a stringBuilder automatically and convert back to string when needed.
with Railo Appollo (4.0) we will replace java reflection with a more native interaction with java, this will make StringBuilder/StringBuffer even faster.
Example with StringBuilder:
sb=createObject('java','java.lang.StringBuilder').init("Hello ");
sb.append("World");

 
so I write everything to use arrays and then arraytolist at the end.
If I knew one of my components was 50mb or the local scope was getting
huge, I might reorganize that to be more efficient. It seems a bit
easier to measure memory usage with php.  These features should
probably only work during debugging to avoid overhead, perhaps a
cfsetting or application setting to turn it on / off - like
this.trackMemoryStatistics="true".
Main Problem is that java does not provide this kind of information, because of that we stick on counting the objects atm. 

5.
A built in way of detect static file changes and handling versioning /
url rewriting automatically.  I often find it annoying to have to
rename css / js files to get the browser to update the cache.  You
often want to have caching store files permanently if possible but you
have to design the whole app to use this method and it takes more
time.  I'm making the new framework able to handle this by storing
changes to the filesystem in the database and incrementing a version
number which the app will output and I'll cache this information to
shared memory to prevent constant disk I/O overhead.  I'm also using
the same system to compile HTML skins into CFML code because I made a
template language.  A rewrite rule that maps the fake version url to
the static file minimizes the overhead.   For example /versions/3/
stylesheets/style.css could map to /stylesheets/style.css     CFML
would assist with this by having tags for stylesheets, javascript and
images that generate the appropriate HTML.
not sure if something should happen on language level, sound more like a framework feature to me. how this should look like?

 

example.tld

Michael Offner

unread,
Dec 1, 2011, 4:52:48 AM12/1/11
to ra...@googlegroups.com

br...@bradwood.com

unread,
Dec 1, 2011, 10:55:52 AM12/1/11
to ra...@googlegroups.com
>> I'm aware that complex values pass by reference instead of copy.
> nope, complex types are never passed by value (cloned). ACF does this with arrays but railo dont.

To clarify, ACF does NOT duplicate arrays (deep copy) on assignment, but instead makes a shallow copy of them.  i.e. complex objects INSIDE an array are still passed by reference.

s = { x = 1 };
a = [ s ];
b = a;
b[1].y = 2;
// s is now { x = 1, y = 2 }

>> perhaps a cfsetting or application setting to turn it on / off - like this.trackMemoryStatistics="true".
> Main Problem is that java does not provide this kind of information, because of that we stick on counting the objects atm.

Bruce, for what it's worth, you can't access these methods at runtime via code (that I know of), but if you just want debugging during development there are heap analyzers which can calculate the retained set size for a a given object in memory.  JRockit Mission Control (assuming Railo runs on the custom JRE) will do it live as your app runs, and the MAT (Memory Analyzer Tool) will do it on a heap dump post mortem.

Thanks!

~Brad

Bruce Kirkpatrick

unread,
Dec 1, 2011, 12:36:14 PM12/1/11
to Railo
I need to read the wiki more. The resource you gave only discussed
library/tags in the comments. I understand now.

It seems this feature is documented under
http://wiki.getrailo.org/wiki/ -> FAQ -> How do I make my custom tag
built-in (e.g.: cfwave instead of cf_wave)?

http://wiki.getrailo.org/wiki/TIPS:BuiltInTag

I'm sorry.

I noticed that the global location was using file names for tags like
<cfdump> without having the cf prefix. I registered on the wiki
because I wanted to update it to have a note that you should name your
file File.cfc or File.cfm if you instead to replace <cffile>. I
also believe you have to restart the server. People might know this
is the case under ACF, but maybe railo docs should mention that too.
I have to be approved as a collaborator first.

This is a very nice feature.


On Dec 1, 4:52 am, Michael Offner <mich...@getrailo.com> wrote:
> FYI:https://issues.jboss.org/browse/RAILO-1650
>

> 2011/12/1 Michael Offner <mich...@getrailo.com>


>
>
>
>
>
>
>
> > see my comments in text
>
> > /micha
>

> > 2011/12/1 Bruce Kirkpatrick <skyfl...@gmail.com>


>
> >> Thank you for replying.  Some of that is very interesting.  You are
> >> trying to do some of the things I've been working on it seems.  I have
> >> an ORM and skin system in CFML that is going to do what you said about
> >> changing * to be only the fields because I wrote an HTML parser and my
> >> skin tags are html comments and html 5 "data-" attributes.
>
> >> normal custom tags end up like this <cf_file>   I was asking to be
> >> able to do a wrapper for <cffile> that retains the same name.
> >> And more importantly, to be able to override the cfscript functions
> >> too.  Like filecopy().
>
> > copy a file named file.cfc or file.cfm to library/tag and you overwrite
> > the existing cffile.
> > copy a file named filecopy.cfm to library/function to overwrite the
> > existing filecopy.
> > but have in mind that the railo tags not only support the local filesystem.
>
> >> It appears php has "runkit" extension that can rename existing
> >> functions if you enable the option.
> >> For example, i'd rename native <cffile> to be <railo_cffile>  and then
> >> i'd rename my function from <cf_file> to <cffile> and my <cf_file>
> >> would call <railo_cffile> optionally.
>
> > all core tags are defined in a single .tld file and all functions in a
> > single .fld
>

> >https://github.com/getrailo/railo/blob/3.3/railo-java/railo-core/src/...
>
> >https://github.com/getrailo/railo/blob/3.3/railo-java/railo-core/src/...

> ...
>
> read more »

Todd Rafferty

unread,
Dec 1, 2011, 12:42:02 PM12/1/11
to ra...@googlegroups.com
There's extensive coverage on the blog as well, oh, wait.. that page has it. :D
--
~Todd Rafferty
Volunteer
Community Manager
Reply all
Reply to author
Forward
0 new messages