| 
					
				 | 
			
			
				@@ -172,7 +172,8 @@ class Component(StartStopComponent): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 pool=w.pool, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 timer=w.timer, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 app=w.app, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                controller=w) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                controller=w, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                use_eventloop=w.use_eventloop) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -303,7 +304,7 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def __init__(self, ready_queue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             init_callback=noop, send_events=False, hostname=None, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             initial_prefetch_count=2, pool=None, app=None, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            timer=None, controller=None, **kwargs): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            timer=None, controller=None, use_eventloop=False, **kwargs): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.app = app_or_default(app) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.connection = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.task_consumer = None 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -318,6 +319,7 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.heart = None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.pool = pool 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.timer = timer or timer2.default_timer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.use_eventloop = use_eventloop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         pidbox_state = AttributeDict(app=self.app, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      hostname=self.hostname, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      listener=self,     # pre 2.2 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -332,7 +334,7 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._does_info = logger.isEnabledFor(logging.INFO) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.strategies = {} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if self.use_eventloop: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.hub = Hub(self.priority_timer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.hub = Hub(self.timer) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def update_strategies(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         S = self.strategies 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -360,11 +362,10 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def consume_messages(self, sleep=sleep, min=min, Empty=Empty): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Consume messages forever (or until an exception is raised).""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.task_consumer.consume() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        debug("Ready to accept tasks!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         with self.hub as hub: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             qos = self.qos 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            concurrency = self.pool.num_processes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             update_qos = qos.update 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             update_fds = hub.update 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             fdmap = hub.fdmap 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -373,8 +374,34 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             scheduled = hub.timer._queue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             transport = self.connection.transport 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             on_poll_start = transport.on_poll_start 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            self.task_consumer.callbacks.append(fire_timers) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            strategies = self.strategies 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            buffer = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            def flush_buffer(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                for name, body, message in buffer: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        strategies[name](message, body, message.ack_log_error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    except KeyError, exc: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.handle_unknown_task(body, message, exc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    except InvalidTaskError, exc: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        self.handle_invalid_task(body, message, exc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                buffer[:] = [] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            def on_task_received(body, message): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    name = body["task"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                except (KeyError, TypeError): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return self.handle_unknown_message(body, message) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #    strategies[name](message, body, message.ack_log_error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #except KeyError, exc: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #    self.handle_unknown_task(body, message, exc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #except InvalidTaskError, exc: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #    self.handle_invalid_task(body, message, exc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                buffer.append((name, body, message)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if len(buffer) >= concurrency * 10: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    flush_buffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                #fire_timers() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             update_fds(self.connection.eventmap, self.pool.eventmap) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for handler, interval in self.pool.timers.iteritems(): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -389,6 +416,10 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self.pool.on_process_down = on_process_down 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             transport.on_poll_init(hub.poller) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.task_consumer.callbacks = [on_task_received] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.task_consumer.consume() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            debug("Ready to accept tasks!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             while self._state != CLOSE and self.connection: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 # shutdown if signal handlers told us to. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -406,6 +437,7 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 update_fds(on_poll_start()) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if fdmap: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    #for timeout in (time_to_sleep, 0.1, 0.1): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     for fileno, event in poll(time_to_sleep) or (): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             fdmap[fileno](fileno, event) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -414,8 +446,10 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         except socket.error: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                             if self._state != CLOSE:        # pragma: no cover 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                 raise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    if buffer: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        flush_buffer() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    sleep(min(time_to_sleep, 1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    sleep(min(time_to_sleep, 0.1)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def on_task(self, task): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Handle received task. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -424,7 +458,6 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         otherwise we move it the ready queue for immediate processing. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if task.revoked(): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -477,6 +510,18 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      safe_repr(message.content_encoding), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                                      safe_repr(message.delivery_info)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def handle_unknown_message(self, body, message): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn(UNKNOWN_FORMAT, self._message_report(body, message)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message.reject_log_error(logger, self.connection_errors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def handle_unknown_task(self, body, message, exc): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error(UNKNOWN_TASK_ERROR, exc, safe_repr(body), exc_info=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message.reject_log_error(logger, self.connection_errors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def handle_invalid_task(self, body, message, exc): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error(INVALID_TASK_ERROR, str(exc), safe_repr(body), exc_info=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        message.reject_log_error(logger, self.connection_errors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def receive_message(self, body, message): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Handles incoming messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -487,18 +532,14 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             name = body["task"] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         except (KeyError, TypeError): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            warn(UNKNOWN_FORMAT, self._message_report(body, message)) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            message.reject_log_error(logger, self.connection_errors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return self.handle_unknown_message(body, message) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         try: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             self.strategies[name](message, body, message.ack_log_error) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         except KeyError, exc: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            error(UNKNOWN_TASK_ERROR, exc, safe_repr(body), exc_info=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            message.reject_log_error(logger, self.connection_errors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.handle_unknown_task(body, message, exc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         except InvalidTaskError, exc: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            error(INVALID_TASK_ERROR, str(exc), safe_repr(body), exc_info=True) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            message.reject_log_error(logger, self.connection_errors) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            self.handle_invalid_task(body, message, exc) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def maybe_conn_error(self, fun): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Applies function but ignores any connection or channel 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -646,9 +687,6 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.qos = QoS(self.task_consumer, self.initial_prefetch_count) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.qos.update() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        # receive_message handles incoming messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        self.task_consumer.register_callback(self.receive_message) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Setup the process mailbox. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.reset_pidbox_node() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -747,7 +785,10 @@ class Consumer(object): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class BlockingConsumer(Consumer): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def consume_messages(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # receive_message handles incoming messages. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        self.task_consumer.register_callback(self.receive_message) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.task_consumer.consume() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         debug("Ready to accept tasks!") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         while self._state != CLOSE and self.connection: 
			 |