structurizr / lite

Structurizr Lite
https://docs.structurizr.com/lite
MIT License
232 stars 28 forks source link

Layout json file getting reset #19

Closed mark-seesharp closed 1 year ago

mark-seesharp commented 1 year ago

Hi,

I've been using structurizr lite using docker via Windows Subsystem for Linux. It's generally been working really well, the one problem that I've had is regarding the json layout file. I don't tend to use autolayout, except for the most simple diagrams. For more complex diagrams I manually position the components on the diagram. However I've been finding that the layout file is getting frequently "reset" so that all of the diagram components get positioned back in the top left hand corner. I'm working around this by creating local git repos so that i can revert the json when it occurs but i'm ending up with lots of unnecessary local repos, and sometimes i forget to commit my changes. It typically seems to happens when I stop working on the diagram for a few hours and then go back to it.

Can you think what might be the cause? I was wondering whether it could be related to the running docker using WSL? My colleagues are all experiencing the same behaviour so I don't think its something specific/unusual to my setup.

Thanks, Mark

simonbrowndotje commented 1 year ago

Whenever you refresh Structurizr Lite, it will parse the workspace.dsl file and transform it into a workspace ... but that new workspace doesn't include any layout information, because it's not stored in the DSL. But the workspace.json file does. So Structurizr Lite will load the workspace.json file, and copy the layout information across into the newly created version (source). This is done via a pluggable merging algorithm in the Java library. This algorithm works most of the time, but doesn't cater for a number of edge cases unfortunately. In general, layout information can be lost when:

Much of this depends on how you're using the DSL. If you are not using stable keys for your views, that would be my first recommendation. So:

systemLandscape "MyViewKey" {
  include *
}

Rather than:

systemLandscape {
  include *
}
mark-seesharp commented 1 year ago

Thanks for the response, I've tried adding a key onto the views (I didn't have them before), but the diagram has just reset the view again. Must be something else going on!

I've read through the other scenarios and they don't apply either - nothing in the DSL file has been changed.

simonbrowndotje commented 1 year ago

but the diagram has just reset the view again.

Yes, the first time you set a view key, you will likely lose the diagram layout ... because the key will likely differ from that generated by the DSL parser. You should find the layout is retained from now onwards though.

mark-seesharp commented 1 year ago

I've set the key but unfortunately I'm still finding that I'm losing the diagram layout periodically. Can you think of anything else that i might be able to try?

simonbrowndotje commented 1 year ago

Perhaps you could explain your workflow?

My colleagues are all experiencing the same behaviour

Are you attempting to share a single Structurizr Lite container? Or are you collaborating on the same workspace with your own Structurizr Lite containers? If so, are you sure that everybody is updating to the latest version of the DSL+JSON before editing the workspace?

mark-seesharp commented 1 year ago

We're all running our own instance of Structurizr Lite locally via docker in wsl. In the majority of cases we haven't been collaborating on the same diagrams, the diagrams have been authored locally, untouched by anybody else and then get reset after not using them for a while (typically a few hours). Sometimes I've noticed that this happens after I've restarted wsl and docker. I'm not sure if it happens without the restart - i'll keep an eye on this.

mark-seesharp commented 1 year ago

Slightly more information - in the last few days i've noticed that this has only happened when i've restarted WSL. This happens quite regularly though as structurizr seems to stop working periodically and i have to restart WSL to get it going again. However, if i actively shutdown WSL (or even restart my laptop) then it correctly retains the json layout.

So perhaps its relating to the conditions that are causing structurizr to freeze. I'll keep an eye on it to see if this pattern continues...

simonbrowndotje commented 1 year ago

If you suspect it's related to WSL, you may want to try the non-Docker version -> https://structurizr.com/share/76352/documentation#spring-boot

Structurizr Lite is now fully open sourced, so you have the option to build from source (and debug) too.

mark-seesharp commented 1 year ago

I noticed that I got the following error logged at the same time as the json got corrupted:

[ERROR] 2023-02-06 10:44:36.152 [http-nio-8080-exec-179] ApacheLuceneSearchComponentImpl - java.nio.file.FileAlreadyExistsException: /usr/local/structurizr/.structurizr/index [ERROR] 2023-02-06 10:44:36.162 [http-nio-8080-exec-131] ApacheLuceneSearchComponentImpl - java.nio.file.NoSuchFileException: /usr/local/structurizr/.structurizr/index com.fasterxml.jackson.databind.JsonMappingException: Unexpected end-of-input in field name at [Source: (FileReader); line: 126, column: 21] (through reference chain: com.structurizr.Workspace["model"]->com.structurizr.model.Model["softwareSystems"]->java.util.HashSet[4]->com.structurizr.model.SoftwareSystem["relationships"]->java.util.HashSet[0]) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:392) at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:363) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:371) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28) at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer._deserializeFromArray(CollectionDeserializer.java:355) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:28) at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176) at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176) at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:323) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3642)

jplane commented 1 year ago

I have the same setup as @mark-seesharp:

And am seeing similar issues:

I'm frankly having trouble narrowing down to a concise reproducible sequence of steps, but use of the autoLayout button in the UI anecdotally seems to be part of the problem.

I've tried experimenting with autoSaveInterval setting to do either frequent autosaves (1000 ms) or no autosaves (0 ms)... I see the same issue in either case.

Very frustrating... I really like Structurizr and would love to use it with my team, but these usability nags make it currently a non-starter.

simonbrowndotje commented 1 year ago

Thank you @jplane ... yes, it's the auto-layout button that's causing the issue. I will put a fix together.

simonbrowndotje commented 1 year ago

I believe that build 2934 (being released now) will resolve this.

jplane commented 1 year ago

Awesome! Thanks for such a quick turnaround Simon... I'll give it a look later this afternoon and will report back. Cheers!

simonbrowndotje commented 1 year ago

Build 2934 is available.

Off-topic, but...

these usability nags make it currently a non-starter

If you have more "nags", feel free to open new issues ... if nobody mentions them, they won't get fixed. 😀

jplane commented 1 year ago

I can confirm that build 2934 appears to fix my issue. Thank you @simonbrowndotje!

And to be clear, this was the only usability issue I found after using Structurizr for several days... I appreciate the obvious amount of work you've invested.

Looking forward to piloting it with my team on an upcoming project!

simonbrowndotje commented 1 year ago

Thanks @jplane ... and over to you @mark-seesharp ... hopefully this is the cause of your issue too.

mark-seesharp commented 1 year ago

Unfortunately still seeing the issue after upgrading to the latest build. I think my issue is different to the issue experienced by @jplane, I've never lost the layout while I've been actively using structurizr, its always after a period of inactivity.

simonbrowndotje commented 1 year ago

As I said before, I'd give the non-Docker version a try. And if you have multiple Lite instances running during the day (for different workspaces, via the same exposed port), make sure that you're closing any browser windows, especially if you have auto-refresh enabled.

simonbrowndotje commented 1 year ago

Moving to discussion...