google-code-export / google-guice

Automatically exported from code.google.com/p/google-guice
Apache License 2.0
2 stars 1 forks source link

Allow filters and servlets bound in different ServletModules to specify ordering #426

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
Within one ServletModule, filters and servlets are dispatched in the order 
in which they're bound in the module. Across modules, filters and servlets 
are dispatched in the order in which the modules are installed (with intra-
module ordering as above).

Lexical ordering within a ServletModule is fine, but it would be nice to 
have a way to specify inter-module filter and servlet (but especially 
filter) ordering that's separate from module order.

One problem with module order is that for large applications with many 
modules, it's difficult to maintain necessary ordering, especially when 
only a small subset of the modules are installation-order-specific. After 
all, everything else in Guice is really constrained by dependency-graph 
order.

One possible solution would be to provide the ability to add an ordering 
hint, either at the ServletModule level or at the level of the individual 
serve or filter call. The hind could be a simple int, where serves and 
filters are sorted on the int value, with equal hints preserving the 
lexical ordering of the calls/installs. I'm sure there are others.

Original issue reported on code.google.com by net...@gmail.com on 10 Sep 2009 at 5:19

GoogleCodeExporter commented 9 years ago
The current code has this limitation: stuff that is interdependent must be 
colocated. I don't know how I feel 
about encouraging users to put distance between interdependent things...

Original comment by limpbizkit on 11 Sep 2009 at 3:16

GoogleCodeExporter commented 9 years ago
Yea, we kinda discussed this at length before implementing the feature. 
something like a salience (<load-on-
startup> tag) was even considered. But as Jesse says it's a bit kludgey and 
probably signals the wrong design 
vector.

But if there is significant clamor for this maybe we can open it up for better 
ideas.

Original comment by dha...@gmail.com on 11 Sep 2009 at 7:59

GoogleCodeExporter commented 9 years ago
A motivating example is a module that installs a default servlet, which must be 
at the bottom of the list of 
servlets because it's bound to "/*". Or an authentication filter, which really 
should be near the top of the list of 
filters? To ensure that, would you suggest putting all servlet bindings into 
one ServletModule, so that 
interdependent stuff is colocated?

I'm not sure what the best solution for this is. Maybe instead of the specific 
integer hint solution above, we 
could accept, for any bound collection (like filters, or servlets, or 
multibindings, or mapbindings), a 
Comparator that provides a partial ordering on the collection, and if such a 
thing is bound, we ensure that the 
relevant collection is ordered according to that comparator. If no comparator 
is bound, then it's lexical 
ordering.

Comparator<? super Foo> fooComparator = ...;
Multibinder.newMultibinder(binder(), Foo.class).order(fooComparator); // only 
allowed once per Set key unless 
the comparators are equal
MapBinder.newMapBinder(binder(), Foo.class, Bar.class).order(fooComparator);; 
// only allowed once per Map 
key unless the comparators are equal
Comparator<? super Filter> filterComparator = ...;
orderFilters(filterComparator); // in ServletModule; only allowed once unless 
the comparators are equal
Comparator<? super Servlet> servletComparator = ...;
orderServlets(servletComparator); // in ServletModule; only allowed once unless 
the comparators are equal

Original comment by net...@gmail.com on 11 Sep 2009 at 12:47

GoogleCodeExporter commented 9 years ago
@3 We don't advocate everything only in one module, but for example, installing 
the auth module first, and 
the default servlet module last. Note that binder().install() is another option 
for ordering groups of servlet and 
filter definitions. Does this solution not suffice?

There is no limit to the number of servlet modules you can install from a 
parent servlet module, I find this to 
be a good pattern for grouping bindings, generally.

Your multibinder solution is roughly what the servlet module is doing 
underneath, but the binding syntax IMO 
is simpler and saves on knowing the specifics of multiple contributions to a 
set.

Original comment by dha...@gmail.com on 11 Sep 2009 at 1:16

GoogleCodeExporter commented 9 years ago
@4: OK, I'll buy that I think. Build a module for each ordered set of modules 
that 
installs in order. I still think there's a more targeted solution out there, 
but I 
don't know what it is.

Original comment by net...@gmail.com on 11 Sep 2009 at 2:19

GoogleCodeExporter commented 9 years ago
If the OP is happy, closing this issue out.

Original comment by dha...@gmail.com on 30 Oct 2009 at 4:07