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

Remove lambdas from Arc that are used at startup #45741

Merged
merged 1 commit into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public Set<ContextInstanceHandle<?>> getAllPresent() {
@Override
public void removeEach(Consumer<? super ContextInstanceHandle<?>> action) {
if (action != null) {
instances.getPresentValues().forEach(action);
instances.forEachExistingValue(action);
}
instances.clear();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,12 @@ public void destroy(ContextState state) {
CurrentContextState currentState = ((CurrentContextState) state);
if (currentState.invalidate()) {
fireIfNotNull(beforeDestroyedNotifier);
currentState.contextInstances.removeEach(ContextInstanceHandle::destroy);
currentState.contextInstances.removeEach(new Consumer<>() {
@Override
public void accept(ContextInstanceHandle<?> contextInstanceHandle) {
contextInstanceHandle.destroy();
}
});
fireIfNotNull(destroyedNotifier);
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

Expand Down Expand Up @@ -122,7 +123,13 @@ private Notifier<? super T> getNotifier(Class<?> runtimeType) {
if (notifier != null && notifier.runtimeType.equals(runtimeType)) {
return notifier;
}
return this.lastNotifier = notifiers.computeIfAbsent(runtimeType, this::createNotifier);
return this.lastNotifier = notifiers.computeIfAbsent(runtimeType,
new Function<>() {
@Override
public Notifier<? super T> apply(Class<?> clazz) {
return createNotifier(clazz);
}
});
}

@Override
Expand Down Expand Up @@ -260,7 +267,14 @@ static class Notifier<T> {
this.runtimeType = runtimeType;
this.observerMethods = observerMethods;
this.eventMetadata = eventMetadata;
this.hasTxObservers = observerMethods.stream().anyMatch(this::isTxObserver);
boolean hasTxObservers = false;
for (var method : observerMethods) {
if (isTxObserver(method)) {
hasTxObservers = true;
break;
}
}
this.hasTxObservers = hasTxObservers;
this.activateRequestContext = activateRequestContext;
}

Expand All @@ -272,8 +286,8 @@ void notify(T event) {
void notify(T event, ObserverExceptionHandler exceptionHandler, boolean async) {
if (!isEmpty()) {

Predicate<ObserverMethod<? super T>> predicate = async ? ObserverMethod::isAsync
: Predicate.not(ObserverMethod::isAsync);
Predicate<ObserverMethod<?>> predicate = async ? ObserverMethodIsAsync.INSTANCE
: ObserverMethodIsNotAsync.INSTANCE;

if (!async && hasTxObservers) {
// Note that tx observers are never async
Expand Down Expand Up @@ -303,13 +317,13 @@ void notify(T event, ObserverExceptionHandler exceptionHandler, boolean async) {
// See for instance discussions on https://github.com/eclipse-ee4j/cdi/issues/467
txManager.getTransaction().registerSynchronization(sync);
// registration succeeded, notify all non-tx observers synchronously
predicate = predicate.and(this::isNotTxObserver);
predicate = predicate.and(ObserverMethodIsNotTxObserver.INSTANCE);
} catch (Exception e) {
if (e.getCause() instanceof RollbackException
|| e.getCause() instanceof IllegalStateException
|| e.getCause() instanceof SystemException) {
// registration failed, AFTER_SUCCESS OMs are accordingly to CDI spec left out
predicate = predicate.and(this::isNotAfterSuccess);
predicate = predicate.and(ObserverMethodIsNotAfterSuccessTxObserver.INSTANCE);
}
}
}
Expand Down Expand Up @@ -343,9 +357,9 @@ void notify(T event, ObserverExceptionHandler exceptionHandler, boolean async) {

@SuppressWarnings({ "rawtypes", "unchecked" })
private void notifyObservers(T event, ObserverExceptionHandler exceptionHandler,
Predicate<ObserverMethod<? super T>> predicate) {
Predicate<ObserverMethod<?>> predicate) {
EventContext eventContext = new EventContextImpl<>(event, eventMetadata);
for (ObserverMethod<? super T> observerMethod : observerMethods) {
for (ObserverMethod<?> observerMethod : observerMethods) {
if (predicate.test(observerMethod)) {
try {
observerMethod.notify(eventContext);
Expand All @@ -360,18 +374,10 @@ boolean isEmpty() {
return observerMethods.isEmpty();
}

private boolean isTxObserver(ObserverMethod<?> observer) {
private static boolean isTxObserver(ObserverMethod<?> observer) {
return !observer.getTransactionPhase().equals(TransactionPhase.IN_PROGRESS);
}

private boolean isNotAfterSuccess(ObserverMethod<?> observer) {
return !observer.getTransactionPhase().equals(TransactionPhase.AFTER_SUCCESS);
}

private boolean isNotTxObserver(ObserverMethod<?> observer) {
return !isTxObserver(observer);
}

}

static class ArcSynchronization implements Synchronization {
Expand Down Expand Up @@ -401,6 +407,48 @@ public void afterCompletion(int i) {
}
}

private static class ObserverMethodIsAsync implements Predicate<ObserverMethod<?>> {

private static final Predicate<ObserverMethod<?>> INSTANCE = new ObserverMethodIsAsync();

@Override
public boolean test(ObserverMethod<?> observerMethod) {
return observerMethod.isAsync();
}
}

private static class ObserverMethodIsNotAsync implements Predicate<ObserverMethod<?>> {

private static final Predicate<ObserverMethod<?>> INSTANCE = new ObserverMethodIsNotAsync();

@Override
public boolean test(ObserverMethod<?> observerMethod) {
return !observerMethod.isAsync();
}
}

private static class ObserverMethodIsNotTxObserver implements Predicate<ObserverMethod<?>> {

private static final Predicate<ObserverMethod<?>> INSTANCE = new ObserverMethodIsNotTxObserver();

@Override
public boolean test(ObserverMethod<?> observerMethod) {
return !EventImpl.Notifier.isTxObserver(observerMethod);
}

}

private static class ObserverMethodIsNotAfterSuccessTxObserver implements Predicate<ObserverMethod<?>> {

private static final Predicate<ObserverMethod<?>> INSTANCE = new ObserverMethodIsNotAfterSuccessTxObserver();

@Override
public boolean test(ObserverMethod<?> observerMethod) {
return !observerMethod.getTransactionPhase().equals(TransactionPhase.AFTER_SUCCESS);
}

}

@SuppressWarnings("rawtypes")
static class DeferredEventNotification<T> implements Runnable {

Expand Down
Loading