TYPO3 API  SVNRelease
ThrottlerPlugin.php
Go to the documentation of this file.
00001 <?php
00002 
00003 /*
00004  * This file is part of SwiftMailer.
00005  * (c) 2004-2009 Chris Corbyn
00006  *
00007  * For the full copyright and license information, please view the LICENSE
00008  * file that was distributed with this source code.
00009  */
00010 
00011 //@require 'Swift/Events/SendEvent.php';
00012 //@require 'Swift/Plugins/BandwidthMonitorPlugin.php';
00013 //@require 'Swift/Plugins/Sleeper.php';
00014 //@require 'Swift/Plugins/Timer.php';
00015 
00016 /**
00017  * Throttles the rate at which emails are sent.
00018  * @package Swift
00019  * @subpackage Plugins
00020  * @author Chris Corbyn
00021  */
00022 class Swift_Plugins_ThrottlerPlugin
00023   extends Swift_Plugins_BandwidthMonitorPlugin
00024   implements Swift_Plugins_Sleeper, Swift_Plugins_Timer
00025 {
00026 
00027   /** Flag for throttling in bytes per minute */
00028   const BYTES_PER_MINUTE = 0x01;
00029 
00030   /** Flag for throttling in emails per minute */
00031   const MESSAGES_PER_MINUTE = 0x10;
00032 
00033   /**
00034    * The Sleeper instance for sleeping.
00035    * @var Swift_Plugins_Sleeper
00036    * @access private
00037    */
00038   private $_sleeper;
00039 
00040   /**
00041    * The Timer instance which provides the timestamp.
00042    * @var Swift_Plugins_Timer
00043    * @access private
00044    */
00045   private $_timer;
00046 
00047   /**
00048    * The time at which the first email was sent.
00049    * @var int
00050    * @access private
00051    */
00052   private $_start;
00053 
00054   /**
00055    * The rate at which messages should be sent.
00056    * @var int
00057    * @access private
00058    */
00059   private $_rate;
00060 
00061   /**
00062    * The mode for throttling.
00063    * This is {@link BYTES_PER_MINUTE} or {@link MESSAGES_PER_MINUTE}
00064    * @var int
00065    * @access private
00066    */
00067   private $_mode;
00068 
00069   /**
00070    * An internal counter of the number of messages sent.
00071    * @var int
00072    * @access private
00073    */
00074   private $_messages = 0;
00075 
00076   /**
00077    * Create a new ThrottlerPlugin.
00078    * @param int $rate
00079    * @param int $mode, defaults to {@link BYTES_PER_MINUTE}
00080    * @param Swift_Plugins_Sleeper $sleeper (only needed in testing)
00081    * @param Swift_Plugins_Timer $timer (only needed in testing)
00082    */
00083   public function __construct($rate, $mode = self::BYTES_PER_MINUTE,
00084     Swift_Plugins_Sleeper $sleeper = null, Swift_Plugins_Timer $timer = null)
00085   {
00086     $this->_rate = $rate;
00087     $this->_mode = $mode;
00088     $this->_sleeper = $sleeper;
00089     $this->_timer = $timer;
00090   }
00091 
00092   /**
00093    * Invoked immediately before the Message is sent.
00094    * @param Swift_Events_SendEvent $evt
00095    */
00096   public function beforeSendPerformed(Swift_Events_SendEvent $evt)
00097   {
00098     $time = $this->getTimestamp();
00099     if (!isset($this->_start))
00100     {
00101       $this->_start = $time;
00102     }
00103     $duration = $time - $this->_start;
00104 
00105     if (self::BYTES_PER_MINUTE == $this->_mode)
00106     {
00107       $sleep = $this->_throttleBytesPerMinute($duration);
00108     }
00109     else
00110     {
00111       $sleep = $this->_throttleMessagesPerMinute($duration);
00112     }
00113 
00114     if ($sleep > 0)
00115     {
00116       $this->sleep($sleep);
00117     }
00118   }
00119 
00120   /**
00121    * Invoked when a Message is sent.
00122    * @param Swift_Events_SendEvent $evt
00123    */
00124   public function sendPerformed(Swift_Events_SendEvent $evt)
00125   {
00126     parent::sendPerformed($evt);
00127     ++$this->_messages;
00128   }
00129 
00130   /**
00131    * Sleep for $seconds.
00132    * @param int $seconds
00133    */
00134   public function sleep($seconds)
00135   {
00136     if (isset($this->_sleeper))
00137     {
00138       $this->_sleeper->sleep($seconds);
00139     }
00140     else
00141     {
00142       sleep($seconds);
00143     }
00144   }
00145 
00146   /**
00147    * Get the current UNIX timestamp
00148    * @return int
00149    */
00150   public function getTimestamp()
00151   {
00152     if (isset($this->_timer))
00153     {
00154       return $this->_timer->getTimestamp();
00155     }
00156     else
00157     {
00158       return time();
00159     }
00160   }
00161 
00162   // -- Private methods
00163 
00164   /**
00165    * Get a number of seconds to sleep for.
00166    * @param int $timePassed
00167    * @return int
00168    * @access private
00169    */
00170   private function _throttleBytesPerMinute($timePassed)
00171   {
00172     $expectedDuration = $this->getBytesOut() / ($this->_rate / 60);
00173     return (int) ceil($expectedDuration - $timePassed);
00174   }
00175 
00176   /**
00177    * Get a number of seconds to sleep for.
00178    * @param int $timePassed
00179    * @return int
00180    * @access private
00181    */
00182   private function _throttleMessagesPerMinute($timePassed)
00183   {
00184     $expectedDuration = $this->_messages / ($this->_rate / 60);
00185     return (int) ceil($expectedDuration - $timePassed);
00186   }
00187 
00188 }