Post on 11-May-2015
transcript
TURBOCHARGINGYOUR
EXTENSION
© Klas Berlič & BzZzZ 2010
HOW IT ALL CAME ABOUT// How I got involved with cache //
Quite an amazing storyof a willpower
and turning a failure into a sucess
with contributions to common goodas a final consequence
In 2007 approached by a client to build travel portal for a client.
No clearly defined business strategy, exact site scope was unknown
Joint venture starting with visibility study
NOT AT ALL AN EASY TASK!especially if you look unimportant in the eyes of big players
2Took 2 years
Only after then
development finally began.
TrafficsTibetXML
TrafficsTibet
Cosmo
Ge
rma
n
sup
plie
rs
Manual booking
Routing searchesCombining resultsRouting booking requests
XML search
sta
tic X
ML
ADMINISTRATION
Own inventory management
Bookings management
Website search box
Rendering results
Booking request formPa
lma
XML results
XM
LO
the
r SL
O s
up
plie
rs
Already made airticket booking engine
html integration
Vacations, Hotels, Travel and Airtickets booking management system
temporary bookingover XML
CORE
And then..
Development subcontractor left withonly 10% done
..when we should have been at beta stage
actual plan
If your partners fail, you have to do the job yourself.
// Problem was I knew php only briefly //
3ßLearned php & OOP & brought it to level in 3 months.
// compare that to Joomla 1.6. :))
End result
Probably one of the most complex and technologically advanced sites ever built on Joomla (it is simple..but in a Google way)
Combined power of Joomla php framework
and ExtJS javascript framework used on a presentation layer
TrafficsTibetXMLG
erm
an
sup
plie
rs
Routing searchesCombining resultsRouting booking requests
XML search
Own database
Website search box
Rendering results
Booking requests
XML results
temporary bookingover XML
CORE
De
scrip
tions
& im
ag
es
2
De
scrip
tions
& im
ag
es
1
Results from own database merged with results from multiple different on-demand XML data sources
Initially it took 45-65 seconds to perform a search & render results.
Site badly needed a speed boost.
on average
Speed?
Speed?
// No, nothing illegal :)
Found an an answer in
CACHING
JOOMLA! CACHE// explained //
How simple solutionscan speed up things
10 timesor more
CACHETemporary store an unit of informationto be reused later
// a kind of digital recycling //
Multiple layers of web caching:
�Network (content delivery networks)�Server (proxy servers, load distribution..)�Daemons and interpreters – Apache mod_cache, Php –
opcode caching, Mysql query cache
�Web application (Joomla cache)�Customer (browser cache) - used by Joomla Page cache
plugin
Web application caching
creating temporary static copies of otherwise dynamic pages (or smaller data units).
Typical web site is displaying the same content over and over again
No cache: everything has to be generated for each and every page view
Caching: �store some or all of the information your code generates
in a cache object�serve it when next user requests the same page or
particular piece of information.
JOOMLA! CACHING TYPOLOGY& when to use each of them
page cache componentview cache
module cache
function/callback cache
output cacheraw cache
smallerunits
modules
functions
component
template
PAGE CACHE
Takes snapshots of entire pages including everything - component, modules, plugins and a template.
The widest and the least flexible approach of all caching options.
// enabled by core system plugin -> site administrators choice //
MODULE & COMPONENT VIEW CACHE
A group as they they both create a static copy of complete output of a component or a module
J1.5. Records based on the calling URL
J1.6. Changes
// UNSAFE, DOS //
// more later //
Important difference
module caching can only be set on/off for all instances, can’t be controlled from within the module
// J1.5., changed in J1.6! //
Most widespread cache type, sometimes equaled with J caching in general.
Performs well in the speed terms
Disables any user<->extension<->framework
interaction until a cached copy has expired
Not suitable for any components or modules that react to user actions or render frequently changing content.
Side effect Cached copy includes only modules or components own output -> any external file that is called by using methods like won't get included
Workarounds performed to come around this limitations
Catch22 Workarounds require computing time -> diminish the effect
$document->addStyleSheet()
FUNCTION / CALLBACK CACHE
The first of flexible caching types that enable us to differentiate between various parts of the extension and cache only those parts that are cacheable, while keeping dynamic parts uncached.
Caches results of function calls
Records (cacheID) based on the arguments passed to the function
Often useful to cache model methods and keep views uncached.
Example useModel performing expensive queries or similar operations is run only once to create a larger pool of data which is then further manipulated inside the view (sorting, pagination, calculations etc.)
OUTPUT CACHE
Caches output of some part od the script
Records based on id passed
Basically output buffering with caching
RAW CACHE
Caches any data units
Records based on id passed
Fully controlled by the coder – what, when to store, how to classify stored units (cache id).
Highly useful when we are dealing with finite number of reusable data units
Example useHigh number of possible combinations of relatively small number of units – e.g. products in online store. No point to cache multiple parameter searches, cache each product separately.
Other examplesExpensive queries, remote XML, thumbnails, reusable texts or any reusable data set.
Also useful to pass large amounts of data between different parts of application (e.g. steps in click flow)
Used in Joomla core: list of components, list of modules, menu tree, available languages, user groups, html renderers etc.
CASE STUDYtravel booking engine
PROBLEM
It took on average 45 to 65 seconds to display a search result
DIAGNOSIS
Largest portion of time spent on remote XML requests, waiting for and receiving replies.
Other two performance hogs were resizing images and internal database queries.
2nd and other pages of paginated results displayed instantly
TrafficsTibetXMLG
erm
an
sup
plie
rs
Routing searchesCombining resultsRouting booking requests
XML search
Own database
Website search box
Rendering results
Booking requests
XML results
temporary bookingover XML
CORE
De
scrip
tions
& im
ag
es
2
De
scrip
tions
& im
ag
es
1
Each result from badly designed primary XML paired with description and image that come from separate XML sources (one by one)
TrafficsTibetXMLG
erm
an
sup
plie
rs
Routing searchesCombining resultsRouting booking requests
XML search
Own database
Website search box
Rendering results
Booking requests
XML results
temporary bookingover XML
CORE
De
scrip
tions
& im
ag
es
2
De
scrip
tions
& im
ag
es
1
SLOW
SOLUTIONCache data on multiple levels:
�Cache pages that were fully rendered - a lot of users search with default parameters or click lastminute links, most just check one or two pages of paginated results
�Cache XML queries (with longer lifetime). Pass data from short results to detail pages
�Long-term caching of images and descriptions -> most important one
ALSO..
Add more indexes to Mysql tables
Query and render images and descriptions per page: primary source queried once, secondary separately for each subpage (pagination).
RESULT
Site runs 10 times fasterAverage first page loads in 5-6 secondsSubpages (paginated) load in 0.5 - 1 seconds
Those timings further drop dramaticaly (50% or more) on peak hours, when most popular searches are returned from the cache.
The bigger number of users on a site, the faster it goes.
// within the hosting limits //
JOOMLA! 1.6. CACHE CHANGES// firsthand //
A very long story made short:
"It finally works"
FRAMEWORK LEVEL
Almost everyhing was redone under the hood.
Cache library has been completely refactored.
Most important framework changes
Cache handlers are now known as cache controllers (page, view, output, callback)
Parent JCacheController was added - among other things it controls raw get and store calls.
New cachelite and wincache storage handlers (drivers). File cache handler heavily optimised
All other handlers fixed with missing functions (gc, clean) added, their code cleaned and tested and should now be working properly.
Semaphore locking was added for reliability and improved performance
Changed component view caching (replaced unsafe cacheID creation method)
Module cache completely reconceptualized
CMS FRAMEWORK LEVEL CHANGES
Caching implemented in all components and modules that can potentially gain from using it
Caching added to some most expensive and frequent framework calls:JComponentHelper::_load(), JModuleHelper::_load(), JMenuSite::load(), JDocumentHTML::getBuffer()..
USER LEVEL FUNCTIONAL CHANGES
Cache administration (Clean cache, Purge cache) now works with all storage handlers
New standalone garbage collect script to be run from a crontab added
libraries/joomla/utilities/garbagecron.php
API changes// and other changes important for developers //
COMPONENT VIEW CACHE
Takes an array of url parameters and their types to create
Cacheid.
A replacement for a previous unsafe way which took the whole URL and so opened the doors for DOS attacks via random parameters/values added to request
// Old cacheid created from URL retained for backwards compatibility if there are no $safeurlparams (to be removed in 1.7) //
Com_contact controler usage example:
$safeurlparams = array('id'=>'INT', 'catid'=>'INT', 'limit'=>'INT', 'limitstart'=>'INT', 'filter_order'=>'CMD', 'filter_order_Dir'=>'CMD’, 'lang'=>'CMD');
parent::display($cachable,$safeurlparams);
MODULE CACHE
5 different modes of operation, 3 of them are to be set from module XML file, while 2 are meant to be used from within the module itself.
Default is backwards compatible oldstatic mode that requires no changes to a module.
MODES TO BE SET IN XML
Static - one cache file for all pages with the same module parameters
Oldstatic - 1.5. definition of module caching, one cache file for all pages with the same module id and user aid. Default for backwards compatibility
Itemid - changes on itemid change
In addition to cache field that was required in 1.5 there is
now new hidden field called cachemode that sets any of the above modes.
<field name="cachemode" type="hidden" default="static"><option value="static"></option>
MODES TO BE CALLED FROM INSIDE THE MODULE:
Safeuri - id is created from URL params array, as in component view cache
Id - module sets own cache id's
To use this modes rename 'cache' field in xml to
'owncache' field and call from within JModuleHelper::ModuleCache
// actually a shortcut to cache callback to avoid code duplication in every module //
An example that uses safeuri mode and replaces uncached $list = modRelatedItemsHelper::getList($params) :
$cacheparams->modeparams = array('id'=>'int','Itemid'=>'int');$cacheparams->methodparams = $params;$cacheparams->method = 'getList';$cacheparams->class = 'modRelatedItemsHelper';$cacheparams->cachemode = 'safeuri';$cacheparams = new stdClass;
$list = JModuleHelper::ModuleCache ($module, $params, $cacheparams);
RAW CACHE
Raw cache get and store are easily accesed by passing '' (empty string) as cache controller to
Data is auto serialized / deserialized
Locking & unlocking are performed automaticaly
JFactory::getCache
AND HERE THE STORY ENDS// ok..a little more //
If you still remember how it all started..
I hope you like where it ended.// tried to do my best //