CFModule vs CFImport - radically different performance?

That’s a fascinating idea! I guess I would do that in the onApplicationStart() event-handler. Let me try that. I’m very curious to see if that would make a difference … or even work at all.

needs to be a web context mapping

Yeah, when I try this:

<cfset directoryCopy(
	source = "./tags/",
	destination = "ram://tags/",
	recurse = true,
	createPath = true
) />

<cfimport prefix="tags" taglib="ram://tags/" />

… I get the error:

could not find template [MyTag.[cfc|lucee|cfm|lucee|cfs]] in the following directories [ram,//tags/]

Well, it was a nice thought!

And, when I try to create a virtual-mapping in the Lucee Web Context Admin, the <cfimport> tag fails entirely:

invalid definition of the attribute taglib [/ram-tags/]

add filter=“*” to <cfdirectory>

No dice :frowning: Same error - tag not found. And, if I do a directoryList( "ram://tags" ), I do get this:

ram:///tags/MyTag.cfm

ok, I’m going to use my cfml resource provider to debug this :slight_smile:

2 Likes

While I certainly prefer using <cfimport /> (because I like the namespacing of tags), did you try putting the tag folder path into the Application’s this.customtagpaths and just using <cf_tagName /> instead of <tags:name />?

Maybe you did and I just missed that in the thread. That might be at least an easy way to “fix” the problem without refactoring to use <cfmodule />.

Funny you mention that, I was actually just considering that as well (not written down in this thread). My concern there, though, is that the names of the tags I’m using are super generic. And, I’m worried that making them globally available would cause issues. Not that we use a lot of Custom Tags in the app.

I wish there was a way to add custom-tag-path specific to a given file :confused:

Not a perfect solution by any means, but if you can sandbox your email templating code, you could use a custom Application.cfc for the folder with your email code which extends your main Application.cfc and just give it a unique Application name. Definitely not perfect and it could expose other issues.

The other alternative, is just to rename your tags so they are name spaced. So instead of a tag like <html:p> you have <cf_html_p />. Of course that’s really verbose and not very elegant either!

Yeah, renaming the tags is feasible. Though, it would stop it from being more reusable as a separate library.

Sandboxing the tags is an interesting idea. Right now, our emails are all generating as <cfinclude> tags inside a <cfmail> tag; so, I’d have to come up with some way to break that tight-coupling (in a way that doesn’t add too much overhead / complexity). I’ll have to noodle on that. If you have any suggestions, I’m all ears :slight_smile:

Boom! <cfimport> now beats <cfmodule>

got it working with my cfml resource provider

add a custom cfml resource provider mapping called. ct to lucee-server.xml

set the vfsStoreFileSystem.cfc to point to the custom tag dir or extend it etc

create a web or server level mapping/tags pointing to the ct:/// resource (note that’s 3 /s not 2!)

Add this to your Application.cfc (could be in onApplicationStart)

	public boolean function onRequestStart( String targetPage ){
		directoryCopy(source="./tags/", destination="ct://tags/", filter="*", createPath=true);
		echo('Dump(DirectoryList("ct://"));');
		Dump(DirectoryList("ct://"));
		echo('Dump(DirectoryList(path="/tags/", listInfo="query"));');
		Dump(DirectoryList(path="/tags/", listInfo="query"));
		return true;
	}

restart lucee for the new ct resource provider config to show up!

2 Likes

Holy cow!! This is awesome. I don’t really understand how providers work. But, given some of the things you said here, I want to go see if - one more time - if I can get ram:/// to work with triple slashes and no built-in path.

@Zackster what does your <cfimport> statement have in it?

<cfimport prefix="tags" taglib="/tags" />

Ok, well using some of your pointers above, I was at least able to get the ram:// version to compile and run. In the CFAdmin, I setup a web-mapping for:

/mammoth => ram:///

Then, I restarted Lucee. Then, I put this in my test App.cfc:

component {
	this.name = "tagtest";

	public void function onApplicationStart() {

		directoryCopy(
			source = "./tags/",
			destination = "ram://tags/",
			recurse = true,
			filter = "*",
			createPath = true
		);

	}
}

Then, in the test page, I did:

<cfimport prefix="tags" taglib="/mammoth/tags/" />
// ...
<tags:MyTag> ... </tags:MyTag>

Unfortunately, it still runs really slow. Even with the ram:/// mapping setup to only check Once. So, there must be something special that your custom provider is doing that the Ram VFS is not doing :frowning:

is ram:/// slower than a normal filesystem mapping set to once?

It seems to be basically the same. Maybe another Docker oddity, though.

Hmmm, I get this error sometimes with that mapping in place after a restart, then all I get is blank pages

“ERROR”,“main”,“02/25/2021”,“16:17:02”,“configuration”,"-1;-1;java.lang.ArrayIndexOutOfBoundsException: -1
at lucee.runtime.config.ConfigImpl.getPageSources(ConfigImpl.java:981)
at lucee.runtime.config.ConfigImpl.getPageSources(ConfigImpl.java:889)
at lucee.runtime.PageContextImpl.getPageSources(PageContextImpl.java:860)
at lucee.runtime.component.ComponentLoader._search(ComponentLoader.java:254)
at lucee.runtime.component.ComponentLoader._search(ComponentLoader.java:117)
at lucee.runtime.component.ComponentLoader.searchComponent(ComponentLoader.java:79)
at lucee.runtime.PageContextImpl.loadComponent(PageContextImpl.java:3222)
at lucee.commons.io.res.type.cfml.CFMLResourceProvider.getCFC(CFMLResourceProvider.java:269)

at lucee.commons.io.res.type.cfml.CFMLResourceProvider.callResourceRTE(CFMLResourceProvider.java:171)

That’s a strange one! I found that I sometimes had to edit the page with the <cfimport> on it before Lucee would stop complaining – I guess I need to trigger a page-level compilation or something :man_shrugging: