Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

50 lines
2.3KB

  1. import threading
  2. import time
  3. from wechatpy.client import WeChatClient
  4. from wechatpy.exceptions import APILimitedException
  5. from channel.wechatmp.common import *
  6. from common.log import logger
  7. class WechatMPClient(WeChatClient):
  8. def __init__(self, appid, secret, access_token=None, session=None, timeout=None, auto_retry=True):
  9. super(WechatMPClient, self).__init__(appid, secret, access_token, session, timeout, auto_retry)
  10. self.fetch_access_token_lock = threading.Lock()
  11. self.clear_quota_lock = threading.Lock()
  12. self.last_clear_quota_time = -1
  13. def clear_quota(self):
  14. return self.post("clear_quota", data={"appid": self.appid})
  15. def clear_quota_v2(self):
  16. return self.post("clear_quota/v2", params={"appid": self.appid, "appsecret": self.secret})
  17. def fetch_access_token(self): # 重载父类方法,加锁避免多线程重复获取access_token
  18. with self.fetch_access_token_lock:
  19. access_token = self.session.get(self.access_token_key)
  20. if access_token:
  21. if not self.expires_at:
  22. return access_token
  23. timestamp = time.time()
  24. if self.expires_at - timestamp > 60:
  25. return access_token
  26. return super().fetch_access_token()
  27. def _request(self, method, url_or_endpoint, **kwargs): # 重载父类方法,遇到API限流时,清除quota后重试
  28. try:
  29. return super()._request(method, url_or_endpoint, **kwargs)
  30. except APILimitedException as e:
  31. logger.error("[wechatmp] API quata has been used up. {}".format(e))
  32. if self.last_clear_quota_time == -1 or time.time() - self.last_clear_quota_time > 60:
  33. with self.clear_quota_lock:
  34. if self.last_clear_quota_time == -1 or time.time() - self.last_clear_quota_time > 60:
  35. self.last_clear_quota_time = time.time()
  36. response = self.clear_quota_v2()
  37. logger.debug("[wechatmp] API quata has been cleard, {}".format(response))
  38. return super()._request(method, url_or_endpoint, **kwargs)
  39. else:
  40. logger.error("[wechatmp] last clear quota time is {}, less than 60s, skip clear quota")
  41. raise e