Slide 1

Slide 1 text

Neo4j and the JVM Michael Simons, 16th Dezember 2020 The manifold ways of connecting to Neo4j from the JVM

Slide 2

Slide 2 text

Michael Simons @rotnroll666 About me „Michael Simons of Spring Data Neo4j/Reactive/Quarkus/GraalVM fame“ • This ^^ is a quote (and the pressure is high) • Official role: Maintainer of Neo4j-OGM and Spring Data Neo4j • We released Neo4j-OGM 3.2 in 2019, with 20 patch releases following • Not many changes in Spring Data Neo4j 5.x • Changed most everything in Spring Data Neo4j 6

Slide 3

Slide 3 text

Michael Simons @rotnroll666 About me • (:Team {name: "OGM / SDN"}) - [:IS_PART_OF] -> (:Team {name: "Drivers"}) • Very close feedback loop • Happy to test beta code • Nice position between ! users on the one hand, drivers and database on the other "

Slide 4

Slide 4 text

Michael Simons @rotnroll666 About me The rest… • # • $, % and & (no swimming this year… ') • Twitter addict… @rotnroll666 • Enjoys databases with declarative languages in general • Active in both Java and database communities • Likes Spring (wrote a best selling German book about it) • But enjoys other ecosystems too… (Not actually evil, though…)

Slide 5

Slide 5 text

Topics today Where did I use the Neo4j Java Driver?

Slide 6

Slide 6 text

Neo4j-OGM The elephant in the room

Slide 7

Slide 7 text

Michael Simons @rotnroll666 Neo4j-OGM Multiple transport modes, why are they causing issues? • Embedded • Dependency management is a nightmare • Bringing up the database from the mapper is the wrong abstraction layer • Close coupling between OGM and Neo4j versions • Definitely not native ready • HTTP • Not typesafe (we are working on that) • Bolt (Aka the Neo4j Java Driver) • Mostly naming, people mistake bolt-driver with the Java driver itself • Transactional functions (to some extend, later more)

Slide 8

Slide 8 text

Michael Simons @rotnroll666 Neo4j-OGM Spring Data Neo4j 5.x without reactive support. ( • No (sane) way to add a shared abstraction over all modes • Just wrapping lists in reactive datatypes isn’t gonna cut it

Slide 9

Slide 9 text

On the plus side

Slide 10

Slide 10 text

Michael Simons @rotnroll666 Neo4j-OGM On the plus side • More than 20 releases in the last 2 years • Ticket numbers closed to about 4 or 5 • Stable API, ways to mark queries explicitly as r/w and r/o, supports multi database • Native ready since this month • Usage of bolt taught us it’s API and usage • Super flexible mapping, both a benefit and sometimes a PITA • Personal note: I do like maintaining it.

Slide 11

Slide 11 text

Two German Java developers just before Graph Tour 2019 in London „Hmm… Lightweight Spring Data JDBC is cool, should we try this with SDN?“ )

Slide 12

Slide 12 text

Michael Simons @rotnroll666 Goals of SDN⚡RX These days: Spring Data Neo4j 6 • Full support of the reactive story • • • • Neo4j native types • Dedicated ways of decomposing objects into maps to be stored on single nodes / relationships • Clean levels of abstracts (from low to high: Managed driver, Neo4j client, template, repositories, from client onwards with Spring TX Support) • • Compatible with GraalVM native • • Full support of immutable domain objects (Kotlin data classes, Java 16 records, Lombok Data classes) • Full support of all derived finder query building parts • Full support of find by example • • • • Performance •

Slide 13

Slide 13 text

Michael Simons @rotnroll666 (:Topic) - [:RELATED_TO {type: "directly"}] -> (the:Driver) Goals of SDN⚡RX • Full support of the reactive story • Neo4j native types • Dedicated ways of decomposing objects into maps to be stored on single nodes / relationships • Clean levels of abstracts (from low to high: Managed driver, Neo4j client, template, repositories, from client onwards with Spring TX Support) • Compatible with GraalVM native

Slide 14

Slide 14 text

Michael Simons @rotnroll666 Brought in order for today • Full support of the reactive story • Clean levels of abstracts (from low to high: Managed driver, Neo4j client, template, repositories, from client onwards with Spring TX Support) • Neo4j native types • Compatible with GraalVM native

Slide 15

Slide 15 text

Michael Simons @rotnroll666 Session and transaction APIs The big all-in-one-package • org.neo4j.driver.GraphDatabase is the general Driver factory • Instances of org.neo4j.driver.Driver are heavyweight objects and maintain a pool of physical connections • Open as few as possible and keep them around • All sessions are lightweight and basically a lease on connections • Don’t keep them around • Open and close as needed • Concepts are not 1:1 comparable to JDBC wording!

Slide 16

Slide 16 text

Michael Simons @rotnroll666 Session and transaction APIs What you want application wide is as few instances of a driver as possible.

Slide 17

Slide 17 text

Michael Simons @rotnroll666 Session and transaction APIs All major Java platforms do support something like this now

Slide 18

Slide 18 text

Michael Simons @rotnroll666 Session and transaction APIs Reduce driver footprint • i.e. in scenarios where there is more than instance needed (different credentials, different clusters etc.) • Scripting

Slide 19

Slide 19 text

Michael Simons @rotnroll666 Session and transaction APIs Reduce driver footprint • i.e. in scenarios where there is more than instance needed (different credentials, different clusters etc.) • Scripting

Slide 20

Slide 20 text

Michael Simons @rotnroll666 Driver instance hands out sessions Config options apply for all types

Slide 21

Slide 21 text

Michael Simons @rotnroll666 Session purpose Mostly transaction chaining • On the surface • Executes transactional work • Hands out unmanaged transactions • On the inside • Retries your work if necessary and possible • Chains causal bookmarks together

Slide 22

Slide 22 text

Fan out: Transactions • Each session type provides • Auto-commit aka invisible transactions • Managed transactions • Unmanaged transactions • Following examples only showing imperative style 3 x 3 ways of running queries

Slide 23

Slide 23 text

Michael Simons @rotnroll666 Auto-commit transactions The invisible kid.

Slide 24

Slide 24 text

Michael Simons @rotnroll666 Managed transactions The transactions formerly known as transaction functions.

Slide 25

Slide 25 text

Michael Simons @rotnroll666 Unmanaged transactions There might be dragons.

Slide 26

Slide 26 text

Michael Simons @rotnroll666 Unmanaged transactions There might be dragons. • You want to integrate with an external tx manager • You want control over exception handling and retries • Your transactional work is not idempotent

Slide 27

Slide 27 text

Bookmarks • Don’t parse them • Don’t persist them • Sessions handles them for you • Relevant for working against a cluster • Use them when chaining sessions Which I initially though is hard but isn’t

Slide 28

Slide 28 text

Michael Simons @rotnroll666 Bookmarks Usage pattern

Slide 29

Slide 29 text

Michael Simons @rotnroll666 Bookmarks Possible bookmark manager (From SDN 6)

Slide 30

Slide 30 text

The async session

Slide 31

Slide 31 text

The async session Not today.

Slide 32

Slide 32 text

Non blocking, back pressure up into the Bolt server. RxSession

Slide 33

Slide 33 text

Michael Simons @rotnroll666 RxSession: Reactive database access Key facts

Slide 34

Slide 34 text

Michael Simons @rotnroll666 RxSession: Reactive database access Key facts • Fully non blocking, required changes in the Bolt server • Internally using • Netty and existing async behavior • Small parts build with Project Reactor • Build based on PULL_N and TX_STREAMING (See 7687.org, Server v4) • Externally adhering to https://www.reactive-streams.org • Publisher compliant with the TCK (See https://github.com/reactive-streams/ reactive-streams-jvm/tree/master/tck)

Slide 35

Slide 35 text

RxSession drives SDN 6 Well, the reactive parts.

Slide 36

Slide 36 text

Michael Simons @rotnroll666 RxSession: Observations Your mileage may vary. • Better resource usage • More efficient use of threads (non blocking IO is key!) • Slightly less memory usage on the client side • Steep learning curve • All reactive libraries offer a plethora of operators • What is happens on LIMIT / cancel? • Resource handling can be tricky • Reactive context works awesome for user / tenancy information

Slide 37

Slide 37 text

Michael Simons @rotnroll666 RxSession: Observations Your mileage may vary. • For resource usage and some unqualified benchmarking have a look at https://github.com/michael-simons/neo4j-from-the-jvm-ecosystem

Slide 38

Slide 38 text

Michael Simons @rotnroll666 RxSession: Use it with 3rd party libraries Don’t use the publishers alone. • Officially under test are • Project Reactor https://projectreactor.io (Flux and Mono) • RxJava 2 https://github.com/ReactiveX/RxJava (Flowable and Observable) • Works with • SmallRye Mutiny! https://smallrye.io/smallrye-mutiny/ (Multi) • Helidons reactive implementation • Most efficient usage: With Project Reactor (no conversion required)

Slide 39

Slide 39 text

A couple of examples

Slide 40

Slide 40 text

Reading things

Slide 41

Slide 41 text

Michael Simons @rotnroll666 Project Reactor Standard for Spring environments

Slide 42

Slide 42 text

Michael Simons @rotnroll666 Project Reactor Standard for Spring environments Important: This delays the creation of the session until something subscribes!

Slide 43

Slide 43 text

Michael Simons @rotnroll666 Project Reactor Standard for Spring environments Pass the new resource to the actual work

Slide 44

Slide 44 text

Michael Simons @rotnroll666 Project Reactor Standard for Spring environments Clean up the resource. Not needed for tx as this is done via the tx function below

Slide 45

Slide 45 text

Michael Simons @rotnroll666 Project Reactor Standard for Spring environments Create something usable from the publisher API. I usually do this as early as possible.

Slide 46

Slide 46 text

Michael Simons @rotnroll666 Project Reactor Standard for Spring environments Apply back pressure here, i.e. - take(n) (Can replace a LIMIT inside the query*) - skip(n) (Can replace a SKIP inside the query*) - takeUntil() - elementAt(i) - bufferUntil

Slide 47

Slide 47 text

Michael Simons @rotnroll666 RxJava2 For example with Micronaut

Slide 48

Slide 48 text

Michael Simons @rotnroll666 RxJava2 For example with Micronaut Yikes… No async clean up here… At least, session creation is correctly deferred

Slide 49

Slide 49 text

Michael Simons @rotnroll666 SmallRye Mutiny! Used in Quarkus

Slide 50

Slide 50 text

Michael Simons @rotnroll666 SmallRye Mutiny! Used in Quarkus Better. Async clean up, too.

Slide 51

Slide 51 text

Writing things

Slide 52

Slide 52 text

Michael Simons @rotnroll666 Very much the same with tx functions

Slide 53

Slide 53 text

Michael Simons @rotnroll666 Very much the same with tx functions Better don’t do a take(n), skip here in case of multiple results. Also not the best idea to expose such a flow directly as an endpoint. take(n) is effectively a „cancel“ and so is an interrupted browser request. in such case a transaction would be rolled back!

Slide 54

Slide 54 text

Michael Simons @rotnroll666 Take control on cancel You will need unmanaged transactions.

Slide 55

Slide 55 text

Michael Simons @rotnroll666 Take control on cancel You will need unmanaged transactions.

Slide 56

Slide 56 text

Michael Simons @rotnroll666 Take control on cancel You will need unmanaged transactions. Create a nested resource: RxSession provides transactions, transactions provides supplier for committing or rolling them back.

Slide 57

Slide 57 text

Michael Simons @rotnroll666 Take control on cancel You will need unmanaged transactions. The usingWhen form has distinct hooks for async complete, error and cancel. Cancel can be „good“ (taken enough) or „bad“ (somethings gone…)

Slide 58

Slide 58 text

Michael Simons @rotnroll666 Just a couple of pitfalls • Inner project semantics, i.e. here Project Reactor, on a Flux • flatMap: Takes every item and maps it concurrently into a new Publisher • concatMap: Same as above, but one at a time • switchMap: Takes the next item, cancels the inner publisher and maps that item into a new Publisher • Different behaviors between libraries Flux/Mono are both Publishers (never null items, strict failures) Multi/Uni feel like Publishers, but only Multi is. Uni drops everything after 1st

Slide 59

Slide 59 text

Michael Simons @rotnroll666 Just a couple of pitfalls • Cancel: Good or bad? Intended or not accident? • Be careful with transaction boundaries

Slide 60

Slide 60 text

SDN 6 For a better living. Imperative and reactive repositories Imperative and reactive templates Imperative and reactive client Integrated with Spring Transactions and Context Driver

Slide 61

Slide 61 text

Michael Simons @rotnroll666 SDN 6 reactive examples

Slide 62

Slide 62 text

Michael Simons @rotnroll666 SDN 6 reactive examples

Slide 63

Slide 63 text

https://github.com/neo4j-examples/sdn6-reactive-multidatabase More examples https://github.com/michael-simons/neo4j-from-the-jvm-ecosystem Spring Data Neo4j 6 centric, with focus on multi db and fabric JVM in general: Plain driver and various OGMs in various frameworks

Slide 64

Slide 64 text

The holy Graal? • High-performance runtime • GraalVM compiler: JIT written in Java, integrated with Hotspot VM through JVM Compiler interface • Language independent representation of guest languages: A graph • The Truffle framework for creating new interpreters for additional languages • The polyglot runtime • Native Image Speaking about GraalVM

Slide 65

Slide 65 text

Just an overview, too many things to cover.

Slide 66

Slide 66 text

Michael Simons @rotnroll666 GraalVM Native image Ahead-of-Time-Compilation • Create native executables or shared libraries • Restrictions apply • Classes / methods used via reflections must be enumerated in most cases • Same applies for resources • There’s an agent helping you todo this • Faster startup, lower memory overhead • Maybe less throughput than a fully warmed up JVM

Slide 67

Slide 67 text

Michael Simons @rotnroll666 GraalVM Native image Does it work with the Neo4j Java driver? YES! • Netty needed some „support“ (a couple of substitutions, mainly inspired by our work with the Quarkus people) • SSL is kinda hard to get right, requires JNI and others enabled on native image generation • Tested to work with • Quarkus • Spring Boot (with SDN 6, currently in Beta) • Helidon (from Oracle, currently in Alpha, PR-Stage)

Slide 68

Slide 68 text

Michael Simons @rotnroll666 GraalVM Native image Use cases • Workloads that needs to be super elastic • „Scale to 0“ • CLI

Slide 69

Slide 69 text

Michael Simons @rotnroll666 GraalVM Polyglot programming Lots of fun.

Slide 70

Slide 70 text

Thank you for your time.

Slide 71

Slide 71 text

Michael Simons @rotnroll666 Image sources • Ventilator by Ronan Furuta: https://unsplash.com/photos/7p8cFwM0Y1s • Bookmarks by Kasturi Roy: https://unsplash.com/photos/bYy9hndOx0k • Goblet by Shannon Douglas: https://unsplash.com/photos/8yeyzVfMv0M • Graal and Neo4j polyglot by Oleg Šelajev for my Medium article: https://medium.com/graalvm/3-ways-to-polyglot-with-graalvm- fb28c1542b45