Skip to content

Commit

Permalink
GitHub comments resolve
Browse files Browse the repository at this point in the history
Signed-off-by: Radek Felcman <[email protected]>
  • Loading branch information
rfelcman committed Jan 28, 2025
1 parent b77aa2d commit 9561d62
Show file tree
Hide file tree
Showing 9 changed files with 80 additions and 63 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2025 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/

// Contributors:
// Oracle - initial API and implementation
package org.eclipse.persistence.config;

/**
* INTERNAL:
* <p>
* <b>Purpose</b>: It is data model behind {@linkplain org.eclipse.persistence.config.SystemProperties#CONCURRENCY_MANAGER_ALLOW_GET_CACHE_KEY_FOR_MERGE_MODE}
* or {@linkplain org.eclipse.persistence.config.PersistenceUnitProperties#CONCURRENCY_MANAGER_ALLOW_GET_CACHE_KEY_FOR_MERGE_MODE}.
*/
public final class MergeManagerOperationMode {

/**
* {@code ORIGIN} (DEFAULT) - There is infinite {@linkplain java.lang.Object#wait()} call in case of some conditions during time when object/entity referred from
* {@code org.eclipse.persistence.internal.identitymaps.CacheKey} is locked and modified by another thread. In some cases it should leads into deadlock.
*/
public static final String ORIGIN = "ORIGIN";

/**
* {@code WAITLOOP} - Merge manager will try in the loop with timeout wait {@code cacheKey.wait(ConcurrencyUtil.SINGLETON.getAcquireWaitTime());}
* fetch object/entity from {@linkplain org.eclipse.persistence.internal.identitymaps.CacheKey}. If fetch will be successful object/entity loop finish and continue
* with remaining code. If not @{code java.lang.InterruptedException} is thrown and caught and used {@linkplain org.eclipse.persistence.internal.identitymaps.CacheKey} instance
* status is set into invalidation state. This strategy avoid deadlock issue, but there should be impact to the performance.
*/
public static final String WAITLOOP = "WAITLOOP";
}
Original file line number Diff line number Diff line change
Expand Up @@ -4056,36 +4056,36 @@ public final class PersistenceUnitProperties {
* mechanism and related extended logging will be activated.
* Default value is 0 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME = SystemProperties.CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME;
public static final String CONCURRENCY_MANAGER_ACQUIRE_WAIT_TIME = "eclipselink.concurrency.manager.waittime";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager.
* It controls how much time ConcurrencyManager will wait before it will identify, that thread which builds new object/entity instance
* should be identified as a potential deadlock source. It leads into some additional log messages.
* Default value is 0 (unit is ms). In this case extended logging is not active. Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME = SystemProperties.CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME;
public static final String CONCURRENCY_MANAGER_BUILD_OBJECT_COMPLETE_WAIT_TIME = "eclipselink.concurrency.manager.build.object.complete.waittime";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager.
* It controls how long we are willing to wait before firing up an exception
* Default value is 40000 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_MAX_SLEEP_TIME = SystemProperties.CONCURRENCY_MANAGER_MAX_SLEEP_TIME;
public static final String CONCURRENCY_MANAGER_MAX_SLEEP_TIME = "eclipselink.concurrency.manager.maxsleeptime";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager and org.eclipse.persistence.internal.helper.ConcurrencyUtil.
* It controls how frequently the tiny dump log message is created.
* Default value is 40000 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE = SystemProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE;
public static final String CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_TINY_MESSAGE = "eclipselink.concurrency.manager.maxfrequencytodumptinymessage";

/**
* This system property in milliseconds can control thread management in org.eclipse.persistence.internal.helper.ConcurrencyManager and org.eclipse.persistence.internal.helper.ConcurrencyUtil.
* It controls how frequently the massive dump log message is created.
* Default value is 60000 (unit is ms). Allowed values are: long
*/
public static final String CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE = SystemProperties.CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE;
public static final String CONCURRENCY_MANAGER_MAX_FREQUENCY_DUMP_MASSIVE_MESSAGE = "eclipselink.concurrency.manager.maxfrequencytodumpmassivemessage";

/**
* <p>
Expand All @@ -4103,7 +4103,7 @@ public final class PersistenceUnitProperties {
* threads to progress.
* </ul>
*/
public static final String CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION = SystemProperties.CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION;
public static final String CONCURRENCY_MANAGER_ALLOW_INTERRUPTED_EXCEPTION = "eclipselink.concurrency.manager.allow.interruptedexception";

/**
* <p>
Expand All @@ -4112,11 +4112,11 @@ public final class PersistenceUnitProperties {
* <p>
* <b>Allowed Values</b> (case-sensitive String)<b>:</b>
* <ul>
* <li>{@code ORIGIN} (DEFAULT) - There is infinite {@code java.lang.Object.wait()} call in case of some conditions during time when object/entity referred from
* <li>{@code ORIGIN} (DEFAULT) - There is infinite {@linkplain java.lang.Object#wait()} call in case of some conditions during time when object/entity referred from
* {@code org.eclipse.persistence.internal.identitymaps.CacheKey} is locked and modified by another thread. In some cases it should leads into deadlock.
* <li>{@code WAITLOOP} - Merge manager will try in the loop with timeout wait {@code cacheKey.wait(ConcurrencyUtil.SINGLETON.getAcquireWaitTime());}
* fetch object/entity from {@code org.eclipse.persistence.internal.identitymaps.CacheKey}. If fetch will be successful object/entity loop finish and continue
* with remaining code. If not @{code java.lang.InterruptedException} is thrown and caught and used {@code org.eclipse.persistence.internal.identitymaps.CacheKey} instance
* fetch object/entity from {@linkplain org.eclipse.persistence.internal.identitymaps.CacheKey}. If fetch will be successful object/entity loop finish and continue
* with remaining code. If not @{code java.lang.InterruptedException} is thrown and caught and used {@linkplain org.eclipse.persistence.internal.identitymaps.CacheKey} instance
* status is set into invalidation state. This strategy avoid deadlock issue, but there should be impact to the performance.
* </ul>
*/
Expand All @@ -4137,7 +4137,7 @@ public final class PersistenceUnitProperties {
* locks and allow other threads to progress.
* </ul>
*/
public static final String CONCURRENCY_MANAGER_ALLOW_CONCURRENCY_EXCEPTION = SystemProperties.CONCURRENCY_MANAGER_ALLOW_CONCURRENCY_EXCEPTION;
public static final String CONCURRENCY_MANAGER_ALLOW_CONCURRENCY_EXCEPTION = "eclipselink.concurrency.manager.allow.concurrencyexception";

/**
* <p>
Expand All @@ -4149,7 +4149,7 @@ public final class PersistenceUnitProperties {
* <li>{@code true} - collect debug/trace information during ReadLock acquisition. Has negative impact to the performance.
* </ul>
*/
public static final String CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK = SystemProperties.CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK;
public static final String CONCURRENCY_MANAGER_ALLOW_STACK_TRACE_READ_LOCK = "eclipselink.concurrency.manager.allow.readlockstacktrace";

/**
* <p>
Expand All @@ -4167,7 +4167,7 @@ public final class PersistenceUnitProperties {
* vanilla behavior).
* </ul>
*/
public static final String CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_OBJECT_BUILDING = SystemProperties.CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_OBJECT_BUILDING;
public static final String CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_OBJECT_BUILDING = "eclipselink.concurrency.manager.object.building.semaphore";

/**
* <p>
Expand All @@ -4186,7 +4186,7 @@ public final class PersistenceUnitProperties {
* vanilla behavior).
* </ul>
*/
public static final String CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS = SystemProperties.CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS;
public static final String CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS = "eclipselink.concurrency.manager.write.lock.manager.semaphore";

/**
* <p>
Expand All @@ -4195,7 +4195,7 @@ public final class PersistenceUnitProperties {
* If "eclipselink.concurrency.manager.object.building.semaphore" property is {@code false} (DEFAULT) number of threads is unlimited.
* </p>
*/
public static final String CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS = SystemProperties.CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS;
public static final String CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS = "eclipselink.concurrency.manager.object.building.no.threads";

/**
* <p>
Expand All @@ -4204,7 +4204,7 @@ public final class PersistenceUnitProperties {
* If "eclipselink.concurrency.manager.write.lock.manager.semaphore" property is {@code false} (DEFAULT) number of threads is unlimited.
* </p>
*/
public static final String CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS = SystemProperties.CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS;
public static final String CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS = "eclipselink.concurrency.manager.write.lock.manager.no.threads";

/**
* <p>
Expand All @@ -4213,15 +4213,15 @@ public final class PersistenceUnitProperties {
* Default value is 2000 (unit is ms). Allowed values are: long
* </p>
*/
public static final String CONCURRENCY_SEMAPHORE_MAX_TIME_PERMIT = SystemProperties.CONCURRENCY_SEMAPHORE_MAX_TIME_PERMIT;
public static final String CONCURRENCY_SEMAPHORE_MAX_TIME_PERMIT = "eclipselink.concurrency.semaphore.max.time.permit";

/**
* <p>
* This property control timeout between log messages in {@link org.eclipse.persistence.internal.helper.ConcurrencySemaphore#acquireSemaphoreIfAppropriate(boolean)} when method/thread tries to get permit for the execution.
* Default value is 10000 (unit is ms). Allowed values are: long
* </p>
*/
public static final String CONCURRENCY_SEMAPHORE_LOG_TIMEOUT = SystemProperties.CONCURRENCY_SEMAPHORE_LOG_TIMEOUT;
public static final String CONCURRENCY_SEMAPHORE_LOG_TIMEOUT = "eclipselink.concurrency.semaphore.log.timeout";

/**
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,11 +165,11 @@ public final class SystemProperties {
* <p>
* <b>Allowed Values</b> (case-sensitive String)<b>:</b>
* <ul>
* <li>{@code ORIGIN} (DEFAULT) - There is infinite {@code java.lang.Object.wait()} call in case of some conditions during time when object/entity referred from
* <li>{@code ORIGIN} (DEFAULT) - There is infinite {@linkplain java.lang.Object#wait()} call in case of some conditions during time when object/entity referred from
* {@code org.eclipse.persistence.internal.identitymaps.CacheKey} is locked and modified by another thread. In some cases it should leads into deadlock.
* <li>{@code WAITLOOP} - Merge manager will try in the loop with timeout wait {@code cacheKey.wait(ConcurrencyUtil.SINGLETON.getAcquireWaitTime());}
* fetch object/entity from {@code org.eclipse.persistence.internal.identitymaps.CacheKey}. If fetch will be successful object/entity loop finish and continue
* with remaining code. If not @{code java.lang.InterruptedException} is thrown and caught and used {@code org.eclipse.persistence.internal.identitymaps.CacheKey} instance
* fetch object/entity from {@linkplain org.eclipse.persistence.internal.identitymaps.CacheKey}. If fetch will be successful object/entity loop finish and continue
* with remaining code. If not @{code java.lang.InterruptedException} is thrown and caught and used {@linkplain org.eclipse.persistence.internal.identitymaps.CacheKey} instance
* status is set into invalidation state. This strategy avoid deadlock issue, but there should be impact to the performance.
* </ul>
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
// IBM - ConcurrencyUtil call of ThreadMXBean.getThreadInfo() needs doPriv
package org.eclipse.persistence.internal.helper;

import org.eclipse.persistence.config.MergeManagerOperationMode;
import org.eclipse.persistence.config.SystemProperties;
import org.eclipse.persistence.internal.helper.type.CacheKeyToThreadRelationships;
import org.eclipse.persistence.internal.helper.type.ConcurrencyManagerState;
import org.eclipse.persistence.internal.helper.type.DeadLockComponent;
import org.eclipse.persistence.internal.helper.type.MergeManagerOperationMode;
import org.eclipse.persistence.internal.helper.type.ReadLockAcquisitionMetadata;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.localization.TraceLocalization;
Expand Down Expand Up @@ -75,7 +75,7 @@ public class ConcurrencyUtil {
private boolean useSemaphoreToLimitConcurrencyOnWriteLockManagerAcquireRequiredLocks = getBooleanProperty(SystemProperties.CONCURRENCY_MANAGER_USE_SEMAPHORE_TO_SLOW_DOWN_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS, DEFAULT_USE_SEMAPHORE_TO_SLOW_DOWN_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS);
private int noOfThreadsAllowedToObjectBuildInParallel = getIntProperty(SystemProperties.CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS, DEFAULT_CONCURRENCY_MANAGER_OBJECT_BUILDING_NO_THREADS);
private int noOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel = getIntProperty(SystemProperties.CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS, DEFAULT_CONCURRENCY_MANAGER_WRITE_LOCK_MANAGER_ACQUIRE_REQUIRED_LOCKS_NO_THREADS);
private MergeManagerOperationMode concurrencyManagerAllowGetCacheKeyForMergeMode = (MergeManagerOperationMode)getEnumProperty(SystemProperties.CONCURRENCY_MANAGER_ALLOW_GET_CACHE_KEY_FOR_MERGE_MODE, MergeManagerOperationMode.ORIGIN);
private String concurrencyManagerAllowGetCacheKeyForMergeMode = getStringProperty(SystemProperties.CONCURRENCY_MANAGER_ALLOW_GET_CACHE_KEY_FOR_MERGE_MODE, MergeManagerOperationMode.ORIGIN);
private long concurrencySemaphoreMaxTimePermit = getLongProperty(SystemProperties.CONCURRENCY_SEMAPHORE_MAX_TIME_PERMIT, DEFAULT_CONCURRENCY_SEMAPHORE_MAX_TIME_PERMIT);
private long concurrencySemaphoreLogTimeout = getLongProperty(SystemProperties.CONCURRENCY_SEMAPHORE_LOG_TIMEOUT, DEFAULT_CONCURRENCY_SEMAPHORE_LOG_TIMEOUT);

Expand Down Expand Up @@ -340,11 +340,11 @@ public void setNoOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParal
this.noOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel = noOfThreadsAllowedToDoWriteLockManagerAcquireRequiredLocksInParallel;
}

public MergeManagerOperationMode getConcurrencyManagerAllowGetCacheKeyForMergeMode() {
public String getConcurrencyManagerAllowGetCacheKeyForMergeMode() {
return concurrencyManagerAllowGetCacheKeyForMergeMode;
}

public void setConcurrencyManagerAllowGetCacheKeyForMergeMode(MergeManagerOperationMode concurrencyManagerAllowGetCacheKeyForMergeMode) {
public void setConcurrencyManagerAllowGetCacheKeyForMergeMode(String concurrencyManagerAllowGetCacheKeyForMergeMode) {
this.concurrencyManagerAllowGetCacheKeyForMergeMode = concurrencyManagerAllowGetCacheKeyForMergeMode;
}

Expand Down Expand Up @@ -1748,13 +1748,17 @@ private boolean getBooleanProperty(final String key, final boolean defaultValue)
return defaultValue;
}

private Enum<?> getEnumProperty(final String key, final Enum<?> defaultValue) {
final String propertyValue = PrivilegedAccessHelper.callDoPrivileged(
() -> System.getProperty(key)
private String getStringProperty(final String key, final String defaultValue) {
final String value = PrivilegedAccessHelper.callDoPrivileged(
() -> System.getProperty(key, String.valueOf(defaultValue))
);
if (propertyValue == null) {
return defaultValue;
if (value != null) {
try {
return value.trim();
} catch (Exception ignoreE) {
return defaultValue;
}
}
return Enum.valueOf(defaultValue.getClass(), propertyValue);
return defaultValue;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
// - 494610: Session Properties map should be Map<String, Object>
package org.eclipse.persistence.internal.sessions;

import org.eclipse.persistence.config.MergeManagerOperationMode;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.config.ReferenceMode;
Expand Down Expand Up @@ -2828,7 +2829,7 @@ protected CacheKey getCacheKeyFromTargetSessionForMerge(Object implementation, O
cacheKey.acquireDeferredLock();

switch (ConcurrencyUtil.SINGLETON.getConcurrencyManagerAllowGetCacheKeyForMergeMode()) {
case ORIGIN -> {
case MergeManagerOperationMode.ORIGIN -> {
original = cacheKey.getObject();
if (original == null) {
cacheKey.getInstanceLock().lock();
Expand All @@ -2846,7 +2847,7 @@ protected CacheKey getCacheKeyFromTargetSessionForMerge(Object implementation, O
}
}
}
case WAITLOOP -> {
case MergeManagerOperationMode.WAITLOOP -> {
final Thread currentThread = Thread.currentThread();
final String currentThreadName = currentThread.getName();
final long whileStartTimeMillis = System.currentTimeMillis();
Expand Down
Loading

0 comments on commit 9561d62

Please sign in to comment.