Skip to content

IGNITE-26608 Added a unified mechanism for propagating Context Attributes#12429

Open
petrov-mg wants to merge 6 commits intoapache:masterfrom
petrov-mg:IGNITE-26608
Open

IGNITE-26608 Added a unified mechanism for propagating Context Attributes#12429
petrov-mg wants to merge 6 commits intoapache:masterfrom
petrov-mg:IGNITE-26608

Conversation

@petrov-mg
Copy link
Contributor

Thank you for submitting the pull request to the Apache Ignite.

In order to streamline the review of the contribution
we ask you to ensure the following steps have been taken:

The Contribution Checklist

  • There is a single JIRA ticket related to the pull request.
  • The web-link to the pull request is attached to the JIRA ticket.
  • The JIRA ticket has the Patch Available state.
  • The pull request body describes changes that have been made.
    The description explains WHAT and WHY was made instead of HOW.
  • The pull request title is treated as the final commit message.
    The following pattern must be used: IGNITE-XXXX Change summary where XXXX - number of JIRA issue.
  • A reviewer has been mentioned through the JIRA comments
    (see the Maintainers list)
  • The pull request has been checked by the Teamcity Bot and
    the green visa attached to the JIRA ticket (see TC.Bot: Check PR)

Notes

If you need any help, please email dev@ignite.apache.org or ask anу advice on http://asf.slack.com #ignite channel.

* @return Security context holder.
* @return Thread Context Scope.
*
* @see #withContext(Scope, SecurityContext
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* @see #withContext(Scope, SecurityContext
* @see #withContext(Scope, SecurityContext)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@petrov-mg petrov-mg force-pushed the IGNITE-26608 branch 2 times, most recently from 9bf30e8 to 324206b Compare October 17, 2025 11:30
@petrov-mg petrov-mg force-pushed the IGNITE-26608 branch 4 times, most recently from da14337 to 8795941 Compare October 28, 2025 21:44

/** */
<T> T get(ThreadContextAttribute<T> attr) {
if (attr.id() >= attrs.length)
Copy link
Member

Choose a reason for hiding this comment

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

Shoulud we throw assert instead? Is it correct to access to the attribute we actually didn't set?

Could it lead to an error, when user forget to set the var and received default value instead?

Copy link
Contributor Author

@petrov-mg petrov-mg Oct 31, 2025

Choose a reason for hiding this comment

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

No, we shouldn't. The initial value of an attribute literally means - the value returned by the ThreadContext#get method if the attribute's value is not explicitly set.

It can be used to skip explicitly setting attributes for some internal operations/workers and still get some value for attribute.

}
public interface Scope extends AutoCloseable {
/** Binds attribute with specified value to the current scope. */
public <T> Scope withAttribute(ThreadContextAttribute<T> attr, T val);
Copy link
Member

Choose a reason for hiding this comment

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

Broken incapsulation. ThreadContextScope inherits Scope, then ThreadContextAttribute must be part of ThreadContextScrope.

Copy link
Contributor Author

@petrov-mg petrov-mg Oct 31, 2025

Choose a reason for hiding this comment

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

It’s more of a naming problem than an “encapsulation.” Anyway, I’ve updated the PR and removed the Scope interface entirely — on second thought, it’s redundant for the current patch. So now only ThreadContextScope remains.

@petrov-mg petrov-mg force-pushed the IGNITE-26608 branch 6 times, most recently from da9cc26 to a5347c7 Compare November 17, 2025 08:08
/** */
private ContextAttribute(byte id, T initVal) {
this.id = id;
this.bitmask = 1 << id;
Copy link
Member

Choose a reason for hiding this comment

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

Looks that storing ID is enough. The bitmask is a parameter of ContextDataChain only.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope. The bitmask is used in many places to check for the presence of an attribute value. Therefore, it's better to calculate it once and store it in the attribute instance.

}

/** */
public <T> ScopedContext with(ContextAttribute<T> attr, T val) {
Copy link
Member

Choose a reason for hiding this comment

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

Looks weird, an object that stores an attribute value accepts another attribute (name + value). AFAIU, it's a responsibility of Scope to store all attributes within single scope.

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's a responsibility of Scope to store all attributes within single scope

Nope. See comments above.

I changed class naming a bit so it may be less confusing now.

Looks weird, an object that stores an attribute value accepts another attribute (name + value)
Also keep in mind that the current patch is based on intrusive lists and it is unlikely to be possible to avoid the "weirdness" you mentioned.

@petrov-mg petrov-mg force-pushed the IGNITE-26608 branch 3 times, most recently from 0930d07 to fcbcc57 Compare November 28, 2025 23:03
@sonarqubecloud
Copy link

sonarqubecloud bot commented Dec 1, 2025

@petrov-mg petrov-mg force-pushed the IGNITE-26608 branch 4 times, most recently from 31be217 to 98f14f7 Compare January 25, 2026 14:30
* try-with-resource block to close the returned Scope. Note, updates must be undone in the same order they were applied.
*/
public static <T> Scope set(ContextAttribute<T> attr, T val) {
if (get(attr) == val)
Copy link
Member

Choose a reason for hiding this comment

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

WDYT, can we move this optimization into applyUpdates? Currently, there are 2 calls of INSTANCE.get(), that the most expensive part.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


/** */
<T> ContextUpdater set(ContextAttribute<T> attr, T val) {
if (get(attr) == val)
Copy link
Member

Choose a reason for hiding this comment

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

Same here, can we check it later, within Context?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

"already used: " + id);

extPools[id] = ctx.security().enabled() ? new SecurityAwareIoPool(ctx.security(), ex) : ex;
extPools[id] = ctx.security().enabled() ? ContextAwareIoPool.wrap(ex) : ex;
Copy link
Member

Choose a reason for hiding this comment

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

Here and below: looks like we should not check security anymore and use ContextAwareIoPool everywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We will definitely do this, but in a separate ticket.

@petrov-mg petrov-mg changed the title IGNITE-26608 WIP IGNITE-26608 Added a unified mechanism for propagating Context Attributes Feb 3, 2026
}

/** Updates the current context with the specified attributes and their corresponding values. */
private Scope applyAttributeUpdates(AttributeValueHolder<?>... atrVals) {
Copy link
Member

Choose a reason for hiding this comment

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

Misprint, atrVals -> attrVals

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.


changeState(prevSnp, newSnp);

return () -> INSTANCE.get().changeState(newSnp, prevSnp);
Copy link
Member

Choose a reason for hiding this comment

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

It looks it should work with () -> changeState(newSnp, prevSnp). Because we close Scope within the same thread that restores snapshot.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@sonarqubecloud
Copy link

sonarqubecloud bot commented Feb 7, 2026

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