Skip to content

Conversation

@njr-11
Copy link
Contributor

@njr-11 njr-11 commented Aug 22, 2018

pull fixes #3
Signed-off-by: Nathan Rauh nathan.rauh@us.ibm.com

Signed-off-by: Nathan Rauh <nathan.rauh@us.ibm.com>
@FroMage
Copy link
Contributor

FroMage commented Sep 7, 2018

LGTM: we can start with that and work through remaining issues afterwards.

* are removed from the thread of execution for the duration of the
* action or task.</p>
*/
String[] context() default { ThreadContext.APPLICATION, ThreadContext.CDI, ThreadContext.SECURITY };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should ALL be the default?

Copy link
Contributor Author

@njr-11 njr-11 Sep 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The prior default was chosen to match the EE Concurrency requirement for only a specific set of context types to be propagated by default, where
@Inject @ManagedExecutorConfig ManagedExecutor executor1;
would create an instance with the same context propagation as
@Inject ManagedExecutor executor2;
which would also have the same context propagation as EE Concurrency's default instance,
@Resource ManagedExecutorService executor3;
The idea was to allow a container that is both MP Concurrency and EE Concurrency to return the same instance from all of these.

That said, it would be possible to instead default to ALL and require the use of different instance than the EE Concurrency default instance if that would be more useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this some more, defaulting to ThreadContext.ALL would mean that if someone implemented a provider for transaction context that was capable of propagating transactions, then those would also propagate by default. I don't think we want to go that far. It seems better for performance and predictability that we default to the more limited set of core contexts. The user can always specify ALL if they want it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking about this some more, defaulting to ThreadContext.ALL would mean that if someone implemented a provider for transaction context that was capable of propagating transactions, then those would also propagate by default.

If an user provide a transaction context, surely the default one will be overriden. You won't need two of them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 'someone' that I was referring wasn't intended to mean the end user. I was referring to a container implementation of transactions (the transaction manager). In the event that an end user did provide a conflicting implementation of one of already-provided context types, I think we discussed that would be considered an error path for now. Allowing an override of context provided by someone else seems outright dangerous, and in the case of transactions would probably lead to data integrity issues.

* <code>ManagedExecutor</code> or <code>ThreadContext</code> must invoke the
* <code>end</code> method.</p>
*/
public interface ActiveThreadContext {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say this is a controller. How about ThreadContextController?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like how the name ThreadContextController starts with ThreadContext in the same way that ThreadContextProvider and ThreadContextSnapshot do, which will cause them to naturally be listed together when interfaces are shown alphabetically. ActiveThreadContext seems more descriptive/clear, except could be confusing after it is ended, so I'm willing to change it as you suggest.

* </code></pre>
*
* @throws IllegalStateException if invoked more than once on the same instance.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should a method e.g. getState() to return whether it is active or not. end() can check whether it is active or not. If it is, end it. If not, ignore it.

Copy link
Contributor Author

@njr-11 njr-11 Sep 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, we can add this, maybe as a boolean isEnded() given that there are only 2 states.

* does not support capturing context from the current thread and
* propagating it to other threads.
*/
ThreadContextSnapshot currentContext(Map<String, String> props);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be String, String? Maybe String, Object has more coverage.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is Map<String, String> for compatibility with EE Concurrency execution properties. Switching to Object would force code to deal with unwanted casting.

* either captured from a thread or otherwise representing an
* empty/default context.
*/
ActiveThreadContext begin();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this method to ThreadContextController?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leaving it here enforces the contract that each ActiveThreadContext/ThreadContextController represents exactly one contextualized execution. If we move it, then the implementer must deal with the possibility that the user tries to invoke begin multiple times on the same instance, or tries to re-begin one that has already ended. I can't see a reason to place this additional burden/lack of clarity upon the provider of thread context without any clear benefit that would be achieved by doing so.

@Emily-Jiang
Copy link
Member

@njr-11 please take a look at my comments.

Signed-off-by: Nathan Rauh <nathan.rauh@us.ibm.com>
@njr-11
Copy link
Contributor Author

njr-11 commented Sep 7, 2018

@Emily-Jiang thanks for the review. I have added a pull with several code review fixes (per comments above) as well as a couple of spelling and punctuation fixes that Nathan M and myself spotted while proofreading.

*
* <code>META-INF/services/org.eclipse.microprofile.concurrent.spi.ThreadContextProvider</code>
*
* <p>The content of the aforementioned file must be a single line that specifies the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually it may be more than one line, each with a different implementation of the interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks - good catch. We definitely want to allow for multiple. I have added a commit correcting the language here to indicate at least one instead of single.

Signed-off-by: Nathan Rauh <nathan.rauh@us.ibm.com>
@FroMage
Copy link
Contributor

FroMage commented Sep 12, 2018

Can we please merge these two PRs ASAP and fix whatever remaining issue afterwards? It really doesn't help implementation to keep these in PRs.

* fully qualified name of the <code>ThreadContextProvider</code> implementation.</p>
* <p>The content of the aforementioned file must be one or more lines, each specifying
* the fully qualified name of a <code>ThreadContextProvider</code> implementation
* that is provided within the JAR file.</p>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

* @return true if <code>endContext</code> was invoked on this controller,
* otherwise false.
*/
boolean isEnded();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that this prevents implementing this interface as a @FunctionalInterface as I had before:

	public ThreadContextSnapshot currentContext(Map<String, String> props) {
		MyContext capturedContext = MyContext.get();
		return () -> {
			MyContext movedContext = MyContext.get();
			MyContext.set(capturedContext);
			return () -> {
				MyContext.set(movedContext);
			};
		};
	}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for spotting this as well. I was previously willing to accommodate the request to have an isEnded method when I saw no benefit either way for including or not including it. However, as you have pointed out, this makes it no longer be a functional interface. I have added a commit to remove the isEnded method.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I noticed it by accident, but I thought it made a good argument in favour of not having that extra method. I suppose we should also add @FunctionalInterface to the interfaces (at least if/until we decide to add methods to it) to make sure that we don't add any new method without just cause.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea. @FunctionalInterface is added to both ThreadContextController and ThreadContextSnapshot. I think as long as they are able to remain functional interfaces for the initial release, they should hopefully remain that way. We won't want to cause a lot of churn in the SPI once implementations of it start to be provided.

Signed-off-by: Nathan Rauh <nathan.rauh@us.ibm.com>
@njr-11 njr-11 force-pushed the 3-copy-from-sandbox branch from e54b29d to 08afbbd Compare September 12, 2018 16:01
@Emily-Jiang Emily-Jiang merged commit a3d6f88 into microprofile:master Sep 12, 2018
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.

Copy over the sandbox APIs and the readme file

3 participants