Refactor configuration of maximum persistent search resource limits
| | |
| | | ds-cfg-etime-resolution: milliseconds |
| | | ds-cfg-entry-cache-preload: false |
| | | ds-cfg-max-allowed-client-connections: 0 |
| | | ds-cfg-max-psearches: -1 |
| | | ds-cfg-allowed-task: org.opends.server.tasks.AddSchemaFileTask |
| | | ds-cfg-allowed-task: org.opends.server.tasks.BackupTask |
| | | ds-cfg-allowed-task: org.opends.server.tasks.DisconnectClientTask |
| | |
| | | ds-cfg-save-config-on-successful-startup $ |
| | | ds-cfg-etime-resolution $ |
| | | ds-cfg-entry-cache-preload $ |
| | | ds-cfg-max-allowed-client-connections) |
| | | ds-cfg-max-allowed-client-connections $ |
| | | ds-cfg-max-psearches ) |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.40 |
| | | NAME 'ds-cfg-root-dn-user' |
| | |
| | | STRUCTURAL |
| | | MUST ( cn $ |
| | | ds-cfg-java-class ) |
| | | MAY ds-cfg-max-psearches |
| | | X-ORIGIN 'OpenDS Directory Server' ) |
| | | objectClasses: ( 1.3.6.1.4.1.26027.1.2.72 |
| | | NAME 'ds-cfg-traditional-work-queue' |
| | |
| | | Global Configurations |
| | | </adm:user-friendly-plural-name> |
| | | <adm:synopsis> |
| | | The |
| | | The |
| | | <adm:user-friendly-name /> |
| | | contains properties that affect the overall |
| | | operation of the |
| | |
| | | Indicates whether schema enforcement is active. |
| | | </adm:synopsis> |
| | | <adm:description> |
| | | When schema enforcement is activated, the Directory Server |
| | | When schema enforcement is activated, the Directory Server |
| | | ensures that all operations result in entries are valid |
| | | according to the defined server schema. It is strongly recommended |
| | | that this option be left enabled to prevent the inadvertent |
| | |
| | | <adm:property name="allow-attribute-name-exceptions" |
| | | advanced="true"> |
| | | <adm:synopsis> |
| | | Indicates whether the Directory Server should allow underscores |
| | | Indicates whether the Directory Server should allow underscores |
| | | in attribute names and allow attribute names |
| | | to begin with numeric digits (both of which are violations of the |
| | | LDAP standards). |
| | |
| | | </adm:property> |
| | | <adm:property name="server-error-result-code" advanced="true"> |
| | | <adm:synopsis> |
| | | Specifies the numeric value of the result code when request |
| | | Specifies the numeric value of the result code when request |
| | | processing fails due to an internal server error. |
| | | </adm:synopsis> |
| | | <adm:default-behavior> |
| | |
| | | <adm:property name="single-structural-objectclass-behavior" |
| | | advanced="true"> |
| | | <adm:synopsis> |
| | | Specifies how the Directory Server should handle operations an entry does |
| | | Specifies how the Directory Server should handle operations an entry does |
| | | not contain a structural object class or contains multiple structural |
| | | classes. |
| | | </adm:synopsis> |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="max-psearches"> |
| | | <adm:synopsis> |
| | | Defines the maximum number of concurrent persistent searches that |
| | | can be performed on Directory Server |
| | | </adm:synopsis> |
| | | <adm:description> |
| | | The persistent search mechanism provides an active channel through which entries that change, |
| | | and information about the changes that occur, can be communicated. Because each persistent search |
| | | operation consumes resources, limiting the number of simultaneous persistent searches keeps the |
| | | performance impact minimal. A value of -1 indicates that there is no limit on the persistent searches. |
| | | </adm:description> |
| | | <adm:default-behavior> |
| | | <adm:defined> |
| | | <adm:value>-1</adm:value> |
| | | </adm:defined> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:integer lower-limit="0" allow-unlimited="true" /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:name>ds-cfg-max-psearches</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | </adm:managed-object> |
| | |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | <adm:property name="max-psearches"> |
| | | <adm:synopsis> |
| | | Defines the maximum number of concurrent persistent searches that |
| | | can be performed on Directory Server |
| | | </adm:synopsis> |
| | | <adm:description> |
| | | The persistent search mechanism provides an active channel through which entries that change, |
| | | and information about the changes that occur, can be communicated. Because each persistent search |
| | | operation uses one thread, limiting the number of simultaneous persistent searches prevents certain |
| | | kinds of denial of service attacks. A value of 0 indicates that there is no limit on the persistent searches. |
| | | </adm:description> |
| | | <adm:default-behavior> |
| | | <adm:alias> |
| | | <adm:synopsis> |
| | | Let the server decide. |
| | | </adm:synopsis> |
| | | </adm:alias> |
| | | </adm:default-behavior> |
| | | <adm:syntax> |
| | | <adm:integer lower-limit="0" upper-limit="2147483647" /> |
| | | </adm:syntax> |
| | | <adm:profile name="ldap"> |
| | | <ldap:attribute> |
| | | <ldap:name>ds-cfg-max-psearches</ldap:name> |
| | | </ldap:attribute> |
| | | </adm:profile> |
| | | </adm:property> |
| | | </adm:managed-object> |
| | |
| | | property.lookthrough-limit.description=This includes any entry that the server must examine in the course of processing the request, regardless of whether it actually matches the search criteria. A value of 0 indicates that no lookthrough limit is enforced. Note that this is the default server-wide limit, but it may be overridden on a per-user basis using the ds-rlim-lookthrough-limit operational attribute. |
| | | property.max-allowed-client-connections.synopsis=Specifies the maximum number of client connections that may be established at any given time |
| | | property.max-allowed-client-connections.description=A value of 0 indicates that unlimited client connection is allowed. |
| | | property.max-psearches.synopsis=Defines the maximum number of concurrent persistent searches that can be performed on Directory Server |
| | | property.max-psearches.description=The persistent search mechanism provides an active channel through which entries that change, and information about the changes that occur, can be communicated. Because each persistent search operation consumes resources, limiting the number of simultaneous persistent searches keeps the performance impact minimal. A value of -1 indicates that there is no limit on the persistent searches. |
| | | property.notify-abandoned-operations.synopsis=Indicates whether the Directory Server should send a response to any operation that is interrupted via an abandon request. |
| | | property.notify-abandoned-operations.description=The LDAP specification states that abandoned operations should not receive any response, but this may cause problems with client applications that always expect to receive a response to each request. |
| | | property.proxied-authorization-identity-mapper.synopsis=Specifies the name of the identity mapper to map authorization ID values (using the "u:" form) provided in the proxied authorization control to the corresponding user entry. |
| | |
| | | synopsis=The Parallel Work Queue is a type of work queue that uses a number of worker threads that watch a queue and pick up an operation to process whenever one becomes available. |
| | | description=The parallel work queue is a FIFO queue serviced by a fixed number of worker threads. This fixed number of threads can be changed on the fly, with the change taking effect as soon as it is made. This work queue implementation is unbound ie it does not block after reaching certain queue size and as such should only be used on a very well tuned server configuration to avoid potential out of memory errors. |
| | | property.java-class.synopsis=Specifies the fully-qualified name of the Java class that provides the Parallel Work Queue implementation. |
| | | property.max-psearches.synopsis=Defines the maximum number of concurrent persistent searches that can be performed on Directory Server |
| | | property.max-psearches.description=The persistent search mechanism provides an active channel through which entries that change, and information about the changes that occur, can be communicated. Because each persistent search operation uses one thread, limiting the number of simultaneous persistent searches prevents certain kinds of denial of service attacks. A value of 0 indicates that there is no limit on the persistent searches. |
| | | property.max-psearches.default-behavior.alias.synopsis=Let the server decide. |
| | | property.num-worker-threads.synopsis=Specifies the number of worker threads to be used for processing operations placed in the queue. |
| | | property.num-worker-threads.description=If the value is increased, the additional worker threads are created immediately. If the value is reduced, the appropriate number of threads are destroyed as operations complete processing. |
| | | property.num-worker-threads.default-behavior.alias.synopsis=Let the server decide. |
| | |
| | | synopsis=The Traditional Work Queue is a type of work queue that uses a number of worker threads that watch a queue and pick up an operation to process whenever one becomes available. |
| | | description=The traditional work queue is a FIFO queue serviced by a fixed number of worker threads. This fixed number of threads can be changed on the fly, with the change taking effect as soon as it is made. You can limit the size of the work queue to a specified number of operations. When this many operations are in the queue, waiting to be picked up by threads, any new requests are rejected with an error message. |
| | | property.java-class.synopsis=Specifies the fully-qualified name of the Java class that provides the Traditional Work Queue implementation. |
| | | property.max-psearches.synopsis=Defines the maximum number of concurrent persistent searches that can be performed on Directory Server |
| | | property.max-psearches.description=The persistent search mechanism provides an active channel through which entries that change, and information about the changes that occur, can be communicated. Because each persistent search operation uses one thread, limiting the number of simultaneous persistent searches prevents certain kinds of denial of service attacks. A value of 0 indicates that there is no limit on the persistent searches. |
| | | property.max-psearches.default-behavior.alias.synopsis=Let the server decide. |
| | | property.max-work-queue-capacity.synopsis=Specifies the maximum number of queued operations that can be in the work queue at any given time. |
| | | property.max-work-queue-capacity.description=If the work queue is already full and additional requests are received by the server, the requests are rejected. A value of zero indicates that there is no limit to the size of the queue. |
| | | property.max-work-queue-capacity.default-behavior.alias.synopsis=The work queue does not impose any limit on the number of operations that can be enqueued at any one time. |
| | |
| | | synopsis=The Work Queue provides the configuration for the server work queue and is responsible for ensuring that requests received from clients are processed in a timely manner. |
| | | description=Only a single work queue can be defined in the server. Whenever a connection handler receives a client request, it should place the request in the work queue to be processed appropriately. |
| | | property.java-class.synopsis=Specifies the fully-qualified name of the Java class that provides the Work Queue implementation. |
| | | property.max-psearches.synopsis=Defines the maximum number of concurrent persistent searches that can be performed on Directory Server |
| | | property.max-psearches.description=The persistent search mechanism provides an active channel through which entries that change, and information about the changes that occur, can be communicated. Because each persistent search operation uses one thread, limiting the number of simultaneous persistent searches prevents certain kinds of denial of service attacks. A value of 0 indicates that there is no limit on the persistent searches. |
| | | property.max-psearches.default-behavior.alias.synopsis=Let the server decide. |
| | |
| | | |
| | | return false; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Specifies the maximum number of simultaneous persistent |
| | | * searches that are allowed. |
| | | * |
| | | * @return The maximum number of simultaneous persistent |
| | | * searches that are allowed. |
| | | */ |
| | | public abstract int getMaxPersistentSearchLimit(); |
| | | } |
| | | |
| | |
| | | * CDDL HEADER END |
| | | * |
| | | * |
| | | * Copyright 2006-2009 Sun Microsystems, Inc. |
| | | * Copyright 2006-2010 Sun Microsystems, Inc. |
| | | */ |
| | | package org.opends.server.core; |
| | | import org.opends.messages.Message; |
| | |
| | | |
| | | DirectoryServer.setMaxAllowedConnections( |
| | | globalConfig.getMaxAllowedClientConnections()); |
| | | |
| | | DirectoryServer.setMaxPersistentSearchLimit( |
| | | globalConfig.getMaxPsearches()); |
| | | } |
| | | |
| | | |
| | |
| | | // The current active persistent searches. |
| | | private AtomicInteger activePSearches = new AtomicInteger(0); |
| | | |
| | | //The maximum number of concurrent persistent searches. |
| | | private int maxPSearches; |
| | | |
| | | // Whether to use collect operation processing times in nanosecond resolution |
| | | private boolean useNanoTime; |
| | | |
| | |
| | | |
| | | |
| | | /** |
| | | * Specifies the maximum number of simultaneous persistent |
| | | * searches that are allowed. |
| | | * |
| | | * @param maxPSearches The maximum number of simultaneous persistent |
| | | * searches that are allowed. |
| | | */ |
| | | public static void setMaxPersistentSearchLimit(int maxPSearches) |
| | | { |
| | | directoryServer.maxPSearches = maxPSearches; |
| | | } |
| | | |
| | | |
| | | |
| | | /** |
| | | * Registers a new persistent search by increasing the count |
| | | * of active persistent searches. After receiving a persistent |
| | | * search request, a Local or Remote WFE must call this method to |
| | |
| | | */ |
| | | public static boolean allowNewPersistentSearch() |
| | | { |
| | | //0 indicates that there is no limit. |
| | | int maxAllowedPSearch = getWorkQueue().getMaxPersistentSearchLimit(); |
| | | if(maxAllowedPSearch ==0 || |
| | | //-1 indicates that there is no limit. |
| | | if(directoryServer.maxPSearches ==-1 || |
| | | directoryServer.activePSearches.get() < |
| | | maxAllowedPSearch) |
| | | directoryServer.maxPSearches) |
| | | { |
| | | return true; |
| | | } |
| | |
| | | // a configuration change has not been completely applied). |
| | | private int numWorkerThreads; |
| | | |
| | | // The number of maximum allowed persistent searches. |
| | | private int maxPSearches; |
| | | |
| | | // The queue that will be used to actually hold the pending operations. |
| | | private ConcurrentLinkedQueue<AbstractOperation> opQueue; |
| | | |
| | |
| | | // Get the necessary configuration from the provided entry. |
| | | numWorkerThreads = getNumWorkerThreads(configuration); |
| | | |
| | | //Check the value of the maximum persistent searches attribute. |
| | | //We don't allow a value greater than the number of threads. |
| | | maxPSearches = configuration.getMaxPsearches()==null? |
| | | numWorkerThreads:configuration.getMaxPsearches(); |
| | | if(maxPSearches > numWorkerThreads) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_MAX_PSEARCH_LIMIT.get( |
| | | maxPSearches, numWorkerThreads, numWorkerThreads); |
| | | throw new ConfigException(message); |
| | | } |
| | | |
| | | // Create the actual work queue. |
| | | opQueue = new ConcurrentLinkedQueue<AbstractOperation>(); |
| | | |
| | |
| | | ParallelWorkQueueCfg configuration, |
| | | List<Message> unacceptableReasons) |
| | | { |
| | | //Check if the max persistent search value is under limit. |
| | | if(configuration.getMaxPsearches() !=null) |
| | | { |
| | | int nPSearches = configuration.getMaxPsearches(); |
| | | int nWorkerThreads = getNumWorkerThreads(configuration); |
| | | if(nPSearches > nWorkerThreads) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_MAX_PSEARCH_LIMIT.get( |
| | | nPSearches, nWorkerThreads, nWorkerThreads); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | //Get the new maximum psearch value. |
| | | maxPSearches = configuration.getMaxPsearches()==null? |
| | | numWorkerThreads:configuration.getMaxPsearches(); |
| | | |
| | | return new ConfigChangeResult(ResultCode.SUCCESS, false, resultMessages); |
| | | } |
| | | |
| | |
| | | |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int getMaxPersistentSearchLimit() |
| | | { |
| | | return maxPSearches; |
| | | } |
| | | |
| | | |
| | | |
| | | // Determine the number of worker threads. |
| | | private int getNumWorkerThreads(ParallelWorkQueueCfg configuration) |
| | | { |
| | |
| | | // a configuration change has not been completely applied). |
| | | private int numWorkerThreads; |
| | | |
| | | //The maximum number of concurrent persistent searches. |
| | | private int maxPSearches; |
| | | |
| | | // The queue that will be used to actually hold the pending operations. |
| | | private LinkedBlockingQueue<AbstractOperation> opQueue; |
| | | |
| | |
| | | |
| | | // Get the necessary configuration from the provided entry. |
| | | numWorkerThreads = getNumWorkerThreads(configuration); |
| | | //Check the value of the maximum persistent searches attribute. |
| | | //We don't allow a value greater than the number of threads. |
| | | maxPSearches = configuration.getMaxPsearches()==null? |
| | | numWorkerThreads:configuration.getMaxPsearches(); |
| | | if(maxPSearches > numWorkerThreads) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_MAX_PSEARCH_LIMIT.get( |
| | | maxPSearches, numWorkerThreads, numWorkerThreads); |
| | | throw new ConfigException(message); |
| | | } |
| | | |
| | | maxCapacity = configuration.getMaxWorkQueueCapacity(); |
| | | |
| | | |
| | |
| | | TraditionalWorkQueueCfg configuration, |
| | | List<Message> unacceptableReasons) |
| | | { |
| | | //Check if the max persistent search value is under limit. |
| | | if(configuration.getMaxPsearches() !=null) |
| | | { |
| | | int nPSearches = configuration.getMaxPsearches(); |
| | | int nWorkerThreads = getNumWorkerThreads(configuration); |
| | | if(nPSearches > nWorkerThreads) |
| | | { |
| | | Message message = ERR_CONFIG_CORE_INVALID_MAX_PSEARCH_LIMIT.get( |
| | | nPSearches, nWorkerThreads, nWorkerThreads); |
| | | unacceptableReasons.add(message); |
| | | return false; |
| | | } |
| | | } |
| | | return true; |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | //Get the new maximum psearch value. |
| | | maxPSearches = configuration.getMaxPsearches()==null? |
| | | numWorkerThreads:configuration.getMaxPsearches(); |
| | | |
| | | // Apply a change to the maximum capacity if appropriate. Since we can't |
| | | // change capacity on the fly, then we'll have to create a new queue and |
| | | // transfer any remaining items into it. Any thread that is waiting on the |
| | |
| | | } |
| | | |
| | | |
| | | /** |
| | | * {@inheritDoc} |
| | | */ |
| | | public int getMaxPersistentSearchLimit() |
| | | { |
| | | return maxPSearches; |
| | | } |
| | | |
| | | |
| | | |
| | | // Determine the number of worker threads. |
| | | private int getNumWorkerThreads(TraditionalWorkQueueCfg configuration) |
| | |
| | | mods.add(new LDAPModification(ModificationType.REPLACE, attr)); |
| | | |
| | | ModifyOperation modifyOperation = |
| | | conn.processModify(ByteString.valueOf("cn=Work Queue,cn=config"), mods); |
| | | conn.processModify(ByteString.valueOf("cn=config"), mods); |
| | | assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS); |
| | | |
| | | //Create a persistent search request. |