Hi,
Couldn't this solved in a simpler manner by implementing a trigger to
clear the resource cache on demand? This way, you get full performance
in production and when you need to update a resource, log-in to an
administrative interface or JMX or something else and trigger the reload.
Regards,
Bertrand
On 12/11/2011 8:52 AM, Peter Ertl wrote:
With this approach you accept that for some period of time your
application may serve references with stale versions, thus client
browsers may still use cached resources.
Don't you do the same when you use predicates like these? (taken from your code
sample below)
new Or(new AccessedMoreThan(5), new OlderThan(30000)))));
In the worst case 5 clients will get the stale version before it gets updated
or any client within duration of 30000 (milliseconds?).
The basic idea behind resource caching (as the class name
IStaticCacheableResource indicates) is to cache static(!) resources which only
change during development.
For dynamic resources you should derive from AbstractResource and set the
caching headers accordingly.
I think it's not that common that people replace parts of the deployment during
runtime on the production server.
In projects I was involved the application always was rolled out as a whole at
certain points in time. Any change of the application usually needs to be
versioned, tested and carefully rolled out. If you need high availability you
should consider load balancing and redundant backend servers that can be taken
offline during re-deployment *imho*
So I think caching resources for the lifetime of an application totally makes
sense.
If you really need to replace files on the production server why not simply use
the same pattern as during development?
// use last-modified timestamp of packaged
resource for resource caching
// cache the version information for the
lifetime of the current http request
new RequestCycleCachedResourceVersion(new
LastModifiedResourceVersion());
The timestamp issues we mentioned for cluster deployment are not necessarily
existant in any case. If you have consistent timestamps across your backend
servers in the cluster last-modified based caching works like a charm.
I am -0 on the UpdatableCachingResourceVersion since I think it's too specific
to be part of core but I don't want to be a code nazi :-)
You use predicates for invalidation, somebody else wants a strategy pattern,
somebody else maybe wants listeners?!
I think the other wicket core devs should decide it.
Cheers
Peter
Am 12.11.2011 um 10:16 schrieb Dominik Drzewiecki:
W dniu 11 listopada 2011 14:56 użytkownik Peter Ertl<[email protected]> napisał:
It might be a better idea to roll out your own version provider
how do you check staleness?
Well, you don't. You just recalculate the version (which requires some
CPU/IO cycles, especially when using MessageDigest). The point is -
with current implementations - you either need to recalculate the
version on each resource link generation (which is bad in production
environments) or you calculate it just once and cache it for
application lifetime (which is much nicer for CPU and IO in producion,
yet it leaves you unable to substitute resources without restart and
be assured that customer's browsers use the most recent versions of
your stylesheets or images rather than the cached ones.). That's why I
proposed (and written) an UpdatableCachingResourceVersion which you
should initialize with some rule specifying how often and/or after
some period of time the getVersion() should be delegated to underlying
implemention and returned version cached.
With this approach you accept that for some period of time your
application may serve references with stale versions, thus client
browsers may still use cached resources.
For applications that keep running unrestarted for weeks (one of major
polish bank's ebanking application runs successfully on wicket, not
1.5 yet though), one can't accept caching versions for the application
lifetime.
And yes, you are right, it is easy and cheap to write my own
implementation of IResourceVersion that just does that, but somehow I
feel that this issue is not that specific to my particular use case
and wanted to share to make wicket better.
I hate to bloat the core and like to see it kept small and concise as
it is now but I really think that UpdateableCachingResourceVersion
belongs there.
https://issues.apache.org/jira/browse/WICKET-4221
regz,
/dd
take that criteria and make it part of the filename version
if that check is cheap you don't need caching
Am 11.11.2011 um 14:29 schrieb Dominik Drzewiecki:
I have a working implementation with passive (on access, rather than
active, requiring some reaper thread) resource staleness checking.
I'll file a jira issue today evening (CET) and attach a patch. BTW,
CachingResourceVersion is considerably non-scalable in terms of
concurrency as it uses Collections#synchronizedMap() underneath.
2011/11/11, Martin Grigorov<[email protected]>:
Hi,
On Fri, Nov 11, 2011 at 12:46 AM, Dominik Drzewiecki
<[email protected]> wrote:
Howdy,
I've been loooking carefully at what's new in wicket 1.5 and how its
concepts map to the earlier versions.
I've been particularly interested in how resource managment had been
given much care in 1.5.
One great feature is consistent resource id suffix generation. I have
however found an issue that may lead to a performace hit.
It is advised to use MessageDigestResourceVersion rather than the
default LastModifiedResourceVersion in production environments,
especially clustered ones. Thus the following code present in
application init() method:
getResourceSettings().setCachingStrategy(
new
FilenameWithVersionResourceCachingStrategy(
new
MessageDigestResourceVersion()));
This however is highly ineficient as each and every access to any
resource (resource link generation, in fact) results in message digest
computation, regardless whether it is going to be sent back to the
browser or not. Lets wrap the MessageDigestResourceVersion with
CachingResourceVersion then:
getResourceSettings().setCachingStrategy(
new
FilenameWithVersionResourceCachingStrategy(
new
CachingResourceVersion(new MessageDigestResourceVersion())));
This looks OK.
Aha! Much better? Not exactly. Now the message digest will be computed
just once, and will stay in a cache for the lifetime of the
application. Whenever resource changes, the browser might be confused
to use stale cached version rather than request a new resource (Yes,
we do substitute context resources during runtime).
In production resources don't change that often. It is not that common
to substitute resources in production.
It'd be nice to have some IResourceVersion implementation that caches
the computed resource version for some preconfigured period of time or
recalculates it on every n-th access. Or is triggeerd by some more
complex rule.
getResourceSettings().setCachingStrategy(
new
FilenameWithVersionResourceCachingStrategy(
new
UpdateableCachingResourceVersion(new
MessageDigestResourceVersion(), new Or(new AccessedMoreThan(5), new
OlderThan(30000)))));
For your use case this will be the best but for the common case just
CachingResourceVersion should be enough, IMO.
If you find it worth putting into core, I can file a jira issue and
provide an appropriate patch.
Sure, do it!
regz,
/dd
--
/* Spelin donut mader if iz ina coment */
--
Martin Grigorov
jWeekend
Training, Consulting, Development
http://jWeekend.com
--
Wysłane z mojego urządzenia przenośnego
/* Spelin donut mader if iz ina coment */
--
/* Spelin donut mader if iz ina coment */