+
+ /**
+ * If a base routes file path has been provided, we can load routes from it if the cache misses.
+ *
+ * @return array
+ * @throws HTTPException\InternalServerErrorException
+ */
+ private function getDispatchData()
+ {
+ $dispatchData = [];
+
+ if ($this->baseRoutesFilepath) {
+ $dispatchData = require $this->baseRoutesFilepath;
+ if (!is_array($dispatchData)) {
+ throw new HTTPException\InternalServerErrorException('Invalid base routes file');
+ }
+ }
+
+ $this->loadRoutes($dispatchData);
+
+ return $this->routeCollector->getData();
+ }
+
+ /**
+ * We cache the dispatch data for speed, as computing the current routes (version 2020.09)
+ * takes about 850ms for each requests.
+ *
+ * The cached "routerDispatchData" lasts for a day, and must be cleared manually when there
+ * is any changes in the enabled addons list.
+ *
+ * Additionally, we check for the base routes file last modification time to automatically
+ * trigger re-computing the dispatch data.
+ *
+ * @return array|mixed
+ * @throws HTTPException\InternalServerErrorException
+ */
+ private function getCachedDispatchData()
+ {
+ $routerDispatchData = $this->cache->get('routerDispatchData');
+ $lastRoutesFileModifiedTime = $this->cache->get('lastRoutesFileModifiedTime');
+ $forceRecompute = false;
+
+ if ($this->baseRoutesFilepath) {
+ $routesFileModifiedTime = filemtime($this->baseRoutesFilepath);
+ $forceRecompute = $lastRoutesFileModifiedTime != $routesFileModifiedTime;
+ }
+
+ if (!$forceRecompute && $routerDispatchData) {
+ return $routerDispatchData;
+ }
+
+ $routerDispatchData = $this->getDispatchData();
+
+ $this->cache->set('routerDispatchData', $routerDispatchData, Duration::DAY);
+ if (!empty($routesFileModifiedTime)) {
+ $this->cache->set('lastRoutesFileMtime', $routesFileModifiedTime, Duration::MONTH);
+ }
+
+ return $routerDispatchData;
+ }