<s> '''<STR_LIT>''' <EOL> from Queue import Empty <EOL> import time <EOL> import logging <EOL> from pushkin . database import database <EOL> from pushkin . sender . nordifier . apns_push_sender import APNsPushSender <EOL> from pushkin . sender . nordifier . gcm_push_sender import GCMPushSender <EOL> from pushkin . util . pool import ProcessPool <EOL> from pushkin import context <EOL> from pushkin import config <EOL> from pushkin . sender . nordifier import constants <EOL> class NotificationSender ( ProcessPool ) : <EOL> def __init__ ( self , num_workers ) : <EOL> ProcessPool . __init__ ( self , self . __class__ . __name__ , num_workers , config . sender_queue_limit ) <EOL> def limit_exceeded ( self , notification ) : <EOL> notification [ '<STR_LIT:status>' ] = constants . NOTIFICATION_SENDER_QUEUE_LIMIT <EOL> self . log_notifications ( [ notification ] ) <EOL> def queue_size ( self ) : <EOL> return self . task_queue . qsize ( ) <EOL> def log_notifications ( self , notifications ) : <EOL> main_logger = logging . getLogger ( config . main_logger_name ) <EOL> notification_logger = logging . getLogger ( config . notifications_logger_name ) <EOL> for notification in notifications : <EOL> try : <EOL> notification [ '<STR_LIT:content>' ] = notification [ '<STR_LIT:content>' ] . encode ( '<STR_LIT:utf-8>' ) . replace ( '<STR_LIT:U+002C>' , '<STR_LIT>' ) <EOL> keys = [ '<STR_LIT:status>' , '<STR_LIT>' , '<STR_LIT:content>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT:time>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> notification_logger . info ( '<STR_LIT:U+002C>' . join ( [ str ( notification [ key ] ) for key in keys ] ) ) <EOL> except : <EOL> main_logger . exception ( "<STR_LIT>" ) <EOL> class ApnNotificationSender ( NotificationSender ) : <EOL> def __init__ ( self ) : <EOL> NotificationSender . __init__ ( self , config . apn_num_processes ) <EOL> self . apn_sender_interval_sec = config . apn_sender_interval_sec <EOL> self . max_batch_size = config . sender_batch_size <EOL> def send_batch ( self , sender ) : <EOL> """<STR_LIT>""" <EOL> sent = [ ] <EOL> try : <EOL> for i in xrange ( self . max_batch_size ) : <EOL> notification = self . task_queue . get_nowait ( ) <EOL> sender . send_in_batch ( notification ) <EOL> sent . append ( notification ) <EOL> except Empty : <EOL> pass <EOL> sender . send_remaining ( ) <EOL> return sent <EOL> def process ( self ) : <EOL> main_logger = logging . getLogger ( config . main_logger_name ) <EOL> while True : <EOL> if self . queue_size ( ) > <NUM_LIT:0> : <EOL> sender = None <EOL> sent = [ ] <EOL> try : <EOL> sender = APNsPushSender ( config . config , main_logger ) <EOL> sent = self . send_batch ( sender ) <EOL> time . sleep ( self . apn_sender_interval_sec ) <EOL> except Exception : <EOL> main_logger . exception ( "<STR_LIT>" ) <EOL> finally : <EOL> if sender is not None : <EOL> sender . close_after_sending ( ) <EOL> self . log_notifications ( sent ) <EOL> else : <EOL> time . sleep ( self . apn_sender_interval_sec ) <EOL> class GcmNotificationSender ( NotificationSender ) : <EOL> def __init__ ( self ) : <EOL> NotificationSender . __init__ ( self , config . gcm_num_processes ) <EOL> def process ( self ) : <EOL> main_logger = logging . getLogger ( config . main_logger_name ) <EOL> while True : <EOL> notification = self . task_queue . get ( ) <EOL> try : <EOL> sender = GCMPushSender ( config . config , main_logger ) <EOL> sender . send_in_batch ( notification ) <EOL> canonical_ids = sender . get_canonical_ids ( ) <EOL> if len ( canonical_ids ) > <NUM_LIT:0> : <EOL> database . update_canonicals ( canonical_ids ) <EOL> unregistered_devices = sender . get_unregistered_devices ( ) <EOL> if len ( unregistered_devices ) > <NUM_LIT:0> : <EOL> database . update_unregistered_devices ( unregistered_devices ) <EOL> except Exception : <EOL> main_logger . exception ( "<STR_LIT>" ) <EOL> finally : <EOL> self . log_notifications ( [ notification ] ) </s>
