Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WFLY-12321 #12449

Merged
merged 2 commits into from
Sep 18, 2019
Merged

WFLY-12321 #12449

merged 2 commits into from
Sep 18, 2019

Conversation

fl4via
Copy link
Contributor

@fl4via fl4via commented Jul 24, 2019

Do not merge yet

Jira: https://issues.jboss.org/browse/WFLY-12321

This PR has to incorporate a few more feedbacks and will most likely be broken into more PRs and Jiras.
EAP Jira (temporary): https://issues.jboss.org/browse/JBEAP-17049

return;
}
task = expireTask;
expireTask = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we be concerned that the expireTask can be reset after this synchronized block completes? Whose cancels the Future in that case?

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 agree, I fixed that by checking if expireTask is different from null at the end of the file, before trying to reschedule it and reset the field.

@fl4via
Copy link
Contributor Author

fl4via commented Jul 29, 2019

@pferraro I've updated the PR with all your feedback. Also, I removed the commit for "At LocalCommandDispatcher for clustering, executeOnMember should check if this node is equal to member, and not if it is equal to itself". I was thinking it shoudl have its own Jira, dont you agree? Or do you prefer to have the commit at this PR as it was before?

@wildfly-ci wildfly-ci added the deps-ok Dependencies have been checked, and there are no significant changes label Jul 29, 2019
@pferraro
Copy link
Contributor

@fl4via

I've updated the PR with all your feedback. Also, I removed the commit for "At LocalCommandDispatcher for clustering, executeOnMember should check if this node is equal to member, and not if it is equal to itself". I was thinking it shoudl have its own Jira, dont you agree? Or do you prefer to have the commit at this PR as it was before?

Agreed. I merged it last week.
#12445

@fl4via fl4via force-pushed the WFLY-12321 branch 2 times, most recently from 4e2b959 to 605d0b3 Compare July 30, 2019 20:22
@fl4via fl4via marked this pull request as ready for review July 30, 2019 20:41
* the near future.
* @author Flavia Rainone
*/
public class PrepareReeschedulingSchedulerCommand<I> implements Command<Void, Scheduler<I>> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Spelling fix: PrepareReschedulingSchedulerCommand :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooops, thanks :-)

@rhusar
Copy link
Member

rhusar commented Jul 31, 2019

With the latest changes org.jboss.as.test.clustering.cluster.ejb.stateful.StatefulTimeoutTestCase#timeout fails consistently.

@fl4via
Copy link
Contributor Author

fl4via commented Jul 31, 2019

Retest this please

private void cancel(Bean<I, T> bean) {
if (this.dispatcher != null) {
final Node node = locatePrimaryOwner(bean.getId());
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove this line.

@@ -219,8 +218,28 @@ public Affinity getWeakAffinity(I id) {
return Affinity.NONE;
}

private void prepareRescheduling(Bean<I, T> bean) {
if (this.dispatcher != null) {
final Node node = locatePrimaryOwner(bean.getId());
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove this line.

}

@Override
public void cancel(Locality locality) {
for (I id: this.expirationFutures.keySet()) {
for (I id: expirationTracker.getTrackedIds()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Iterating over this set will be prone to ConcurrentModificationExceptions.

}

@Override
public void cancel(Locality locality) {
for (I id: this.evictionFutures.keySet()) {
for (I id: this.expirationTracker.getTrackedIds()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Iterating over this set will be prone to ConcurrentModificationExceptions.

firstExpiration != lastExpiration) {
firstExpiration = firstExpiration.nextExpiration;
}
expiration.previousExpiration = null;
Copy link
Contributor

Choose a reason for hiding this comment

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

the nextExpriation must also me cleared, or an endless loop can result

firstExpiration = lastExpiration = expiration;
} else if (lastExpiration != expiration) {
// if the last expiration to occur is not current node, add it to the
// last of the expiration list
Copy link
Contributor

Choose a reason for hiding this comment

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

This logic makes the assumption that the newly tracked bean will be the last to expire. While this is true when scheduling a bean for expiration at the end of an invocation, this is generally not the case when a member takes on the responsibility for expiring a given bean, i.e. when triggered from InfinispanBeanManager.schedule(Locality oldLocality, Locality newLocality).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh, I see. I'll try to think on a solution and I'll assert the perf gains with the benchmark to make sure this PR is really needed.

Copy link
Contributor

@pferraro pferraro Aug 13, 2019

Choose a reason for hiding this comment

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

One solution is to replace the expiration tracker with a collection, e.g. io.undertow.util.ConcurrentDirectDeque. We can then construct the scheduler with a queue implementation appropriate for the use case. In the clustered case, where the assumption above is violated, we could use a priority queue, where elements are inserted according to their next expiration, rather then just appending to the end. Insertions/removals would be slower, i.e. log(N) instead of constant time, but that way we can still optimize for the local case.

@fl4via
Copy link
Contributor Author

fl4via commented Aug 23, 2019

@pferraro this commit is ready for review

@fl4via
Copy link
Contributor Author

fl4via commented Aug 23, 2019

Retest this please

@fl4via
Copy link
Contributor Author

fl4via commented Aug 23, 2019

Retest this please

@fl4via fl4via force-pushed the WFLY-12321 branch 2 times, most recently from 0f4a9a8 to 1178575 Compare August 23, 2019 20:56
@fl4via
Copy link
Contributor Author

fl4via commented Aug 23, 2019

Retest this please

try {
this.executeOnPrimaryOwner(id, new PrepareReschedulingSchedulerCommand<>(id));
} catch (Exception e) {
InfinispanEjbLogger.ROOT_LOGGER.failedToCancelBean(e, id);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@pferraro I didn t think it was worthy to add a new logging message for something that will be later removed. If you prefer to have a logging message created for this, let me know.

@bstansberry
Copy link
Contributor

@fl4via @pferraro Is this meant for WF 18?

public void evict(I id) {
try {
// Cache eviction is a local operation, so we need to broadcast this to the cluster
this.dispatcher.executeOnGroup(new EvictCommand<>(id));
Copy link
Contributor

Choose a reason for hiding this comment

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

Given that this is now a local-only scheduler, there is no need to dispatch an eviction command.

@pferraro pferraro self-requested a review September 16, 2019 12:22
@pferraro
Copy link
Contributor

@bstansberry This is a performance optimization for local SFSBs. Not essential for WF18, but still desirable.

this.executor = executor;
this.idleTimeout = idleTimeout;
this.expirationTracker = new ExpirationTracker<>(idleTimeout);
this.dispatcher = dispatcherFactory.createCommandDispatcher(dispatcherName + "/eviction", evictor);
Copy link
Contributor

Choose a reason for hiding this comment

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

This scheduler no longer has any need to create a CommandDispatcher, no?

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

// do nothing, this is a local-only scheduler
}

static class EvictCommand<I> implements Command<Void, BeanGroupEvictor<I>> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think this class is referenced any longer.

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


@Override
public void evict(I id) {
// do nothing, this is a local-only scheduler
Copy link
Contributor

Choose a reason for hiding this comment

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

This method needs to evict the bean, i.e. this.evictor.evict(id);

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

…a single task for eviction and another for bean expiration and never cancel that task; instead, update the expiration of the bean so it can be checked by the task if the bean has actually expired
@fl4via
Copy link
Contributor Author

fl4via commented Sep 17, 2019

@pferraro all requested changes are done

Copy link
Contributor

@pferraro pferraro left a comment

Choose a reason for hiding this comment

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

Thanks Flavia. I think this is ready now.

@bstansberry bstansberry added the ready-for-merge Only for use by those with merge permissions! label Sep 17, 2019
@bstansberry bstansberry mentioned this pull request Sep 17, 2019
@bstansberry bstansberry merged commit c2d61d9 into wildfly:master Sep 18, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
deps-ok Dependencies have been checked, and there are no significant changes ready-for-merge Only for use by those with merge permissions!
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants