/******************************************************************************* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. *******************************************************************************/ package org.apache.ofbiz.service.config.model; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.ofbiz.base.lang.ThreadSafe; import org.apache.ofbiz.base.util.UtilXml; import org.apache.ofbiz.service.config.ServiceConfigException; import org.w3c.dom.Element; /** * An object that models the <code><thread-pool></code> element. */ @ThreadSafe public final class ThreadPool { public static final int FAILED_RETRY_MIN = 30; public static final int MIN_THREADS = 1; // Must be no less than one or the executor will shut down. public static final int MAX_THREADS = 5; // Values higher than 5 might slow things down. public static final int POLL_WAIT = 30000; // Database polling interval - 30 seconds. public static final int PURGE_JOBS_DAYS = 30; public static final int QUEUE_SIZE = 100; public static final int THREAD_TTL = 120000; // Idle thread lifespan - 2 minutes. private final int failedRetryMin; private final int jobs; private final int maxThreads; private final int minThreads; private final int pollDbMillis; private final boolean pollEnabled; private final int purgeJobDays; private final List<RunFromPool> runFromPools; private final String sendToPool; private final int ttl; ThreadPool(Element poolElement) throws ServiceConfigException { String sendToPool = poolElement.getAttribute("send-to-pool").intern(); if (sendToPool.isEmpty()) { throw new ServiceConfigException("<thread-pool> element send-to-pool attribute is empty"); } this.sendToPool = sendToPool; String purgeJobDays = poolElement.getAttribute("purge-job-days").intern(); if (purgeJobDays.isEmpty()) { this.purgeJobDays = PURGE_JOBS_DAYS; } else { try { this.purgeJobDays = Integer.parseInt(purgeJobDays); if (this.purgeJobDays < 0) { throw new ServiceConfigException("<thread-pool> element purge-job-days attribute value is invalid"); } } catch (Exception e) { throw new ServiceConfigException("<thread-pool> element purge-job-days attribute value is invalid"); } } String failedRetryMin = poolElement.getAttribute("failed-retry-min").intern(); if (failedRetryMin.isEmpty()) { this.failedRetryMin = FAILED_RETRY_MIN; } else { try { this.failedRetryMin = Integer.parseInt(failedRetryMin); if (this.failedRetryMin < 0) { throw new ServiceConfigException("<thread-pool> element failed-retry-min attribute value is invalid"); } } catch (Exception e) { throw new ServiceConfigException("<thread-pool> element failed-retry-min attribute value is invalid"); } } String ttl = poolElement.getAttribute("ttl").intern(); if (ttl.isEmpty()) { this.ttl = THREAD_TTL; } else { try { this.ttl = Integer.parseInt(ttl); if (this.ttl < 0) { throw new ServiceConfigException("<thread-pool> element ttl attribute value is invalid"); } } catch (Exception e) { throw new ServiceConfigException("<thread-pool> element ttl attribute value is invalid"); } } String jobs = poolElement.getAttribute("jobs").intern(); if (ttl.isEmpty()) { this.jobs = QUEUE_SIZE; } else { try { this.jobs = Integer.parseInt(jobs); if (this.jobs < 1) { throw new ServiceConfigException("<thread-pool> element jobs attribute value is invalid"); } } catch (Exception e) { throw new ServiceConfigException("<thread-pool> element jobs attribute value is invalid"); } } String minThreads = poolElement.getAttribute("min-threads").intern(); if (minThreads.isEmpty()) { this.minThreads = MIN_THREADS; } else { try { this.minThreads = Integer.parseInt(minThreads); if (this.minThreads < 1) { throw new ServiceConfigException("<thread-pool> element min-threads attribute value is invalid"); } } catch (Exception e) { throw new ServiceConfigException("<thread-pool> element min-threads attribute value is invalid"); } } String maxThreads = poolElement.getAttribute("max-threads").intern(); if (maxThreads.isEmpty()) { this.maxThreads = MAX_THREADS; } else { try { this.maxThreads = Integer.parseInt(maxThreads); if (this.maxThreads < this.minThreads) { throw new ServiceConfigException("<thread-pool> element max-threads attribute value is invalid"); } } catch (Exception e) { throw new ServiceConfigException("<thread-pool> element max-threads attribute value is invalid"); } } this.pollEnabled = !"false".equals(poolElement.getAttribute("poll-enabled")); String pollDbMillis = poolElement.getAttribute("poll-db-millis").intern(); if (pollDbMillis.isEmpty()) { this.pollDbMillis = POLL_WAIT; } else { try { this.pollDbMillis = Integer.parseInt(pollDbMillis); if (this.pollDbMillis < 0) { throw new ServiceConfigException("<thread-pool> element poll-db-millis attribute value is invalid"); } } catch (Exception e) { throw new ServiceConfigException("<thread-pool> element poll-db-millis attribute value is invalid"); } } List<? extends Element> runFromPoolElementList = UtilXml.childElementList(poolElement, "run-from-pool"); if (runFromPoolElementList.isEmpty()) { this.runFromPools = Collections.emptyList(); } else { List<RunFromPool> runFromPools = new ArrayList<RunFromPool>(runFromPoolElementList.size()); for (Element runFromPoolElement : runFromPoolElementList) { runFromPools.add(new RunFromPool(runFromPoolElement)); } this.runFromPools = Collections.unmodifiableList(runFromPools); } } public int getFailedRetryMin() { return failedRetryMin; } public int getJobs() { return jobs; } public int getMaxThreads() { return maxThreads; } public int getMinThreads() { return minThreads; } public int getPollDbMillis() { return pollDbMillis; } public boolean getPollEnabled() { return pollEnabled; } public int getPurgeJobDays() { return purgeJobDays; } public List<RunFromPool> getRunFromPools() { return this.runFromPools; } public String getSendToPool() { return sendToPool; } public int getTtl() { return ttl; } }