Skip to content
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

Refactor global state #486

Merged
merged 117 commits into from
Nov 12, 2021
Merged

Refactor global state #486

merged 117 commits into from
Nov 12, 2021

Conversation

liamhuber
Copy link
Member

@liamhuber liamhuber commented Oct 22, 2021

Awaiting #484.

I want to break apart the settings object so its responsibility is clearer and more limited in scope. This was already done by breaking database access stuff off it (I forget the PR but it's DatabaseManager). If we just do this, it means more and more imports, cf. Project which now depends on both the Settings and DatabaseManager. My solution is to make a new IDE state singlet helper class that acts as a single point of entry to all the other singlets (except maybe JobTypeChoice, which is anyhow on the chopping block).

Still TODO in this PR:

  • Fix ScriptJob error I introduced (at least that test is failing on my machine)
  • Further rationalisation of Settings
    • Under-the-hood improvements to read and overwrite configuration in a clear way User input > env > specified config > default config, all XOR merging on top of the code defaults
    • Streamline user-facing stuff to a configuration attribute and update method
    • Shift responsibility for constructing database framework-specific connection strings from the Settings over to DatabaseManager
  • Extract logger from Settings
  • Extract queue adapter from Settings
  • Extract publications from Settings
  • Add an update method to state which updates the configuration and reinitializes the database and queue adapter stuff.

Non-objectives for this PR:

  • Any further work on DatabaseManager or database/filetable stuff. For now that the manager singleton can stay where it is.
  • Advancing or polishing the publications stuff

And a bit of streamlining for handling the conda env resource paths
...now it seems to be working on Windows? But something else broke.
Also removed an old debug print I found in the archiving tests, which are, presumably, debugged.
And bask in the glory of having squashed a pain-in-the-ass OS-dependent test bug.
As far as I can tell the *only* place it was used was in the old tests
It doesn't seem to do anything.
The default file was always getting backed up, but previously if the test failed it never got restored.
Now that the settings singleton is not special, we only need one of them
Only leveraged it for the project so far. Also this introduced a bug in script jobs which are seeing weird settings, but someone it's *only* scriptjob that's having trouble
@liamhuber liamhuber added code_smell It's working, but something smells off enhancement New feature or request labels Oct 22, 2021
Ok, this is some deep magic I don't fully understand. Our Singletons are only single (if I understand) within a particular *python* instance. When I run the script job, it seems to be starting a *second* python instance with a *new* set of settings. I figured it out be changing the default behaviour to `project_check_enable=False` and seeing that it worked, but instead of messing with the defaults for now I'll just force the behaviour in the test.

So what's the deep magic about this? Well, for starters, if I run *only* the tests in `test_script.py` it works fine even without this patch, and it only fails when I run *all* the tests. This implies to me that script job is/isn't running on a new intpreter process depending where I start the tests from. Second, it worked *before*, so I have to assume that before it was somehow correctly reading the settings *even on this new python process*, and I really don't understand what I could have changed that stopped this from working.

My take home lesson is that we need to keep working on this corner of the code base, because we shouldn't be messing around with behaviour this complex, it's dangerous.
It would be a bit safer with @classmethod@property so these attributes couldn't get overwritten, but this is only possible in python >=3.9, and in the lower versions an equivalent implementation is hella ugly (https://stackoverflow.com/questions/128573/using-property-on-classmethods), so for now just live a little bit on the dangerous side.
@liamhuber liamhuber marked this pull request as ready for review November 3, 2021 14:19
@liamhuber liamhuber mentioned this pull request Nov 3, 2021
Copy link
Member

@max-hassani max-hassani left a comment

Choose a reason for hiding this comment

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

I could not go through all now, but I made some comments on the parts I viewed. I will look in more details later in the afternoon.

pyiron_base/database/manager.py Show resolved Hide resolved
pyiron_base/database/performance.py Outdated Show resolved Hide resolved
pyiron_base/project/generic.py Outdated Show resolved Hide resolved
pyiron_base/project/generic.py Outdated Show resolved Hide resolved
liamhuber and others added 9 commits November 4, 2021 09:02
Instead of raw values from settings. A very good catch from @muh-hassani's review!!!
# Conflicts:
#	pyiron_base/job/generic.py
I'm seeing info.log instead of pyiron.log files cropping up. I think this is because log messages were happening before the logger was configured. So now that happens right at the beginning of pyiron_base.
These must have slipped in during the merge, oops
@liamhuber
Copy link
Member Author

Last call for reviews. I had to resolve some merge conflicts earlier this week to keep this guy up-to-date...it didn't take long but I still don't want to have to do that again next week 😝 @niklassiemer @muh-hassani if you have concerns or really want some extra time to look at it lmk, otherwise I'll merge this evening.

Copy link
Member

@niklassiemer niklassiemer left a comment

Choose a reason for hiding this comment

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

Only some small comments/ general ideas for the future. LGTM!

pyiron_base/project/generic.py Outdated Show resolved Hide resolved
pyiron_base/state/__init__.py Show resolved Hide resolved
pyiron_base/state/publications.py Show resolved Hide resolved
pyiron_base/state/settings.py Show resolved Hide resolved
pyiron_base/state/settings.py Show resolved Hide resolved
Co-authored-by: Niklas Siemer <70580458+niklassiemer@users.noreply.github.com>
@liamhuber
Copy link
Member Author

Build windows latest for py 3.8 hung indefinitely -- >2hrs, the rest of the builds, including windows on 3.9, finished in <<15 minutes. I'm restarting the build tests.

@liamhuber
Copy link
Member Author

Build windows latest for py 3.8 hung indefinitely -- >2hrs, the rest of the builds, including windows on 3.9, finished in <<15 minutes. I'm restarting the build tests.

Must have been cosmic rays; it ran fine the second time.

@liamhuber liamhuber merged commit b78a9e9 into master Nov 12, 2021
@delete-merged-branch delete-merged-branch bot deleted the refactor_ide branch November 12, 2021 19:39
Copy link
Member

@max-hassani max-hassani left a comment

Choose a reason for hiding this comment

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

Sorry @liamhuber for the delay. Thanks for this careful refactory of the state. I just had one comment

@@ -952,7 +950,7 @@ def run_if_scheduler(self):
self._logger.warning("Job aborted")
self.status.aborted = True
raise ValueError("run_queue.sh crashed")
s.logger.debug("submitted %s", self.job_name)
state.logger.debug("submitted %s", self.job_name)
Copy link
Member

Choose a reason for hiding this comment

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

Here state.logger and self._logger are basically the same!

Copy link
Member

Choose a reason for hiding this comment

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

I guess self._logger is now redundant.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah yeah, up above we have self._logger = state.logger. I guess I was a little too much on autopilot doing the refactor. I would actually suggest to eliminate self._logger in a housekeeping PR later. The extra layer of misdirection is not necessary in the code base, and it's a private attribute anyhow so no one's notebooks should be accessing the logger this way anyhow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code_smell It's working, but something smells off enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants