Two quick questions regarding the Server Side section:

1.  In the Server() method in the error handling for when the CSP web socket is closed, there is code that is doing "kill ^CacheTemp.ChatWebSockets(..WebSocketID)" - shouldn't this actually be:  "kill ^CacheTemp.Chat.WebSockets(..WebSocketID)"? <-- notice the period I added between "Chat" and "WebSockets" in global name.

2.  In the Server() method in the error handling for when the CSP web socket is closed, shouldn't the code that is doing the kill of "kill ^CacheTemp.Chat.WebSockets(..WebSocketID)" also be doing a kill on "^CacheTemp.Chat.Room(..WebSocketID)"?

Thanks.    And this was a good article!

Correct :)   I was just offering an alternate example for those developers who like/prefer While loops versus For loops.  From working with a vast array of Cache Developers over the years, I found that looping structures are one of those topics that provide "good discussion/debate" over which is better, faster, more useful, etc.... :)   Personally, I do not have a preference - I use both While loops and For loops. Which one I use is based on the content I am implementing.

Quick comment/Note regarding the statement "A disadvantage of the 'While' structure is first you need to repeat the iteration construct, e.g. 'Set Sub1=$O(^Trans(Sub1))' before entering the loop and at the end." - this is a common perception for many newer Cache Developers.  

My suggestion for new folks would be to use a simplified structure, such as follows:

Set someVariable=""

While(1) {

     Set someVariable=$Order(^MyGlobal(someVariable))

     If (someVariable="") { Quit }

     // Do your processing here

}

The above structure keeps the looping construct at the start of the loop and is only needed once.  Within your processing logic, you can easily skip to the next iteration of the loop (if needed) via use of the Continue command.  Or if you need to exit the while loop, then you can do so via use of the Quit command.

Hope this was helpful!  And Happy Coding!!!

Excellent Article.   I have a question about options for running pButtons.   Please Note:  It has been awhile since I last used pButtons.   But I can attest that it is a very useful tool.   My question:  Is there an option to run pButtons in "basic mode" versus "advanced mode"?   I thought I recalled such a feature, but cannot seem to remember how to select the run mode.   And from what I recall, basic mode collects less data/information than advanced mode.  This can be helpful for support teams and others when they only need the high-level details.

Thanks!  And I look forward to reading the next 5 articles in this series.

Also, you can use the built-in %RD routine.  After you enter the routine name or names that you want to see the sizes for, then answer "L" for Long Form at the next prompt.   that will display additional attributes about the specified routines - one of which will be the size in bytes.

Example Output:

                 Long Listing of Selected Routine/Include Files
                              Namespace:  TEST
                         22 Aug 2016  6:14 PM   Page 1

NAME                            .EXT.VER  LANG  DATE/TIME             #BYTES

UTTest                          .MAC            20 May 2016  10:21 am  14252
 

If you just want to see data for the class query, then you can also run the query interactively via your Cache Terminal window (or any other type of terminal emulator, such as Putty, Reflections, PowerTerm, etc...).

Here is the command to run the class query from your example:

Do ##class(%ResultSet).RunQuery("LastName.BasicClassQuery","Display")

Note:  If your query accepts input parameters, then you just include them as the 3rd-nth parameters - an example of what that might look like if you needed to pass two input values to your query:    Do ##class(%ResultSet).RunQuery("LastName.BasicClassQuery","Display","value1","value2")

This will list the data in your terminal window and might look something like this:  Notice the first row that is displayed is all your column names (i.e. property names) and all the subsequent rows that are displayed is the data from your table(s).

Code:Name:IsActive:ID:
AF:Archived Forms:1:31:
AR:AdHoc Feedback Report:1:29:
AT:Stain/Request Audit Report:1:11:
CH:Cyto-Histo Correlation:1:23:
CPS:Cytology Population Statistics:1:22:
 

In regards to the first part of your write-up, as a developer, if you want a quick and easy way to test the query from your terminal window (i.e. Cache Terminal, PowerTerm, Putty, Reflections, etc...), then you can run the query as follows:

Do ##class(%ResultSet).RunQuery({className},{queryName}) - if you have input parameters, then you would pass those values as subscripts 3 - n;

Example of running query with two input parameters:

Do ##class(%ResultSet).RunQuery({className},{queryName},{inputValue1},{inputValue2})

So an example of running the first query in your write-up from a terminal window might be:

Do ##class(%ResultSet).RunQuery("Sample.Person","ByName","A")

The output from the query might be:

ID:Name:DOB:SSN:
53:Adam,Ralph O.:41730:657-43-6149:
33:Adam,Zoe X.:56117:982-36-6928:
80:Ahmed,Edgar Q.:33719:546-61-2688:
110:Alton,Umberto B.:30116:877-79-1057:
146:Avery,Valery P.:39515:310-11-8847:
 

Hope this Helps and Have a Great Day!!!   Happy Coding/Testing those queries!

Hi Benjamin,

As a fellow Cache Developer I can offer a couple of suggestions.  If you want the user to have to wait for the server side processing to complete before continuing with their work, then you could override the CSP Gateway Response Timeout:

1.  If you are working with a ZEN page (i.e. that extends from %ZEN.component.page), then you could implement an overridden version of the OnPreHyperEvent method

Example:

 /// OnPreHyperEvent - Event handler which is invoked before a hyperevent
///   method is called on all Zen pages. The purpose of this method is to
///   allow various configuration settings to be overridden prior to making
///   the actual hyperevent call (i.e. executing a query for a tablepane).
ClassMethod OnPreHyperEvent(class As %String, method As %String) As %Status [ ServerOnly = 1 ]
{
// Override the CSP Gateway Response Timeout
Set %response.Timeout={numberOfSecondsYouWantToAllowForServerProcessingToCompleteBeforeRequestTimesOut}

// Call built-in Zen Controller pre hyperevent method
Quit ##class(%ZEN.Controller).OnPreHyperEvent(..%ClassName(1),$G(method),+..#AUTONS,..#RESOURCE)
}
 

2.  If you are working with a CSP page (i.e. that extends from %CSP.Page), then you could implement an overridden version of the OnPreHTTP method

Example:

 /// Event handler for <b>PreHTTP</b> event: this is invoked before
/// the HTTP headers for a CSP page have been sent. All changes to the
/// <class>%CSP.Response</class> class, such as adding cookies, HTTP headers,
/// setting the content type etc. must be made from within the OnPreHTTP() method.
/// Also changes to the state of the CSP application such as changing
/// %session.EndSession or %session.AppTimeout must be made within the OnPreHTTP() method.
/// It is prefered that changes to %session.Preserve are also made in the OnPreHTTP() method
/// as this is more efficient, although it is supported in any section of the page.
/// Return <b>0</b> to prevent <method>OnPage</method> from being called.
ClassMethod OnPreHTTP() As %Boolean [ ServerOnly = 1 ]
{
// Override the CSP Gateway Response Timeout
Set %response.Timeout={numberOfSecondsYouWantToAllowForServerProcessingToCompleteBeforeRequestTimesOut}
Quit $$$OK
}
 

But another option to consider is to implement the ZEN page, so the user can provide the input criteria (if any) for retrieving table data and instead of having the user click a [Search] button to run the server side lookup in foreground mode (i.e. where user has to wait for the server processing to complete), you could instead implement a [Run In Background] button where you job off the server side processing, so it can run in the background, which allows the user to do other things with the application and they can check back at a later point for the status.   You could have some type of mechanism on the ZEN page that shows the user the status of the background process (i.e. Running, Completed, Error, etc...);   You can refer to the built-in  %RunBackgroundMethod method or you could implement your own application specific background type processing - example:  As the user submits various background jobs to run, you could have a tablepane display the various processes that are running with their status - then when complete, you could have a link in that table the user could click to display the associated data that was retrieved from the server.

Hope this helps and Have a Great Day!!    Happy Coding!