Browse Source

Optimization with and without ACPU for calculation of number of connections to course

Yannick Warnier 8 years ago
parent
commit
fef361b439
1 changed files with 40 additions and 12 deletions
  1. 40 12
      main/inc/lib/tracking.lib.php

+ 40 - 12
main/inc/lib/tracking.lib.php

@@ -1658,34 +1658,62 @@ class Tracking
      */
     public static function get_course_connections_count($courseId, $session_id = 0, $start = 0, $stop = null)
     {
-    	if ($start < 0) {
+        if ($start < 0) {
     		$start = 0;
     	}
     	if (!isset($stop) or ($stop < 0)) {
     		$stop = api_get_utc_datetime();
     	}
 
-        $start = Database::escape_string($start);
-        $stop = Database::escape_string($stop);
+        // Given we're storing in cache, round the start and end times
+        // to the lower minute
+        $roundedStart = substr($start, 0, -2) . '00';
+        $roundedStop = substr($stop, 0, -2) . '00';
+        $roundedStart = Database::escape_string($roundedStart);
+        $roundedStop = Database::escape_string($roundedStop);
 
-    	$month_filter = " AND login_course_date > '$start' AND login_course_date < '$stop' ";
+    	$month_filter = " AND login_course_date > '$roundedStart' AND login_course_date < '$roundedStop' ";
 
         $courseId = intval($courseId);
     	$session_id  = intval($session_id);
     	$count = 0;
-
-    	$tbl_track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
-    	$sql = "SELECT count(*) as count_connections
+        $tbl_track_e_course_access = Database :: get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
+        $sql =  "SELECT count(*) as count_connections
                 FROM $tbl_track_e_course_access
                 WHERE
                     c_id = $courseId AND
                     session_id = $session_id
                     $month_filter";
-    	$rs = Database::query($sql);
-    	if (Database::num_rows($rs)>0) {
-    		$row = Database::fetch_object($rs);
-    		$count = $row->count_connections;
-    	}
+
+        //This query can be very slow (several seconds on an indexed table
+        // with 14M rows). As such, we'll try to use APCU if it is
+        // available to store the resulting value for a few seconds
+        $cacheEnabled = function_exists('apcu_exists');
+        if ($cacheEnabled) {
+            $apc = apcu_cache_info(true);
+            $apc_end = $apc['start_time'] + $apc['ttl'];
+
+            $apc_var = 'course_access_'.$courseId.'_'.$session_id.'_'.strtotime($roundedStart).'_'.strtotime($roundedStop);
+            if (apcu_exists($apc_var) && (time() < $apc_end) &&
+                apcu_fetch($apc_var) > 0
+            ) {
+                $count = apcu_fetch($apc_var);
+            } else {
+                $rs = Database::query($sql);
+                if (Database::num_rows($rs)>0) {
+                    $row = Database::fetch_object($rs);
+                    $count = $row->count_connections;
+                }
+                apcu_clear_cache();
+                apcu_store($apc_var, $count, 60);
+            }
+        } else {
+            $rs = Database::query($sql);
+            if (Database::num_rows($rs)>0) {
+                $row = Database::fetch_object($rs);
+                $count = $row->count_connections;
+            }
+        }
 
     	return $count;
     }