UDFs stored in APPLICATION vars

In an attempt to use less memory and reduce the amount of code, we have decided to use APPLICATION vars to store our apps user defined functions. While this has worked great in our test environment, we came across a few things that led us down a terrible rabbit hole.

Problem
Any variable within a component / function that uses the VARIABLES scope, remains persistent for the life of the application. After some thought, this makes perfect sense, since the component / function was being stored in an APPLICATION variable.

SOLUTION: We then re-wrote all the UDFs to use LOCAL / ARGUMENTS vars and everything seems great again.

New Concern
Is there a possibility, that a called function stored in an APPLICATION variable will ever hand back another users data that is executed at the same time? We have functions that return queries with user specific data and want to make sure there is no way another user’s data will end up within another account.

I hope this makes sense. I’ll be happy to provide a simple code example, but was hoping that someone out there in the Lucee-verse might have a simple answer or has dealt with this in the past.

Thanks in advance!

1 Like

as long as you’re only using the local / arguments scope inside a function, you should be totally fine

Thanks @Zackster! One more for you. How about REQUEST vars? We have a timezone function to adjust the display time and we set the timezone and user display preferences in a REQUEST variable at the beginning of the script. We call that from within the function. We use an Elvis operator to see if the REQUEST var exists, otherwise we use the default timezone / display settings.

We did this to avoid using the VARIABLES scope and to be able to set the localization settings at the page level instead of per call to the function.

the request scope is created per request

closures, i.e var =x function(){ //etc }; retain access to the parent scopes

How does moving UDFs into the Application scope do that?

Also, what were your real-world production results re: performance?

Asking because of relevance to my recent topic:

https://lucee.daemonite.io/t/udf-performance-include-udf-cfm-vs-application-singleton-udf-cfc/10567

In all my years of performance tuning CF, I’ve never seen UDF creation be a performance bottleneck. Unless the source code has changed between requests, the bytecode is precompiled and cached so it’s just the creation of the UDF object which isn’t much. I wouldn’t expect you could even measure the memory usage difference.

Now that said, I do love the idea of moving common UDFs into a utility function which is managed as a singleton by a DI engine like WireBox for encapsulation, reuse, and organization. But I would be wary of the pre-optimization aspect here.

That isn’t going to be any different than a method on a singleton CFC. Just be wary of var scoping. If you use ColdBox, there’s even a utility that will scan your app’s memory at run time and tell you if any of your singleton’s have unvarred variables

2 Likes

Is there an alternative to WireBox that doesn’t make me feel like I’m being proselytized by a religious cult?

2 Likes

You can check (they are all outdated software):

But what means “by a religious cult”?
You can use Wirebox independently of the whole “*box” ecosystem.
I do it.
Wirebox is full of features and works very well.

1 Like

Regarding “by a religious cult”: I think it’s because Ortus posts about the bible here and there online and in source code.

We shouldn’t forget that Luis Mayano, the initiator of all the box ecosystem (and Ortus) has roots in Latin America and I think he is a very religious person (like many of latin american friends I have) what I respect. He does a lot for his home country and the rest of latin & south america. He has a very filantropic approach. I never talked to him or know him personally at all: But, what he & his team at Ortus have done for the whole cfml community in development, sponsorships, casts, forgebox, meetUps, CommandBox etc, etc … modernizing cfml and contributing to Lucee Source Code: I’m very thankfull he and all the Ortus guys are around. I’d say they are one of the reasons cfml is still around. As an atheist I read here and there the Bible citings and I just feel very thankfull he and the Ortus team is around. However, I never felt anybody of Ortus was trying to convert me or push me to any other cult then cfml :smiley:

7 Likes

Well it was not my intention to hijack this topic and I’m debating whether this should be moved to its own separate topic, but for now I’ll briefly respond that I’m a non-religious Humanist and I’m skeptical when a business refers to themselves as professional while embedding not just bible quotes but lots of other religious dogma e.g. “HONOR GOES TO GOD ABOVE ALL” into their About page, product marketing, documentation, even in their GitHub repo! CommandBox is also codenamed “Project Gideon”. I think it’s great that they donate to the charity for orphans, but I’m leery of that being an “evangelical mission” aka brainwashing children, and they also donate to a group with a vision “that Houston is Known as a City of God”, which violates separation of church and state. “If you don’t like this, then don’t read it, it’s not for you.” Well then it’s settled: Ortus is not for me. All of this is so completely over the top and most of all very unprofessional. And since Ortus has the monopoly on Lucee frameworks, I’m seriously considering moving on to Node.js. It’s a moral dilemma for sure. Maybe it means more to me as a woman in light of the loss of Roe v. Wade and the Christian impact on a woman’s right to control her own body.

3 Likes

I wouldn’t (yet) class FW/1 as “outdated”, although it’s true it hasn’t been as well supported since Sean handed over the reins. It’s a simple, mature, stable framework and still pretty widely used according to the latest State of the CF Union survey.

DI/1 is the dependency injection element.

2 Likes

And both FW/1 and CFWheels are dependent on CommandBox, which just adds to the Ortus monopoly.

No, that’s not correct. CommandBox may have integration points to make working with FW/1 easier, but FW/1 itself is totally independent, as I believe is CFWheels (which I haven’t used at all).

3 Likes

Ah, thank you for the correction, but then as you mentioned, the decreased support for FW/1 makes me question its future and therefore hesitant to invest myself into it. And CFWheels is even less popular. Well, I love Lucee, so at least for now I’ll just continue without any framework.

2 Likes

3 posts were split to a new topic: Does MVC discourage OOP

For what it’s worth, in my personal ColdFusion blog, I just manually wire-up my components in my onApplicationStart() event handler. I set accessors=true in my components, and then I just do things like:

application.blogService = new lib.blog.BlogService()
    .setGateway( new lib.blog.BlogGateway() )
    .setUtilities( application.utilities )
;

In some way, I actually like having to wire things up manually, since the friction of it makes you stop and question whether or not a given component is accumulating too many dependencies. Maybe this is something that should be broken-out into its own component? Etc. I like that moment of having to reflect on my choices.

5 Likes

Don’t judge a framework by its perceived popularity. Give CFWheels a try you might just end up liking it. The use of Commandbox is meant to simplify the developer experience and the framework does not rely on any third party modules or projects.

2 Likes

FW/1 is a microframework so there’s not much to it, and as far as I can tell it’s mostly “complete”. It does what it sets out to do, and does it well. I’d perhaps not worry too much about how much activity there in the git repo.

Full disclosure: I have not used FW/1 in anger.

I’ve messed with DI/1 experimentally (documented here: Adam Cameron's Dev Blog: CFML: implementing dependency injection in a CFWheels web site), and it does what it says on the tin as well. It’s solid.

If I was building a new CFML app, I would use FW/1 and DI/1.

I use CFWheels on a daily basis and my opinion is that… um… err… how to put this… well I would not recommend it under any circumstances for a new project, anyhow. I have documented my experiences with CFWHeels on my blog: Adam Cameron's Dev Blog: CFWheels. I will not say anything further about it here because it will rile ppl up and I CBA dealing with them. I mean they’ll probably still get riled up because I didn’t gush over it, but… hey.

I too am a bit put off by a coupla things about the Ortus… erm… “approach to things” (no indictment of the people! They are all nice and I deeply respect their technical abilities!)… so I have not looked at ColdBox or WireBox other than superficially. TestBox is bloody brilliant though. It’s also really the only horse in town for testing these days, so is essential. Luis is really really responsive when I find bugs in it, and he’s collaborative to work with when coming up with fixes.

All that said, if getting away from CFML is an option to you (you mention it as a possibility) then that is probably the best direction to take IMO. There will be more & better & more stable options, with more maintenance activity on any other platform you choose.

Cringe.


Adam

6 Likes

As a longtime FW/1 user, that’s very much my experience. In addition, as a single CFC that you can extend, it’s very easy to to customize if there’s something you’re missing or that needs fixing. That makes the lack of forward development a bit less of an issue.

4 Likes

We also use FW/1 at work. The one thing that I really wish I could do is provide some sort of meta-data in the property tags for the path to the components so that CFC names don’t have to be globally unique. Something like:

property name="gateway" fw1:type="lib.featureX.FeatureXGateway";

This would allow me to have simpler names for some of my components since I could provide the path in the CFC itself, rather than make gateway a globally-unique injectable.

Other than that, I’ve had no complaints about FW/1. It does just enough.

1 Like