Created
December 9, 2016 04:51
-
-
Save ryanwang520/3c14f65f47a2f96836e536b55ec713e4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| """ | |
| 在`MessageTask`生成`ISOMessage`后,取出`IOSMessage`推送到apns,然后改变`IOSMessage`的状态 | |
| """ | |
| import concurrent | |
| import logging | |
| from concurrent.futures import ThreadPoolExecutor | |
| import multiprocessing | |
| from horo import Session | |
| from horo.models import commit | |
| from horo.models.message import IOSMessage, IOSPushError | |
| import time | |
| logger = logging.getLogger('horo.daemon.push_ios_message') | |
| def push_message(message): | |
| # try: | |
| message.push() | |
| # message.status = IOSMessage.STATUS_DELIVERED | |
| # commit() | |
| # except IOSPushError: | |
| # # push 失败了,状态改成FAIL, FAIL 的是可能要重试的 | |
| # message.status = IOSMessage.STATUS_FAIL | |
| # commit() | |
| # Session.rollback() | |
| # logger.exception('Fatal! some err occurs when pushing ios message!') | |
| def main(): | |
| """ | |
| 尽量跟踪消息推送的状态,SENDING 状态仅作参考, FAIL则是推送失败,考虑重试 | |
| """ | |
| while True: | |
| messages = IOSMessage.filter_by( | |
| send_in_background=True, status=IOSMessage.STATUS_UNPROCESSED).offset(0).limit( | |
| 50).all() | |
| if not messages: | |
| logger.info('No ios message to push, waiting for 200s till the next round...') | |
| # close session | |
| Session.rollback() | |
| time.sleep(200) | |
| continue | |
| logger.info('begin to push messages.') | |
| # 改为 sending 状态, 如果 push 成功(失败)之后 commit 失败,就一直是这个状态 | |
| for message in messages: | |
| message.status = IOSMessage.STATUS_SENDING | |
| commit() | |
| with ThreadPoolExecutor(max_workers=multiprocessing.cpu_count() * 5) as executor: | |
| result_future = {executor.submit(push_message, message): message.id for message in messages} | |
| # 需要在同一个thread commit | |
| success_ids = set() | |
| failed_ids = set() | |
| for future in concurrent.futures.as_completed(result_future): | |
| message_id = result_future[future] | |
| try: | |
| future.result() | |
| success_ids.add(message_id) | |
| logger.info('finish push message for {}'.format(message_id)) | |
| except IOSPushError: | |
| failed_ids.add(message_id) | |
| logger.exception('Fatal! some err occurs when pushing ios message!') | |
| except Exception: | |
| logger.exception('wtf') | |
| messages = IOSMessage.mget(success_ids | failed_ids) | |
| for message in messages: | |
| if message.id in success_ids: | |
| message.status = IOSMessage.STATUS_DELIVERED | |
| else: | |
| message.status = IOSMessage.STATUS_FAIL | |
| commit() | |
| logger.info('finish pushing messages.') | |
| if __name__ == '__main__': | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment