You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@onami.apache.org by "Mikhail Mazursky (JIRA)" <ji...@apache.org> on 2014/06/24 17:58:24 UTC

[jira] [Commented] (ONAMI-102) Redesign the Modules structure in order to simply APIs usage

    [ https://issues.apache.org/jira/browse/ONAMI-102?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14042279#comment-14042279 ] 

Mikhail Mazursky commented on ONAMI-102:
----------------------------------------

[~simone.tripodi], here are some examples and more details (I cannot implement them as tests because I haven't committed any code yet):

# I have defined an additional interface (with obvious implementation that I omit here) to help with ExecutorServices and AutoCloseables. We can use just Closeable to be compatible with Java < 1.7
{code:java}
public interface AdvancedStager<A extends Annotation> extends Stager<A> {
	<T extends ExecutorService> T register(T executor);
	<T extends AutoCloseable> T register(T closeable);
}
{code}
# I'm only interested in PreDestroy annotation handling so I defined a module that handles it:
{code:java}
public class Jsr250Module extends LifeCycleStageModule {

	private final AdvancedStager<PreDestroy> advStager = new DefaultAdvancedStager<>(
			PreDestroy.class, DefaultStager.Order.FIRST_IN_LAST_OUT);

	@Override
	protected void configureBindings() {
		bind(new TypeLiteral<AdvancedStager<PreDestroy>>() {}).toInstance(advStager);
		bindStager(advStager).matching(new AbstractMatcher<TypeLiteral<?>>() {

			@Override
			public boolean matches(TypeLiteral<?> typeLiteral) {
				Package pkg = typeLiteral.getRawType().getPackage();
				return pkg != null && pkg.getName().startsWith("com.my.project.");
			}
		});
	}

	public AdvancedStager<PreDestroy> getStager() {
		return advStager;
	}
}
{code}
This module can easily be extended to support PostConstruct (and anything else) using two stagers, etc. It is possible to use several lifecycle modules for different annotations.
# Usage in a module is trivial
{code:java}
@Provides
@Singleton
public ExecutorService provideExecutor(AdvancedStager<PreDestroy> stager) {
	return stager.register(Executors.newCachedThreadPool());
}
{code}
# Usage to execute stage (i.e. close objects in our case) is simple too. Here is a pattern for unit tests. If injector creation fails we still shutdown those executors and other stuff Guice managed to instantiate before it failed
{code:java}
public class SomeUnitTest {

	private Injector injector;
	private Stager<PreDestroy> stager;

	@BeforeClass
	public void beforeClass() {
		Jsr250Module jsr250Module = new Jsr250Module();
		stager = jsr250Module.getStager();
		try {
			injector = Guice.createInjector(jsr250Module /* and other modules */);
			injector.injectMembers(this);
			// init other stuff that can throw exceptions
		} catch (Throwable e) {
			stager.stage();
			throw e;
		}
	}

	@AfterClass
	public void afterClass() {
		stager.stage();
	}
}
{code}

WDYT?

> Redesign the Modules structure in order to simply APIs usage
> ------------------------------------------------------------
>
>                 Key: ONAMI-102
>                 URL: https://issues.apache.org/jira/browse/ONAMI-102
>             Project: Apache Onami
>          Issue Type: Improvement
>          Components: lifecycle
>    Affects Versions: lifecycle-0.2.0
>            Reporter: Simone Tripodi
>            Assignee: Mikhail Mazursky
>             Fix For: lifecycle-0.2.0
>
>         Attachments: LifeCycleModule.java, LifeCycleStageModule.java
>
>
> We already started discussing about it in the ML, but let's track progresses on JIRA.
> I detected few areas of approaching the lifecycle design:
>  * IIUC, we want to manage a series of annotations which identify the sequence of staging steps in the lifecycle, so IMHO the AbstractLifeCycleModule constructor with just one annotation has to disappear; it would be nice to have a varargs array, which would simplify the signature - and the usage from our users - but it would generate an annoying warning to our users; IMHO it is still acceptable, but in case we don't find an agreement here, Iterable should be the best way to pass the annotations sequence to the module.
>  * ListBuilder: as already discussed, this sound too generic: I'd propose something like AnnotationsLifecycleSequenceBuilder (maybe it is too verbose :P) but I'd opt for something that gives a precise idea, not a generic one;
>  * Again on the list builder, as we discussed, IMHO the wrapped data structure should be a LinkedHashSet: it preserves the sequence and makes efficient the check for duplicates - if the list has a duplicate, I bet the lifecycle event would be handled twice;
>  * Builder pattern: the way to get the builder is IMHO a little too verbose: Builder.newBuilder() is not a pattern that makes me particularly happy, I'd rather opt for inner class builder such as {{new ConcreteClass.Builder()}} which is used in the AsyncHttpClient - WDYT?
> I can even make a proposal, in order to show you better my ideas, and attach a patch to discuss together



--
This message was sent by Atlassian JIRA
(v6.2#6252)