Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 99AF711B8F for ; Tue, 15 Jul 2014 09:39:00 +0000 (UTC) Received: (qmail 80405 invoked by uid 500); 15 Jul 2014 09:39:00 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 80344 invoked by uid 500); 15 Jul 2014 09:39:00 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 80335 invoked by uid 99); 15 Jul 2014 09:39:00 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 15 Jul 2014 09:39:00 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id 196BE94D419; Tue, 15 Jul 2014 09:39:00 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: ema@apache.org To: commits@cxf.apache.org Message-Id: <74ed8000d5bf4b588445afa652baefb5@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: git commit: [CXF-5880]:Fix Concurrent issue in ResponseTimeCounter Date: Tue, 15 Jul 2014 09:39:00 +0000 (UTC) Repository: cxf Updated Branches: refs/heads/master e53db10b3 -> b39006ba5 [CXF-5880]:Fix Concurrent issue in ResponseTimeCounter Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/b39006ba Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/b39006ba Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/b39006ba Branch: refs/heads/master Commit: b39006ba523c6ef085b863be2b2fd19c2c4fd238 Parents: e53db10 Author: Jim Ma Authored: Tue Jul 15 16:56:04 2014 +0800 Committer: Jim Ma Committed: Tue Jul 15 16:56:31 2014 +0800 ---------------------------------------------------------------------- .../counters/ResponseTimeCounter.java | 126 +++++++++++-------- .../counters/CounterRepositoryTest.java | 4 +- 2 files changed, 78 insertions(+), 52 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/b39006ba/rt/management/src/main/java/org/apache/cxf/management/counters/ResponseTimeCounter.java ---------------------------------------------------------------------- diff --git a/rt/management/src/main/java/org/apache/cxf/management/counters/ResponseTimeCounter.java b/rt/management/src/main/java/org/apache/cxf/management/counters/ResponseTimeCounter.java index ee35a34..e40e036 100644 --- a/rt/management/src/main/java/org/apache/cxf/management/counters/ResponseTimeCounter.java +++ b/rt/management/src/main/java/org/apache/cxf/management/counters/ResponseTimeCounter.java @@ -20,6 +20,8 @@ package org.apache.cxf.management.counters; import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; +import java.util.concurrent.locks.ReentrantLock; import javax.management.ObjectName; @@ -28,14 +30,16 @@ import org.apache.cxf.message.FaultMode; public class ResponseTimeCounter implements ResponseTimeCounterMBean, Counter { private ObjectName objectName; - private AtomicInteger invocations = new AtomicInteger(); - private AtomicInteger checkedApplicationFaults = new AtomicInteger(); - private AtomicInteger unCheckedApplicationFaults = new AtomicInteger(); - private AtomicInteger runtimeFaults = new AtomicInteger(); - private AtomicInteger logicalRuntimeFaults = new AtomicInteger(); - private long totalHandlingTime; - private long maxHandlingTime; - private long minHandlingTime = Integer.MAX_VALUE; + private final AtomicInteger invocations = new AtomicInteger(); + private final AtomicInteger checkedApplicationFaults = new AtomicInteger(); + private final AtomicInteger unCheckedApplicationFaults = new AtomicInteger(); + private final AtomicInteger runtimeFaults = new AtomicInteger(); + private final AtomicInteger logicalRuntimeFaults = new AtomicInteger(); + private final AtomicLong totalHandlingTime = new AtomicLong(); + private final ReentrantLock write = new ReentrantLock(); + private final AtomicLong maxHandlingTime = new AtomicLong(); + private final AtomicLong minHandlingTime = new AtomicLong();; + private final AtomicLong averageProcessingTime = new AtomicLong();; private boolean enabled = true; public ResponseTimeCounter(ObjectName on) { @@ -46,30 +50,6 @@ public class ResponseTimeCounter implements ResponseTimeCounterMBean, Counter { if (!enabled) { return; } - invocations.getAndIncrement(); - FaultMode faultMode = mhtr.getFaultMode(); - if (null == faultMode) { - // no exception occured - } else { - switch (faultMode) { - case CHECKED_APPLICATION_FAULT: - checkedApplicationFaults.incrementAndGet(); - break; - case LOGICAL_RUNTIME_FAULT: - logicalRuntimeFaults.incrementAndGet(); - break; - case RUNTIME_FAULT: - runtimeFaults.incrementAndGet(); - break; - case UNCHECKED_APPLICATION_FAULT: - unCheckedApplicationFaults.incrementAndGet(); - break; - default: - runtimeFaults.incrementAndGet(); - break; - } - } - long handlingTime = 0; if (mhtr.isOneWay()) { // We can count the response time @@ -79,14 +59,39 @@ public class ResponseTimeCounter implements ResponseTimeCounterMBean, Counter { } else { handlingTime = mhtr.getHandlingTime(); } - - totalHandlingTime = totalHandlingTime + handlingTime; - if (maxHandlingTime < handlingTime) { - maxHandlingTime = handlingTime; - } - if (minHandlingTime == 0 || minHandlingTime > handlingTime) { - minHandlingTime = handlingTime; + write.lock(); + try { + FaultMode faultMode = mhtr.getFaultMode(); + + invocations.getAndIncrement(); + if (null == faultMode) { + // no exception occured + } else { + switch (faultMode) { + case CHECKED_APPLICATION_FAULT: + checkedApplicationFaults.incrementAndGet(); + break; + case LOGICAL_RUNTIME_FAULT: + logicalRuntimeFaults.incrementAndGet(); + break; + case RUNTIME_FAULT: + runtimeFaults.incrementAndGet(); + break; + case UNCHECKED_APPLICATION_FAULT: + unCheckedApplicationFaults.incrementAndGet(); + break; + default: + runtimeFaults.incrementAndGet(); + break; + } + } + totalHandlingTime.addAndGet(handlingTime); + averageProcessingTime.getAndSet(totalHandlingTime.get() / invocations.get()); + } finally { + write.unlock(); } + updateMax(handlingTime); + updateMin(handlingTime); } public void reset() { @@ -96,9 +101,10 @@ public class ResponseTimeCounter implements ResponseTimeCounterMBean, Counter { runtimeFaults.set(0); logicalRuntimeFaults.set(0); - totalHandlingTime = 0; - maxHandlingTime = 0; - minHandlingTime = 0; + totalHandlingTime.set(0); + maxHandlingTime.set(0); + minHandlingTime.set(0); + averageProcessingTime.set(0); } public ObjectName getObjectName() { @@ -106,18 +112,15 @@ public class ResponseTimeCounter implements ResponseTimeCounterMBean, Counter { } public Number getAvgResponseTime() { - if (invocations.get() == 0) { - return 0; - } - return (int)(totalHandlingTime / invocations.get()); + return averageProcessingTime.get(); } public Number getMaxResponseTime() { - return maxHandlingTime; + return maxHandlingTime.get(); } public Number getMinResponseTime() { - return minHandlingTime; + return minHandlingTime.get(); } public Number getNumInvocations() { @@ -153,6 +156,29 @@ public class ResponseTimeCounter implements ResponseTimeCounterMBean, Counter { @Override public boolean isEnabled() { return enabled; - } - + } + + private void updateMax(long handleTime) { + while (true) { + long current = maxHandlingTime.get(); + if (current >= handleTime) { + break; + } + if (maxHandlingTime.compareAndSet(current, handleTime)) { + break; + } + } + } + + private void updateMin(long handleTime) { + while (true) { + long current = minHandlingTime.get(); + if (current < handleTime && current != 0) { + break; + } + if (minHandlingTime.compareAndSet(current, handleTime)) { + break; + } + } + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/b39006ba/rt/management/src/test/java/org/apache/cxf/management/counters/CounterRepositoryTest.java ---------------------------------------------------------------------- diff --git a/rt/management/src/test/java/org/apache/cxf/management/counters/CounterRepositoryTest.java b/rt/management/src/test/java/org/apache/cxf/management/counters/CounterRepositoryTest.java index 6027949..a9467c0 100644 --- a/rt/management/src/test/java/org/apache/cxf/management/counters/CounterRepositoryTest.java +++ b/rt/management/src/test/java/org/apache/cxf/management/counters/CounterRepositoryTest.java @@ -123,7 +123,7 @@ public class CounterRepositoryTest extends Assert { assertEquals("The operation counter isn't increased", opCounter.getNumInvocations(), 1); assertEquals("The operation counter's AvgResponseTime is wrong ", - opCounter.getAvgResponseTime(), 1000); + opCounter.getAvgResponseTime(), (long)1000); assertEquals("The operation counter's MaxResponseTime is wrong ", opCounter.getMaxResponseTime(), (long)1000); assertEquals("The operation counter's MinResponseTime is wrong ", @@ -139,7 +139,7 @@ public class CounterRepositoryTest extends Assert { cr.increaseCounter(operationCounter, mhtr2); assertEquals("The operation counter isn't increased", opCounter.getNumInvocations(), 2); assertEquals("The operation counter's AvgResponseTime is wrong ", - opCounter.getAvgResponseTime(), 1500); + opCounter.getAvgResponseTime(), (long)1500); assertEquals("The operation counter's MaxResponseTime is wrong ", opCounter.getMaxResponseTime(), (long)2000); assertEquals("The operation counter's MinResponseTime is wrong ",