"Queue Compression" -- let one do the work for all identical, concurrent searches
authorMike Rylander <mrylander@gmail.com>
Fri, 26 Apr 2013 14:49:17 +0000 (10:49 -0400)
committerMike Rylander <mrylander@gmail.com>
Thu, 2 May 2013 14:08:57 +0000 (10:08 -0400)
Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Jason Etheridge <jason@esilibrary.com>
Open-ILS/src/perlmods/lib/OpenILS/Application/Search/Biblio.pm

index 6d149ca..3975eda 100644 (file)
@@ -1293,6 +1293,23 @@ sub staged_search {
     my $facet_key = $key.'_facets';
     my $cache_data = $cache->get_cache($key) || {};
 
+    # First, we want to make sure that someone else isn't currently trying to perform exactly
+    # this same search.  The point is to allow just one instance of a search to fill the needs
+    # of all concurrent, identical searches.  This will avoid spammy searches killing the
+    # database without requiring admins to start locking some IP addresses out entirely.
+    #
+    # There's still a tiny race condition where 2 might run, but without sigificantly more code
+    # and complexity, this is close to the best we can do.
+
+    if ($cache_data->{running}) { # someone is already doing the search...
+        while ( sleep(1) ) { # sleep for a second ... maybe they'll finish
+            $cache_data = $cache->get_cache($key) || {};
+            last if (!$cache_data->{running});
+        }
+    } else { # we're the first ... let's give it a try
+        $cache->put_cache($key, { running => $$ }, $cache_timeout / 3);
+    }
+
     # keep retrieving results until we find enough to 
     # fulfill the user-specified limit and offset
     my $all_results = [];