From 19648b2f7139f16a564e32113673bcbc92b6873e Mon Sep 17 00:00:00 2001 From: Dirk Groot Date: Fri, 8 Sep 2023 11:17:53 +0200 Subject: [PATCH] Keep a thread safe in-memory cache of generated diagrams with links This should fix the error reported in #279. --- .../site/generatr/site/DiagramGenerator.kt | 31 +++++++++---------- .../site/generatr/site/SiteGenerator.kt | 2 +- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/DiagramGenerator.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/DiagramGenerator.kt index 355fe28c..50f2d2c1 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/DiagramGenerator.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/DiagramGenerator.kt @@ -10,8 +10,10 @@ import net.sourceforge.plantuml.FileFormat import net.sourceforge.plantuml.FileFormatOption import net.sourceforge.plantuml.SourceStringReader import nl.avisi.structurizr.site.generatr.site.C4PlantUmlExporterWithElementLinks.Companion.export +import java.io.ByteArrayOutputStream import java.io.File import java.net.URL +import java.util.concurrent.ConcurrentHashMap fun generateDiagrams(workspace: Workspace, exportDir: File) { val pumlDir = pumlDir(exportDir) @@ -34,22 +36,19 @@ fun generateDiagrams(workspace: Workspace, exportDir: File) { } } -fun generateDiagramWithElementLinks(workspace: Workspace, view: View, url: String, exportDir: File): String { - val pumlDir = pumlDir(exportDir) - val svgDir = svgDir(exportDir) +private val diagramCache = ConcurrentHashMap() +fun generateDiagramWithElementLinks(workspace: Workspace, view: View, url: String): String { val diagram = generatePlantUMLDiagramWithElementLinks(workspace, view, url) val name = "${diagram.key}-${view.key}" - val plantUMLFile = File(pumlDir, "$name.puml") - if (!plantUMLFile.exists() || plantUMLFile.readText() != diagram.definition) { - saveAsSvg(diagram, svgDir, name) - saveAsPUML(diagram, plantUMLFile) - } else { - println("$name UP-TO-DATE") - } + return diagramCache.getOrPut(name) { + val reader = SourceStringReader(diagram.withCachedIncludes().definition) + val stream = ByteArrayOutputStream() - return readSvg(svgDir, name) + reader.outputImage(stream, FileFormatOption(FileFormat.SVG, false)) + stream.toString(Charsets.UTF_8) + } } private fun generatePlantUMLDiagrams(workspace: Workspace): Collection { @@ -80,16 +79,14 @@ private fun saveAsPng(diagram: Diagram, pngDir: File) { } } -private fun readSvg(svgDir: File, name: String): String { - val svgFile = File(svgDir, "$name.svg") - return svgFile.readText() -} - private fun generatePlantUMLDiagramWithElementLinks(workspace: Workspace, view: View, url: String): Diagram { val plantUMLExporter = C4PlantUmlExporterWithElementLinks(url) if (workspace.views.configuration.properties.containsKey("generatr.svglink.target")) { - plantUMLExporter.addSkinParam("svgLinkTarget", workspace.views.configuration.properties.getValue("generatr.svglink.target")) + plantUMLExporter.addSkinParam( + "svgLinkTarget", + workspace.views.configuration.properties.getValue("generatr.svglink.target") + ) } return plantUMLExporter.export(view) diff --git a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/SiteGenerator.kt b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/SiteGenerator.kt index 8bbfa91b..6909c745 100644 --- a/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/SiteGenerator.kt +++ b/src/main/kotlin/nl/avisi/structurizr/site/generatr/site/SiteGenerator.kt @@ -60,7 +60,7 @@ fun generateSite( ) { val generatorContext = GeneratorContext(version, workspace, branches, currentBranch, serving) { key, url -> workspace.views.views.singleOrNull { view -> view.key == key } - ?.let { generateDiagramWithElementLinks(workspace, it, url, exportDir) } + ?.let { generateDiagramWithElementLinks(workspace, it, url) } } val branchDir = File(exportDir, currentBranch)