Last active
October 5, 2018 10:26
-
-
Save assada/06da4018d45130cf2b9194ea5409b1f0 to your computer and use it in GitHub Desktop.
OpenTracing ProxyManager
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
| <?php | |
| declare(strict_types = 1); | |
| namespace SignNow\Core\OpenTracing; | |
| use PDFfiller\OpenTracing\Span\SpanInterface; | |
| use PDFfiller\OpenTracing\Tag\StringTag; | |
| use PDFfiller\OpenTracing\TracerBridgeInterface; | |
| use ProxyManager\Factory\AccessInterceptorScopeLocalizerFactory as Factory; | |
| use ReflectionException; | |
| use Zend\Code\Reflection\ClassReflection; | |
| use Zend\Code\Reflection\MethodReflection; | |
| /** | |
| * Class ProxyManager | |
| * | |
| * @package SignNow\Core\OpenTracing | |
| */ | |
| class ProxyManager implements ProxyManagerInterface | |
| { | |
| /** | |
| * @var Factory | |
| */ | |
| private $factory; | |
| /** | |
| * @var TracerBridgeInterface | |
| */ | |
| private $tracer; | |
| /** | |
| * @var SpanInterface[] | |
| */ | |
| private $spanCache = []; | |
| /** | |
| * @var array | |
| */ | |
| private $reflection = []; | |
| /** | |
| * @var array | |
| */ | |
| private $ignore; | |
| /** | |
| * ProxyManager constructor. | |
| * | |
| * @param Factory $factory | |
| * @param TracerBridgeInterface $tracer | |
| */ | |
| public function __construct(Factory $factory, TracerBridgeInterface $tracer, array $ignore = []) | |
| { | |
| $this->factory = $factory; | |
| $this->tracer = $tracer; | |
| $this->ignore = $ignore; | |
| } | |
| /** | |
| * @param object $object | |
| * | |
| * @return ClassReflection | |
| * @throws ReflectionException | |
| */ | |
| private function getClassReflection($object): ClassReflection | |
| { | |
| $class = \get_class($object); | |
| if (!array_key_exists($class, $this->reflection)) { | |
| $this->reflection[$class] = new ClassReflection($object); | |
| } | |
| return $this->reflection[$class]; | |
| } | |
| /** | |
| * @param $object | |
| * | |
| * @return MethodReflection[] | |
| * @throws ReflectionException | |
| */ | |
| private function getMethods($object): array | |
| { | |
| $reflect = $this->getClassReflection($object); | |
| return $reflect->getMethods(); | |
| } | |
| /** | |
| * @param object $object | |
| * | |
| * @return string | |
| * @throws ReflectionException | |
| */ | |
| private function getClassName($object): string | |
| { | |
| $reflect = $this->getClassReflection($object); | |
| return $reflect->getName(); | |
| } | |
| /** | |
| * @param object $object | |
| * | |
| * @return string | |
| * @throws ReflectionException | |
| */ | |
| private function getClassFile($object): string | |
| { | |
| $reflect = $this->getClassReflection($object); | |
| return $reflect->getDeclaringFile()->getFileName(); | |
| } | |
| /** | |
| * @param object $object | |
| * @param string $methodName | |
| * | |
| * @return string | |
| */ | |
| private function getSpanCacheName($object, string $methodName): string | |
| { | |
| return spl_object_hash($object) . '::' . $methodName; | |
| } | |
| /** | |
| * @param object $object | |
| * @param callable $callback | |
| * | |
| * @return array | |
| * @throws ReflectionException | |
| */ | |
| private function getAction($object, string $stage): array | |
| { | |
| $methods = $this->getMethods($object); | |
| $className = $this->getClassName($object); | |
| $callbacks = []; | |
| foreach ($methods as $method) { | |
| $methodName = $method->getName(); | |
| if (\in_array($className . '::' . $methodName, $this->ignore, true)) { | |
| continue; | |
| } | |
| $callbacks[$methodName] = call_user_func_array( | |
| [$this, $stage . 'Callback'], | |
| [$methodName, $className, $object] | |
| ); | |
| } | |
| return $callbacks; | |
| } | |
| /** | |
| * @param string $methodName | |
| * @param string $className | |
| * @param object $object | |
| * | |
| * @return callable | |
| */ | |
| private function beforeCallback(string $methodName, string $className, $object): callable | |
| { | |
| return function () use ($methodName, $className, $object) { | |
| $spanCacheName = $this->getSpanCacheName($object, $methodName); | |
| $this->spanCache[$spanCacheName] = $this->tracer->start($className . '::' . $methodName) | |
| ->addTag(new StringTag('file', $this->getClassFile($object))) | |
| ->addTag(new StringTag('class', $className)) | |
| ->addTag(new StringTag('method', $methodName)); | |
| }; | |
| } | |
| /** | |
| * @return callable | |
| */ | |
| private function afterCallback(string $methodName, string $className, $object): callable | |
| { | |
| return function () use ($methodName, $className, $object) { | |
| $spanCacheName = $this->getSpanCacheName($object, $methodName); | |
| if (array_key_exists($spanCacheName, $this->spanCache)) { | |
| $this->spanCache[$spanCacheName]->finish(); | |
| } | |
| }; | |
| } | |
| /** | |
| * @param object $object | |
| * | |
| * @return object | |
| * @throws ReflectionException | |
| */ | |
| public function proxy($object) | |
| { | |
| return $this->factory->createProxy( | |
| $object, | |
| $this->getAction($object, ProxyManagerInterface::BEFORE_ACTION), | |
| $this->getAction($object, ProxyManagerInterface::AFTER_ACTION) | |
| ); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment