Turbocharging your extension // Joomla

Post on 11-May-2015

2,793 views 0 download

Tags:

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 //