caching view with user specific data per session

I'm trying to cache a viewlet with user specific data per user
session. my handler code:
var userID = oSession.getVar("userinfo.ID");
rc.metrics = StructNew();

rc.metrics.volume1 = "1,025";
rc.metrics.volume2 = "150";
rc.metrics.volume3 = "82";
rc.metrics.volume4 = "0";

Event.showdebugpanel("false");
Event.setView(name="global/
volumemetrics",noLayout="true",cache="true", cacheSuffix=userID);

the view is cached, but userID suffix is not appended. the latest and
greatest of the DOCS doesn't event have this optional variable of
cacheSuffix, i'm trying it because i found a discussion here from
early 2010 that suggested it.

I also don't see the option supported in renderView.

How can I accomplish this with in 318-GENESIS-14:14 ?

I don't know where in the DOCS i would find this but i tried it on
renderView and it worked.

Here is what i did:
EVENT HANDLER
var userID = oSession.getVar("userinfo.id");
rc.metrics = StructNew();
DataStruct = CoreAPI.metrics(userID);
rc.metrics.volume1 = DataStruct.vol1;
rc.metrics.volume2 = DataStruct.vol2;
rc.metrics.volume3 = DataStruct.vol3;
rc.metrics.volume4 = DataStruct.vol4;
Event.showdebugpanel("false");
Event.setLayout("Layout.Metrics");

LAYOUT
renderView(view='global/
volumemetrics',cache=true,cacheTimeout='60',cacheSuffix="#userID#")

CACHE REPORT
cbox_view-:global/metrics42700841

Nope that's what cache suffix is for.

Luis, ok i'm caching the data output per user. However, my event
handler is calling the API (cfhttp to 3rd party webservice) on every
page load. So to really increase performance if i could only call the
API every 60 mins that would be best or lastAccesstimeout at 30 mins.

It starts with a little ajax, and as you can see I'm only caching the
viewlet:

HOMEPAGE HTML

<div id="advanced-metrics"></div>
<script type="text/javascript">
     $('#advanced-metrics').load('/index.cfm/WebService/getMetrics?
layout=header');
</script>

WEBSERVICE HANDLER

<cfcomponent output="false">
  <cfproperty name="CoreAPI" inject="model:CoreAPI">

  <cffunction name="getMetrics" access="public" returntype="void"
output="false">
    <cfargument name="Event" type="any">
    <cfscript>
      //Do Login Procedure.
      var rc = Event.getCollection();
      var DataStruct = StructNew();
      var oSession = getPlugin("SessionStorage");
      var oClient = getPlugin("ClientStorage");
      var userID = oSession.getVar("userinfo.id");

      DataStruct = CoreAPI.metrics(userID);
      rc.metrics = StructNew();
      rc.metrics.volume1 = DataStruct.vol1;
                       rc.metrics.volume2 = DataStruct.vol2;
                       rc.metrics.volume3 = DataStruct.vol3;
                       rc.metrics.volume4 = DataStruct.vol4;

      Event.showdebugpanel("false");
      Event.setLayout("Layout.Metrics");

    </cfscript>
  </cffunction>
</cfcomponent>

COREAPI MODEL

<cfcomponent output="false">

  <!--- Dependencies --->
  <cfproperty name="APIBaseURL" inject="coldbox:setting:APIBaseURL"
scope="instance" />
  <cfproperty name="APIUser" inject="coldbox:setting:APIuser"
scope="instance" />
  <cfproperty name="APIPass" inject="coldbox:setting:APIpass"
scope="instance" />

       <cffunction name="metrics" access="public" returntype="struct"
output="false">
    <cfargument name="sessionid" type="string" required="true">

                <cfsavecontent variable="soapBody">
      <cfoutput>
        <?xml version="1.0" encoding="utf-8"?>
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/
envelope/" xmlns:web="http://webservices.xx.com" xmlns:web1="http://
webservice.services.xx.com">
          <soapenv:Header/>
          <soapenv:Body>
            <web:#arguments.method#>
              <web:in0>#arguments.sessionid#</web:in0>
              <web:in1>
                <!--Optional:-->
                <web1:password>#instance.APIPass#</web1:password>
                <!--Optional:-->
                <web1:userId>#instance.APIUser#</web1:userId>
              </web:in1>
            </web:#arguments.method#>
          </soapenv:Body>
        </soapenv:Envelope>
      </cfoutput>
    </cfsavecontent>
    <cfhttp url="#instance.APIBaseURL#/services/ICustomWebServices"
method="post" result="apiResponse">
          <!--- Most SOAP action require some sort of SOAP Action
header to be used. --->
          <cfhttpparam type="header" name="SOAPAction" value=""/>
          <!--- I typically use this header because CHTTP cannot handle
GZIP encoding. This "no-compression" directive tells the server not to
pass back GZIPed content. --->
          <cfhttpparam type="header" name="accept-encoding"
value="gzip,deflate"/>
          <!--- When posting the SOAP body, I use the CFHTTPParam type
of XML. This does two things: it posts the XML as a the BODY and sets
the mime-type to be XML. --->
          <cfhttpparam type="xml" value="#trim(soapBody)#"/>
      </cfhttp>
             <cfset soapResponse = xmlParse( apiResponse )>
              <cfset vol1 = xmlSearch(soapResponse, "//
*[name()='volume1']")>
               <cfset vol2 = xmlSearch(soapResponse, "//
*[name()='volume2']")>
                <cfset vol3 = xmlSearch(soapResponse, "//
*[name()='volume3']")>
                <cfset vol4 = xmlSearch(soapResponse, "//
*[name()='volume4']")>
                 <cfset rtnStruct.vol1 = vol1>
                 <cfset rtnStruct.vol2 = vol2>
                 <cfset rtnStruct.vol3 = vol3>
                 <cfset rtnStruct.vol4 = vol4>
    <cfreturn rtnStruct>
  </cffunction>
</cfcomponent>

LAYOUT

<cfouput>#renderView(view='global/
volumemetrics',cache=true,cacheTimeout='60',cacheSuffix="#userID#")#</

VIEW

<cfoutput>
  <table id="subheader" width="320" cellpadding="0" cellspacing="0"
border="0">
          <tbody>
                <tr>
                    <td
class="leftCell">#getResource("metrics.vol1")#: #rc.metrics.volume1#</

                    <td
class="rightCell">#getResource("metrics.vol2")#: #rc.metrics.volume2#</

                </tr>
                <tr>

                    <td
class="leftCell">#getResource("metrics.vol3")#: #rc.metrics.volume3#</

                    <td
class="rightCell">#getResource("metrics.vol4")#: #rc.metrics.volume4#</

                </tr>
            </tbody>
        </table>
</cfoutput>

I'm trying EVENT_CACHE_SUFFIX

<cfcomponent output="false" cache="true" cachetimeout="60"
cacheLastAccessTimeout="30">

  <cfproperty name="CoreAPI" inject="model:CoreAPI">
  <cfset this.EVENT_CACHE_SUFFIX = "42700841 ">

i'm not getting any errors, however i'm not seeing the cached event in
the cache report.

Am I going in the right direction?

Sweet. I enabled event caching with eventCaching = true, in the config
file.
I added
cache="true" cacheTimeout="60" cacheLastAccessTimeout="30"
and
this.EVENT_CACHE_SUFFIX = userID;
to the getMetrics event

Now i get this in my cache report:
cbox_event-
webservice.getmetrics-42700841-6995dc01f9d3beedf2900adb83d0fbed

I'm not sure exactly where the 6995dc... number came from. What is
this for?

With my little experience in caching I suppose that my API call
(cfhttp) doesn't execute again until 30 min lastaccess or 60 min
timeout. Is this how caching works?

I missed the note that said caching is not meant for secure events or
session events. It is application wide, not user wide.

So ofcourse my event is being cached (cool) but all users are getting
the same output (not cool).

So apperently I don't know how to cache events user wide. Any help?

I think you need to use a viewlet
http://ortus.svnrepository.com/coldbox/trac.cgi/wiki/cbLayoutsViewsGuide#Viewlets

then do something like this, and volumemetrics.cfm calls runEvent so
that you can cache it.

Your Layout

i've got this working really well. thanks for the direction.

I'd like to use these cached views externally. and it appears ok to
call the cached view like so:
http://localhost/index.cfm?debugpanel=cacheviewer&cbox_cacheName=TEMPLATE&key=cbox_view-:global/dataviewlet5100217

Also everytime the cache view is called this way it updates the Last
Accessed datetime. So externally I don't have to do anything to
recache or manually update it.

Not sure if cached views were meant to be used in this way. I have a
feeling this URL action is meant for debugging.

Any thoughts?

for debugging only.

Luis F. Majano
President
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Social: twitter.com/lmajano facebook.com/lmajano