I was talking about the first step.

Just a nice consistent way to calculate last-modified, for dynamic pages with complex components and different data streams. Because the only way to do that right now is for me to put a filter which does all last-mod logic: calculate last-modified and handle the if-modified-since headers. But then how it calculates the last-modified must be kept in sync with the page is actually rendering. And then the right filter has to be placed infront of the right page, etc, etc. That's fine for a few pages, but sadly it'll get onerous quickly.

but of course, as we start down this path, it won't take long for someone to experiment with caching layers around each component render call, so that tapestry could cache each component render, just as you were talking about (this would probably be configurable per component, or something). But I see that as secondary. Though interesting, tapestry would then just be a framework to composition and piece together renderings from different components, and it could do this on the server-side or from the clent-side as Howard was alluding to earlier. interesting, full circle.

so, I am just asking for leaders to keep in mind the last-modified and expires attributes for pages/components as you evolve on tapestry code. they're useful.



Gordon Henriksen wrote:
On Apr 12, 2006, at 3:42 PM, Fernando Padilla wrote:

right. the issue/goal with 'last-modified' is that calculating 'last-modified' will be cheaper than rebuilding the whole output.


Indeed, just returning a cached rendering of a component can be valuable, but I'm not sure the last-modified model is the best one for server-side cache validation. Most operating systems now support filesystem change notifications; SQL Server 2005 can even notify clients when a query's results would change. These are fundamentally "push" models. To support both push and pull, how about something like this:

    public interface Dependency {
        boolean isInvalid();
    }

    void SimpleFileDependency implements Dependency {
        File file;
        long cachedModificationTime;
        public SimpleFileDependency(File file) {
            this.file = file;
            cachedModificationTime = file.lastModified();
        }
        public boolean isInvalid() {
            return cachedModificationTime != file.lastModified();
        }
    }

    class NotificationFileDependency implements Dependency {
        FileChangeNotification notification;
        boolean isInvalid;
        public NotificationFileDependency(File file) {
            notification = new MysicalMagicalFileChangeNotification {
                public void fileChanged() {
                    isInvalid = true;
                }
            };
        }
        public boolean isInvalid() {
            return isInvalid;
        }
        public static boolean isSupported() {
            magic!
        }
    }

    public class CacheEntry {
        ...
        public void addDependency(File file) {
            if (NotificationFileDependency.isSupported())
                addDependency(new NotificationFileDependency(file));
            else
                addDependency(new SimpleFileDependency(file));
        }
        public void addDependency(Dependency dependency) {
            ...
        }
    }

A CacheEntry can easily know when it was generated, and can simply report that as its modification date for the Last-Modified HTTP header field. Thus, dependencies don't need to calculate that data.

Generically determining whether something is cacheable in Tapestry strikes me as harder, though.

— G
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to