From 38ac2629f94f3ece41aaa8b9f70b9b2093d29a12 Mon Sep 17 00:00:00 2001 From: Jessica Wright <49636617+AlexicaWright@users.noreply.github.com> Date: Mon, 27 May 2024 11:11:01 +0200 Subject: [PATCH 1/7] bump dev to 5.21 (#205) --- antora.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/antora.yml b/antora.yml index e070e4e..2451ef0 100644 --- a/antora.yml +++ b/antora.yml @@ -6,10 +6,10 @@ nav: - modules/ROOT/content-nav.adoc asciidoc: attributes: - neo4j-version: '5.20' - neo4j-version-exact: '5.20.0' - neo4j-buildnumber: '5.20' - java-driver-version: '5.20.0' + neo4j-version: '5.21' + neo4j-version-exact: '5.21.0' + neo4j-buildnumber: '5.21' + java-driver-version: '5.21.0' neo4j-documentation-branch: 'dev' page-origin-private: false neo4j-javadocs-base-uri: "https://neo4j.com/docs/java-reference/5/javadocs" From 175f8f4814bf98378cb37a6ef1fdd91919f442f1 Mon Sep 17 00:00:00 2001 From: Lidia Zuin <102308961+lidiazuin@users.noreply.github.com> Date: Mon, 10 Jun 2024 12:49:52 +0200 Subject: [PATCH 2/7] Replacing underscores with hyphens for crawlability (#206) --- modules/ROOT/content-nav.adoc | 6 +++--- modules/ROOT/images/README.md | 16 ++++++++-------- .../{jconsole_beans.png => jconsole-beans.png} | Bin ...{jconsole_beans1.png => jconsole-beans1.png} | Bin ...console_connect.png => jconsole-connect.png} | Bin ...nsole_connect1.png => jconsole-connect1.png} | Bin ...mple.svg => traversal-framework-example.svg} | 0 ...ph.png => traversal-order-example-graph.png} | Bin modules/ROOT/pages/jmx-metrics.adoc | 4 ++-- ...c => bidirectional-traversal-framework.adoc} | 2 +- .../ROOT/pages/traversal-framework/index.adoc | 8 ++++---- ...le.adoc => traversal-framework-example.adoc} | 4 ++-- ...i.adoc => traversal-framework-java-api.adoc} | 2 +- 13 files changed, 21 insertions(+), 21 deletions(-) rename modules/ROOT/images/{jconsole_beans.png => jconsole-beans.png} (100%) rename modules/ROOT/images/{jconsole_beans1.png => jconsole-beans1.png} (100%) rename modules/ROOT/images/{jconsole_connect.png => jconsole-connect.png} (100%) rename modules/ROOT/images/{jconsole_connect1.png => jconsole-connect1.png} (100%) rename modules/ROOT/images/{traversal_framework_example.svg => traversal-framework-example.svg} (100%) rename modules/ROOT/images/{traversal_order_example_graph.png => traversal-order-example-graph.png} (100%) rename modules/ROOT/pages/traversal-framework/{bidirectional_traversal_framework.adoc => bidirectional-traversal-framework.adoc} (99%) rename modules/ROOT/pages/traversal-framework/{traversal_framework_example.adoc => traversal-framework-example.adoc} (97%) rename modules/ROOT/pages/traversal-framework/{traversal_framework_java_api.adoc => traversal-framework-java-api.adoc} (99%) diff --git a/modules/ROOT/content-nav.adoc b/modules/ROOT/content-nav.adoc index c87629d..16c8b51 100644 --- a/modules/ROOT/content-nav.adoc +++ b/modules/ROOT/content-nav.adoc @@ -30,9 +30,9 @@ ** xref:java-embedded/query-parameters.adoc[] * xref:traversal-framework/index.adoc[] -** xref:traversal-framework/traversal_framework_java_api.adoc[] -** xref:traversal-framework/bidirectional_traversal_framework.adoc[] -** xref:traversal-framework/traversal_framework_example.adoc[] +** xref:traversal-framework/traversal-framework-java-api.adoc[] +** xref:traversal-framework/bidirectional-traversal-framework.adoc[] +** xref:traversal-framework/traversal-framework-example.adoc[] * xref:transaction-management.adoc[] diff --git a/modules/ROOT/images/README.md b/modules/ROOT/images/README.md index 3026dd5..14cffc8 100644 --- a/modules/ROOT/images/README.md +++ b/modules/ROOT/images/README.md @@ -25,24 +25,24 @@ Images. ![](hello-world.png) -`jconsole_beans.png` +`jconsole-beans.png` -![](jconsole_beans.png) +![](jconsole-beans.png) -`jconsole_beans1.png` +`jconsole-beans1.png` -![](jconsole_beans.png) +![](jconsole-beans.png) -`jconsole_connect.png` +`jconsole-connect.png` -![](jconsole_beans.png) +![](jconsole-beans.png) -`jconsole_connect1.png` +`jconsole-connect1.png` -![](jconsole_connect1.png) +![](jconsole-connect1.png) `play.png` diff --git a/modules/ROOT/images/jconsole_beans.png b/modules/ROOT/images/jconsole-beans.png similarity index 100% rename from modules/ROOT/images/jconsole_beans.png rename to modules/ROOT/images/jconsole-beans.png diff --git a/modules/ROOT/images/jconsole_beans1.png b/modules/ROOT/images/jconsole-beans1.png similarity index 100% rename from modules/ROOT/images/jconsole_beans1.png rename to modules/ROOT/images/jconsole-beans1.png diff --git a/modules/ROOT/images/jconsole_connect.png b/modules/ROOT/images/jconsole-connect.png similarity index 100% rename from modules/ROOT/images/jconsole_connect.png rename to modules/ROOT/images/jconsole-connect.png diff --git a/modules/ROOT/images/jconsole_connect1.png b/modules/ROOT/images/jconsole-connect1.png similarity index 100% rename from modules/ROOT/images/jconsole_connect1.png rename to modules/ROOT/images/jconsole-connect1.png diff --git a/modules/ROOT/images/traversal_framework_example.svg b/modules/ROOT/images/traversal-framework-example.svg similarity index 100% rename from modules/ROOT/images/traversal_framework_example.svg rename to modules/ROOT/images/traversal-framework-example.svg diff --git a/modules/ROOT/images/traversal_order_example_graph.png b/modules/ROOT/images/traversal-order-example-graph.png similarity index 100% rename from modules/ROOT/images/traversal_order_example_graph.png rename to modules/ROOT/images/traversal-order-example-graph.png diff --git a/modules/ROOT/pages/jmx-metrics.adoc b/modules/ROOT/pages/jmx-metrics.adoc index e9b2c07..fd877d8 100644 --- a/modules/ROOT/pages/jmx-metrics.adoc +++ b/modules/ROOT/pages/jmx-metrics.adoc @@ -172,7 +172,7 @@ $JAVA_HOME/bin/jconsole Connect to the process running your Neo4j database instance: .Connecting JConsole to the Neo4j Java process -image::jconsole_connect1.png[alt="Connecting with JConsole", width=300] +image::jconsole-connect1.png[alt="Connecting with JConsole", width=300] [NOTE] ==== @@ -187,5 +187,5 @@ Under that, you have access to all the monitoring information exposed by Neo4j. For opening JMX to remote monitoring access, please see <> and link:https://docs.oracle.com/en/java/javase/11/management/monitoring-and-management-using-jmx-technology.html#GUID-805517EC-2D33-4D61-81D8-4D0FA770D1B8[the JMX documention^]. .Neo4j MBeans view -image::jconsole_beans1.png[alt="Neo4j MBeans view", width=600] +image::jconsole-beans1.png[alt="Neo4j MBeans view", width=600] diff --git a/modules/ROOT/pages/traversal-framework/bidirectional_traversal_framework.adoc b/modules/ROOT/pages/traversal-framework/bidirectional-traversal-framework.adoc similarity index 99% rename from modules/ROOT/pages/traversal-framework/bidirectional_traversal_framework.adoc rename to modules/ROOT/pages/traversal-framework/bidirectional-traversal-framework.adoc index e656923..ac6df24 100644 --- a/modules/ROOT/pages/traversal-framework/bidirectional_traversal_framework.adoc +++ b/modules/ROOT/pages/traversal-framework/bidirectional-traversal-framework.adoc @@ -22,7 +22,7 @@ In the accepted path `(1)-[:A]->(2)-[:A]->(3)-[:B]->(4)-[:B]->(5)`, the traverse ==== The `Uniqueness` is shared between both traversals, which means that there will be no results if the `Uniqueness` is set to `Uniqueness.NODE_GLOBAL` (which is the default) as both traversals need to reach the same node to cause a collision. Therefore, when using `BidirectionalTraversalDescription`, always set the `Uniqueness` manually. -For more information on the available options, see xref:traversal-framework/traversal_framework_java_api.adoc#traversal-java-api-uniqueness[`Uniqueness` options]. +For more information on the available options, see xref:traversal-framework/traversal-framework-java-api.adoc#traversal-java-api-uniqueness[`Uniqueness` options]. ==== == Defining the bidirectional traverser diff --git a/modules/ROOT/pages/traversal-framework/index.adoc b/modules/ROOT/pages/traversal-framework/index.adoc index 7e00dc1..50e6810 100644 --- a/modules/ROOT/pages/traversal-framework/index.adoc +++ b/modules/ROOT/pages/traversal-framework/index.adoc @@ -29,7 +29,7 @@ image::graphdb-traversal-description.svg[role="middle"] The Traversal Framework can be used xref:java-embedded/traversal.adoc[embedded in Java applications]. It can also be used when extending Neo4j with a xref:/extending-neo4j/procedures.adoc[User-defined Procedure]. -For an example, see xref:traversal-framework/traversal_framework_example.adoc#traversal-in-a-procedure-example[User-defined procedure with a Traversal Framework]. +For an example, see xref:traversal-framework/traversal-framework-example.adoc#traversal-in-a-procedure-example[User-defined procedure with a Traversal Framework]. [[traversal-vs-cypher]] == Traversal Framework vs Cypher @@ -41,11 +41,11 @@ Some of the advantages of using the Traversal Framework over Cypher include: * The Traversal Framework allows the use of any desired Java library to help in the evaluation of the traversal. * It allows customized pruning during the traversal of a path, which could potentially improve the performance of a traversal. -See xref:/traversal-framework/traversal_framework_java_api.adoc#traversal-java-api-evaluator[Evaluator] for more information. +See xref:/traversal-framework/traversal-framework-java-api.adoc#traversal-java-api-evaluator[Evaluator] for more information. * With Cypher, it is not possible to specify the order in which paths are expanded (e.g. depth-first). -However, with the Traversal Framework, it is possible to specify the xref:/traversal-framework/traversal_framework_java_api.adoc#traversal-java-api-branchselector[order of paths traversed]. +However, with the Traversal Framework, it is possible to specify the xref:/traversal-framework/traversal-framework-java-api.adoc#traversal-java-api-branchselector[order of paths traversed]. * With Cypher, relationships are only traversed when `RELATIONSHIP_GLOBAL` uniqueness is specified. -By using the Traversal Framework, it is possible to specify the xref:/traversal-framework/traversal_framework_java_api.adoc#traversal-java-api-uniqueness[uniqueness constraints on the path traversed]. +By using the Traversal Framework, it is possible to specify the xref:/traversal-framework/traversal-framework-java-api.adoc#traversal-java-api-uniqueness[uniqueness constraints on the path traversed]. [WARNING] ==== diff --git a/modules/ROOT/pages/traversal-framework/traversal_framework_example.adoc b/modules/ROOT/pages/traversal-framework/traversal-framework-example.adoc similarity index 97% rename from modules/ROOT/pages/traversal-framework/traversal_framework_example.adoc rename to modules/ROOT/pages/traversal-framework/traversal-framework-example.adoc index 2d452af..d5b1355 100644 --- a/modules/ROOT/pages/traversal-framework/traversal_framework_example.adoc +++ b/modules/ROOT/pages/traversal-framework/traversal-framework-example.adoc @@ -8,7 +8,7 @@ The following are some examples of how you can use the Traversal Framework. The source code for the examples can be found in link:https://github.com/neo4j/neo4j-documentation/blob/dev/embedded-examples/src/main/java/org/neo4j/examples/TraversalExample.java[`TraversalExample.java`^]. -image::traversal_framework_example.svg[role="middle"] +image::traversal-framework-example.svg[role="middle"] This graph illustrates a small group of friends with the definition of `RelationshipType`: @@ -119,7 +119,7 @@ This gives the following output: (0)-[KNOWS,0]->(2)<-[KNOWS,2]-(3)<-[KNOWS,3]-(4)<-[KNOWS,4]-(1) ---- -For other useful evaluators, see xref:traversal-framework/traversal_framework_java_api.adoc#traversal-java-api-evaluator[Using Evaluators]. +For other useful evaluators, see xref:traversal-framework/traversal-framework-java-api.adoc#traversal-java-api-evaluator[Using Evaluators]. The `Traverser` also has a `nodes()` method, which returns an `Iterable` of all the nodes in the paths: diff --git a/modules/ROOT/pages/traversal-framework/traversal_framework_java_api.adoc b/modules/ROOT/pages/traversal-framework/traversal-framework-java-api.adoc similarity index 99% rename from modules/ROOT/pages/traversal-framework/traversal_framework_java_api.adoc rename to modules/ROOT/pages/traversal-framework/traversal-framework-java-api.adoc index a60c2f1..45d51b9 100644 --- a/modules/ROOT/pages/traversal-framework/traversal_framework_java_api.adoc +++ b/modules/ROOT/pages/traversal-framework/traversal-framework-java-api.adoc @@ -230,7 +230,7 @@ Keep in mind that breadth-first traversals have a higher memory overhead than de The following example shows the result of `BranchOrderingPolicy` without any extra filter: -image::traversal_order_example_graph.png[align="center", role="middle", width=200] +image::traversal-order-example-graph.png[align="center", role="middle", width=200] [cols="1,1"] |=== From 2fb4d8d99eef349b700c3dc1502bc0a195c1eb31 Mon Sep 17 00:00:00 2001 From: NataliaIvakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Fri, 28 Jun 2024 12:43:21 +0200 Subject: [PATCH 3/7] Bump Neo4j version to 5.22 and driver v to 5.23 (#208) --- antora.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/antora.yml b/antora.yml index 2451ef0..b17e379 100644 --- a/antora.yml +++ b/antora.yml @@ -6,10 +6,10 @@ nav: - modules/ROOT/content-nav.adoc asciidoc: attributes: - neo4j-version: '5.21' - neo4j-version-exact: '5.21.0' - neo4j-buildnumber: '5.21' - java-driver-version: '5.21.0' + neo4j-version: '5.22' + neo4j-version-exact: '5.22.0' + neo4j-buildnumber: '5.22' + java-driver-version: '5.23.0' neo4j-documentation-branch: 'dev' page-origin-private: false neo4j-javadocs-base-uri: "https://neo4j.com/docs/java-reference/5/javadocs" From be4952bd16ebdd6d37462e78d9f7a7165892b6e9 Mon Sep 17 00:00:00 2001 From: NataliaIvakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Tue, 23 Jul 2024 16:40:41 +0200 Subject: [PATCH 4/7] Update `dev` to 5.23 (#213) --- antora.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/antora.yml b/antora.yml index b17e379..eb34407 100644 --- a/antora.yml +++ b/antora.yml @@ -6,10 +6,10 @@ nav: - modules/ROOT/content-nav.adoc asciidoc: attributes: - neo4j-version: '5.22' - neo4j-version-exact: '5.22.0' - neo4j-buildnumber: '5.22' - java-driver-version: '5.23.0' + neo4j-version: '5.23' + neo4j-version-exact: '5.23.0' + neo4j-buildnumber: '5.23' + java-driver-version: '5.24.0' neo4j-documentation-branch: 'dev' page-origin-private: false neo4j-javadocs-base-uri: "https://neo4j.com/docs/java-reference/5/javadocs" From c8d6fb516594c310563ca78b3f90510c75600fd1 Mon Sep 17 00:00:00 2001 From: NataliaIvakina <82437520+NataliaIvakina@users.noreply.github.com> Date: Thu, 22 Aug 2024 17:00:07 +0200 Subject: [PATCH 5/7] Bump version number to 5.24 (#215) --- antora.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/antora.yml b/antora.yml index eb34407..501c0fe 100644 --- a/antora.yml +++ b/antora.yml @@ -6,9 +6,9 @@ nav: - modules/ROOT/content-nav.adoc asciidoc: attributes: - neo4j-version: '5.23' - neo4j-version-exact: '5.23.0' - neo4j-buildnumber: '5.23' + neo4j-version: '5.24' + neo4j-version-exact: '5.24.0' + neo4j-buildnumber: '5.24' java-driver-version: '5.24.0' neo4j-documentation-branch: 'dev' page-origin-private: false From 936bfd48aa74fab1bb72bcfdab0350c087e182ad Mon Sep 17 00:00:00 2001 From: Reneta Popova Date: Thu, 26 Sep 2024 13:44:13 +0100 Subject: [PATCH 6/7] Update preview version to 5.25 (#220) --- antora.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/antora.yml b/antora.yml index 501c0fe..f125dae 100644 --- a/antora.yml +++ b/antora.yml @@ -6,10 +6,10 @@ nav: - modules/ROOT/content-nav.adoc asciidoc: attributes: - neo4j-version: '5.24' - neo4j-version-exact: '5.24.0' - neo4j-buildnumber: '5.24' - java-driver-version: '5.24.0' + neo4j-version: '5.25' + neo4j-version-exact: '5.25.0' + neo4j-buildnumber: '5.25' + java-driver-version: '5.25.0' neo4j-documentation-branch: 'dev' page-origin-private: false neo4j-javadocs-base-uri: "https://neo4j.com/docs/java-reference/5/javadocs" From 0394a3cb69f53caea6cec087ff1043bc10ac11b5 Mon Sep 17 00:00:00 2001 From: Love Kristofer Leifland Date: Thu, 31 Oct 2024 11:13:36 +0100 Subject: [PATCH 7/7] Add documentation for user procedure memory resource tracking --- .../pages/extending-neo4j/procedures.adoc | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/modules/ROOT/pages/extending-neo4j/procedures.adoc b/modules/ROOT/pages/extending-neo4j/procedures.adoc index 8344cca..22b8a62 100644 --- a/modules/ROOT/pages/extending-neo4j/procedures.adoc +++ b/modules/ROOT/pages/extending-neo4j/procedures.adoc @@ -190,9 +190,86 @@ The classes that can be injected are: * `Transaction` //* `SecurityContext` //* `ProcedureTransaction` +//* `ProcedureMemory` Candidate for public API but not stable yet All of the above classes are considered safe and future-proof and do not compromise the security of the database. Several unsupported (restricted) classes can also be injected and can be changed with little or no notice. Procedures written to use these restricted APIs are not loaded by default, and you need to use the `dbms.security.procedures.unrestricted` to load unsafe procedures. Read more about this config setting in link:{neo4j-docs-base-uri}/operations-manual/{page-version}/security/securing-extensions[Operations Manual -> Securing extensions]. +[[memory-resource-tracking]] +== Memory Resource Tracking + +[NOTE] +==== +The memory resource tracking API for the procedure framework is available for preview. +Future versions of Neo4j might contain breaking changes to this API. +==== + +If your procedure or function allocates significant amounts of heap memory, you can register allocations to count towards the configured transaction limits, see link:{neo4j-docs-base-uri}/operations-manual/{page-version}/performance/memory-configuration/#memory-configuration-limit-transaction-memory[Operations Manual -> Limit transaction memory usage] for more information. +This allows you to avoid `OutOfMemory` errors that cause database restarts. +Memory allocations also show up in query profiles. + +To do this you need to inject `org.neo4j.procedure.memory.ProcedureMemory` as a field in your procedure/function class. +`ProcedureMemory` has various methods to allow you to register allocations. +For example (see javadocs for a full reference): + +* `ProcedureMemoryTracker newTracker()` creates a new memory resource tracker that is bound to the current transaction. +* `HeapEstimator heapEstimator()` estimates the heap size of classes and instances. +* `HeapTrackingCollectionFactory collections()` lets you create collections that have built-in memory tracking of their internal structure. + +It's usually difficult and time-consuming to implement memory resource tracking. +These are a few considerations and caveats that are worth keeping in mind: + +- Limit the scope of the memory management. + Focus only on parts that can grow significantly in memory and ignore minor underestimation. +- Beware of overestimation by registering allocations of the same instance multiple times. + You can add reference counting or other mechanisms to avoid overestimation if that is a concern. +- It's common not to know the size of an instance before it has been allocated, which may lead you to register allocations after they have already been made. + The memory tracker implementation tries to prevent this by always pre-registering a certain amount of memory in the internal memory pools. +- It's cumbersome in Java to know when an instance has been garbage-collected. + Typically, you register the release of memory at the point when it's possible for that memory to be garbage-collected. + To account for this, memory trackers may internally choose not to register the release of memory instantaneously. +- Testing memory resource tracking can be difficult. + One approach is to use a third-party library, like JAMM (Java Agent for Memory Measurements), and assert that the estimates are close enough for some given input. + + +.A basic example of memory resource tracking in user defined procedures. +[source, java] +---- +package org.example; + +import org.neo4j.procedure.Context; +import org.neo4j.procedure.Name; +import org.neo4j.procedure.Procedure; +import org.neo4j.procedure.memory.ProcedureMemory; + +import java.util.Arrays; +import java.util.stream.Stream; + +public class MyProcedures { + + @Context + public ProcedureMemory memory; + + record Output(Long value) {} + + @Procedure("org.example.memoryHungryRange") + public Stream memoryHungryRange(@Name("size") int size) { + final var tracker = memory.newTracker(); + + // Register the allocation of the long array below + tracker.allocateHeap(memory.heapEstimator().sizeOfLongArray(size)); + // The actual allocation + final var result = new long[size]; + + for (int i = 0; i < size; i++) result[i] = i; + + return Arrays.stream(result) + .mapToObj(Output::new) + // Release all registered allocations when the stream is closed + .onClose(tracker::close); + } +} + +----