Package restkit :: Package ext :: Module eventlet_pool
[hide private]
[frames] | no frames]

Source Code for Module restkit.ext.eventlet_pool

  1  # -*- coding: utf-8 - 
  2  # 
  3  # This file is part of restkit released under the MIT license.  
  4  # See the NOTICE for more information. 
  5   
  6  from __future__ import with_statement 
  7   
  8  import collections 
  9  import eventlet 
 10  from eventlet import queue 
 11  from eventlet.timeout import Timeout 
 12   
 13  from restkit.pool import PoolInterface 
 14  from restkit import sock 
 15   
16 -class _Host(object):
17
18 - def __init__(self, address):
19 self._addr = address 20 self.pool = queue.LightQueue(0) 21 self.free_connections = collections.deque() 22 self.nb_connections = 0
23
24 - def waiting(self):
25 return max(0, self.pool.getting() - self.pool.putting())
26
27 -class EventletPool(PoolInterface):
28 """ 29 Eventlet pool to manage connections. after a specific timeout the 30 sockets are closes. Default timeout is 300s. 31 32 To use restkit with eventlet:: 33 34 >>> import eventlet 35 >>> eventlet.monkey_patch(all=False, socket=True) 36 >>> from restkit import request 37 >>> from restkit.ext.eventlet_pool import EventletPool 38 >>> pool = EventletPool(max_connections=5) 39 >>> r = request('http://friendpaste.com', pool_instance=pool) 40 41 """ 42
43 - def __init__(self, max_connections=4, timeout=300):
44 """ Initialize EventletPool 45 46 :param max_connexions: int, number max of connections in the pool. 47 Default is 4 48 :param timeout: int, number max of second a connection is kept alive. 49 Default is 300s. 50 """ 51 self.max_connections = max_connections 52 self.timeout = 60 53 self.hosts = {} 54 self.sockets = {}
55
56 - def get(self, address):
57 """ Get connection for (Host, Port) address 58 :param address: tuple (Host, address) 59 """ 60 61 host = self.hosts.get(address) 62 if not host: 63 return None 64 if host.free_connections: 65 socket = host.free_connections.popleft() 66 eventlet.spawn(self._remove_socket, socket) 67 return socket 68 if host.nb_connections < self.max_connections: 69 host.nb_connections += 1 70 return None 71 socket = host.pool.get() 72 eventlet.spawn(self._remove_socket, socket) 73 return socket
74
75 - def _monitor_socket(self, fn):
76 """ function used to monitor the socket """ 77 with Timeout(self.timeout, False): 78 if fn in self.sockets: 79 socket = self.sockets[fn] 80 sock.close(socket) 81 del self.sockets[fn]
82
83 - def monitor_socket(self, socket):
84 self.sockets[socket.fileno()] = socket 85 eventlet.spawn(self._monitor_socket, socket.fileno())
86
87 - def put(self, address, socket):
88 """ release socket in the pool 89 90 :param address: tuple (Host, address) 91 :param socket: a socket object 92 """ 93 host = self.hosts.get(address) 94 if not host: 95 host = _Host(address) 96 97 if host.nb_connections > self.max_connections: 98 sock.close(socket) 99 host.nb_connections -= 1 100 101 elif host.waiting(): 102 host.pool.put(socket) 103 self.monitor_socket(socket) 104 else: 105 host.free_connections.append(socket) 106 self.monitor_socket(socket)
107 108
109 - def clean(self, address):
110 """ close all sockets in the pool for this address 111 112 :param address: tuple (Host, address) 113 """ 114 host = self.hosts.get(address) 115 if not host: 116 return 117 if host.free_connections: 118 while host.free_connections: 119 socket = host.free_connections.popleft() 120 sock.close(socket) 121 while host.nb_connections: 122 socket = host.pool.get() 123 sock.close(socket) 124 host.nb_connections -= 1
125