svn commit: r1620907 - /ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

svn commit: r1620907 - /ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java

jacopoc
Author: jacopoc
Date: Wed Aug 27 15:10:12 2014
New Revision: 1620907

URL: http://svn.apache.org/r1620907
Log:
First part of the overhaul of ServerHitBin class: now ServerHitBin objects are thread-safe; however the ServerHitBin class isn't because of its static maps (more work is needed in order to fix this).

Modified:
    ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java

Modified: ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java?rev=1620907&r1=1620906&r2=1620907&view=diff
==============================================================================
--- ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java (original)
+++ ofbiz/trunk/framework/webapp/src/org/ofbiz/webapp/stats/ServerHitBin.java Wed Aug 27 15:10:12 2014
@@ -105,6 +105,35 @@ public class ServerHitBin {
         }
     }
 
+    private static long getNewBinLength() {
+        long binLength = (long) UtilProperties.getPropertyNumber("serverstats", "stats.bin.length.millis");
+
+        // if no or 0 binLength specified, set to 30 minutes
+        if (binLength <= 0) binLength = 1800000;
+        // if binLength is more than an hour, set it to one hour
+        if (binLength > 3600000) binLength = 3600000;
+        return binLength;
+    }
+
+    private static long getEvenStartingTime(long binLength) {
+        // binLengths should be a divisable evenly into 1 hour
+        long curTime = System.currentTimeMillis();
+
+        // find the first previous millis that are even on the hour
+        Calendar cal = Calendar.getInstance();
+
+        cal.setTime(new Date(curTime));
+        cal.set(Calendar.MINUTE, 0);
+        cal.set(Calendar.SECOND, 0);
+        cal.set(Calendar.MILLISECOND, 0);
+
+        while (cal.getTime().getTime() < (curTime - binLength)) {
+            cal.add(Calendar.MILLISECOND, (int) binLength);
+        }
+
+        return cal.getTime().getTime();
+    }
+
     private static void countHit(String baseId, int type, HttpServletRequest request, long startTime, long runningTime, GenericValue userLogin, boolean isOriginal) {
         Delegator delegator = (Delegator) request.getAttribute("delegator");
         if (delegator == null) {
@@ -202,16 +231,48 @@ public class ServerHitBin {
                 }
                 if (bin == null) {
                     bin = new ServerHitBin(id, type, true, delegator);
-                    if (binList.size() > 0) {
-                        binList.add(0, bin);
-                    } else {
-                        binList.add(bin);
+                    binList.add(0, bin);
+                }
+            }
+        }
+
+        long toTime = startTime + runningTime;
+        // advance the bin
+        // first check to see if the bin has expired, if so save and recycle it
+        while (bin.limitLength && toTime > bin.endTime) {
+            // the first in the list will be this object, remove and copy it,
+            // put the copy at the first of the list, then put this object back on
+            if (bin.getNumberHits() > 0) {
+                // persist each bin when time ends if option turned on
+                if (UtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist." + ServerHitBin.typeIds[type] + ".bin", "true")) {
+                    GenericValue serverHitBin = delegator.makeValue("ServerHitBin");
+                    serverHitBin.set("contentId", bin.id);
+                    serverHitBin.set("hitTypeId", ServerHitBin.typeIds[bin.type]);
+                    serverHitBin.set("binStartDateTime", new java.sql.Timestamp(bin.startTime));
+                    serverHitBin.set("binEndDateTime", new java.sql.Timestamp(bin.endTime));
+                    serverHitBin.set("numberHits", Long.valueOf(bin.getNumberHits()));
+                    serverHitBin.set("totalTimeMillis", Long.valueOf(bin.getTotalRunningTime()));
+                    serverHitBin.set("minTimeMillis", Long.valueOf(bin.getMinTime()));
+                    serverHitBin.set("maxTimeMillis", Long.valueOf(bin.getMaxTime()));
+                    // get localhost ip address and hostname to store
+                    if (VisitHandler.address != null) {
+                        serverHitBin.set("serverIpAddress", VisitHandler.address.getHostAddress());
+                        serverHitBin.set("serverHostName", VisitHandler.address.getHostName());
+                    }
+                    try {
+                        delegator.createSetNextSeqId(serverHitBin);
+                    } catch (GenericEntityException e) {
+                        Debug.logError(e, "Could not save ServerHitBin:", module);
                     }
                 }
+            } else {
+                binList.remove(0);
             }
+            bin = new ServerHitBin(bin, bin.endTime + 1);
+            binList.add(0, bin);
         }
 
-        bin.addHit(startTime, runningTime);
+        bin.addHit(runningTime);
         if (isOriginal) {
             try {
                 bin.saveHit(request, startTime, runningTime, userLogin);
@@ -222,9 +283,9 @@ public class ServerHitBin {
 
         // count since start global and per id hits
         if (!id.startsWith("GLOBAL")) {
-            countHitSinceStart(id, type, startTime, runningTime, delegator);
+            countHitSinceStart(id, type, runningTime, delegator);
             if (isOriginal) {
-                countHitSinceStart(makeIdTenantAware("GLOBAL", delegator), type, startTime, runningTime, delegator);
+                countHitSinceStart(makeIdTenantAware("GLOBAL", delegator), type, runningTime, delegator);
             }
         }
 
@@ -238,7 +299,7 @@ public class ServerHitBin {
         }
     }
 
-    private static void countHitSinceStart(String id, int type, long startTime, long runningTime, Delegator delegator) {
+    private static void countHitSinceStart(String id, int type, long runningTime, Delegator delegator) {
         ServerHitBin bin = null;
 
         // save in global, and try to get bin by id
@@ -315,7 +376,7 @@ public class ServerHitBin {
             }
         }
 
-        bin.addHit(startTime, runningTime);
+        bin.addHit(runningTime);
     }
 
     private final Delegator delegator;
@@ -323,8 +384,9 @@ public class ServerHitBin {
     private final int type;
     private final boolean limitLength;
     private final long binLength;
-    private long startTime;
-    private long endTime;
+    private final long startTime;
+    private final long endTime;
+
     private long numberHits;
     private long totalRunningTime;
     private long minTime;
@@ -336,21 +398,37 @@ public class ServerHitBin {
         this.limitLength = limitLength;
         this.delegator = delegator;
         this.binLength = getNewBinLength();
-        reset(getEvenStartingTime());
+        this.startTime = getEvenStartingTime(this.binLength);
+        if (this.limitLength) {
+            // subtract 1 millisecond to keep bin starting times even
+            this.endTime = this.startTime + this.binLength - 1;
+        } else {
+            this.endTime = 0;
+        }
+        this.numberHits = 0;
+        this.totalRunningTime = 0;
+        this.minTime = Long.MAX_VALUE;
+        this.maxTime = 0;
     }
 
-    private ServerHitBin(ServerHitBin oldBin) {
+    private ServerHitBin(ServerHitBin oldBin, long startTime) {
         this.id = oldBin.id;
         this.type = oldBin.type;
         this.limitLength = oldBin.limitLength;
         this.delegator = oldBin.delegator;
         this.binLength = oldBin.binLength;
-        this.startTime = oldBin.startTime;
-        this.endTime = oldBin.endTime;
-        this.numberHits = oldBin.numberHits;
-        this.totalRunningTime = oldBin.totalRunningTime;
-        this.minTime = oldBin.minTime;
-        this.maxTime = oldBin.maxTime;
+
+        this.startTime = startTime;
+        if (limitLength) {
+            // subtract 1 millisecond to keep bin starting times even
+            this.endTime = this.startTime + this.binLength - 1;
+        } else {
+            this.endTime = 0;
+        }
+        this.numberHits = 0;
+        this.totalRunningTime = 0;
+        this.minTime = Long.MAX_VALUE;
+        this.maxTime = 0;
     }
 
     public Delegator getDelegator() {
@@ -396,136 +474,44 @@ public class ServerHitBin {
         return (this.getBinLength()) / 60000.0;
     }
 
-    public long getNumberHits() {
+    public synchronized long getNumberHits() {
         return this.numberHits;
     }
 
-    public double getMinTimeSeconds() {
-        return (this.minTime) / 1000.0;
+    public synchronized long getMinTime() {
+        return this.minTime;
     }
 
-    public double getMaxTimeSeconds() {
-        return (this.maxTime) / 1000.0;
+    public synchronized long getMaxTime() {
+        return this.maxTime;
     }
 
-    public double getAvgTime() {
-        return ((double) this.totalRunningTime) / ((double) this.numberHits);
+    public synchronized long getTotalRunningTime() {
+        return this.totalRunningTime;
     }
 
-    public double getAvgTimeSeconds() {
-        return this.getAvgTime() / 1000.0;
+    public double getMinTimeSeconds() {
+        return (this.getMinTime()) / 1000.0;
     }
 
-    /** return the hits per minute using the entire length of the bin as returned by getBinLengthMinutes() */
-    public double getHitsPerMinute() {
-        return (this.numberHits) / this.getBinLengthMinutes();
+    public double getMaxTimeSeconds() {
+        return (this.getMaxTime()) / 1000.0;
     }
 
-    private long getNewBinLength() {
-        long binLength = (long) UtilProperties.getPropertyNumber("serverstats", "stats.bin.length.millis");
-
-        // if no or 0 binLength specified, set to 30 minutes
-        if (binLength <= 0) binLength = 1800000;
-        // if binLength is more than an hour, set it to one hour
-        if (binLength > 3600000) binLength = 3600000;
-        return binLength;
+    public synchronized double getAvgTime() {
+        return ((double) this.getTotalRunningTime()) / ((double) this.getNumberHits());
     }
 
-    private long getEvenStartingTime() {
-        // binLengths should be a divisable evenly into 1 hour
-        long curTime = System.currentTimeMillis();
-
-        // find the first previous millis that are even on the hour
-        Calendar cal = Calendar.getInstance();
-
-        cal.setTime(new Date(curTime));
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-
-        while (cal.getTime().getTime() < (curTime - this.binLength)) {
-            cal.add(Calendar.MILLISECOND, (int) this.binLength);
-        }
-
-        return cal.getTime().getTime();
+    public double getAvgTimeSeconds() {
+        return this.getAvgTime() / 1000.0;
     }
 
-    private void reset(long startTime) {
-        this.startTime = startTime;
-        if (limitLength) {
-            // subtract 1 millisecond to keep bin starting times even
-            this.endTime = startTime + this.binLength - 1;
-        } else {
-            this.endTime = 0;
-        }
-        this.numberHits = 0;
-        this.totalRunningTime = 0;
-        this.minTime = Long.MAX_VALUE;
-        this.maxTime = 0;
+    /** return the hits per minute using the entire length of the bin as returned by getBinLengthMinutes() */
+    public double getHitsPerMinute() {
+        return this.getNumberHits() / this.getBinLengthMinutes();
     }
 
-    private synchronized void addHit(long startTime, long runningTime) {
-        long toTime = startTime + runningTime;
-        // advance the bin
-        // first check to see if this bin has expired, if so save and recycle it
-        while (limitLength && toTime > this.endTime) {
-            List<ServerHitBin> binList = null;
-
-            switch (type) {
-            case REQUEST:
-                binList = requestHistory.get(id);
-                break;
-
-            case EVENT:
-                binList = eventHistory.get(id);
-                break;
-
-            case VIEW:
-                binList = viewHistory.get(id);
-                break;
-
-            case ENTITY:
-                binList = entityHistory.get(id);
-                break;
-
-            case SERVICE:
-                binList = serviceHistory.get(id);
-                break;
-            }
-
-            // the first in the list will be this object, remove and copy it,
-            // put the copy at the first of the list, then put this object back on
-            binList.remove(0);
-            if (this.numberHits > 0) {
-                binList.add(0, new ServerHitBin(this));
-
-                // persist each bin when time ends if option turned on
-                if (UtilProperties.propertyValueEqualsIgnoreCase("serverstats", "stats.persist." + ServerHitBin.typeIds[type] + ".bin", "true")) {
-                    GenericValue serverHitBin = delegator.makeValue("ServerHitBin");
-                    serverHitBin.set("contentId", this.id);
-                    serverHitBin.set("hitTypeId", ServerHitBin.typeIds[this.type]);
-                    serverHitBin.set("binStartDateTime", new java.sql.Timestamp(this.startTime));
-                    serverHitBin.set("binEndDateTime", new java.sql.Timestamp(this.endTime));
-                    serverHitBin.set("numberHits", Long.valueOf(this.numberHits));
-                    serverHitBin.set("totalTimeMillis", Long.valueOf(this.totalRunningTime));
-                    serverHitBin.set("minTimeMillis", Long.valueOf(this.minTime));
-                    serverHitBin.set("maxTimeMillis", Long.valueOf(this.maxTime));
-                    // get localhost ip address and hostname to store
-                    if (VisitHandler.address != null) {
-                        serverHitBin.set("serverIpAddress", VisitHandler.address.getHostAddress());
-                        serverHitBin.set("serverHostName", VisitHandler.address.getHostName());
-                    }
-                    try {
-                        delegator.createSetNextSeqId(serverHitBin);
-                    } catch (GenericEntityException e) {
-                        Debug.logError(e, "Could not save ServerHitBin:", module);
-                    }
-                }
-            }
-            this.reset(this.endTime + 1);
-            binList.add(0, this);
-        }
-
+    private synchronized void addHit(long runningTime) {
         this.numberHits++;
         this.totalRunningTime += runningTime;
         if (runningTime < this.minTime)
@@ -569,26 +555,6 @@ public class ServerHitBin {
             
             Debug.logInfo("Visit delegatorName=" + visit.getDelegator().getDelegatorName() + ", ServerHitBin delegatorName=" + this.delegator.getDelegatorName(), module);
             
-            /* this isn't needed, the problem was better solved elsewhere, and without adding another query; leaving it here because it might be useful for something in the future
-             * else {
-                try {
-                    // see if the error was caused by a bad visitId, and if so create a new visit and try again
-                    GenericValue freshVisit = delegator.findOne("Visit", false, "visitId", visitId);
-                    if (freshVisit == null) {
-                        Debug.logInfo("Visit with ID [" + visitId + "] does not exist in the database, removing from session and making a new one", module);
-                        // something happened, have a bad visit in the session so remove it and try again
-                        request.getSession().removeAttribute("visit");
-                        visitId = VisitHandler.getVisitId(request.getSession());
-                        Debug.logInfo("After making new Visit the ID is [" + visitId + "]", module);
-                    }
-                } catch (GenericEntityException e) {
-                    // this is an error on the retry and not part of the main flow, so log it and let it go
-                    Debug.logWarning(e, "Error retrying ServerHit: " + e.toString(), module);
-                }                
-                
-            }
-            */
-
             GenericValue serverHit = delegator.makeValue("ServerHit");
 
             serverHit.set("visitId", visitId);