From 42e9a08c1b3ab06420da452a91c40af39f6ca00c Mon Sep 17 00:00:00 2001 From: Jean Date: Fri, 9 Jun 2023 20:51:21 +0200 Subject: [PATCH] cache type descriptors and media types (#145) Co-authored-by: jlabedo Co-authored-by: Dariusz Gafka --- .../Ecotone/src/Messaging/Conversion/MediaType.php | 7 ++++++- .../Processor/MethodInvoker/MethodInvoker.php | 2 +- .../src/Messaging/Handler/TypeDescriptor.php | 14 ++++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/packages/Ecotone/src/Messaging/Conversion/MediaType.php b/packages/Ecotone/src/Messaging/Conversion/MediaType.php index 90b4227a3..89244130c 100644 --- a/packages/Ecotone/src/Messaging/Conversion/MediaType.php +++ b/packages/Ecotone/src/Messaging/Conversion/MediaType.php @@ -36,6 +36,8 @@ final class MediaType private const TYPE_PARAMETER = 'type'; + private static array $parsedMediaTypes = []; + private string $type; private string $subtype; /** @@ -184,6 +186,9 @@ public static function createWithParameters(string $type, string $subtype, array */ public static function parseMediaType(string $mediaType): self { + if (isset(self::$parsedMediaTypes[$mediaType])) { + return self::$parsedMediaTypes[$mediaType]; + } $parsedMediaType = explode('/', $mediaType); Assert::keyExists($parsedMediaType, 0, "Passed media type {$mediaType} has no type"); @@ -196,7 +201,7 @@ public static function parseMediaType(string $mediaType): self $parameters[$parameter[0]] = $parameter[1]; } - return self::createWithParameters($parsedMediaType[0], $subtype, $parameters); + return self::$parsedMediaTypes[$mediaType] = self::createWithParameters($parsedMediaType[0], $subtype, $parameters); } /** diff --git a/packages/Ecotone/src/Messaging/Handler/Processor/MethodInvoker/MethodInvoker.php b/packages/Ecotone/src/Messaging/Handler/Processor/MethodInvoker/MethodInvoker.php index 4e03b8a5f..399ebed34 100644 --- a/packages/Ecotone/src/Messaging/Handler/Processor/MethodInvoker/MethodInvoker.php +++ b/packages/Ecotone/src/Messaging/Handler/Processor/MethodInvoker/MethodInvoker.php @@ -256,7 +256,7 @@ public function getMethodCall(Message $message): MethodCall )) { $convertedData = $this->doConversion($this->interfaceToCall, $interfaceParameter, $data, $sourceTypeDescriptor, $currentParameterMediaType, $parameterType, $parameterMediaType); } elseif ($message->getHeaders()->containsKey(MessageHeaders::TYPE_ID)) { - $resolvedTargetParameterType = $message->getHeaders()->containsKey(MessageHeaders::TYPE_ID) ? TypeDescriptor::create($message->getHeaders()->get(MessageHeaders::TYPE_ID)) : $parameterType; + $resolvedTargetParameterType = TypeDescriptor::create($message->getHeaders()->get(MessageHeaders::TYPE_ID)); if ($this->canConvertParameter( $sourceTypeDescriptor, $currentParameterMediaType, diff --git a/packages/Ecotone/src/Messaging/Handler/TypeDescriptor.php b/packages/Ecotone/src/Messaging/Handler/TypeDescriptor.php index ec3065a89..c9ae2ca55 100644 --- a/packages/Ecotone/src/Messaging/Handler/TypeDescriptor.php +++ b/packages/Ecotone/src/Messaging/Handler/TypeDescriptor.php @@ -45,6 +45,8 @@ final class TypeDescriptor implements Type public const MIXED = 'mixed'; public const NULL = 'null'; + private static array $cache = []; + private string $type; private static function resolveCollectionTypes(string $foundCollectionTypes): array @@ -163,6 +165,10 @@ public function isCompatibleWith(Type $toCompare): bool return false; } + if (is_a($this->type, $toCompare->getTypeHint(), true)) { + return true; + } + if ($this->isAnything() || $toCompare->isAnything()) { return true; } @@ -173,7 +179,7 @@ public function isCompatibleWith(Type $toCompare): bool if (! $this->isScalar() && $toCompare->isScalar()) { if ($this->isClassOrInterface()) { - if ($this->equals(TypeDescriptor::create(TypeDescriptor::OBJECT))) { + if ($this->isCompoundObjectType()) { return false; } @@ -256,6 +262,10 @@ public static function isItTypeOfExistingClassOrInterface(string $typeHint): boo private static function initialize(?string $typeHint, ?string $docBlockTypeDescription): Type { + $cacheKey = $typeHint . ':' . $docBlockTypeDescription; + if (isset(self::$cache[$cacheKey])) { + return self::$cache[$cacheKey]; + } $resolvedType = []; foreach (self::resolveType($typeHint)->getUnionTypes() as $declarationType) { if ($declarationType->isIterable() && ! $declarationType->isCollection() && $docBlockTypeDescription) { @@ -280,7 +290,7 @@ private static function initialize(?string $typeHint, ?string $docBlockTypeDescr } } - return UnionTypeDescriptor::createWith($resolvedType); + return self::$cache[$cacheKey] = UnionTypeDescriptor::createWith($resolvedType); } /**