With soft-permutations though, this could cut back on the explosion, though you are right that the app would be unable to switch at runtime between which version it is running. That said, once a user has been set to a particular set of features, you probably want to keep them there. And a runAsync split point for each possible feature will have its own kind of explosion issues, affecting the user more than the compiler though.
Deferred binding lets you replace whole classes, which is probably why you started down this road in the first place. The lib you linked to appears to hook into Google Analytics for collecting data, and leaves the cohort selection to the browser's own random pick. Building this in GWT, I'd probably want to take the approach of making some of these decisions the server's problem - writing out one or more meta tags to help guide permutation (soft or hard) selection lets you tie it to session or user (consistent across page load, across browsers/devices). Additionally, when you make a decision on which implementation to use, simply remove whatever is auto-selecting an implementation in your module file. Interfaces or base classes would be defined in your code, along with 1 or more implementations. A implementation would be requested in code via GWT.create(MyBaseClass.class), and rules established to decide which to pick. The basic idea behind those rules would be to define the property and its values, and what each value would cause to have happen. <!-- declare the name of the feature, possibly how it is selected --> <define-property name="ab.featureOne" values="a,b,c" /> <!-- defaults to selecting via meta tag with name="gwt:property" and content="ab.featureOne=X" where X is a, b, or c. This can be modified via a property-provider tag to either describe the js used to select a property, or to point at a java file that will build that js. --> <!-- Suppress additional permutations - this is optional, and results in the final js build being larger than it might otherwise be, but with fewer permutations. runAsync can still be used to push all of these into another file - but use runAsync normally, don't deliberatly push these out unless needed (very large or rarely used). --> <collapse-property name="ab.featureOne" values="*" /> <!-- next, declare rebind instructions --> <replace-with class="my.package.client.WidgetA"> <when-type-is class="my.package.client.FeatureOne" /> <when-property-is name="ab.featureOne" value="a" /> </replace-with> <replace-with class="my.package.client.WidgetB"> <when-type-is class="my.package.client.FeatureOne" /> <when-property-is name="ab.featureOne" value="b" /> </replace-with> <replace-with class="my.package.client.WidgetA"> <when-type-is class="my.package.client.FeatureOne" /> <when-property-is name="ab.featureOne" value="a" /> </replace-with> There are lots of options to further customize this, as that is a lot of XML just to specify three classes to try out (and we still have to set the page up to write out that meta tag). That being said, there are several ways we can make this simpler if you plan to use it a lot: Get rid of the replace-with rules: Define the test to run (ab.featureOne) and the possible options (a,b,c), but build a generator to deal with doing the rebind replacements. Easiest way for this would probably be to add a few annotations and a marker interface: public interface ABTestable { } public @interface ABTestName { String value(); } public @interface ABTestOption { String value(); } The generator would be defined to build any class that implements ABTestable, and would look around for any possible impls, and pick one based on the option annotation it is decorated with. This xml would then replace the <replace-with> tags for all tests and all options - only needs to be declared once: <generate-with class="my.package.rebind.ABOptionGenerator"> <when-type-is class="my.package.client.ABTestable" /> </generate-with> And your code would look something like this: @ABTestName("ab.featureOne") public interface FeatureOne extends ABTestable { ... } @ABTestOption("a") public class WidgetA implements FeatureOne { ... } etc. And once testing is complete, a single replace-with (or gin bind().to()) can be used, and the AB* annotations and marker interfaces removed. Better selection: Instead of always writing out meta tags with the name gwt:property, the bootstrap js file can read from any data available on page load - your own meta tags, the url string itself, cookies, whatever makes sense for your data collection and testing system - even just falling back on random number generation, and writing that value out somewhere. The GWT I18n framework has several options built into it in its PropertyProviderGenerator implementation. You could even use this to read from a single meta tag, query param for all possible values, picking the char to read based on the order of all of the features that are being compiled in: <meta name="ab-selection" content="acaababca"> would indicate 'a' for the first feature, 'c' for the second, etc. Server participation: Any server spitting out these meta tags will probably need to know what the possible options are - a generator (possibly in conjunction with a linker) can be set to spit out a file (a.k.a. artifact) with information collected during the compile. This could look something like a properties file, full of name=values pairs to define what the possible options are that need to be given to the running page. Presumably the client/server already have some way to discuss what is considered a 'successful' test, and to decide how to continue with future tests, but more metadata about those tests and how to run them could be added with additional annotations. Useful examples, references: http://code.google.com/p/google-web-toolkit/wiki/SoftPermutations - description of what soft perms are, how to use them com.google.gwt.core.ext.Generator - base class for defining rebind rules in Java - can create new classes, or select from existing ones com.google.gwt.core.ext.linker.PropertyProviderGenerator - interface that describes how to programmatically make permutation selection in the bootstrap /com/google/gwt/user/UserAgent.gwt.xml - example of existing permutation selection wiring, and how to pass that off to a generator com.google.gwt.user.rebind.UserAgentPropertyGenerator /com/google/gwt/i18n/I18N.gwt.xml - more permutation selection, this time talking about reading from url, cookies, etc On Sunday, June 24, 2012 9:30:49 PM UTC-5, Nick Siderakis wrote: > > Some reasons why this is a bad idea > > - Does not scale well for many tests (permutation explosion) > - Would not support dynamic (in app) cohort assignment > > runAsync seems like a better choice. > > On Sunday, June 24, 2012 1:43:01 PM UTC-4, Nick Siderakis wrote: >> >> I'm thinking about building a small framework similar to cohorts.js for >> GWT that takes advantage of deferred binding. >> >> Does this seem like a good idea? >> >> >> ( cohorts.js https://github.com/jamesyu/cohorts ) >> >> -- You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group. To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/-iO-Gs3CReMJ. To post to this group, send email to google-web-toolkit@googlegroups.com. To unsubscribe from this group, send email to google-web-toolkit+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.