Skip to content

Commit

Permalink
Issue OpenLiberty#24293 purge futures list when application is stopped
Browse files Browse the repository at this point in the history
  • Loading branch information
njr-11 committed Feb 15, 2023
1 parent 7b7d278 commit 14a48ac
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 16 deletions.
@@ -1,31 +1,80 @@
/*******************************************************************************
* Copyright (c) 2020,2022 IBM Corporation and others.
* Copyright (c) 2020,2023 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-2.0/
*
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package com.ibm.ws.concurrent.internal;

import java.security.AccessController;
import java.util.Collection;

import javax.enterprise.concurrent.ManagedScheduledExecutorService;

import org.osgi.framework.BundleContext;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.ConfigurationPolicy;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;

import com.ibm.websphere.ras.Tr;
import com.ibm.websphere.ras.TraceComponent;
import com.ibm.websphere.ras.annotation.Trivial;
import com.ibm.ws.concurrent.TriggerService;
import com.ibm.ws.concurrent.ext.ConcurrencyExtensionProvider;
import com.ibm.ws.container.service.metadata.ApplicationMetaDataListener;
import com.ibm.ws.container.service.metadata.MetaDataEvent;
import com.ibm.ws.container.service.metadata.MetaDataException;
import com.ibm.ws.kernel.service.util.SecureAction;
import com.ibm.ws.runtime.metadata.ApplicationMetaData;

@Component(configurationPolicy = ConfigurationPolicy.REQUIRE, service = { ConcurrencyService.class, ApplicationMetaDataListener.class })
public class ConcurrencyService implements ApplicationMetaDataListener {
static final SecureAction priv = AccessController.doPrivileged(SecureAction.get());
private static final TraceComponent tc = Tr.register(ConcurrencyService.class);

@Component(configurationPolicy = ConfigurationPolicy.REQUIRE, service = ConcurrencyService.class)
public class ConcurrencyService {
@Reference(policy = ReferencePolicy.STATIC, cardinality = ReferenceCardinality.OPTIONAL, target = "(id=unbound)")
ConcurrencyExtensionProvider extensionProvider;

@Reference
TriggerService triggerSvc;

@Override
@Trivial
public void applicationMetaDataCreated(MetaDataEvent<ApplicationMetaData> event) throws MetaDataException {
if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
Tr.debug(this, tc, "applicationMetaDataCreated: " + event.getMetaData().getJ2EEName());
}

@Override
@Trivial
public void applicationMetaDataDestroyed(MetaDataEvent<ApplicationMetaData> event) {
if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
Tr.debug(this, tc, "applicationMetaDataDestroyed: " + event.getMetaData().getJ2EEName());

BundleContext bc = priv.getBundleContext(FrameworkUtil.getBundle(getClass()));
try {
Collection<ServiceReference<ManagedScheduledExecutorService>> refs = //
priv.getServiceReferences(bc, ManagedScheduledExecutorService.class,
"(service.factoryPid=com.ibm.ws.concurrent.managedScheduledExecutorService)");
for (ServiceReference<ManagedScheduledExecutorService> ref : refs) {
ManagedScheduledExecutorServiceImpl executor = (ManagedScheduledExecutorServiceImpl) priv.getService(bc, ref);
if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
Tr.debug(this, tc, "purge futures list for " + executor);
executor.purgeFutures();
}
} catch (InvalidSyntaxException x) {
throw new RuntimeException(x); // should never occur because a valid filter is hard-coded
}
}
}
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2012, 2022 IBM Corporation and others.
* Copyright (c) 2012, 2023 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-2.0/
*
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
Expand Down Expand Up @@ -74,7 +74,6 @@
import com.ibm.ws.context.service.serializable.ContextualObject;
import com.ibm.ws.context.service.serializable.ThreadContextManager;
import com.ibm.ws.javaee.version.JavaEEVersion;
import com.ibm.ws.kernel.service.util.SecureAction;
import com.ibm.ws.runtime.metadata.ComponentMetaData;
import com.ibm.ws.threadContext.ComponentMetaDataAccessorImpl;
import com.ibm.wsspi.application.lifecycle.ApplicationRecycleComponent;
Expand All @@ -100,8 +99,6 @@ public class ContextServiceImpl implements ContextService, //
ResourceFactory, ThreadContext, WSContextService, ApplicationRecycleComponent {
private static final TraceComponent tc = Tr.register(ContextServiceImpl.class);

private static final SecureAction priv = AccessController.doPrivileged(SecureAction.get());

// Names of references
private static final String BASE_INSTANCE = "baseInstance",
THREAD_CONTEXT_MANAGER = "threadContextManager";
Expand Down Expand Up @@ -642,15 +639,15 @@ private final Executor executorForCompletionStages() {
String parentPid = (String) properties.get("config.parentPID");
if (parentPid != null) {
String filter = FilterUtils.createPropertyFilter("service.pid", parentPid);
BundleContext bc = priv.getBundleContext(componentContext);
BundleContext bc = ConcurrencyService.priv.getBundleContext(componentContext);
Collection<ServiceReference<ManagedExecutorService>> refs = //
priv.getServiceReferences(bc, ManagedExecutorService.class, filter);
ConcurrencyService.priv.getServiceReferences(bc, ManagedExecutorService.class, filter);
if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
Tr.debug(this, tc, filter + " found:", refs);
Iterator<ServiceReference<ManagedExecutorService>> it = refs.iterator();
if (it.hasNext()) {
ServiceReference<ManagedExecutorService> ref = refs.iterator().next();
executor = priv.getService(bc, ref);
executor = ConcurrencyService.priv.getService(bc, ref);
if (executor == null)
throw new IllegalStateException(filter);
else
Expand Down Expand Up @@ -879,7 +876,7 @@ private void init() {
}

// Inherit complementary thread context config from base instance
ContextServiceImpl baseInstance = (ContextServiceImpl) priv.locateService(componentContext, BASE_INSTANCE);
ContextServiceImpl baseInstance = (ContextServiceImpl) ConcurrencyService.priv.locateService(componentContext, BASE_INSTANCE);
if (baseInstance != null)
baseInstance.addComplementaryThreadContextConfigurationsTo(this);

Expand Down
@@ -1,10 +1,10 @@
/*******************************************************************************
* Copyright (c) 2013, 2020 IBM Corporation and others.
* Copyright (c) 2013, 2023 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-2.0/
*
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
Expand Down Expand Up @@ -88,7 +88,7 @@ protected void deactivate(ComponentContext context) {
* This method should be invoked every so often so that we don't leak memory.
*/
@Trivial
private final void purgeFutures() {
final void purgeFutures() {
for (Iterator<ScheduledFuture<?>> it = futures.iterator(); it.hasNext();)
if (it.next().isDone())
it.remove();
Expand Down

0 comments on commit 14a48ac

Please sign in to comment.