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

feat(SCIM): optimize performance #568

Merged
merged 11 commits into from
Aug 29, 2023

Conversation

danflomin
Copy link
Collaborator

In this PR the main changes relate to using async overloads of DB queries.
Using async overloads is considered as the good practice in asp.net, and after a benchmark I conducted, these changes improved the performance by several magnitudes.

Also, the usage of yield in DB queries is considered to be less efficient with respect to network.

Another performance improvements introduced in here:

  • The ResolveChildren and ResolveParents functions, queried the same representations multiple times, so I added a check that makes sure that each representation is queried only once.
  • The implementation of GET methods can use the AsNoTracking behavior which improves performance.
  • I used the paginated variation in a few places that did not use it.

result.FlatAttributes = filteredAttrs.ToList();
return result;
}

representations = representations.Include(r => r.FlatAttributes).ThenInclude(s => s.SchemaAttribute);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This was moved to EFSCIMRepresentationQueryRepository

@danflomin danflomin force-pushed the release/4.0.4-flomin-optimize branch from a0da371 to d073474 Compare August 23, 2023 08:42
}

public virtual IEnumerable<RepresentationSyncResult> Sync(string resourceType, SCIMRepresentation oldScimRepresentation, SCIMRepresentation newSourceScimRepresentation, string location, SCIMSchema schema, bool updateAllReferences = false, bool isScimRepresentationRemoved = false)
public virtual async Task<List<RepresentationSyncResult>> Sync(string resourceType, SCIMRepresentation oldScimRepresentation, SCIMRepresentation newSourceScimRepresentation, string location, SCIMSchema schema, bool updateAllReferences = true, bool isScimRepresentationRemoved = false)
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I rebased my code which originated from 4.0.2 using master, and I see that you made some changes like false -> 'true.
@thabart should I change this?

Copy link
Owner

Choose a reason for hiding this comment

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

I checked the master branch, by default, the field updateAllReferences is equals to false and not to true :

public class RepresentationReferenceSync : IRepresentationReferenceSync

The field must be false

}

foreach (var attributeMapping in kvp.Where(r => !r.IsSelf))
{
result = new RepresentationSyncResult();
var targetSchema = mappedSchemas.First(s => s.ResourceType == attributeMapping.TargetResourceType && s.Attributes.Any(a => a.Id == attributeMapping.TargetAttributeId));
var targetSchema = targetSchemas.First(s => s.ResourceType == attributeMapping.TargetResourceType);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same about this one

Copy link
Owner

Choose a reason for hiding this comment

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

"This portion of code has been updated by pull request #557.
There was an issue during the resolution of the attribute present in a custom schema.
You are welcome to retain this change :)

var targetAttribute = targetSchema.GetAttributeById(attributeMapping.TargetAttributeId);
var sourceAttribute = sourceSchema.GetAttributeById(attributeMapping.SourceAttributeId);
var sourceAttribute = schema.GetAttributeById(attributeMapping.SourceAttributeId);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same

Copy link
Owner

Choose a reason for hiding this comment

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

Same remark

@danflomin danflomin force-pushed the release/4.0.4-flomin-optimize branch 3 times, most recently from 2d821a1 to d8acd2f Compare August 23, 2023 08:50
@simpleidserver
Copy link
Owner

simpleidserver commented Aug 23, 2023

Hello,

Firstly, thank you for your pull request.

Are you sure that the yield clause is less efficient in DB queries? I checked with and without the yield keyword, and the number of RPC requests made against the SQLSERVER is the same. It should also be the same with a POSTGRESQL database. In the pull request, all the data is stored in-memory, which can be problematic if there are many references to update.

I'm okay with using .NET version 7, but please remember to upgrade the other projects that reference this project.

Unfortunately, the solution is not compiling. Could you please fix the issues?

Thank you.

@danflomin
Copy link
Collaborator Author

Hello @simpleidserver

  1. Yes - I'm sure it is less efficient.
  2. Eventually we will have all the references in the handlers anyway, right?
  3. The change I made in the ResolveChildren and ResolveParents actually solved an OOM exception I previously got.
  4. I updated the PR and the build now works.

Kind regards
Dan

Comment on lines 233 to 234
var targetSchema = targetSchemas.Single(s => s.Name == propagatedAttribute.TargetResourceType);
var sourceSchema = targetSchemas.Single(s => s.Name == propagatedAttribute.SourceResourceType);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

same

@simpleidserver
Copy link
Owner

simpleidserver commented Aug 23, 2023

Unfortunately, the unit tests are not functioning properly :(
Could you please revert your changes to the TargetFramework or modify the unit test projects accordingly?

Don't forget to include the changes made on the master branch.

Additionally, for my curiousity :), do-you have a link to documentation that explains why the yield keyword should not be used during database querying. As far as my understanding goes, when the yield statement is employed, the compiler transforms it into a state machine that implements IEnumerable. Subsequently, the foreach loop invokes the MoveNext method to retrieve results.

I have checked the performance, and there is an improvement in memory usage!

Ty again for your contribution.

@danflomin danflomin force-pushed the release/4.0.4-flomin-optimize branch 2 times, most recently from 50bca19 to 7b0baf8 Compare August 24, 2023 09:04
@danflomin danflomin force-pushed the release/4.0.4-flomin-optimize branch from 7b0baf8 to 8a4f81e Compare August 24, 2023 13:07
@simpleidserver
Copy link
Owner

Hello @danflomin ,

I fixed the UTs and also issues in the RepresentationReferenceSync class.
If you are agree with the changes, i'll merge them into the branch.

KR,

SID

@@ -2,11 +2,13 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<Description>SCIM2.0 implementation.</Description>
<LangVersion>latest</LangVersion>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

why is this needed?

Copy link
Owner

Choose a reason for hiding this comment

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

Because some changes in the pull request are not supported by previous c# version for example ??=

@danflomin
Copy link
Collaborator Author

Hello

I will try to find a good explanation for the issue with the yield.

Thank you for your fixes, I went over most of it and it looks fine.
I still need to understand the changes in RepresentationReferenceSync and in RepresentationSyncResult.

I will let you know once done.

Kind regards
Dan

@gabrielemilan
Copy link
Contributor

Hello, do you have ETA of this PR?

Kind regards.
Gabriele

@simpleidserver simpleidserver changed the base branch from master to release/4.0.4 August 29, 2023 09:49
@simpleidserver simpleidserver merged commit b5d811f into release/4.0.4 Aug 29, 2023
1 check was pending
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.

5 participants