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

Unregister topic listener on region shutdown #164

Merged
merged 2 commits into from
Jun 4, 2020

Conversation

EzequielB
Copy link
Contributor

@EzequielB EzequielB commented May 22, 2020

Fix for #163

  • Signed Contributor Agreement

@EzequielB EzequielB requested review from enozcan, pivovarit and a team as code owners May 22, 2020 21:24
@devOpsHazelcast
Copy link
Contributor

devOpsHazelcast commented May 22, 2020

CLA assistant check
All committers have signed the CLA.

@devOpsHazelcast
Copy link
Contributor

Can one of the admins verify this patch?

pivovarit
pivovarit previously approved these changes May 23, 2020
Copy link
Contributor

@pivovarit pivovarit left a comment

Choose a reason for hiding this comment

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

Thanks! Looks solid.

@enozcan
Copy link
Contributor

enozcan commented May 23, 2020

Thanks for the contribution! I want to make some points clear.

When I run the test

/* LocalRegionFactorySlowTest.java */

@Test
public void cleanUpRegisteredTopicOnRegionShutdown() {
    HazelcastInstance sf1Instance = HazelcastAccessor.getHazelcastInstance(sf);
    List<String> regions = new ArrayList<>(Arrays.asList(sf.getStatistics().getSecondLevelCacheRegionNames()));    
    // 'Query' cache is not subscribed to a topic in 5 and 52. 
    regions.removeIf(n -> n.contains("Query")); 
    regions.forEach(r ->
            assertEquals(r,2, Accessors.getNodeEngineImpl(sf1Instance)
                    .getEventService().getRegistrations(TopicService.SERVICE_NAME, r).size()));

    sf2.close();
    regions.forEach(r ->
            assertEquals(r,1, Accessors.getNodeEngineImpl(sf1Instance)
                    .getEventService().getRegistrations(TopicService.SERVICE_NAME, r).size()));
}

I get

hazelcast-hibernate5:  com.hazelcast.hibernate.entity.AnnotatedEntity##NaturalId expected:<1> but was:<2>
hazelcast-hibernate52:  com.hazelcast.hibernate.entity.AnnotatedEntity##NaturalId expected:<1> but was:<2>
hazelcast-hibernate53:  default-update-timestamps-region expected:<1> but was:<2>

As I added some logs at the points where a listener is registered to and removed from the topic, I noticed NaturalId region listener is not removed in 5 and 52 but 53. Also timestamps region listener is not removed in 53.

Any idea about this behavior?

@EzequielB
Copy link
Contributor Author

@enozcan I checked and it seems Hibernate is not calling the Region.destroy method for all regions (StorageAccess.release method in case of version 5.3)
To prevent regions not being destroyed by Hibernate, I added the logic for calling the destroy method of LocalRegion instances into the CleanupService.
Also I had to change the order on the Factory since otherwise the Hz instance would be shutdown first before any unsubscription can happen.

@@ -31,19 +33,23 @@
private final Duration fixedDelay;
private final String name;
private final ScheduledExecutorService executor;
private final List<Runnable> cacheDestroy;
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it be easier to actually store LocalRegionCache instances and then iterate over them and call destroy() on each?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, it would be simpler. Also, it would increase the coupling for future changes, the idea was to just use the needed parts and hide the rest inside the CleanupService.
We can do it that other way too.

Copy link
Contributor

@pivovarit pivovarit Jun 2, 2020

Choose a reason for hiding this comment

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

I don't think that that would result in extra coupling. Keep in mind that the registerCache() method accepts LocalRegionCache objects and the rest is encapsulated within the CleanupService class and doesn't really leak out in any way.

So I'd suggest we just store them as List<LocalRegionCache>


public CleanupService(final String name, final Duration fixedDelay) {
this.fixedDelay = fixedDelay;
this.name = name;
executor = Executors.newSingleThreadScheduledExecutor(new CleanupThreadFactory());
cacheDestroy = new LinkedList<>();
Copy link
Contributor

@pivovarit pivovarit Jun 2, 2020

Choose a reason for hiding this comment

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

Any particular reason why LinkedList is better over ArrayList here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since is was just add at the end, one iteration on stop and an unknown size, I thought it would perform better. But doing some review, the cases an ArrayList would underperform are too edgy, so we should go with an ArrayList. I'll move to that.

@pivovarit pivovarit changed the title issue-163 - Unregister topic listener on region shutdown Unregister topic listener on region shutdown Jun 2, 2020
Copy link
Contributor

@pivovarit pivovarit left a comment

Choose a reason for hiding this comment

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

Comments already provided

@EzequielB
Copy link
Contributor Author

@pivovarit , changes committed
Let me know how that goes

Copy link
Contributor

@pivovarit pivovarit left a comment

Choose a reason for hiding this comment

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

Just one last thing and I think we're good to go

@EzequielB
Copy link
Contributor Author

Done

Copy link
Contributor

@pivovarit pivovarit left a comment

Choose a reason for hiding this comment

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

Looks good to me. Let's wait for @enozcan to have a final look

@enozcan enozcan self-requested a review June 4, 2020 09:11
@enozcan enozcan merged commit ae9dff0 into hazelcast:master Jun 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants