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

TINKERPOP-3029 Fix enumeration for .NET 8 #2424

Merged
merged 1 commit into from
Jan 15, 2024
Merged

Conversation

FlorianHockmann
Copy link
Member

https://issues.apache.org/jira/browse/TINKERPOP-3029

IEnumerable<T>.Current has been changed in .NET 8. Before .NET 8, it simply returned null if MoveNext() wasn't called first. With .NET 8 however it throws an exception.
Since this has apparently already been undefined behavior before, we should fix this irrespective of .NET 8:
dotnet/runtime#85243 (comment)

The problem can be reproduced by executing the Gherkin tests with .NET without the change in DefaultTraversal (by changing the TargetFramework in Gremlin.Net.IntegrationTest.csproj to net8.0). .NET 8 needs to be installed for this of course.

VOTE +1

@codecov-commenter
Copy link

codecov-commenter commented Jan 3, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (e86eed2) 75.16% compared to head (8fda42f) 75.17%.

Additional details and impacted files
@@              Coverage Diff              @@
##             3.6-dev    #2424      +/-   ##
=============================================
+ Coverage      75.16%   75.17%   +0.01%     
- Complexity     12316    12322       +6     
=============================================
  Files           1057     1057              
  Lines          63470    63470              
  Branches        6936     6936              
=============================================
+ Hits           47706    47716      +10     
+ Misses         13191    13187       -4     
+ Partials        2573     2567       -6     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

if (_fetchedNext) return _nextAvailable;

if (!_nextAvailable || _nextAvailable && TraverserEnumerator.Current?.Bulk == 0)
Copy link
Contributor

Choose a reason for hiding this comment

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

can be simplified

Suggested change
if (!_nextAvailable || _nextAvailable && TraverserEnumerator.Current?.Bulk == 0)
if (!_nextAvailable || TraverserEnumerator.Current?.Bulk == 0)

Choose a reason for hiding this comment

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

This code will also throw an exception if called without first starting the iterator: You will need to track that the iterator has not been started.

private object GetCurrent()
{
    // Use dynamic to object to prevent runtime dynamic conversion evaluation
    return TraverserEnumerator.Current?.Object;
}

Please review the new .Net code here

Copy link
Member Author

Choose a reason for hiding this comment

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

@EricSites sure, but DefaultTraversal is an IEnumerator itself so GetCurrent() just forwards to TraverserEnumerator.Current. If it's illegal to call TraverserEnumerator.Current before calling TraverserEnumerator.MoveNext(), then it's also illegal to call GetCurrent() before calling MoveNext().
We could of course use a flag to check whether enumeration has been started in GetCurrent() and return null otherwise, but I don't think it's a good idea to deviate from the default behavior of .NET enumerators.

Did you see GetCurrent() in any stack trace?

`IEnumerable<T>.Current` has been changed in .NET 8. Before .NET 8, it
simply returned `null` if `MoveNext()` wasn't called first. With .NET 8
however it throws an exception.
Since this has apparently already been undefined behavior before, we
should fix this irrespective of .NET 8:
dotnet/runtime#85243 (comment)

The problem can be reproduced by executing the Gherkin tests with .NET
without the change in `DefaultTraversal` (by changing the
`TargetFramework` in `Gremlin.Net.IntegrationTest.csproj` to `net8.0`).
.NET 8 needs to be installed for this of course.
@FlorianHockmann
Copy link
Member Author

I added a CHANGELOG / upgrade docs entry and applied the suggestion by @vkagamlyk.

@vkagamlyk
Copy link
Contributor

thank you @FlorianHockmann!

VOTE+1

@xiazcy
Copy link
Contributor

xiazcy commented Jan 11, 2024

VOTE +1

Copy link
Contributor

@jorgebay jorgebay left a comment

Choose a reason for hiding this comment

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

VOTE +1

@FlorianHockmann FlorianHockmann merged commit 8fda42f into 3.6-dev Jan 15, 2024
40 checks passed
@FlorianHockmann FlorianHockmann deleted the TINKERPOP-3029 branch January 15, 2024 11:31
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.

6 participants