[MGNLRSSAGG-188] Memory leaks and application hangs created by FastRSSFeedFetcher Created: 10/Dec/14  Updated: 01/Jul/15  Resolved: 02/Feb/15

Status: Closed
Project: Magnolia RSS Aggregator Module
Component/s: rss_generator
Affects Version/s: 2.3.1
Fix Version/s: 2.3.3

Type: Bug Priority: Major
Reporter: Lars Fischer Assignee: Jaroslav Simak
Resolution: Fixed Votes: 0
Labels: support
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: Zip Archive rss.news.xml.zip    
Issue Links:
relation
Template:
Acceptance criteria:
Empty
Task DoD:
[ ]* Doc/release notes changes? Comment present?
[ ]* Downstream builds green?
[ ]* Solution information and context easily available?
[ ]* Tests
[ ]* FixVersion filled and not yet released
[ ]  Architecture Decision Record (ADR)
Bug DoR:
[ ]* Steps to reproduce, expected, and actual results filled
[ ]* Affected version filled
Date of First Response:

 Description   

When the webapplication is shut down during RSS aggregator updates, the Thread pool of FastRSSFeedFetcher is not shut down properly and prevents the application from being shut down properly.

To fix this, Namics created a method in the ModuleLifecycle to fix this.

private void shutdownRssFeedFetcher() {
        RSSFeedFetcher fetcher = Components.getComponent(RSSAggregator.class).getFetcher();
        if (fetcher instanceof FastRSSFeedFetcher) {
            FastRSSFeedFetcher fastFetcher = (FastRSSFeedFetcher) fetcher;

            try {
                Field executorServiceField = FastRSSFeedFetcher.class.getDeclaredField("executorService");
                executorServiceField.setAccessible(true);

                Object executorServiceObject = executorServiceField.get(fastFetcher);

                if (executorServiceObject instanceof ExecutorService) {
                    ExecutorService executorService = (ExecutorService) executorServiceObject;

                    log.info("Shutting down feed fetcher executor service: " + executorService);
                    List<Runnable> terminated = executorService.shutdownNow();
                    log.info("Cancelled {} Runnable instances.", terminated.size());

                    log.info("Terminating feed fetcher executor service: " + executorService);
                    executorService.awaitTermination(5, TimeUnit.MINUTES);
                }
            } catch (Throwable e) {
                log.error("Could not shutdown RSS Feed Fetcher", e);
            }

        }
    }

Of course, it would be nice if the RSSFeedFetcher interface had a stop() method, and the RSSAggregator Module itself would stop it's fetcher.

To do this, I suggest a method like this:

    public void shutdown() {
        List<Runnable> runnables = executor.shutdownNow();
        log.info("Canceling {} RSS Update Tasks because of shutdown...", runnables.size());

        try {
            if (executor.awaitTermination(5, TimeUnit.MINUTES)) {
                log.info("Termination successful.");
            } else {
                log.error("Termination timed out.");
            }
        } catch (InterruptedException e) {
            log.error("Termination error.", e);
        }
    }

Generated at Mon Feb 12 07:06:26 CET 2024 using Jira 9.4.2#940002-sha1:46d1a51de284217efdcb32434eab47a99af2938b.