Skip to content

Conversation

@maximveksler
Copy link

The code will fail on attempting to lock the workspace, a feature which is not supported on the free tier.

This PR introduces logic to cope with that by attempting to derive if the user is running on a free tier, in which case the failure should not be considered fatal.

Would appreciate help to test if it's working for the paid tier as well before merging.

@Midnighter
Copy link
Owner

Hi @maximveksler,

Thank you for the contribution. Maybe there are multiple approaches to take here:

  1. I had hoped that it was clear from the docs that using a context is not necessary at all. You can just call .get and .put which will not attempt to lock the workspace. So the docs clearly need improvement.
  2. @yt-ms previously suggested changing the way that a context is entered which should also make it more clear that the purpose of the context is to lock the workspace.

I favour a solution as proposed by @yt-ms that includes logic as you propose here. That means, ignoring the lock if on a free plan (with a warning) and only raising an exception if (un-)locking fails on a paid plan.

@maximveksler
Copy link
Author

@Midnighter kudos on the implemention quality. A pleasure to read your code.

On the topic of free / paid -

I think that exception behaviour should be consistent between the plans.

I.e. warn on lock and unlock on the free.
And error on lock fail and unlock failure on paid.

It's not super clear why the locking is required in the 1st if a merge strategy is implements, but that's a different topic.

What happens if you attempt to unlock an unlocked workspace? I believe that should not be an error as it's idempotent with no side effects.

Thoughts?

@Midnighter
Copy link
Owner

It's not super clear why the locking is required in the 1st if a merge strategy is implements, but that's a different topic.

As far as I'm aware, no merge strategy is implemented on the Structurizr API side but @simonbrowndotje and team are constantly adding new features so I might have missed that. Allowing multi-tenancy via something like CRDT would be a very exciting feature 😃 but it would probably mean starting over for the backend.

I have thought about implementing a diff on the client side. So whenever a user calls .put, it would internally get the remote workspace and then display a diff with maybe an interactive confirmation for overwriting the remote workspace. One could expand on this. However, the general strategy for architecture as code would be to have everything checked into version control so that you can always generate your workspace from scratch. That means, git should take care of conflicts for teamwork and thus there is no need on the API side to handle this.

The diff display plus confirmation is not a lot of work, though, so that could be implemented.

What happens if you attempt to unlock an unlocked workspace? I believe that should not be an error as it's idempotent with no side effects.

Indeed the response from the API is always success.

@simonbrowndotje
Copy link

It's not super clear why the locking is required in the 1st if a merge strategy is implements, but that's a different topic.

The workspace locking mechanism is a pessimistic approach to concurrency, and only needed for paid plans where workspaces can be shared using the role-based access mechanism. For free plans, there's no need to lock/unlock.

@simonbrowndotje
Copy link

As far as I'm aware, no merge strategy is implemented on the Structurizr API side

Correct, all workspace merging (of manual layout information) is done client-side ... it's a more flexible approach, and users can customise the merging algorithm if desired.

The diff display plus confirmation is not a lot of work, though, so that could be implemented.

I started work on a semantic workspace diff engine for the CLI and it's not particularly straightforward. 😀 I will resurrect this at some point though.

@Midnighter
Copy link
Owner

I started work on a semantic workspace diff engine for the CLI and it's not particularly straightforward. grinning I will resurrect this at some point though.

I was thinking of a cheap way where I would use an existing tool to just do a JSON diff of the serialized workspaces. Probably not always the most intelligible output but better than nothing 🤷🏼‍♂️ Do you see difficulties with that, too, @simonbrowndotje?

@simonbrowndotje
Copy link

I tried a number of JSON diff tools myself, and even integrated a couple as a basis for my diff engine - they're very noisy, and usually don't give good results when the ordering of elements changes between versions, etc.

@yt-ms
Copy link
Collaborator

yt-ms commented Apr 27, 2021

I tried a number of JSON diff tools myself, and even integrated a couple as a basis for my diff engine - they're very noisy, and usually don't give good results when the ordering of elements changes between versions, etc.

I actually have an approach that I've been using on a small scale that seems to work well. I have some Python code built on top of this library that will output a workspace in C4 DSL, but with deterministic ordering. The DSL is very good for being human-readable as well as system-readable, and once you sort out the ordering problem then a standard diff tool is remarkably effective.

@maximveksler
Copy link
Author

Thanks for the discussion guys, indeed worth consideration.

@simonbrowndotje I believe it could be an interesting approach (as well as useful dog food) to open source the design of
structurizr.com using well.. structurizr.com. Would be interested in your thoughts on this? This might allow further discussion on issues such as the above (i.e. lock and merge strategies).

Regarding this PR, what fixes are required, or should this be merged?

@simonbrowndotje
Copy link

simonbrowndotje commented Apr 28, 2021

Diagrams for the cloud service and on-premises installation are linked to from the Structurizr help page. What's the purpose of the PR though ... are you building some tooling on top of the Python library? If not, you don't need to call lock and unlock from your Python program if you're using a free workspace.

@Midnighter
Copy link
Owner

Regarding this PR, what fixes are required, or should this be merged?

As mentioned I would like to combine this with #62. I can do so later today, unless you're very keen on taking this on?

What's the purpose of the PR though ... are you building some tooling on top of the Python library? If not, you don't need to call lock and unlock from your Python program if you're using a free workspace.

One problem that I need to correct is that the current example for uploading workspaces uses the context and thus locking.


return self._paid_plan(response), response.success

def unlock_workspace(self) -> bool:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return type needs updating to reflect the new values returned.

)
return response.success

return self._paid_plan(response), response.success
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Return type of the method needs updating to match

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also be tempted to put the success first as it's the more significant of the two values.

@yt-ms
Copy link
Collaborator

yt-ms commented Apr 28, 2021

In terms of the overall approach, it feels a bit odd for the lock and unlock methods to be returning a paid_plan flag. Can this be ascertained when the workspace is initially fetched so it is then just a property on StructurizrClient rather than having to return it from lock/unlock?

@yt-ms
Copy link
Collaborator

yt-ms commented May 3, 2021

I've now incorporated handling lock errors on free plans into PR #74 which also does the syntax changes for issue #62.

@Midnighter
Copy link
Owner

Thank you for your contribution @maximveksler. I'm closing this one.

@Midnighter Midnighter closed this May 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants