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

Optimize resolveGroupShare #27434

Merged
merged 1 commit into from
Mar 23, 2017
Merged

Optimize resolveGroupShare #27434

merged 1 commit into from
Mar 23, 2017

Conversation

mrow4a
Copy link
Contributor

@mrow4a mrow4a commented Mar 20, 2017

This optimizes the case in which you do PROPFIND to some folder, in which you had group share, and that share was moved to another folder (generaly people reorganise stuff from root folder to their required folders)

  • Unit tests
  • Verify integration tests

selection_100
Below is what happens when you move file testgrshare.txt which has some group shares receiver/send to another folder and then propfind the "old" root folder:
selection_098

@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 20, 2017

@DeepDiver1975 @SergioBertolinSG @PVince81 Do we have integration for this scenario of moving group share to other folder, group share folder, fed share whatever?

Unit test cover the changes already.

@PVince81 PVince81 added this to the 10.0 milestone Mar 21, 2017
* Resolve a group share to a user specific share
* Thus if the user moved their group share make sure this is properly reflected here.
* Resolve a group shares to a user specific share.
* Returns in the array both the updated share if one was found and for not found in DB passing predicate, the original shares.
Copy link
Contributor

Choose a reason for hiding this comment

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

mind clarifying what you mean with "updated share" and "original share" ?

Do you mean that "original share" is the actual group share and "updated share" is the user-specific special entry ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm, ok, I should say resolved :>

Copy link
Member

Choose a reason for hiding this comment

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

an the line is too long - 80 chars please

@SergioBertolinSG
Copy link
Contributor

@mrow4a There are quite a few int. tests about sharing, perhaps the test you are looking for is this one https://github.com/owncloud/core/blob/master/tests/integration/features/sharing-v1.feature#L522 .

If you miss some specific case, please tell me / open a ticket in QA repo.

* Resolve a group share to a user specific share
* Thus if the user moved their group share make sure this is properly reflected here.
* Resolve a group shares to a user specific share.
* Returns in the array both the updated share if one was found and for not found in DB passing predicate, the original shares.
Copy link
Member

Choose a reason for hiding this comment

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

an the line is too long - 80 chars please

$qb = $this->dbConn->getQueryBuilder();

$stmt = $qb->select('*')
$shareParentIds = array_keys($parentIdToShareMap);
Copy link
Member

Choose a reason for hiding this comment

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

chunk to 1000 max?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point

@mrow4a mrow4a force-pushed the optimize_resolvegroupshare branch 2 times, most recently from bb6291e to 63b95a4 Compare March 21, 2017 12:52
->setMaxResults(1)
->execute();
$shareParentIds = [];
$parentIdToShareMap = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

Rename to shareIdToShareMap or simply sharesMap ? Because it seems that's what it is.
It can of course be used to resolve parents but that's only one possibility
The "parent" bit confused me.

))
->setMaxResults(1)
->execute();
$shareParentIds = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

I have trouble understanding the chunking part, it seems this array stores chunks so call it something with "chunk" in its name. See comment below to possibly avoid saying "parent".

} else {
$shareNo++;
}
$shareParentIds[$chunkId][] = $parentId;
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain the chunking part with code comments ?

It seems it's basically just building a chunked array of share ids ?
The "parent" part in the name makes it more confusing, I suggest removing it.

$parentId is just $shareId.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, it just optimised for this case array_chunk, avoiding unnecessary loops.

@PVince81
Copy link
Contributor

@mrow4a code looks good. Took me a while due to the variable names confusing me.
Please adjust.

@mrow4a mrow4a force-pushed the optimize_resolvegroupshare branch from 63b95a4 to 1b4520c Compare March 21, 2017 16:53
$shareIdToShareMap = [];
$chunkId = 0;
$shareNo = 0;
foreach($shares as $share) {
Copy link
Member

Choose a reason for hiding this comment

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

Move this to another function so we can unittest it?

Copy link
Contributor Author

@mrow4a mrow4a Mar 22, 2017

Choose a reason for hiding this comment

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

TO unit tests it is to have >100 shares

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

This part of code involves chunking the shares list, which isn't related to the DB access that the rest of the function perform. That another reason to extract this piece out.

Copy link
Contributor Author

@mrow4a mrow4a Mar 22, 2017

Choose a reason for hiding this comment

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

I have no idea what you want to achieve here, I need to contruct $shareIdToShareMap and $chunkedShareIds, and this is what the loop is doing. I need that to avoid unnecesairly loops over shares

Copy link
Member

Choose a reason for hiding this comment

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

I need to contruct $shareIdToShareMap and $chunkedShareIds

My point is that another private function could take care of the chunking in order to make this function to focus on fetching the data from the DB. It's fine if this function calls the "chunking function" and then fetch the data.

Copy link
Contributor Author

@mrow4a mrow4a Mar 22, 2017

Choose a reason for hiding this comment

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

This function would need to return 2 arrays...

Copy link
Contributor Author

@mrow4a mrow4a Mar 22, 2017

Choose a reason for hiding this comment

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

Ok, will try it and see how it looks like. I get your point.

Copy link
Contributor Author

@mrow4a mrow4a Mar 22, 2017

Choose a reason for hiding this comment

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

@jvillafanez Addressed this in the commit, wrote function chunkSharesToMaps()

Copy link
Member

Choose a reason for hiding this comment

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

👍


return $share;
$resolvedShares = array_values($shareIdToShareMap);
Copy link
Member

Choose a reason for hiding this comment

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

is the array_values needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hmm good question, how array merge will handle it in upper layer. This is basicaly converting from map to classical array, which is used in upper layer

Copy link
Member

Choose a reason for hiding this comment

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

$shareId = $data['parent']; I guess this won't be unqiue, will it? But if it won't be unique, the check above (if (isset($shareIdToShareMap[$shareId]))) could be problematic.... I need some light there.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Parent is basicaly unique share ID. It is needed to track received shares moved over user folders, as in the picture in the first post. Below are DB entries to enlighten you.

selection_106

Copy link
Member

Choose a reason for hiding this comment

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

but there could be several entries with the same parent.... that's what worries me.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am discussing this with @cdamken lets see what comes out

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok we tried things and seems impossible

Copy link
Member

Choose a reason for hiding this comment

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

If consider the parent will be unique, I think it's better to make the consideration all the way through, so if the assumption is wrong 💥 and 🚑 , otherwise it will be a pain to debug what's going on.

So, the key of the $shareIdToShareMap map will be unique and the array_merge (without the array_values) shouldn't be a problem. The only question is if those keys are used in any other place, if not we could ignore the array_values

Copy link
Contributor Author

@mrow4a mrow4a Mar 22, 2017

Choose a reason for hiding this comment

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

I think we need array_values... the other array in upper layer is not a map

Copy link
Member

Choose a reason for hiding this comment

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

ok, fair enough. Maybe something to check in the future. Anyway 👍

// If we pass to resolveGroupShares map with one element, we expect to receive exactly one element, otherwise it is error
$share = $resolvedShares[0];
} else {
throw new \Exception("ResolveGroupShares() returned wrong result");
Copy link
Member

Choose a reason for hiding this comment

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

Any other better exception that we could throw here? I'm not fan of throwing plain exceptions

Copy link
Contributor Author

@mrow4a mrow4a Mar 22, 2017

Choose a reason for hiding this comment

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

We already throw this exception in this class, and this error is basicaly WTF error which should not happen -> if developer later touches this and breaks, he will know immedietaly :> Other alternative is just to throw IndexError as default, but it will probably confuse

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will use @throws ProviderException

$share = $this->resolveGroupShare($share, $recipientId);
$resolvedShares = $this->resolveGroupShares([$share], $recipientId);
if (count($resolvedShares) === 1){
// If we pass to resolveGroupShares map with one element, we expect to receive exactly one element, otherwise it is error
Copy link
Member

Choose a reason for hiding this comment

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

80 chars 😉

@mrow4a mrow4a force-pushed the optimize_resolvegroupshare branch 4 times, most recently from 3297113 to a14d271 Compare March 22, 2017 17:07
if (!isset($shareParents[$shareParent])) {
$shareParents[] = $shareParent;
}else {
throw new ProviderException('Parent of share should be unique');
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jvillafanez I think this should be what you wanted to achieve

Copy link
Member

Choose a reason for hiding this comment

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

👍

@mrow4a mrow4a force-pushed the optimize_resolvegroupshare branch from a14d271 to d195262 Compare March 22, 2017 17:11
// Ensure uniquenes of parents
if (!isset($shareParents[$shareParent])) {
$shareParents[] = $shareParent;
}else {
Copy link
Member

Choose a reason for hiding this comment

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

sneak a whitespace here?

@jvillafanez
Copy link
Member

The code is fine for me, just #27434 (review) , but unless there is any other change I don't think it's worthy.
👍 for the code.

@mrow4a mrow4a force-pushed the optimize_resolvegroupshare branch from d195262 to c64f0e4 Compare March 22, 2017 17:38
@mrow4a
Copy link
Contributor Author

mrow4a commented Mar 23, 2017

I think I addressed the reviewed code @DeepDiver1975 any ideas?

@PVince81
Copy link
Contributor

PVince81 commented Mar 23, 2017

👍 from me as well, code is way more readable now.

@PVince81 PVince81 merged commit ac842f6 into master Mar 23, 2017
@PVince81 PVince81 deleted the optimize_resolvegroupshare branch March 23, 2017 19:36
@PVince81
Copy link
Contributor

Not sure if we should backport this, it's a huge change and a bit risky. Needs proper retesting.

Thoughts ?

@cdamken @DeepDiver1975

@cdamken
Copy link
Contributor

cdamken commented Apr 24, 2017

Long story short:

The patch was sent to the customer because it looks like the fixes the issue.
The customer have 9.1.4
The patch was applied.
The problem was fixed by the customer.

I'm not sure if cherry pick will work, but anyhow the solution works for master and 9.1.4 too.

@tomneedham
Copy link
Contributor

Agreed to not backport due to the risk. Advise to update to 10 or can provide this patch to other customers on 9.1.4 if they really want - with the risk that comes with it.

@cdamken
Copy link
Contributor

cdamken commented May 23, 2017

Ok, I asked to upgrade to 10.

@lock
Copy link

lock bot commented Aug 3, 2019

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@lock lock bot locked as resolved and limited conversation to collaborators Aug 3, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants