Skip to content

Conversation

@dvdkon
Copy link

@dvdkon dvdkon commented Dec 17, 2025

Currently there can be multiple instances of MerginProject in memory that represent a single project (directory). This is an issue, because doing an operation on one instance will desync metadata in the others, which caused syncing to fail in db-sync.

This PR changes the MerginProject constructor to return the existing instance for a given directory, if one exists. It also bumps the library version, so I can make subsequent changes in db-sync.

# directory paths to instances.
# The dictionary is a WeakValueDictionary so we don't cause memory leaks
# (when the instance is GC'd, the entry is deleted).
project_cache: weakref.WeakValueDictionary[str, "MerginProject"] = {}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure if I understand... the type annotation is WeakValueDictionary - but doesn't project_cache become a normal dict if set it to {} ?

Copy link
Author

Choose a reason for hiding this comment

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

Thanks, that's just me being an idiot, sorry. Though I wonder why my IDE didn't complain...

I've force-pushed a fix, since it's just one line.

@dvdkon dvdkon force-pushed the project-single-instance branch from 0596d56 to 9ab77de Compare December 18, 2025 16:38
Copy link
Contributor

@MarcelGeo MarcelGeo left a comment

Choose a reason for hiding this comment

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

Hi @dvdkon , could you run tests with your version of code? You probably do not need to fork repo, instead of this -> use clone.

This is good idea to do it in this way. I'm wondering if this is not like 🩹 for buggy behavior in db-sync itself. In plugin are flying the MerginProject instances and no issues with that. Yeah, we could probably solve initialisation of Geodiff. @wonder-sk

return instance

instance = super().__new__(cls)
cls.project_cache[directory] = instance
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need to pass project_cache to class directly?

Copy link
Author

Choose a reason for hiding this comment

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

No, it's already there since it's defined as a class property. cls.project_cache here is equivalent to MerginProject.project_cache.

@dvdkon
Copy link
Author

dvdkon commented Dec 19, 2025

could you run tests with your version of code?

Sadly I don't have the right (non-trial) account to run tests on the dev instance.

I'm wondering if this is not like 🩹 for buggy behavior in db-sync itself. In plugin are flying the MerginProject instances and no issues with that.

We could probably work around the desync issues by just being careful in db-sync, but I think since it doesn't make sense to have multiple instances for one project, it's better to just ensure that it doesn't happen. It also makes sure no more bugs like this will appear in the future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants