PageRenderTime 21ms CodeModel.GetById 10ms app.highlight 6ms RepoModel.GetById 1ms app.codeStats 0ms

/framework/vendor/swift/lib/classes/Swift/Transport/LoadBalancedTransport.php

http://zoop.googlecode.com/
PHP | 188 lines | 93 code | 20 blank | 75 comment | 8 complexity | 85af76b41b15cdf54b4f6ef8e10d24a1 MD5 | raw file
  1<?php
  2
  3/*
  4 * This file is part of SwiftMailer.
  5 * (c) 2004-2009 Chris Corbyn
  6 *
  7 * For the full copyright and license information, please view the LICENSE
  8 * file that was distributed with this source code.
  9 */
 10
 11//@require 'Swift/Transport.php';
 12//@require 'Swift/Mime/Message.php';
 13//@require 'Swift/Events/EventListener.php';
 14
 15/**
 16 * Redudantly and rotationally uses several Transports when sending.
 17 * 
 18 * @package Swift
 19 * @subpackage Transport
 20 * @author Chris Corbyn
 21 */
 22class Swift_Transport_LoadBalancedTransport implements Swift_Transport
 23{
 24  
 25  /** Transports which are deemed useless */
 26  private $_deadTransports = array();
 27  
 28  /**
 29   * The Transports which are used in rotation.
 30   * 
 31   * @var array Swift_Transport
 32   * @access protected
 33   */
 34  protected $_transports = array();
 35  
 36  /**
 37   * Creates a new LoadBalancedTransport.
 38   */
 39  public function __construct()
 40  {
 41  }
 42  
 43  /**
 44   * Set $transports to delegate to.
 45   * 
 46   * @param array $transports Swift_Transport
 47   */
 48  public function setTransports(array $transports)
 49  {
 50    $this->_transports = $transports;
 51    $this->_deadTransports = array();
 52  }
 53  
 54  /**
 55   * Get $transports to delegate to.
 56   * 
 57   * @return array Swift_Transport
 58   */
 59  public function getTransports(array $transports)
 60  {
 61    return array_merge($this->_transports, $this->_deadTransports);
 62  }
 63  
 64  /**
 65   * Test if this Transport mechanism has started.
 66   * 
 67   * @return boolean
 68   */
 69  public function isStarted()
 70  {
 71    return count($this->_transports) > 0;
 72  }
 73  
 74  /**
 75   * Start this Transport mechanism.
 76   */
 77  public function start()
 78  {
 79    $this->_transports = array_merge($this->_transports, $this->_deadTransports);
 80  }
 81  
 82  /**
 83   * Stop this Transport mechanism.
 84   */
 85  public function stop()
 86  {
 87    foreach ($this->_transports as $transport)
 88    {
 89      $transport->stop();
 90    }
 91  }
 92  
 93  /**
 94   * Send the given Message.
 95   * 
 96   * Recipient/sender data will be retreived from the Message API.
 97   * The return value is the number of recipients who were accepted for delivery.
 98   * 
 99   * @param Swift_Mime_Message $message
100   * @param string[] &$failedRecipients to collect failures by-reference
101   * @return int
102   */
103  public function send(Swift_Mime_Message $message, &$failedRecipients = null)
104  {
105    $maxTransports = count($this->_transports);
106    $sent = 0;
107    
108    for ($i = 0; $i < $maxTransports
109      && $transport = $this->_getNextTransport(); ++$i)
110    {
111      try
112      {
113        if (!$transport->isStarted())
114        {
115          $transport->start();
116        }
117        if ($sent = $transport->send($message, $failedRecipients))
118        {
119          break;
120        }
121      }
122      catch (Swift_TransportException $e)
123      {
124        $this->_killCurrentTransport();
125      }
126    }
127    
128    if (count($this->_transports) == 0)
129    {
130      throw new Swift_TransportException(
131        'All Transports in LoadBalancedTransport failed, or no Transports available'
132        );
133    }
134    
135    return $sent;
136  }
137  
138  /**
139   * Register a plugin.
140   * 
141   * @param Swift_Events_EventListener $plugin
142   */
143  public function registerPlugin(Swift_Events_EventListener $plugin)
144  {
145    foreach ($this->_transports as $transport)
146    {
147      $transport->registerPlugin($plugin);
148    }
149  }
150  
151  // -- Protected methods
152  
153  /**
154   * Rotates the transport list around and returns the first instance.
155   * 
156   * @return Swift_Transport
157   * @access protected
158   */
159  protected function _getNextTransport()
160  {
161    if ($next = array_shift($this->_transports))
162    {
163      $this->_transports[] = $next;
164    }
165    return $next;
166  }
167  
168  /**
169   * Tag the currently used (top of stack) transport as dead/useless.
170   * 
171   * @access protected
172   */
173  protected function _killCurrentTransport()
174  {
175    if ($transport = array_pop($this->_transports))
176    {
177      try
178      {
179        $transport->stop();
180      }
181      catch (Exception $e)
182      {
183      }
184      $this->_deadTransports[] = $transport;
185    }
186  }
187  
188}