Mappings directory with corresponding single cfclasses directory


#1

In a virtual hosts environment (we have 300+ virtual hosts running Lucee 5.2.4.37 on IIS 10) we have a mapping to a global components and other directories. As mentioned in previous posts updating a single or multiple files in a mapped directory causes re-compiling in all WEB-INF/lucee/cfclasses within all virtual hosts which fills the server memory and often requires a Lucee restart.

My question
Is there a way to have a single global compiled cfclasses directory for these mapped directories to avoid the overhead of the redundant file compilation in all the virtual hosts directories as the same changed file is essentially compiled to the exact same file 300+ times currently.

I appreciate any guidance on scaling this better.
Thanks,
Andrew


#2

Does each site have separate settings? i.e. Could you just have them all share the same web context? One of the reasons the class files are stored separately is because you might have “full null support” enabled in one web context but disabled in another, which would generate two different versions of the bytecode.

If you must have different web contexts, you could try some symlinks to share the class files, but I’ll warn that I’ve never tried this and I don’t really know if it will work. It also likely won’t prevent each web context from having it’s own in-memory cache of the class files.

I am curious if precompiling your shared libs as a lar file and then creating mappings that point to the same lar would make any difference. I’m not entire sure how the class files are handled from lucee archives (LARs)


#3

Thank you for your reply.

  1. Yes all sites could share the same web context, there is nothing different about each site. How would I achieve this?
  2. I am not aware of how to enable “NULL” support at the web level, I only see that setting at the “Server” level in Administrator.

#4

Sorry, I might have been wrong about null support specifically. The point was the web context settings could potentially affect bytecode generation

I think to lock everything into a single web context, you can just set the init-param in your web.xml to override the lucee-web-directory setting.

<init-param>
  <param-name>lucee-web-directory</param-name>
  <param-value>/path/to/shared/web-context</param-value>
</init-param>

I’m not 110% on that, but I think it should work. If not, the next step would be to remove mod_cfml and manually define a single Tomcat host and you’d probably need some rewrite and virtual dir nonsense to still have separate web roots for everything possibly. But before you get off in those weeds, see if a single web context improves anything.


#5

I know this is a long period after but just for anyone else reading this post.

Doing the above simply moves the location of the web context/s it does not create a global web context that all sites will use (like <= ACF9). Thus the initial reason for this change (performance issues with 200+ sites on a single Lucee install) still remains as a problem we are yet to resolve. For now the server hangs when multiple shared (mapped directory) files are modified. The only resolution is to kill Lucee/Tomcat and restart the service


#6

are the shared mappings per context or per server?


#7

Mapped directories are at the server level / context. It appears that lets say 3 new files are uploaded to a mapped directory accessed by 200+ sites that Lucee is re-compiling all 200+ web contexts at once which can take upwards of 5 minutes and causes IIS to spawn hundreds of processes thus the inevitable 100% cpu. Lucee service can then no longer be stopped.

If we could somehow avoid this by only compiling the content in mapped / custom tag directories in a single location that would solve the issue. Lucee seems to think something is changing in every web context as a result of a change in a mapped directory which is not actually the case.


#8

A reproducible test case would be great to be able to address this problem

I guess that’s going to be more challenging with IIS, as with Apache you could easily generate a sample .conf file to include, or is IIS more scriptable these days?


#9

OK, Not sure how to do that as this is simply a re-compilation performance problem within lucee web-inf (web contexts) not really anything to do with IIS/Apache - we previously used Apache and had same issue, we moved to IIS to hopefully improve situation but result was the same. To reproduce it you would need to

  1. Setup 300+ sites in IIS (all Lucee enabled)
  2. Create 2 or 3 mapped directories
  3. Create a template in each of the 300+ sites that call files located in these mapped directories
  4. Browse to any of these sites to trigger re-compiling of the classes in each local WEB-INF directory

#10

So if 200 sites takes 300 seconds (5 minutes), we could assume that a test case with say 20 sites would take 30 seconds, 10 sites would take 15 seconds to update? Which would still demonstrate the problem and be more manageable.

I’d suggest creating a demo apache .conf include file which creates 10 or 20 demo virtualhosts , all with a ServerName directive of site1.local, site2.local, site3.local etc, all listening on port 80

To avoid having to mess around with DNS or hosts file, the test case would need to then override host header.

I’m not sure if you can override the host-header with cfhttpparam, so you might need to use a batch file with curl (https://daniel.haxx.se/blog/2018/04/05/curl-another-host/) to then call all the sites (site1.local, site2.local, site3.local etc) to demonstrate the problem.

Or does just hitting one site trigger all the other sites to also update? even if it does, you’d need to initially call each and every demo site/context to automatically generate the context via mod_cfml


#11

Thank you for the guidance, so it looks like our issue is the same as the thread here which basically notes that the recompilation of every file should happen very quickly but nevertheless it does happen and that is our main issue. This seems extremely inefficient for files in a mapped drive, why do they need to be recompiled and place in every sites WEB-INF classes directory when this seems to defeat the purpose of having a mapped (global shared) directory

https://groups.google.com/forum/#!topic/lucee/56WHZlWc9rI

I have seemed to solve our issue (for now) by changing the “Inspect” setting for each of our Mappings (In Server context) to “Never ( Best Performance )”. My understanding is that new files can then be uploaded to the mapped directory without triggering a re-compilation until a Lucee service restart?


#12

I guess one lingering question I have though is my original one posed in this thread

Is there a way to have a global WEB-INF directory with only one copy of all compiled files for multiple sites or even better a global WEB-INF directory for all Mapped resources?

Thank you kindly in advance.


#13

I gave you the information to do that back in March with the servlet’s init param. It should work because I just tested it on two CommandBox servers right now. I have two completely separate server installs sharing the same web context. I add a datasource to one server and it shows up in the other. Note, this is not a recommend/supported approach by the Lucee developers, for what it’s worth.


#14

Yes, sorry for not being clearer but I guess our private interpretation of "working" is inconsistent as it does not "work" as I was intending/hoping.

All this does is create a WEB-INF directory in a global location and then under that web context folders for every virtual site are still created which although more centrally organized it provides no benefit as it still equals the exact same number of files and massive duplication of mapped directory classes which all have to be updated for every change.

I agree that all of that makes sense but I guess my real "wish" is that there was some way to make the files in the Mapped directory act as labelled (Mapped) and thus only compiled and accessed in one place as compiling them and copying them to the WEB-INF/lucee/cfclasses directory of every single site really defeats the purpose of having a mapped directory right? Or am I really missing something with the purpose of the Mapped resources functionality?


#15

That is not at all what I just saw in my test. One single web context. Not 2. Not 3. Just one. I would guess you’re doing something wrong. Perhaps you can show us your web.xml. Every time this doesn’t work, you shoot down a path of going on about what you’re trying to solve. Let’s stick to one thing at a time and figure out why you’re not sharing the same web context.


#16

OK, that is good news. I was hoping I did something wrong!
So this is from my test environment (Win Server 2012/IIS / Lucee 5) - 3 Test IIS Sites

<init-param>
      <param-name>lucee-web-directory</param-name>
      <param-value>C:/lucee/web-contexts-global/{web-context-label}</param-value> 
      <description>Lucee Web Directory (for Website-specific configurations, settings, and libraries)</description>
    </init-param>

If I omit the `{web-context-label}` then basically an error is thrown and the WEB-INF directory is created locally in the site httpd directory.

Below is how this web-contexts-global directory appears after saving this setting and restarting Lucee and browsing to each of the 3 test sites configured in IIS.

![lucee-web-context|516x306](upload://za1sTfPvlulsyOQw32fTzzJcvR4.png)

#17

The inclusion of {web-context-label} is precisely why you’re getting the behavior you’ve described. You’ll notice my original reply to you in March did not include that placeholder.

basically an error is thrown

I’d love to help you, I really would. But until you start volunteering a lot more information I have nothing to go on.


#18

OK, I appreciate the help and understand your frustration so I am thinking I’ll just soldier on as we are and try to figure this one out myself so you may help others. As I will no doubt come back and search this thread again, like I did this week, I will lay out (for mine and anyone else reference) everything I know/currently understand about this issue.

Environment
My test/dev environment is Windows Server 2012 / IIS 8, Lucee 5.2.9.31 (updated today), 3 IIS Sites vm-01.localhost, vm-02.localhost, vm-03.localhost. One single mapped resource for global includes. All IIS site directories are empty except for a single index.cfm that references a file via

<cfinclude template="/global-includes/date.cfm">

that mapped file is located here c:\lucee\mapped-resource\date.cfm

init-param setting C:/lucee/web-contexts-global
I did uncomment the init-param and enter exactly as Brad had suggested per my post above

If I omit the `{web-context-label}` then basically an error is thrown and the WEB-INF directory is created locally in the site httpd directory.

This, in an unclear way, says I did first try saving the init-param block as

<init-param>
      <param-name>lucee-web-directory</param-name>
      <param-value>C:/lucee/web-contexts-global</param-value> 
      <description>Lucee Web Directory (for Website-specific configurations, settings, and libraries)</description>
    </init-param>

As also shown here as direct screenshot from c:\lucee\tomcat\conf\web.xml

The result of this setting is as follows

C:\lucee\web-contexts-global
Went from being empty to populating with all the “WEB-INF” directories also and a separate web context directory for ROOT

lucee-web-context-no-placeholder

Lucee Admin showing the web contexts now available

C:\sites\vm-01.localhost
Went from being an empty directory to now having a WEB-INF (local directory)

vm-01-dir

With the contents of this WEB-INF directory containing a local copy of the compiled “mapped resources” file as shown below

lucee-web-context-no-placeholder-vm-01

as well as all the same directories present essentially if I had made no change to the root web.xml

vm-01-web-inf-dir

init-param setting C:/lucee/web-contexts-global/{web-context-label}
When I change setting to what I noted in my previous post the results change to

C:\sites\vm-01.localhost\WEB-INF\lucee
lucee-web-context-placeholder-vm-01

C:\lucee\web-contexts-global
lucee-web-contexts-global

Lucee Admin Web Contexts

Summary

  1. Without a placeholder nothing really changes too much except more duplication (web context is created local to the site as well as in the global web contexts directory

  2. With a placeholder to the same global web contexts directory duplicate copies of all WEB-INF diretcories to the local site is NOT made however in it’s place a web context directory is created in the global web contexts parent directory for this site with a cfclasses folder containing a compiled version of the mapped resources files called.

  3. Thus no reduction the number of files generated was achieved via either setting change, just the location and placement of the files.

  4. The goal was to achieve non-duplication of “Mapped directories” as in a larger virtual hosted environment this leads to serious performance issues in generating and re-generating all these files for every site on every file change. The only quasi solution I found was to set the Inspect property of the Mapped directory to “Never” and restart Lucee late at night to propagate any changes to all sites. This seems to work as follows, when a change is made to files in the C:\lucee\mapped-resources directory, if a site has not accessed this file at all during the current server lifetime it will see the latest change. If a site has accessed this file previously it will not the the latest change until a service restart.


#19

Thank you for all of that information, however you literally left out the single piece of information I actually wanted. You said when you don’t use the placeholder in the web context path, “an error is thrown”. What was the error?? We can’t get past step one until we know exactly what happened when you tried.

Also, no additional information or screen shots are necessary for the behavior you get when using the {web-context-label} label. We all know how that works and that it’s the opposite of what you want, so there’s no need to keep explaining what it did and how it isn’t what you wanted. I know that and it’s the reason I didn’t have you use it in the first place,.

Also, we really don’t need any information about the mapings at this point. We’ve already determined that so long as you have separate web contexts, you’ll have issues with the mappings. So let’s focus on making the single web context work and we can all assume that until that is done, the mapping issue will remain unresolved. No need to keep covering that ground in every post.

Without a placeholder nothing really changes too much except more duplication (web context is created local to the site as well as in the global web contexts directory

But there is an error right? An error that’s been brought up twice now without actually being described. Also, are you sure that the web context is actually being created twice? I would guess that you simply forgot to delete the old web context when changing the setting so the “duplicate” you saw was simply the old web context. Again, I tested this with two CommandBox servers yesterday before replying just to make sure it all still works and I only got a single web context directory.


#20

OK, again appreciate you sticking with this, as I certainly don’t expect you to after my shoddy explanations :slight_smile:

  1. “Error” may not be correct, but my reason for it is that the following is logged in lucee-stderr when I omit the placeholder
20-Sep-2018 09:11:39.909 INFO [w3svc2-startStop-1] org.apache.catalina.startup.HostConfig.deployDescriptor Deploying configuration descriptor C:\lucee\tomcat\conf\Catalina\w3svc2\ROOT.xml
20-Sep-2018 09:11:39.987 SEVERE [w3svc2-startStop-1] org.apache.catalina.core.StandardContext.loadOnStartup Servlet [CFMLServlet] in web application [] threw load() exception

  1. Yes, I certainly did not overlook the fact that remnant directories could have been present. I failed to mention that I deleted all folder in C:\lucee\web-contexts-global and in my virtual sites directories between each change to web.xml so everything I report for each scenario can be considered starting from a fresh install position. FWIW your setup using commandbox, in my limited understanding, is different to mine being a local install directly into windows