UdpSocketAspect.php 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * This file is part of Hyperf.
  5. *
  6. * @link https://www.hyperf.io
  7. * @document https://hyperf.wiki
  8. * @contact group@hyperf.io
  9. * @license https://github.com/hyperf/hyperf/blob/master/LICENSE
  10. */
  11. namespace Hyperf\Logger\Aspect;
  12. use Hyperf\Coroutine\Coroutine;
  13. use Hyperf\Di\Aop\AbstractAspect;
  14. use Hyperf\Di\Aop\ProceedingJoinPoint;
  15. use Monolog\Handler\SyslogUdp\UdpSocket;
  16. use Socket;
  17. use WeakMap;
  18. /**
  19. * @property null|Socket $socket
  20. */
  21. class UdpSocketAspect extends AbstractAspect
  22. {
  23. public array $classes = [
  24. UdpSocket::class . '::getSocket',
  25. ];
  26. public static WeakMap $coSockets;
  27. public function __construct()
  28. {
  29. self::$coSockets = new WeakMap();
  30. }
  31. public function process(ProceedingJoinPoint $proceedingJoinPoint)
  32. {
  33. if (! Coroutine::inCoroutine()) {
  34. return $proceedingJoinPoint->process();
  35. }
  36. $instance = $proceedingJoinPoint->getInstance();
  37. if (isset(self::$coSockets[$instance]) && self::$coSockets[$instance] instanceof Socket) {
  38. return self::$coSockets[$instance];
  39. }
  40. return self::$coSockets[$instance] = (function () use ($proceedingJoinPoint) {
  41. $nonCoSocket = $this->socket; // Save the socket of non-coroutine.
  42. $this->socket = null; // Unset the socket of non-coroutine.
  43. $coSocket = $proceedingJoinPoint->process(); // ReCreate the socket in coroutine.
  44. $this->socket = $nonCoSocket; // Restore the socket of non-coroutine.
  45. return $coSocket;
  46. })->call($instance);
  47. }
  48. }