myexperiment-hackers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[myexperiment-hackers] [2015] branches/invitation_throttling/app: Thrott


From: noreply
Subject: [myexperiment-hackers] [2015] branches/invitation_throttling/app: Throttling.
Date: Fri, 28 Nov 2008 12:40:02 -0500 (EST)

Revision
2015
Author
alekses6
Date
2008-11-28 12:40:01 -0500 (Fri, 28 Nov 2008)

Log Message

Throttling. The actual code that deals with the limits is relocated to ActivityLimit class instead of ApplicationController.

Modified Paths

Diff

Modified: branches/invitation_throttling/app/controllers/application.rb (2014 => 2015)


--- branches/invitation_throttling/app/controllers/application.rb	2008-11-28 17:10:15 UTC (rev 2014)
+++ branches/invitation_throttling/app/controllers/application.rb	2008-11-28 17:40:01 UTC (rev 2015)
@@ -38,100 +38,7 @@
     return res
   end
   
-  
-  # the single point in the application governing validation of all features that have
-  # limited allowance of usage (e.g. 5 messages a day, etc)
-  def check_activity_limit(contributor, limit_feature, update_counter=true)
-    time_now = Time.now
-    limit_save_required = false
-    
-    if (limit = ActivityLimit.find(:first, :conditions => ["contributor_type = ? AND contributor_id = ? AND limit_feature = ?", contributor.class.name, contributor.id, limit_feature]))
-      # limit exists - check its validity
-      if (limit.limit_frequency && limit.reset_after && time_now > limit.reset_after)
-        # "reset_after" / "limit_frequency" are not NULL - so the limit is periodic;
-        # now it's the time to reset the counter to zero - no matter what its value was before
-        # (this will never be executed for non-periodic counters)
-        limit.current_count = 0
-        limit.reset_after = time_now + limit.limit_frequency.hours
-        limit_save_required = true
 
-        # also check if the contributor needs to be "promoted" to the next level --
-        # e.g. in the first month of membership on myExperiment one can send 10 messages daily,
-        # but after that can send 15 (because the user becomes more "trusted")
-        if (limit.promote_after && time_now > limit.promote_after)
-          absolute_max_limit_value = eval("#{limit_feature.upcase}_LIMIT_MAX_VALUE")
-          limit_increment_value = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_INCREMENT")
-          promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
-          
-          if limit_increment_value
-            if absolute_max_limit_value
-              # absolute max value set -->
-              # increase the limit only if not exceeded absolute maximum just yet
-              if (limit.limit_max < absolute_max_limit_value)
-                limit.limit_max += limit_increment_value
-                limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
-               else
-                # absolute maximum already reached / exceeded, disable further promotions
-                limit.promote_after = nil
-              end
-              
-              # make sure that it's not set to exceed the absolute maximum
-              # (which can happen if increment is not factor of the absolute maximum value)
-              if (limit.limit_max > absolute_max_limit_value)
-                limit.limit_max = absolute_max_limit_value
-              end
-            else
-              # absolute value not set --> simply increment
-              limit.limit_max += limit_increment_value
-              limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
-            end
-          else 
-            # increment not set - this will be a one-time promotion
-            # (if the absolute max value is set - set limit to it; if not - the feature becomes unlimited)
-            limit.limit_max = absolute_max_limit_value
-            limit.promote_after = nil
-          end   
-        end # END of PROMOTION code
-        
-      end # END of COUNTER RESET code
-      
-    else
-      # limit doesn't exist yet - create it, then proceed to validation and saving
-      limit_frequency = eval("#{limit_feature.upcase}_LIMIT_FREQUENCY")
-      promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
-      
-      limit = ActivityLimit.new(:contributor_type => contributor.class.name, :contributor_id => contributor.id,
-                                :limit_feature => limit_feature, 
-                                :limit_max => eval("#{limit_feature.upcase}_LIMIT_START_VALUE"),
-                                :limit_frequency => limit_frequency,
-                                :reset_after => (limit_frequency ? (time_now + limit_frequency.hours) : nil),
-                                :promote_after => (promote_every ? (time_now + promote_every.days) : nil),
-                                :current_count => 0)
-                                
-      limit_save_required = true
-    end
-    
-    
-    # decide if the requested action is allowed - check on the current counter value
-    action_allowed = true
-    if limit.limit_max
-      # (NULL in "limit_max" would mean unlimited allowance - not this case)
-      # deny the action if the "current_count" is equal / exceeded the "limit_max" value
-      action_allowed = false if (limit.current_count >= limit.limit_max)
-    end
-    
-    # update counter for the "current" action
-    if action_allowed && update_counter
-      limit.current_count += 1
-      limit_save_required = true
-    end
-    limit.save if limit_save_required # saves all changes (including counter resets, etc) if any were made
-    
-    # return if action is allowed / denied and when the next reset is going to be (nil for non-periodic counters) 
-    return [action_allowed, (limit.reset_after ? (limit.reset_after - time_now) : nil)]
-  end
-  
-  
   def formatted_timespan(time_period)
     # Takes a period of time in seconds and returns it in human-readable form (down to minutes)
     # from (http://www.postal-code.com/binarycode/category/devruby/)

Modified: branches/invitation_throttling/app/controllers/messages_controller.rb (2014 => 2015)


--- branches/invitation_throttling/app/controllers/messages_controller.rb	2008-11-28 17:10:15 UTC (rev 2014)
+++ branches/invitation_throttling/app/controllers/messages_controller.rb	2008-11-28 17:40:01 UTC (rev 2015)
@@ -81,7 +81,7 @@
         flash[:error] = "You cannot send a message to yourself"
         format.html { redirect_to new_message_url }
       end
-    elsif (allowed_plus_timespan = check_activity_limit(current_user, "internal_message", false))[0]
+    elsif (allowed_plus_timespan = ActivityLimit.check_limit(current_user, "internal_message", false))[0]
       # the user is allowed to send messages - limit not yet reached; show the new message screen 
       # (but the counter is not updated just yet - the user might not send the message after all,
       #  so this is a mere validation - which saves user from typing the message in and learning that
@@ -115,7 +115,7 @@
   # POST /messages
   def create
     # check if sending is allowed and increment the message counter
-    sending_allowed = check_activity_limit(current_user, "internal_message")[0]
+    sending_allowed = ActivityLimit.check_limit(current_user, "internal_message")[0]
     
     if sending_allowed
       @message = Message.new(params[:message])

Modified: branches/invitation_throttling/app/models/activity_limit.rb (2014 => 2015)


--- branches/invitation_throttling/app/models/activity_limit.rb	2008-11-28 17:10:15 UTC (rev 2014)
+++ branches/invitation_throttling/app/models/activity_limit.rb	2008-11-28 17:40:01 UTC (rev 2015)
@@ -1,2 +1,95 @@
 class ActivityLimit < ActiveRecord::Base
+  
+  # the single point in the application governing validation of all features that have
+  # limited allowance of usage (e.g. 5 messages a day, etc)
+  def self.check_limit(contributor, limit_feature, update_counter=true)
+    time_now = Time.now
+    limit_save_required = false
+    
+    if (limit = ActivityLimit.find(:first, :conditions => ["contributor_type = ? AND contributor_id = ? AND limit_feature = ?", contributor.class.name, contributor.id, limit_feature]))
+      # limit exists - check its validity
+      if (limit.limit_frequency && limit.reset_after && time_now > limit.reset_after)
+        # "reset_after" / "limit_frequency" are not NULL - so the limit is periodic;
+        # now it's the time to reset the counter to zero - no matter what its value was before
+        # (this will never be executed for non-periodic counters)
+        limit.current_count = 0
+        limit.reset_after = time_now + limit.limit_frequency.hours
+        limit_save_required = true
+
+        # also check if the contributor needs to be "promoted" to the next level --
+        # e.g. in the first month of membership on myExperiment one can send 10 messages daily,
+        # but after that can send 15 (because the user becomes more "trusted")
+        if (limit.promote_after && time_now > limit.promote_after)
+          absolute_max_limit_value = eval("#{limit_feature.upcase}_LIMIT_MAX_VALUE")
+          limit_increment_value = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_INCREMENT")
+          promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
+          
+          if limit_increment_value
+            if absolute_max_limit_value
+              # absolute max value set -->
+              # increase the limit only if not exceeded absolute maximum just yet
+              if (limit.limit_max < absolute_max_limit_value)
+                limit.limit_max += limit_increment_value
+                limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
+               else
+                # absolute maximum already reached / exceeded, disable further promotions
+                limit.promote_after = nil
+              end
+              
+              # make sure that it's not set to exceed the absolute maximum
+              # (which can happen if increment is not factor of the absolute maximum value)
+              if (limit.limit_max > absolute_max_limit_value)
+                limit.limit_max = absolute_max_limit_value
+              end
+            else
+              # absolute value not set --> simply increment
+              limit.limit_max += limit_increment_value
+              limit.promote_after = (promote_every ? (time_now + promote_every.days) : nil)
+            end
+          else 
+            # increment not set - this will be a one-time promotion
+            # (if the absolute max value is set - set limit to it; if not - the feature becomes unlimited)
+            limit.limit_max = absolute_max_limit_value
+            limit.promote_after = nil
+          end   
+        end # END of PROMOTION code
+        
+      end # END of COUNTER RESET code
+      
+    else
+      # limit doesn't exist yet - create it, then proceed to validation and saving
+      limit_frequency = eval("#{limit_feature.upcase}_LIMIT_FREQUENCY")
+      promote_every = eval("#{limit_feature.upcase}_LIMIT_PROMOTE_EVERY")
+      
+      limit = ActivityLimit.new(:contributor_type => contributor.class.name, :contributor_id => contributor.id,
+                                :limit_feature => limit_feature, 
+                                :limit_max => eval("#{limit_feature.upcase}_LIMIT_START_VALUE"),
+                                :limit_frequency => limit_frequency,
+                                :reset_after => (limit_frequency ? (time_now + limit_frequency.hours) : nil),
+                                :promote_after => (promote_every ? (time_now + promote_every.days) : nil),
+                                :current_count => 0)
+                                
+      limit_save_required = true
+    end
+    
+    
+    # decide if the requested action is allowed - check on the current counter value
+    action_allowed = true
+    if limit.limit_max
+      # (NULL in "limit_max" would mean unlimited allowance - not this case)
+      # deny the action if the "current_count" is equal / exceeded the "limit_max" value
+      action_allowed = false if (limit.current_count >= limit.limit_max)
+    end
+    
+    # update counter for the "current" action
+    if action_allowed && update_counter
+      limit.current_count += 1
+      limit_save_required = true
+    end
+    limit.save if limit_save_required # saves all changes (including counter resets, etc) if any were made
+    
+    # return if action is allowed / denied and when the next reset is going to be (nil for non-periodic counters) 
+    return [action_allowed, (limit.reset_after ? (limit.reset_after - time_now) : nil)]
+  end
+  
 end

reply via email to

[Prev in Thread] Current Thread [Next in Thread]