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

Fixes to Persistance #10101

Merged
merged 27 commits into from
Jun 10, 2024
Merged

Conversation

radeusgd
Copy link
Member

Pull Request Description

  • Follow-up to Support cycles in the serialized IR structure #9361
    • Enables assertions and fixes count check
    • Tests and fixes null references
    • Tests and fixes serializing a deserialized structure - by saving the id of the Persistance corresponding to the entry
  • After the change to how we determine which Persistance instance to use, the most specific one is now used (based on the saved id). This has an unfortunate consequence that Seq which is most of the time represented by a subtype of List, is now using PersistScalaList which is not lazy.
  • To alleviate that, we no longer use Seq to store some field lazily and instead use a dedicated type for that purpose: InlineReference.

Important Notes

Checklist

Please ensure that the following checklist has been satisfied before submitting the PR:

  • The documentation has been updated, if necessary.
  • Screenshots/screencasts have been attached, if there are any visual changes. For interactive or animated visual changes, a screencast is preferred.
  • All code follows the
    Scala,
    Java,
    TypeScript,
    and
    Rust
    style guides. In case you are using a language not listed above, follow the Rust style guide.
  • Unit tests have been written where possible.

@radeusgd radeusgd added the CI: No changelog needed Do not require a changelog entry for this PR. label May 27, 2024
@enso-bot enso-bot bot mentioned this pull request May 27, 2024
6 tasks
@radeusgd radeusgd added the CI: Clean build required CI runners will be cleaned before and after this PR is built. label May 27, 2024
@JaroslavTulach
Copy link
Member

There is an advice describing how to generate a javadoc. I had to add a classpath:

find lib/java/persistance/src/main/java/ | grep java$ | xargs ~/bin/graalvm-21/bin/javadoc -d target/javadoc/ -cp $HOME/.m2/repository/org/slf4j/slf4j-api/2.0.7/slf4j-api-2.0.7.jar:$HOME/.m2/repository/org/netbeans/api/org-openide-util-lookup/RELEASE150/org-openide-util-lookup-RELEASE150.jar --snippet-path lib/java/persistance/src/test/java/

then the Javadoc appeared in target/javadoc/index.html

obrazek

There is a new class without Javadoc PersistInlineReference - probably unexpected. Then there is the InlineReference with Javadoc - I am assuming, it is expected.

Copy link
Member

@JaroslavTulach JaroslavTulach left a comment

Choose a reason for hiding this comment

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

I'll play with the PR more.

@@ -1258,6 +1258,7 @@ lazy val `persistance` = (project in file("lib/java/persistance"))
commands += WithDebugCommand.withDebug,
frgaalJavaCompilerSetting,
Compile / javacOptions := ((Compile / javacOptions).value),
inConfig(Compile)(truffleRunOptionsSettings),
Copy link
Member

Choose a reason for hiding this comment

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

Thank you.

LazySeq.forbidden = true;
var out = serde(java.util.Map.class, in, 72);
LazyString.forbidden = true;
var out = serde(java.util.Map.class, in, 76);
Copy link
Member

@JaroslavTulach JaroslavTulach May 28, 2024

Choose a reason for hiding this comment

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

Increasing these numbers is OK due to the consequences of changing the serialization format.

var tu = processingEnv.getTypeUtils();
var cnt = 0;
for (var p : parameters) {
var type = tu.asElement(tu.erasure(p.asType()));
if (type != null && type.getSimpleName().toString().equals("Seq")) {
if (type != null && type.getSimpleName().toString().equals("InlineReference")) {
Copy link
Member

Choose a reason for hiding this comment

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

I've almost forgotten about this hack.

assert position == NULL_REFERENCE_ID;
out.writeInt(NULL_REFERENCE_ID);
} else {
out.writeInt(position);
Copy link
Member

Choose a reason for hiding this comment

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

I have to think why this is necessary and whether there isn't a better solution. When using Output.writeObject the persistance ID is written.

Only when using writeInline it is not - because it is expected one knows the inlined type. But objects written inline shall not be referenceble from outside.

Strange.


var refsOut = new ByteArrayOutputStream();
var refsData = new DataOutputStream(refsOut);
refsData.writeInt(-1); // space for size of references
refsData.writeInt(objAt); // the main object
root.writePositionAndPersistanceId(refsData);
Copy link
Member

@JaroslavTulach JaroslavTulach May 28, 2024

Choose a reason for hiding this comment

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

Storing the type for all roots is seems however fine so probably my comments aren't that important.

* use {@link Reference} instead. It should be used when we want to ensure that a part of a
* structure is only read lazily.
*/
public abstract static sealed class InlineReference<T>
Copy link
Member

Choose a reason for hiding this comment

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

I don't like two classes doing the same, but having different type. Such an approach looks like Text | Column | Regex union type, but that's not how object orientation works. According to On understanding, data abstraction OOP prefers common interface with multiple implementation. Because we are designing an API in object oriented language, I prefer it as well.

Copy link
Member

Choose a reason for hiding this comment

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

While working on #10117 I also noticed that the APIs are slightly different. Reference has get with parameter. InlineReference has get without parameter. I'd say consistency matters and unless there is a reason why the original decision was wrong, I'd stick with it.

PR #10117 solves this inconsistency by exposing only Persistance.Reference abstract class.

}

@ServiceProvider(service = Persistance.class)
public static final class PersistInlineReference extends Persistance<InlineReference> {
Copy link
Member

Choose a reason for hiding this comment

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

This class is accidentally visible in the Javadoc.

Copy link
Member

Choose a reason for hiding this comment

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

In the #10117 PR I made the class package private and registered it manually in PerMap static initializer.

@JaroslavTulach
Copy link
Member

I've created a PR on top of this PR:

I didn't want to commit directly to your PR, @radeusgd as I am not sure all your use-cases are working.

@radeusgd
Copy link
Member Author

I've created a PR on top of this PR:

I didn't want to commit directly to your PR, @radeusgd as I am not sure all your use-cases are working.

Thank you very much for your propositions. I will rebase my Types PR on top of them and see if the practical use cases are all working - then we can merge the PRs. I will do it when I have my next Types work slot (probably around next week, unless we want to have this finished faster).

* Exposing just a single Persistance.Reference abstraction

* Reference.of(obj, deferredWrite)

* Encapsulating Reference serde in PerReferencePeristance
@radeusgd radeusgd added the CI: Ready to merge This PR is eligible for automatic merge label Jun 1, 2024
@mergify mergify bot merged commit 99a1d05 into develop Jun 10, 2024
36 checks passed
@mergify mergify bot deleted the wip/radeusgd/cycles-in-persistance-followup branch June 10, 2024 11:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CI: Clean build required CI runners will be cleaned before and after this PR is built. CI: No changelog needed Do not require a changelog entry for this PR. CI: Ready to merge This PR is eligible for automatic merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants