There are times where you need to store user related variables in some kind of permanent storage then relocate the user into another section of your application, be able to retrieve the data, use it and then clean it. All of these tedious operations are definitely doable but why reinvent the wheel if we can have the platform give us a tool for maintaing conversation variables across requests. The key point for Flash RAM is where will the data be stored so that it is unique per user. ColdFusion gives us several persistent scopes that we can use and we have also created several flash storages for this purpose. Since the ColdBox flash scope is based on an interface, the flash scope storage can be virtually anywhere. You will find all of these implementations in the following package: coldbox.system.web.flash. In order to choose what implementation to use in your application you need to tell the ColdBox.cfc
which one to use via flash configuration structure:
Below is a nice chart of all the keys in this configuration structure so you can alter behavior of the Flash RAM objects:
The included flash implementations for ColdBox are:
Each RAM implementation can also use properties in order to alter its behavior upon construction via the properties
configuration struct. Below are the properties our core implementations can use:
Session Flash Settings
none
Cluster Flash Settings
none
Client Flash Settings
none
Mock Flash Settings
none
Cache Flash Settings
cacheName
: The cache provider name declared in CacheBox
Key
Type
Required
Default
Description
scope
string or instantiation path
false
session
Determines what scope to use for Flash RAM. The available aliases are: session, client, cluster, cache or a custom instantiation path
properties
struct
false
{}
Properties that can be used inside the constructor of any Flash RAM implementation
inflateToRC
boolean
false
true
Whatever variables you put into the Flash RAM, they will also be inflated or copied into the request collection for you automatically.
inflateToPRC
boolean
false
false
Whatever variables you put into the Flash RAM, they will also be inflated or copied into the private request collection for you automatically
autoPurge
boolean
false
true
This is what makes the Flash RAM work, it cleans itself for you. Be careful when setting this to false as it then becomes your job to do the cleaning
autoSave
boolean
false
true
The Flash RAM saves itself at the end of requests and on relocations via setNextEvent(). If you do not want auto-saving, then turn it off and make sure you save manually
Name
Class
Description
Session
coldbox.system.web.flash.SessionFlash
Persists variables in session scope
Cluster
coldbox.system.web.flash.ClusterFlash
Persists variables in cluster scope via Railo only
Client
coldbox.system.web.flash.ClientFlash
Persists variables in client scope
Mock
coldbox.system.web.flash.MockFlash
Mocks the storage of Flashed variables. Great for unit/integration testing.
Cache
coldbox.system.web.flash.ColdboxCacheFlash
Persists variables in the ColdBox Cache
There are several ways to interact with the ColdBox Flash RAM:
Using the flash
scope object (Best Practice)
Using the persistVariables()
method from the super type and ColdBox Controller
Using the persistence
arguments in the setNextEvent()
method from the super type and ColdBox Controller.
All of these methods interact with the Flash RAM object but the last two methods not only place variables in the temporary storage bin but actually serialize the data into the Flash RAM storage immediately. The first approach queues up the variables for serialization and at the end of a request it serializes the variables into the correct storage scope, thus saving precious serialization time. In the next section we will learn what all of this means.
The flash
scope object is our best practice approach as it clearly demarcates the code that the developer is using the flash scope for persistence. Any flash scope must inherit from our AbstractFlashScope
and has access to several key methods that we will cover in this section. However, let's start with how the flash scope stores data:
The flash persistence methods are called for saving data, the data is stored in an internal temporary request bin and awaiting serialization and persistence either through relocation or termination of the request.
If the flash methods are called with immediate save arguments, then the data is immediately serialized and stored in the implementation's persistent storage.
If the flash's saveFlash()
method is called then the data is immediately serialized and stored in the implementation's persistent storage.
If the application relocates via setNextEvent() or a request finalizes then if there is data in the request bin, it will be serialized and stored in the implementation's storage.
Caution By default the Flash RAM queues up serializations for better performance, but you can alter the behavior programmatically or via the configuration file.
Info If you use the
persistVariables()
method or any of the persistence arguments on thesetNextEvent()
method, those variables will be saved and persisted immediately.
To review the Flash Scope methods, please go to the API and look for the correct implementation or the AbstractFlashScope
.
Info Please note that the majority of a Flash scope methods return itself so you can concatenate method calls. Below are the main methods that you can use to interact with the Flash RAM object:
Clears the temporary storage bin
Clears the persistence flash storage implementation
Discards all or some keys from flash storage. You can use this method to implement flows.
Checks if a key exists in the flash storage
Get a value from flash storage and optionally pass a default value if it does not exist.
Get a list of all the objects in the temp flash scope.
Get a reference to the permanent storage implementation of the flash scope.
Get the flash temp request storage used throughout a request until flashed at the end of a request.
Check if the flash scope is empty or not.
Keep flash temp variable(s) alive for another relocation. Usually called from interceptors or event handlers to create conversations and flows of data from event to event.
Persist variable(s) from the ColdBox request collection into flash scope. Persist the entire request collection or limit the variables to be persisted by providing the keys in a list. "Include" will only try to persist request collection variables with keys in the list. "Exclude" will try to persist the entire request collection except for variables with keys in the list.
The main method to place data into the flash scope. Optional arguments control whether to save the flash immediately, inflate to RC or PRC on the next request, and if the data should be auto-purged. You can also use the configuration settings to have a consistent flash experience, but you can most certainly override the defaults. By default all variables placed in flash RAM are automatically purged in the next request once they are inflated UNLESS you use the keep() methods in order to persist them longer or create flows. However, you can also use the autoPurge argument and set it to false so you can control when the variables will be removed from flash RAM. Basically a glorified ColdFusion scope that you can use.
Pass an entire structure of name-value pairs into the flash scope (similar to the put() method).
Remove an object from the temporary flash scope so it will not be included when the flash scope is serialized. To remove a key from the flash scope and make sure your changes are effective in the persistence storage immediately, use the saveNow argument.
Remove the entire flash storage. We recommend using the clearing methods instead.
Save the flash storage immediately. This process looks at the temporary request flash scope, serializes it if needed, and persists to the correct flash storage on demand.
Info We would advice to not overuse this method as some storage scopes might have delays and serializations
Get the number of the items in flash scope.
The purpose of the Flash RAM is to allow variables to be persisted seamlessly from one request and be picked up in a subsequent request(s) by the same user. This allows you to hide implementation variables and create web flows or conversations in your ColdBox applications. So why not just use session or client variables? Well, most developers forget to clean them up and sometimes they just end up overtaking huge amounts of RAM and no clean cut definition is found for them. With Flash RAM, you have the facility already provided to you in an abstract and encapsulated format. This way, if you need to change your flows storage scope from session to client scope, the change is seamless and painless.
Every handler, plugin, interceptor, layout and view has a flash object in their variables scope already configured for usage. The entire flash RAM capabilities are encapsulated in a flash object that you can use in your entire ColdBox code. Not only that, but the ColdBox Flash object is based on an interface and you can build your own Flash RAM implementations very easily. It is extremely flexible to work on a concept of a Flash RAM object than on a storage scope directly. So future changes are easily done at the configuration level.
Our Flash Scope also can help you maintain flows or conversations between requests by using the discard()
and keep()
methods. This will continue to expand in our 3.X releases as we build our own conversations DSL to define programmatically wizard like or complex web conversations. Also, the ColdBox Flash RAM has the capability to not only maintain this persistence scope but it also allows you to seamlessly re-inflate these variables into the request collection or private request collection, both or none at all.
The ColdBox Flash capabilities are very flexible and you can easily create your own Flash Implementations by doing two things:
Create a CFC that inherits from coldbox.system.web.flash.AbstractFlashScope
Implement the following functions: clearFlash(), saveFlash(), flashExists(), and getFlash()
Caution It is the developer's responsibility to provide consistent storage locking and synchronizations.
All of the methods must be implemented and they have their unique purposes as you read in the description. Let's see a real life example, below you can see the flash implementation for the session scope:
As you can see from the implementation, it is very straightforward to create a useful session flash RAM object.
Method
ReturnType
Description
clearFlash()
void
Will destroy or clear the entire flash storage structure.
saveFlash()
void
Will be called before relocations or on demand in order to flash the storage. This method usually talks to the getScope() method to retrieve the temporary flash variables and then serialize and persist.
flashExists()
boolean
Checks if the flash storage is available and has data in it.
getFlash()
struct
This method needs to return a structure of flash data to reinflate and use during a request.