[coldbox 3.6] Flash loads before ModuleConfigs

Hi everybody,

Ran into a small issue. I have a Module called SessionModule.

Inside its configure method I define 3 wirebox bindings:

binder.map(“SessionDAO@DAO”)
.to("#moduleMapping#.model.dao.SessionDAO");

binder.map(“sessionService@services”)
.to("#moduleMapping#.model.services.SessionService")
.asSingleton();

binder.map(“Cookie@Plugins”)
.to("#moduleMapping#.plugins.Cookie");

I also created a SessionModuleFlash component:

/**
* Flash component to handle flash data using our custom session module
*/
component extends=“coldbox.system.web.flash.AbstractFlashScope” singleton{

property name=“sessionService” type=“any”;

any function init(required any controller){
super.init(arguments.controller);
instance.flashKey = “cbox_flash”;
variables.sessionService = controller.getWireBox().getInstance(“sessionService@services”);
return this;
}

public string function getFlashKey(){
return instance.flashKey;
}

public void function saveFlash(){
sessionService.add(instance.flashKey, getScope());
}

public void function clearFlash(){
if(flashExists()){
sessionService.remove(instance.flashKey);
}
}

public struct function getFlash(){
if(flashExists()){
return sessionService.get(instance.flashKey);
}
return {};
}

public boolean function flashExists(){
return sessionService.exists(instance.flashKey);
}
}

In my main application’s coldbox.cfc:

flash = {
scope = “modules.SessionModule.model.flash.SessionModuleFlash”,
properties = {}, // constructor properties for the flash scope implementation
inflateToRC = true, // automatically inflate flash data into the RC scope
inflateToPRC = false, // automatically inflate flash data into the PRC scope
autoPurge = true, // automatically purge flash data for you
autoSave = true // automatically save flash scopes at end of a request and on relocations.
}

This will not work because flash is initialized before any of the ModuleConfigs are loaded. This means that wirebox does not yet know about the plumbing of your modules flash component.

It is easily fixed by moving the bindings into your main apps wirebox.cfc, but this goes against my code-smell where I want my module to encapsulate its plumbing.

Ideally I would want to define or override the flash settings of my main application so that any application using my SessionModule will automatically use it for Flash RAM.

I will have a look at the coldbox bootstrap sequence to see if I can remedy the Issue, but I was just wondering if anyone else ran into this and maybe already has a solution?

Tom I think you can change this via the parent settings in your module. Basically you are altering the setting from the parent config.

Does that make sense?

Luis Majano
CEO
Ortus Solutions, Corp
Toll Free/Fax: 1-888-557-8057
Direct: 909-248-3408
www.ortussolutions.com
Twitter: @lmajano, @ortussolutions

HI Luis,

You would think so, but that was the first path I took;

No flash struct in my main’s coldbox.cfc but in my ModuleConfig:

component output = false {

this.title = “Session Module”;
this.author = “Tutuka”;
this.webURL = “”;
this.description = “Session handling for Tutuka applications”;
this.version = “0.1”;

function configure(){
binder.map(“SessionDAO@DAO”)
.to("#moduleMapping#.model.dao.SessionDAO");

binder.map(“sessionService@services”)
.to("#moduleMapping#.model.services.SessionService")
.asSingleton();

binder.map(“Cookie@Plugins”)
.to("#moduleMapping#.plugins.Cookie");

parentSettings = {
flash = {
scope = “common.modules.SessionModule.model.flash.SessionModuleFlash”,
properties = {}, // constructor properties for the flash scope implementation
inflateToRC = true, // automatically inflate flash data into the RC scope
inflateToPRC = false, // automatically inflate flash data into the PRC scope
autoPurge = true, // automatically purge flash data for you
autoSave = true // automatically save flash scopes at end of a request and on relocations.
}
};
}

function preProcess(event, interceptData){
controller.getWireBox().getInstance(“sessionService@services”).checkSession();
}

}

But as you can see from the dump:

Session.index

struct
FLASH
component coldbox.system.web.flash.SessionFlash
extends coldbox.system.web.flash.AbstractFlashScope
METHODS

NAMESPACE [empty string]
NAMESPACEROUTING [empty string]
PERSIST I am persisting
event Session.myTest

The default flash (SessionFlash) is being used.

When I move the flash struct into my main app’s coldbox.cfc, then I also have to move the mappings into my main app’s wirebox.cfc or the wiring is incomplete during flash init.

I think because flash is loaded before any module configs are loaded, the parrentSettings directives do not trigger a reinit of the flash.

Your thoughts?

Cheers,
Tom

Hi Luis,

Line 81 in system.web.services.LoaderService

Here are the services who’s configurations need to be loaded:

struct
DEBUGGERSERVICE
component coldbox.system.web.services.DebuggerService
extends coldbox.system.web.services.BaseService
METHODS

HANDLERSERVICE
component coldbox.system.web.services.HandlerService
extends coldbox.system.web.services.BaseService
METHODS

INTERCEPTORSERVICE
component coldbox.system.web.services.InterceptorService
extends coldbox.system.web.services.BaseService
METHODS

LOADERSERVICE
component coldbox.system.web.services.LoaderService
extends coldbox.system.web.services.BaseService
METHODS

MODULESERVICE
component coldbox.system.web.services.ModuleService
extends coldbox.system.web.services.BaseService
METHODS

PLUGINSERVICE
component coldbox.system.web.services.PluginService
extends coldbox.system.web.services.BaseService
METHODS

REQUESTSERVICE
component coldbox.system.web.services.RequestService
extends coldbox.system.web.services.BaseService
METHODS

Doing structKeyArray I can find the order in which these will be processed:

array
1 LOADERSERVICE
2 REQUESTSERVICE
3 DEBUGGERSERVICE
4 HANDLERSERVICE
5 PLUGINSERVICE
6 MODULESERVICE
7 INTERCEPTORSERVICE

The flash object is created on line 68 of system.web.services.RequestService long before ModuleService.onConfigurationLoad() is called.

Therefore the flash config can never be overridden by a module.

I am trying to create a fix for this. If I find a nice clean way I will send you a pull request.

Cheers,
Tom

Hi Luis,

I can get it to work when I change the order of the services.

Line 52 to 58 of system.web.Controller changed to:

// Setup the ColdBox Services
services.ModuleService = CreateObject(“component”, “coldbox.system.web.services.ModuleService”).init( this );
services.RequestService = CreateObject(“component”,“coldbox.system.web.services.RequestService”).init( this );
services.DebuggerService = CreateObject(“component”,“coldbox.system.web.services.DebuggerService”).init( this );
services.HandlerService = CreateObject(“component”, “coldbox.system.web.services.HandlerService”).init( this );
services.PluginService = CreateObject(“component”,“coldbox.system.web.services.PluginService”).init( this );
services.InterceptorService = CreateObject(“component”, “coldbox.system.web.services.InterceptorService”).init( this );

So effectively making ModuleService.onConfigurationLoad() run before RequestService.onConfigurationLoad() but I am afraid of other hidden consequences.

Your thoughts?

Cheers,
Tom

Hi guys,

Anyone have some feedback on this?

I have changed it in our local coldbox and all of our applications are running flawlessly so should I create a pull request for this fix?

Cheers,
Tom

Tom I am not sure about this. I know there was a reason for the linked map but would need to retrace it.

Maybe a better way of overriding it via config or exposing it via the request service.

Luis Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Social: twitter.com/ortussolutions | twitter.com/coldbox | twitter.com/lmajano

Actually after looking at the code it might also make sense to load the flash scope at the register aspects level in the loader service. Then exposing a few more methods in the request service to create the flash scope s it could also be called on demand if needed. I would suggest you enter a ticket for this. I can definitely see the value To override via modules

Luis Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Social: twitter.com/ortussolutions | twitter.com/coldbox | twitter.com/lmajano

Ok. Where do I create a ticket? Is it at coldbox.assembla.com?

Scratch previous.

Created issue at https://ortussolutions.atlassian.net/browse/COLDBOX-183

Will attempt to solve on my own though :wink:

Cheers,
Tom

Created a pull request on Github

Nice will check

Luis Majano
CEO
Ortus Solutions, Corp
Toll Free/Fax: 1-888-557-8057
Direct: 909-248-3408
www.ortussolutions.com
Twitter: @lmajano, @ortussolutions