Hey guys,
I'm wondering about the best way to go about getting a progress bar on the
resolution of guice things.
Rougly speaking, if I have a dependency tree with
RootItem
-> 1-to-1 instance-of Dependency-1,
-> 1-to-1 instance-of Dependency-2
-> 1-to-1 instance-of Grand-Child-Dep-2
-> 1-to-1 instance-of Dependency-3
-> 1-to-many instance-of GrandChildDep-3
and dependency-3's ctor looks like this:
public Dep3{
@Inject
public Dep3(List<Model> models){
for(Model model : models){
GrandChildDep3 deepdep = guiceProvidedFactory.createFor(model);
//...
}
}
}
What would be the best process to make a progress bar for such a system?
I've got an object that I use for serialization that uses a stack to track
progress. In this way we can have a tree like structure of tasks, so long
as we can get the number of child tasks under any given task.
public NotifyingSerializer extends RealSerializer{
ProgressBarUpdater updater;
@Override
public marshal(...){
updater.pushNewTask(/*speculate, or use meta about the model, to
guess at how many child-tasks this one has*/ 45);
super.marshall(...);
updater.popTask();
}
//similar for unmarshal
}
I'd like to use this same object for guice tasks.
The best I've been able to do so far is putting the pushTask call in a SPI
ProvisionListener, and the corresponding popTask at the end of each
constructor.
eg:
binder().bindListener(
new AbstractMatcher<Binding<?>>() {
Set<Class> types = ImmutableSet.of(
(Class) RootItem.class, Dependency1.class,
Dependency2.class, Dependency3.class,
GrandChildDep2.class, GrandChildDep3.class);
@Override public boolean matches(Binding<?> binding) {
return types.contains(binding.getKey().getTypeLiteral().
getRawType());
}
},
new ProvisionListener(){
Class provisionedType = provision.getBinding().getKey().
getTypeLiteral().getRawType();
//do a filter to find out if this provision is just because of
a factory call
if(provision.getDependenyChain().stream().filter(dep -> dep.
getDependency().getKey().getTypeLiteral().getRawType().equals(
provisionedTyped)).size() == 1){
updater.pushTask(/*use static knowledge to figure out how
many subtasks this dep will have*/);
}
}
);
//...
public Class RootItem{
@Inject
public RootItem(Dependency1 dep1, Dependency2 dep2, Dependency3 dep3,
/*other misc items*/,
ProgressBarUpdater updater){
//... ctor-things
updater.popTask();
}
}
This is not a great solution because
- it involves modifying a lot of production code to include the popTask
line,
- In the event that the object is resolved without a
progress-watching-provision-listener (IE, a component uses guice to resolve
the component but doesnt include the provision listener that gives us the
progress bars), there will be a popTask call with no prior pushTask call. I
could handle this case, but it wouldn't be nice.
What I would really like is one of the following:
- an SPI object that would allow me to get something like
onProvisionEnter and onProvisionExit
- a wrapper Provisioner for all provisioners, so it could contain
similar code to whats in my above serializer-wrapper
Is there something I'm missing? Is there an existing elegant way to, from
withen guice, get a piece of code executed when a component has been
constructed?
Thanks for any help,
-Geoff
--
You received this message because you are subscribed to the Google Groups
"google-guice" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/google-guice.
To view this discussion on the web visit
https://groups.google.com/d/msgid/google-guice/548d5336-e0a2-409b-b16f-e657ff688782%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.