Skip to content

Conversation

@hinerm
Copy link
Member

@hinerm hinerm commented Mar 18, 2013

Adds the capacity to mark services as lazy so they won't be loaded during context construction, but can be loaded on demand later.

To test:

This is easiest to see with a Service implementation that will fail when loaded .. e.g. https://github.com/hinerm/bioformats/blob/scifio-master/components/scifio/src/loci/formats/services/LuraWaveServiceImpl.java .. but any service will work as long as it's not a parameter of another class (as parameters will be loaded before the parent class, regardless of whether they are lazy or not)

  1. Verify the service fails or loads as appropriate when "new Context()" is invoked.
  2. add "lazy=true" to the service's Plugin annotation
  3. repeat (1) and verify there's no error or success message for the service
  4. test that context.getService(service.class) causes the same output as before setting lazy to true.

@dscho
Copy link
Contributor

dscho commented Mar 18, 2013

I'd prefer an alternative where a Service can fail to initialize and is simply not added to the Context in that case. That way, you can rely on the fact that all Services that can be obtained from the Context actually work...

The Plugin annotation now has a "lazy" attribute. If true, the
ServiceHelper will not load these services during its first loadServices
pass.

After loading the non-lazy services, standard calls to the Context's
getService(Class) method will check the lazy service list for a matching
service, if an implementation was not already loaded.

NB: these changes require the Context to maintain a reference to a
ServiceHelper.

ServiceHelper has a canLoadLazy() flag to determine if it is capable of
loading lazy services or not (that is, if loadServices() has already
been called or not).
@hinerm
Copy link
Member Author

hinerm commented Mar 19, 2013

@dscho, could you clarify your preferences? I'm not sure what you mean about obtaining services that don't work. Right now, lazy or not, if a service fails to initialize it's not accessible via the context.

In my mind, if SampleServiceImpl has a dependency that may or may not be on the class path, context.getService(SampleService.class) will always be a legitimate invocation... whether the service is loaded at initialization of the context, lazily, or not at all because of the missing dependency. So lazy loading doesn't change getService's behavior.. if the service was loaded (at initialization or lazily) its impl is returned. If not, you get back null.

A lazy service doesn't get added to the ServiceIndex until it's loaded, so I don't think there's any way to perceive failing/unloaded services as available. Since the lazy flag is intended for services that may regularly fail to load, the only behavior change should be delaying error messages until the service is requested, which in many cases will be never.

So I think avoiding these error messages is valuable, but I'm happy to hear it if you still think there's a better alternative.

@hinerm
Copy link
Member Author

hinerm commented Mar 19, 2013

closing this PR. Just going to change the output so that when a service fails to load it will be printed as a warning instead of an error, since execution continues, and the stack trace will get logged to debug.

@hinerm hinerm closed this Mar 19, 2013
@dscho
Copy link
Contributor

dscho commented Mar 19, 2013

Sorry for the delay. It was not clear to me what problem exactly you wanted to solve, and I guess that your change to turn the error into a warning makes it much clearer. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants