In a multi-tenancy setup, the gsguard function ensures that a user only has access to the information within his virtual container. In essence, a database query is constructed and executed to check the ownership. Even if multiple tables are joined, the query is run fairly efficiently.
A typical Gyroscope application organizes information in tabs. Each tab displays information in two parts - core information about the record, and its related information. All the display units are bite sized; this is good for both humans and machines.
There are, of course, exceptions to the ideal scenario. In a document-centric view where the "core information", or the "truck" of a record contains many parts in a single tab, many LCHH containers are involved. This is a High Density LCHH situation.
When Multi-Tenancy and High Density LCHH are combined, the calls to gsguard, or, gsguard queries, are likely to be redundant. Consider the following scenario:
The initial tab view of a car is rendered with a showcar function, which in turn calls a master gsguard query:
The function also includes LCHH containers to two sub sections. Their contents are instantly rendered through server-side inclusion:
Sub Query 1:
Sub Query 2:
This is three database queries. We can use the DB Profiling feature to confirm the queries.
Starting 16.9, Gyroscope's gsguard function keeps track of the previous calls in the same page cycle. This means repeated calls in the same web request is queried only once.
If all the sub queries were simply verifying the record ownership, the caching method would have been trivial. However, the above example also uses gsguard's shorthand for returning data fields. This makes the result of the master query not reusable because it contains no information on the model or make of the car. Even though Sub Query 2's questions are partly answered by Sub Query 1, the database is still not spared because the color information is unknown.
In the definition of gsguard, which is located in auth.php, there is a debugging line we can uncomment:
echo "CACHE MISS: $k<br>";
This will help identify what fields each gsguard query is missing:
Q1: model, make
With this information, we can combine the sub query fields to the master query:
Now the database is queried only once in the initial page load. In a realistic multi-tenant project where a single tab view may contain many LCHH containers, the gsguard cache gain could be significant. In a Gyroscope-based financial product we have measured a reduction to 273 gsguard queries from 309 - that is a 12% query reduction!
One may quickly point out that not all queries are created equal, and the gsguard queries, in particular, are fast executing. However, the sheer number of database queries contributes to congestion. When users from different containers (different GS ID's) send simultaneous queries, the results are often fetched from different storage locations. The locality factor contributes to page misses, which, subsequently degrades performance.
No Cache Mode
The new gsguard function takes an optional argument "nocache". When this parameter is set to true, the very gsguard will not fetch from the cache. However, the result of this call still contributes to the gsguard cache.
In practice, the need to call no-cache is extremely rare. It is important to understand why that is the case - when a web request is sent to modify a record, it is no longer the "L-C" in the initial page load. The cache survives until the end of a request. The secondary request that's invoked by either reloadtab or ajxpgn has a fresh start. So the gsguard query pattern is typically "write-first, then read".
Finally, the gsguard cache can be turned off by uncommenting the following line in auth.php: