The hashing of the file and placing that in the filename (or Sling selector, in this case) is typically a better strategy for controlling hashing. This is one of the reasons why the hashfiles tool is used instead of simply appending rotating timestamps to the filename as a GET parameter. Here are some articles as to why you should prefer the hashing in the filename (fingerprinting) approach to the GET param approach:
http://guides.rubyonrails.org/asset_pipeline.html#what-is-fingerprinting-and-why-should-i-care https://developers.google.com/speed/docs/best-practices/caching http://www.stevesouders.com/blog/2008/08/23/revving-filenames-dont-use-querystring/ -- Chris Roby On Apr 27, 2012, at 6:09 AM, Nicolaas Matthijs wrote: > Stuart does raise a very good point indeed. > >>> If we fixed the issues with Sling-Initial-Content that cause us to >>> set >>> ignoreImportProviders:=json all the config info could be loaded to >>> sparse >>> as data by Sling's native methods. Then you could change the >>> individual >>> properties just like we do on any other content in sparse (you >>> could even >>> make a config editing widget). > > The current config file contains quite a few arrays where order does > matter, so if we can sort those issues out with Sling-Initial-Content, > using Sling-Initial-Content could be a good and simple way forward, > making it equally easy to put an admin interface on top of it. > >> If we simply use Sling to store configuration and omit it from the >> optimization and hashing, is there a way to control its caching >> reliably across browsers? If so then my work may not be as necessary >> as first perceived. > > Yes, there is. Once excluded from the optimization and hashing, we can > load the config file by using /.../config.json?_=hash. The hash could > be a timestamp as well, so we re-load the latest configuration file > into cache every minute/10 minutes, hour, etc. The querystring > approach will work fine with all modern browsers ... > > Hope that helps, > Nicolaas > > > > On 26 Apr 2012, at 18:40, Duffy Gillman wrote: > >> No, that's a good thing to consider. This effort was aimed at >> working with the current caching scheme. At present configuration is >> embodied in javascript files that must go through the optimization >> and hashing steps of the 3akai-ux deployment in order to allow >> caching until such time as the configuration changes. The big >> benefit of the service I've written is to allow configuration to be >> obtained through a URL like: >> >> /system/dynamic-config/config.1bff8df77ea37c304bcf8.json >> >> Where 1bff8df77ea37c304bcf8 changes to something new when the >> configuration changes. In this way the browser can cache the old >> configuration and will only load new configuration when the >> 1bff8df77ea37c304bcf8 changes to a new value. >> >> If we simply use Sling to store configuration and omit it from the >> optimization and hashing, is there a way to control its caching >> reliably across browsers? If so then my work may not be as necessary >> as first perceived. >> >> Thanks, >> Duffy >> >> ------------------------------ >> Duffy Gillman >> Sr. Software Engineer >> The rSmart Group, Inc. >> >> On Apr 26, 2012, at 10:29 AM, D. Stuart Freeman wrote: >> >>> I'm not convinced that writing a servlet for this is necessary >>> (though >>> I'm willing to be proved wrong). >>> >>> If we fixed the issues with Sling-Initial-Content that cause us to >>> set >>> ignoreImportProviders:=json all the config info could be loaded to >>> sparse >>> as data by Sling's native methods. Then you could change the >>> individual >>> properties just like we do on any other content in sparse (you >>> could even >>> make a config editing widget). >>> >>> None of this is meant to undermine the work that's been done. It's a >>> great goal that I'm happy to see us working toward. I just hope we >>> aren't >>> introducing a lot of unneccesary infrastructure to do something >>> that's >>> already provided for us. >>> >>> On Thu, Apr 26, 2012 at 10:12:15AM -0700, Duffy Gillman wrote: >>>> Nicolaas, >>>> >>>> Thanks for the thoughtful feedback. I'll respond to some points >>>> inline below: >>>> >>>>> De-coupling config_custom.js from the production build could have >>>>> a similar effect, but asking operations to maintain their >>>>> configurations in javascript/json files might not be ideal. >>>> >>>> Operations will have to maintain configuration somewhere - >>>> ultimately in some file. So the question is whether JSON is worse >>>> than other options (XML, .properties, ... ?). Javascript is >>>> certainly a bad idea: it opens the possibility of including logic >>>> (as is currently done) in the configuration file. >>>> >>>> It is reasonable to argue that some format other than JSON may be >>>> more familiar to to operations staff. JSON was the easy choice for >>>> now since it is the wire format transmitted to the UI. If we need >>>> to change to another format we need to consider that some work >>>> needs to be done to convert from the input format to JSON. That >>>> becomes work more complicated if we use a flat format >>>> like .properties instead of a hierarchical format like XML. A flat >>>> format would require that we develop a method to encode/decode >>>> hierarchy, which I argue would be more trouble for operations than >>>> using JSON. >>>> >>>> Is there a preference against using JSON that is strong enough to >>>> argue for the additional effort to transcode from XML >>>> or .properties to JSON for transmission or storage? >>>> >>>>> I would definitely be interested in seeing your solution in >>>>> action, perhaps a screencast could be really useful. >>>> >>>> Good idea! I'll see if I can pull something together. >>>> >>>>> 1) I'm assuming configuration changes can be made at runtime by >>>>> doing a POST to this service? Because these don't happen >>>>> regularly, it could be sufficient to give this URL a short >>>>> caching lifetime (i.e. roughly 1 session) >>>> >>>> That is the goal! I have created the POST endpoint [1] in the >>>> dynamic configuration servlet. I have created an API method [2] to >>>> handle merging the POSTed JSON into the configuration. But the >>>> current implementation [3] does not support the POST call since >>>> the configuration is read directly files on the server. I do not >>>> want to alter the configuration files that operations has >>>> deployed. So for the current implementation the service is read >>>> only from REST calls. It is dynamic in the sense that any change >>>> to the files on the server will be reflected in the configuration. >>>> >>>> An implementation which uses sparse or JCR to store the >>>> configuration would be better and should be pursued soon. This >>>> would better support implementation of the POST REST call. Initial >>>> configuration could still be read from the filesystem and pushed >>>> into the store. Subsequently POST operations could update the >>>> configuration in the store without concern for changing the >>>> deployed files. >>>> >>>>> 2) We probably need to come up with a strategy in which widgets >>>>> can be configured/re-configured easily at runtime, so we don't >>>>> need to centralize all of their configurations. We'd also have to >>>>> make sure that it's easy for widget developers (students, >>>>> lecturers, etc.) to be able to add config options to their >>>>> widgets. This is currently done in the widget config file >>>>> (default configuration), and is then passed on to the widget when >>>>> loaded. We should probably make it possible to adjust these >>>>> configs at run-time as well. Have you given this any thought? >>>> >>>> I agree. This is needed. Both config.json and i18n files need to >>>> be configurable. Technically these can be handled now by issuing >>>> curl POSTs. But if you thought javascript/json were a bad idea for >>>> operations try telling them they need to issue a bunch of curl >>>> commands! >>>> >>>> Presently I am handling this awkwardly. I created a >>>> ConfigurationOverrideService [4]. You can register bundles with >>>> this service. When Sling reports that one of these bundles has >>>> started, any files in a configured path on the filesystem are >>>> read. If the files are newer than the JCR content the files are >>>> read and will override the JCR content. >>>> >>>> This is *not* an elegant solution. But it works given the current >>>> function of nakamura and 3akai-ux. I definitely think this could >>>> be made better with the dynamic configuration service. It would >>>> require replacing the information obtained from the WidgetServlet >>>> with dynamic configuration, or would require altering the backend >>>> service that supplies the widget data to WidgetServlet. >>>> >>>> i18n files are another matter. Perhaps the Sakai javascript widget >>>> API could be revised to use JSON data for i18n instead >>>> of .properties file and i18n could be folded into dynamic >>>> configuration as well. Otherwise the dynamic configuration service >>>> could be extended to handle the .properties extension as well and >>>> could have parallel logic for managing that format. >>>> >>>>> 3) The fact that it's currently only possible to replace top >>>>> level properties is slightly annoying, but I think that should do >>>>> initially and can be solved further down the line. >>>> >>>> Yes. This is absolutely in the "annoying, but it works" column. I >>>> get itchy when I consider this. It will have to change soon. >>>> >>>> Thank you for your feedback and questions. I will see what I can >>>> do to create a screencast so it is easier for people to digest/ >>>> review this work. >>>> >>>> Cheers, >>>> >>>> Duffy >>>> >>>> [1] >>>> https://github.com/rSmart/nakamura/blob/develop/bundles/dynamicconfig/src/main/java/org/sakaiproject/nakamura/dynamicconfig/servlet/DynamicGlobalConfigurationServlet.java >>>> >>>> #L117 >>>> >>>> [2] >>>> https://github.com/rSmart/nakamura/blob/develop/bundles/dynamicconfig/src/main/java/org/sakaiproject/nakamura/api/dynamicconfig/DynamicConfigurationService.java >>>> >>>> #L19 >>>> >>>> [3] >>>> https://github.com/rSmart/nakamura/blob/develop/bundles/dynamicconfig/src/main/java/org/sakaiproject/nakamura/dynamicconfig/file/FileBackedDynamicConfigurationServiceImpl.java >>>> >>>> [4] >>>> https://github.com/rSmart/nakamura/blob/develop/bundles/dynamicconfig/src/main/java/org/sakaiproject/nakamura/dynamicconfig/override/ConfigurationOverrideServiceImpl.java >>>> >>>> ------------------------------ >>>> Duffy Gillman >>>> Sr. Software Engineer >>>> The rSmart Group, Inc. >>>> >>>> _______________________________________________ >>>> oae-dev mailing list >>>> [email protected] >>>> http://collab.sakaiproject.org/mailman/listinfo/oae-dev >>> >>> -- >>> D. Stuart Freeman >>> Georgia Institute of Technology >> > > _______________________________________________ > oae-production mailing list > [email protected] > http://collab.sakaiproject.org/mailman/listinfo/oae-production _______________________________________________ oae-dev mailing list [email protected] http://collab.sakaiproject.org/mailman/listinfo/oae-dev
