I feel I should know the answer to this... how do ...
# lucee
a
I feel I should know the answer to this... how do I determine how long the Lucee server has been up for? Having googled, I seem to be able to do this to get how long the whole JVM has been up for:
Copy code
uptimeInMillis = createObject("java", "java.lang.management.ManagementFactory").getRuntimeMXBean().getUptime()
But: a) wondering if there's a more CFML- /Lucee -idiomatic way of doing it; b) that is not reset by a Lucee Server restart (via the admin), for obvious reasons. This is probably not an issue for what I need, but figured I'd mention it anyhow.
r
Maybe use Server.cfc and store the getTickCount() into server cope: https://docs.lucee.org/guides/cookbooks/Startup_Listeners.html
ā­ 1
Not sure if that fires when lucee is restarted in admin
a
Yeah I wondered if I'd need to fall-back to that.
b
@Adam Cameron
Copy code
createObject( 'java', 'lucee.loader.engine.CFMLEngineFactory' ).getInstance().uptime()
āœ… 2
The output is a
long
which is what
System.currentTimeMillis()
returned at the time the CFML engine was starting
So it appears you'd need to subtract it from the current tick count to get the time-from-start
For example, it would appear my local CLI has been running for nearly 5 days
Copy code
CFSCRIPT-REPL: ( getTickCount() - createObject( 'java', 'lucee.loader.engine.CFMLEngineFactory' ).getInstance().uptime() ) / 1000 / 60 / 60 / 24
4.871677847222
ā­ 1
a
Hey @bdw429s thanks pal. Have stepped away from my work env for the day, but will experiment with that tomorrow.
šŸ‘ 1
OK @bdw429s looking at this now. This also might be one for @zackster if I'm assessing this correctly. I am looking at the API docs for CFMLEngineFactory: https://javadoc.lucee.org/lucee/loader/engine/CFMLEngineFactory.html And followed that through
getInstance
(https://javadoc.lucee.org/lucee/loader/engine/CFMLEngineFactory.html#getInstance()), which returns a
CFMLEngine
(https://javadoc.lucee.org/lucee/loader/engine/CFMLEngine.html). I do not see an
uptime
method on that?
But it does seem to give me what I want. Just wondering if it's OK to use that method though, as you seem to be specifically not documenting it.
BTW thanks again @bdw429s
b
@Adam Cameron I can bet that's more of an oversight than anything. Micha loves to use interfaces, especially so the loader can parlance about the objects it's going to have in its method signatures which may come from the core, and therefore aren't available at compile time. The CFML Engine factory uses a static method to act as a singleton pattern for fetching the CFML engine, and its method signature points to the CFMLEngine interface like so
Copy code
public static CFMLEngine getInstance()
However, at runtime, the actual class instance you get is the
CFMLEngineImpl
class which comes from the runtime (lco. or core file). So what happens is after creating the interface, Micha will add methods to the actual implementation and not go back and update the interface. (He only likes to update interfaces for major Lucee versions, so they tend to stagnate). So this means the compiler wouldn't allow you to use that method from within Lucee's loader since it's not in the interface, but there's really no reason you can't use it in CFML (which is all based on reflection anyway). As far as whether you "should" use it, pretty much all of Lucee's internal classes come with the "at-your-own-risk" sort of disclaimer. The fact that he never added that method to the interface just means things are a bit sloppy, it's not IMO any official statement of whether the method is fit to use.
āœ… 1
This does bring up an interesting question of whether Lucee ever throught to find all the missing methods from their interface signatures. I ran into this several times when working on Lucee's QoQ where the
Query
interface doesn't have all the methods from the
QueryImpl
class. Micha likes to always use the interface as the "type" in the code, but I was unable to do that due to several methods having been added to the implementation and never added to the interface. Lucee 6 would be a great time to clean some of that up.
a
So this means the compiler wouldn't allow you to use that method from within Lucee's loader since it's not in the interface, but there's really no reason you can't use it in CFML
Yeah makes sense.
z
changing the loader breaks the ability to update, so we avoid it at all costs. So Micha uses the Pro suffix, like ConfigWebPro to extend interfaces without changing the loader signature. https://dev.lucee.org/t/how-to-code-around-limitations-imposed-by-the-lucee-loader-architecture/8396
a
I mean... to me... if we're saying that to get the Engine implementation one would use the
getInstance
factory method, and the one calls
getUptime
on that... then
getUpTime
really ought to be in the interface. I get that classes implementing interfaces can obvs also implement other methods, but what we're talking about here seems -as you say - sloppy to me. If
getInstance
starts to return some other implementation of
CFMLEngineImpl
that doesn't additionally implement the
getUptime
method... code breaks. And for purely sloppy reasons, which is kinda counter to the whole idea of interfaces in the first place. Anyway, never mind... I doubt we'll ever be using a version of Lucee after 5.x anyhow, so if it works for now: all good. I'll put some tests on it so we know if it happens to break in the mean time.
Thanks for the more thorough explanation.
z
i'd say just file a PR asking for start time to be added to the server scope
a
I don't wanna cause your devs unnecessary work when they should be focusing on important stuff.
z
nah, that's a good one, it's only a few lines of code and it means lucee devs don't need to dive into java
i'd show that on the server admin overview page, the admin code isn't allowed to dive into java, otherwise, it would break if users have disabled java access
b
changing the loader breaks the ability to update
@zackster But this isn't a blanket true statement. Adding a method to an interface in the loader would only break if the method didn't exist in the implementation class from the runtime. i.e., if we dreamed up a brand new method to a runtime class and added it today, adding it to the loader would break anyone ā€¢ using a newer loader ā€¢ using an older runtime which makes sense. But this can't be a white flag we just throw up and never keep anything in sync
Let's look at this particular method-- not only is it in every single commit of the entire history of Lucee's source code, but it's from 9 years ago in Railo's source
Note the comment
Copy code
// FUTURE add to interface
a
Note the age
b
The question then becomes, when is "future"? Lucee needs to have an actual strategy for defining "future" and not just saying blanket things like "we can't break the loader" etc
We could add this method to the CFMLEngine interface today and every single version of Lucee would work just fine.
a
I doubt that was the right approach at the time. Adding it to the interface first and then to the implementation would be better. Also might suggest if there was no basis to put it in other implementations that it was premature interface extraction.
Lucee needs to have an actual strategy
Or just a code review policy that's "mate, we're not in a rush. Just take yer time and do it properly".
z
Lucee actual strategy is just don't break anything unless we have to
a
(could well have been a good reason, but I doubt it)
b
Yeah, the entire idea is built around the concept of someone installing Lucee once and leaving the loader jar in place for years while only applying core updates via the admin.
a
That's not a strategy, Zac. That's just "being a programmer"
šŸ¤£ 1
(granted one that not so many programmers manage to meet)
z
should Lucee adopt ACFs horrible update strategy?
b
The irony is the "bad" scenario is when the loader jar gets "ahead" of the core jars, which is actually not very likley unless you install a version of Lucee, then downgrade it, whcih I actually thought Lucee prevented against
a
Oh excellent the "whatabouttery" has arrived. I wondered where it had got to
z
@bdw429s doesn't it... i know the admin interface prevents it
b
lol, it doesn't need to be a false dichotomy. Just some pragmatism. Major Lucee updates are the only time Micha likes to update the interfaces, and I understand the reasoning. That means Lucee 6 is our chance to update some of this stuff.
āœ… 1
z
Lucee 6 won't being updating the loader interface
b
That's sort of.... unfortunate
I'm old enough to remember years ago when Micha told me it was 'too late' to get cache-related changes into Lucee 5's loader and that I'd need to wait until Lucee 6 to do so
z
why, as a normal end user of lucee, being able to just update to 6 is nice
b
Now years later, just kidding-- you never get those, lol
z
i'm having enough trouble pushing to dump java 8 support lol
b
Extra irony is that CommandBox users don't even care as every engine download is a fresh loader anyway so the distinction is minimalized
šŸ‘ 1
Lucee 6 won't being updating the loader interface
Is it possible to make a distinction between "_breaking"_ updates and non-breaking? For example, adding the uptime() method would break nothing.
z
of course
b
Plus again, is there a serious concern that people will update their servers to the latest Lucee 6 loader jar and then run very old Lucee 5.x core jars? I'm just not seeing this as a reasonable concern
And, unless I'm mistaken, that's the only place where additional interfaces methods would ever be an issue. (leaving aside for a moment changes in existing methods)
z
no the main concern is the other way around. at the moment you can update a 4.5 loader to 5.3.9
b
Do you mean loader or core. because I've never seen anyone update their loader jar only and leave their core version behind.
I'm not even sure that's possible
z
loader interface errors can be very confusing
updating the loader force (usually) force updates the core version
which is bundled in the loader
b
That's not answering the question
If I have a Lucee 4.5 server and I update the loader jar to 5.3.9, it will automatically update the core jar to 5.3.9 as well.
I don't think I would even have the option to continue running the 4.5 core jar on top of the 5.3.9 loader
z
we are furiously agreeing there
b
lol
I'm just trying to make sense of your example above
z
let me try that again, you can deploy a 5.3.9 core on top of a 4.5 loader
b
Correct, but that's not a reason not to update the 5.3.9 loader, right?
If we add the uptime() method to the 5.3.9 loader, then it has no affect on the scenario above
Only when you have a newer loader and an older core does the issue arise-- a scenario I've never seen and I'm not actually sure is possible
z
but i'd rather add it to the server scope, avoid diving into java / internals where ever possible
b
irrelevant
This is not a CFML design question, this is a Lucee architecture question
Forget the specifics of this example, what is the plan to keep Lucee's interfaces in sync?
z
currently we have no plans to rev the loader signature
bug fixes and improvements which help our users is our focus
b
Thanks for the clarification, tho it does sound like the reasoning changed from "Because it would break stuff" to "well, ok it wouldn't actually break anything, but we just don't want to do it".
z
yeah the loader often shits me, this bug requires loader gymnastics https://luceeserver.atlassian.net/browse/LDEV-1673