-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Do not completely synchronize read-only modules and models #154
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
c6c6512
to
cea1f14
Compare
14a7dd2
to
6c71d69
Compare
…ly models and modules
8a8c9be
to
2e65f87
Compare
2e65f87
to
0e8be13
Compare
to avoid a serializer not found exception at runtime
…eparate method because we have to do some more checks and steps than just simply creating the MPSModelImportReference
…eference otherwise the reference cannot be serialized
…any time Track if the ResolvableModelImport has been resolved (i.e. synced to the cloud) and if so then remove it from the pending this. This way, we can sync model imports directly after they were added to the model.
…he cache Because they may change behind-the-scenes without any warning. As a consequence, they will not be found in the cache as keys, even though they did not change. (MODELIX-787)
…iceLocator so the MPS Repository is always directly accessible and we do not have to go to the MPS Project first
… mappings from the cache, when the corresponding ModelImport, ModuleDependency, LanguageDependency, DevKitDependency is removed
mhuster23
reviewed
Sep 30, 2024
...ain/kotlin/org/modelix/mps/sync/transformation/modelixToMps/transformers/ModelTransformer.kt
Outdated
Show resolved
Hide resolved
...c/main/kotlin/org/modelix/mps/sync/transformation/mpsToModelix/initial/ModuleSynchronizer.kt
Outdated
Show resolved
Hide resolved
...c/main/kotlin/org/modelix/mps/sync/transformation/mpsToModelix/initial/ModuleSynchronizer.kt
Outdated
Show resolved
Hide resolved
...c/main/kotlin/org/modelix/mps/sync/transformation/mpsToModelix/initial/ModuleSynchronizer.kt
Outdated
Show resolved
Hide resolved
mps-sync-plugin-lib/src/main/kotlin/org/modelix/mps/sync/mps/factories/SNodeFactory.kt
Outdated
Show resolved
Hide resolved
...lin/org/modelix/mps/sync/transformation/modelixToMps/incremental/ModelixTreeChangeVisitor.kt
Outdated
Show resolved
Hide resolved
...rc/main/kotlin/org/modelix/mps/sync/transformation/mpsToModelix/initial/ModelSynchronizer.kt
Outdated
Show resolved
Hide resolved
...c/main/kotlin/org/modelix/mps/sync/transformation/cache/MpsToModelixMapInitializerVisitor.kt
Outdated
Show resolved
Hide resolved
mhuster23
approved these changes
Sep 30, 2024
🎉 This PR is included in version 0.9.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In the followings, the term "cloud" can be interchangeably used with "modelix model server".
Problem
Sometimes our users would like to refer to SNodes in their models, which are not part of their Project, but are coming from SModels in pre-installed plugins.
So far such referred SNodes were synched to the cloud with their full structure (properties, refereces, and their children recursively). Moreover, their parent SModel / SModules were also synched to the cloud completely (including all model imports, module dependencies, language dependencies, content, etc). Synching all those elements recursively to the cloud is an exhaustive task, especially if the transitive Module Dependencies are built in a way, that basically the whole application has to be synched.
As an example, imagine an MPS-based application, where the user just includes the root SModule in a DevKit (that are coming from pre-installed plugins) and this root SModule transitively includes all sub-modules the application is composed of. If the user puts a Module Dependency or a DevKit dependency for this SModule inside their Project, then all SModules will be synched to the cloud, which can be very exhaustive.
Solution
Since the aformentioned SNodes, SModels and SModules are coming from pre-installed plugins, they are read-only by default (thanks to MPS). It means, that since their structure cannot be changed, we do not have to replicate them in the cloud, but we could just save some "special references" (c.f. MPSNodeReference, MPSModelImportReference) for them which say that these elements are in MPS and we persist their MPS-based references in the cloud. It means, that when those elements are downloaded from the cloud, then we just resolve them locally in MPS, because we assume that they exist (since they are coming from the pre-installed plugins).
It simplifies the implementation a lot as we can see in the followings:
References for read-only SNodes
If an SNode 'A' refers to a read-only SNode 'B', then we create a serialized MPSNodeReference, which includes the MPS-based node reference (identifier). We put this serialized reference in a NodeReference, that is used as the Reference Target in the cloud.
When such reference arrives from the cloud, then we decide if the serialized reference refers to an INode (because INode references can be also serialized) or to an MPS-node. If it refers to an INode, then we fetch that node and transform it to an SNode (just like before). If it refers to an MPS-node, then we resolve that node locally in MPS. (For details see lines 94-111 in ModelixTreeChangeVisitor.)
Model imports for read-only SModels
If an SModel 'C' imports a read-only SModel 'D', then we create a serialized MPSModelImportReference, which includes the MPS-based model reference (identifier). We put this serialized reference in a NodeReference, that is used as the Reference Target in the cloud.
When such model import arrives from the cloud, then we decide if the serialized reference refers to an INode or to an SModel in MPS. If it refers to an INode, then we fetch that node and create a ResolvableModelImport from it (because the referred model might not have been transformed yet; just like before). If it refers to an SModel in MPS, then we resolve that SModel locally. For details see lines 163-186 in ModelTransformer.
Module dependencies for read-only SModules
If an SModule 'E' puts a dependency on a read-only SModule 'F', then not too much changes. Read-only SModules will not be transformed to INodes (see lines 149-154 in ModuleSynchronizer), but only the ModuleDependency will be created. The ModuleDependency has a UUID field which contains the UUID of the read-only SModule. There is an extra
isReadOnly
property in the ModuleDependency, that is set to true if the target SModule ('F') is read-only.Note that the
isReadOnly
property is an extra, that is not part of the original ModuleDependency Concept definition. However, it does not cause any problems, even if someone uses the generated API for this Concept. That's because the generated API ignores those properties and references that are not part of the definition and can therefore transform the INode to TypedNode (N_ModuleDependency), even if it has some extra properties in its property store.When such module dependency arrives from the cloud, then we check if its
isReadOnly
property is true. If it is true, then we do not try to transform the target module from INode to SModule, because we know that it must exist in MPS. Instead, we just simply create the ModuleDependency in MPS like before. For details, see lines 164-171 in ModuleTransformer (where we skip the target module transformation if the module dependency is read-only), and lines 213-220 in Module Transformer (where we create the Module Dependency in MPS, just like before).Languages and DevKits
Languages and DevKits are not synched to the cloud, only the SimpleLanguageDependency and the DevKitDepepdency are created. Nothing changed here, even though Languages and DevKits are also read-only.
Read-only SModels and SModules
Testing
I tested the code manually in the following way:
isReadOnly
property was set to true.To test the change detection from the cloud (i.e. when something changes in the cloud, then this change must also appear locally), I implemented some pieces of kotlin code in a separate intelliJ, that could do the following actions separately, when they are run:
In a separate MPS, I had the aforementioned SModule, SModel opened which was my test example. In intelliJ, I ran the aforementioned actions separately (one-by-one) and in MPS I observed in debug mode if the changes were correctly executed in the ModelixTreeChangeVisitor (that is responsible for handling changes from modelix into MPS) and the effects appeared in MPS as expected. If there was some mismatch then I fixed the code an reran the manual test scenarios until no bugs remained.
During testing, I discovered some corner-cases that I forgot to fix earlier:
Auxiliary information