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

Move Interface Definitions to the ServerContainer #3901

Merged
merged 9 commits into from
Mar 21, 2017
Merged

Conversation

rullzer
Copy link
Member

@rullzer rullzer commented Mar 17, 2017

Followup of #3897
Implementation of #2043 (comment)

This should allow us to the interface defintions to the servercontainer. So we don't duplicate everything for each App.

@mention-bot
Copy link

@rullzer, thanks for your PR! By analyzing the history of the files in this pull request, we identified @BernhardPosselt, @MorrisJobke and @nickvergessen to be potential reviewers.

@@ -79,7 +79,7 @@ public function query($name) {
$segments = explode('\\', $name);
$appContainer = $this->getAppContainer(strtolower($segments[1]));
try {
return $appContainer->query($name);
return $appContainer->query($name, false);
Copy link
Member

Choose a reason for hiding this comment

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

Why is the false here needed? Shouldn't it try the server container from the app container and done?

Copy link
Member Author

Choose a reason for hiding this comment

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

To avoid possible endless loops. Like if you request a non existing class.

Copy link
Member

Choose a reason for hiding this comment

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

Is there a way to maybe fix this by overriding the method in the server container instead?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is in the servercontainer. The thing is that once we call the query method of the servercontainer we don't know which container called that.

Copy link
Member

Choose a reason for hiding this comment

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

ok, lol my bad :D

Copy link
Member

Choose a reason for hiding this comment

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

Ah right, i mean the method above which is defined in the DIContainer

Copy link
Member

Choose a reason for hiding this comment

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

Ah got it, the inerhitance hierarchy is borked. The DIContainer is the base container for apps, however the server container also uses it.

Then I'd say simply subclass it and replace it here: https://github.com/nextcloud/server/blob/master/lib/public/AppFramework/App.php#L68

@rullzer rullzer added 3. to review Waiting for reviews and removed 2. developing Work in progress labels Mar 19, 2017
@rullzer
Copy link
Member Author

rullzer commented Mar 19, 2017

So 1 thing I did think of is:

Assume that in the server there is a registeredService Foo that wants a service Bar Injected.

Now if an app myApp overwrites Bar and wants Foo injected. Then that will not happen with this code. Since when looking for Foo we no longer search for Bar in the apps container.

Mmmm. let me set this back to develop to think some more.

@rullzer rullzer added 2. developing Work in progress and removed 3. to review Waiting for reviews labels Mar 19, 2017
@rullzer
Copy link
Member Author

rullzer commented Mar 19, 2017

I'll see if I can come up with some tests to check the behavior we want. Should make discussing a bit easier.

@@ -79,7 +79,7 @@ public function query($name) {
$segments = explode('\\', $name);
$appContainer = $this->getAppContainer(strtolower($segments[1]));
try {
return $appContainer->query($name);
return $appContainer->query($name, false);
Copy link
Member

Choose a reason for hiding this comment

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

ok, lol my bad :D

@@ -79,7 +79,7 @@ public function query($name) {
$segments = explode('\\', $name);
$appContainer = $this->getAppContainer(strtolower($segments[1]));
try {
return $appContainer->query($name);
return $appContainer->query($name, false);
Copy link
Member

Choose a reason for hiding this comment

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

Ah right, i mean the method above which is defined in the DIContainer

@@ -79,7 +79,7 @@ public function query($name) {
$segments = explode('\\', $name);
$appContainer = $this->getAppContainer(strtolower($segments[1]));
try {
return $appContainer->query($name);
return $appContainer->query($name, false);
Copy link
Member

Choose a reason for hiding this comment

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

Ah got it, the inerhitance hierarchy is borked. The DIContainer is the base container for apps, however the server container also uses it.

Then I'd say simply subclass it and replace it here: https://github.com/nextcloud/server/blob/master/lib/public/AppFramework/App.php#L68

try {
return parent::query($name);
} catch (QueryException $e) {
if ($checkServerContainer === false) {
Copy link
Member

Choose a reason for hiding this comment

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

if (strpos(OC\App::buildAppNamespace($this->query('AppName')), $name) !== 0) {
    return $this->getServer()->query($name);
}

Copy link
Member

Choose a reason for hiding this comment

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

Only forwards the request to the server container if the classes lie somewhere else. If you swap out interfaces from the server in your own container it wont hit the server container since you don't hit the catch block

try {
return parent::query($name);
} catch (QueryException $e) {
if ($checkServerContainer === false) {
Copy link
Member

Choose a reason for hiding this comment

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

Only forwards the request to the server container if the classes lie somewhere else. If you swap out interfaces from the server in your own container it wont hit the server container since you don't hit the catch block

@codecov-io
Copy link

codecov-io commented Mar 19, 2017

Codecov Report

Merging #3901 into master will decrease coverage by 0.01%.
The diff coverage is 98.85%.

@@             Coverage Diff              @@
##             master    #3901      +/-   ##
============================================
- Coverage     54.28%   54.27%   -0.02%     
- Complexity    21147    21156       +9     
============================================
  Files          1304     1304              
  Lines         80805    80793      -12     
  Branches       1282     1282              
============================================
- Hits          43867    43852      -15     
- Misses        36938    36941       +3
Impacted Files Coverage Δ Complexity Δ
lib/private/Server.php 92.96% <100%> (+0.17%) 120 <1> (ø) ⬇️
...e/AppFramework/DependencyInjection/DIContainer.php 82.97% <96.15%> (-6.13%) 25 <3> (+9)
lib/private/Security/CertificateManager.php 93.81% <0%> (+1.03%) 38% <0%> (ø) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fd0e42e...92f50c7. Read the comment docs.

.htaccess Outdated
#### DO NOT CHANGE ANYTHING ABOVE THIS LINE ####

ErrorDocument 403 /core/templates/403.php
ErrorDocument 404 /core/templates/404.php
Copy link
Member

Choose a reason for hiding this comment

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

😱

Copy link
Member Author

Choose a reason for hiding this comment

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

yeah yeah fixed. It just still sucks that I can't just do a git commit -a because I ran the testsuite.

@@ -477,7 +494,7 @@ public function __construct($webRoot, \OC\Config $config) {
$this->registerService('CredentialsManager', function (Server $c) {
return new CredentialsManager($c->getCrypto(), $c->getDatabaseConnection());
});
$this->registerService('DatabaseConnection', function (Server $c) {
$this->registerService(IDBConnection::class, function (Server $c) {
Copy link
Member

Choose a reason for hiding this comment

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

Needs adjustments in the unit tests as well

\OC::$server->registerService('DatabaseConnection', function () {

Copy link
Member

Choose a reason for hiding this comment

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

PS its multiple times.

@rullzer rullzer force-pushed the di_ng branch 5 times, most recently from 6c92710 to 38068ed Compare March 20, 2017 15:56
@BernhardPosselt
Copy link
Member

Looks good I think 👍

@MorrisJobke
Copy link
Member

@rullzer Could you have a look why that many integration tests fail?

@rullzer
Copy link
Member Author

rullzer commented Mar 21, 2017

@MorrisJobke yes on it. It is because doing it half isn't going to work ;)

To align with #2043 (comment)
This would mean that AppContainers only hold the AppSpecific services

Signed-off-by: Roeland Jago Douma <[email protected]>
Signed-off-by: Roeland Jago Douma <[email protected]>
Signed-off-by: Roeland Jago Douma <[email protected]>
* Moved some interface definitions to Server.php (more to come)
* Build/Query only for existing classes in the AppContainer
* Build/Query only for classes of the App in the AppContainer
* Offload other stuff to the servercontainer

Signed-off-by: Roeland Jago Douma <[email protected]>
Signed-off-by: Roeland Jago Douma <[email protected]>
Signed-off-by: Roeland Jago Douma <[email protected]>
Signed-off-by: Roeland Jago Douma <[email protected]>
@LukasReschke LukasReschke merged commit 04f419b into master Mar 21, 2017
@LukasReschke LukasReschke deleted the di_ng branch March 21, 2017 10:06
@icewind1991
Copy link
Member

icewind1991 commented Mar 21, 2017

💥 causes infinite recursion in DI for me 💥

@icewind1991
Copy link
Member

Seems to be caused by apps where there namespace is not equal to their app id (files_automatedtagging vs \OCA\FilesAutomatedTagging)

@rullzer
Copy link
Member Author

rullzer commented Mar 21, 2017

@icewind1991 mmm fuck. yeah of course that could happen. Let me fix a PR for that. I think we have a way around it.

rullzer added a commit that referenced this pull request Mar 21, 2017
As stated in #3901 (comment)
appid's don't have to match the namespace.

Work around this

Signed-off-by: Roeland Jago Douma <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants