Skip to content

Commit d63e21f

Browse files
authored
Introduce BookmarkManager (#1285)
Bookmark manager is a new opt-in feature that is enabled via driver `Config`. It is responsible for providing an up-to-date set of bookmarks to driver on session creation and database data access. Driver provides a default implementation via `BookmarkManagers.defaultManager`. The default implementation keeps track of a single local driver instance bookmarks only. However, it supports 2 extension points: - `updateListener` - a listener for new bookmarks - `bookmarkSupplier` - a supplier of additional bookmarks It is possible to turn off bookmark manager on session level using `SessionConfig` even when it is enabled on the driver level. Please note that this feature might have an impact on setups that do not manage the driver directly since there is a chance of getting a driver with bookmarks manager enabled. Javadoc includes more general details.
1 parent 7a0515f commit d63e21f

File tree

57 files changed

+1248
-453
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1248
-453
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver;
20+
21+
import java.io.Serializable;
22+
import java.util.Set;
23+
24+
/**
25+
* Keeps track of database bookmarks and is used by the driver to ensure causal consistency between sessions and query executions.
26+
* <p>
27+
* Please note that implementations of this interface MUST NOT block for extended periods of time.
28+
* <p>
29+
* Implementations must avoid calling driver.
30+
*
31+
* @see org.neo4j.driver.Config.ConfigBuilder#withBookmarkManager(BookmarkManager)
32+
*/
33+
public interface BookmarkManager extends Serializable {
34+
/**
35+
* Updates database bookmarks by deleting the given previous bookmarks and adding the new bookmarks.
36+
*
37+
* @param database the database name, this might be an empty string when session has no database name configured and database discovery is unavailable
38+
* @param previousBookmarks the previous bookmarks
39+
* @param newBookmarks the new bookmarks
40+
*/
41+
void updateBookmarks(String database, Set<Bookmark> previousBookmarks, Set<Bookmark> newBookmarks);
42+
43+
/**
44+
* Gets an immutable set of bookmarks for a given database.
45+
*
46+
* @param database the database name
47+
* @return the set of bookmarks or an empty set if the database name is unknown to the bookmark manager
48+
*/
49+
Set<Bookmark> getBookmarks(String database);
50+
51+
/**
52+
* Gets an immutable set of bookmarks for all databases.
53+
*
54+
* @return the set of bookmarks or an empty set
55+
*/
56+
Set<Bookmark> getAllBookmarks();
57+
58+
/**
59+
* Deletes bookmarks for the given databases.
60+
* <p>
61+
* This method should be called by driver users if data deletion is desired when bookmarks for the given databases are no longer needed.
62+
*
63+
* @param databases the set of database names
64+
*/
65+
void forget(Set<String> databases);
66+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver;
20+
21+
import java.util.Collections;
22+
import java.util.Map;
23+
import java.util.Objects;
24+
import java.util.Set;
25+
import java.util.function.BiConsumer;
26+
27+
/**
28+
* Bookmark configuration used to configure bookmark manager supplied by {@link BookmarkManagers#defaultManager(BookmarkManagerConfig)}.
29+
*/
30+
public final class BookmarkManagerConfig {
31+
private final Map<String, Set<Bookmark>> initialBookmarks;
32+
private final BiConsumer<String, Set<Bookmark>> updateListener;
33+
private final BookmarkSupplier bookmarkSupplier;
34+
35+
private BookmarkManagerConfig(BookmarkManagerConfigBuilder builder) {
36+
this.initialBookmarks = builder.initialBookmarks;
37+
this.updateListener = builder.updateListener;
38+
this.bookmarkSupplier = builder.bookmarkSupplier;
39+
}
40+
41+
/**
42+
* Creates a new {@link BookmarkManagerConfigBuilder} used to construct a configuration object.
43+
*
44+
* @return a bookmark manager configuration builder.
45+
*/
46+
public static BookmarkManagerConfigBuilder builder() {
47+
return new BookmarkManagerConfigBuilder();
48+
}
49+
50+
/**
51+
* Returns the map of bookmarks used to initialise the bookmark manager.
52+
*
53+
* @return the map of bookmarks
54+
*/
55+
public Map<String, Set<Bookmark>> initialBookmarks() {
56+
return initialBookmarks;
57+
}
58+
59+
/**
60+
* Returns a bookmark update listener that will be notified when database bookmarks are updated.
61+
*
62+
* @return the update listener or {@code null}
63+
*/
64+
public BiConsumer<String, Set<Bookmark>> updateListener() {
65+
return updateListener;
66+
}
67+
68+
/**
69+
* Returns bookmark supplier that will be used by the bookmark manager when getting bookmarks.
70+
*
71+
* @return the bookmark supplier or {@code null}
72+
*/
73+
public BookmarkSupplier bookmarkSupplier() {
74+
return bookmarkSupplier;
75+
}
76+
77+
/**
78+
* Builder used to configure {@link BookmarkManagerConfig} which will be used to create a bookmark manager.
79+
*/
80+
public static class BookmarkManagerConfigBuilder {
81+
private Map<String, Set<Bookmark>> initialBookmarks = Collections.emptyMap();
82+
private BiConsumer<String, Set<Bookmark>> updateListener;
83+
private BookmarkSupplier bookmarkSupplier;
84+
85+
private BookmarkManagerConfigBuilder() {}
86+
87+
/**
88+
* Provide a map of initial bookmarks to initialise the bookmark manager.
89+
*
90+
* @param databaseToBookmarks database to bookmarks map
91+
* @return this builder
92+
*/
93+
public BookmarkManagerConfigBuilder withInitialBookmarks(Map<String, Set<Bookmark>> databaseToBookmarks) {
94+
Objects.requireNonNull(databaseToBookmarks, "databaseToBookmarks must not be null");
95+
this.initialBookmarks = databaseToBookmarks;
96+
return this;
97+
}
98+
99+
/**
100+
* Provide a bookmarks update listener.
101+
* <p>
102+
* The listener will be called outside bookmark manager's synchronisation lock.
103+
*
104+
* @param updateListener update listener
105+
* @return this builder
106+
*/
107+
public BookmarkManagerConfigBuilder withUpdateListener(BiConsumer<String, Set<Bookmark>> updateListener) {
108+
this.updateListener = updateListener;
109+
return this;
110+
}
111+
112+
/**
113+
* Provide a bookmark supplier.
114+
* <p>
115+
* The supplied bookmarks will be served alongside the bookmarks served by the bookmark manager. The supplied bookmarks will not be stored nor managed by the bookmark manager.
116+
* <p>
117+
* The supplier will be called outside bookmark manager's synchronisation lock.
118+
*
119+
* @param bookmarkSupplier the bookmarks supplier
120+
* @return this builder
121+
*/
122+
public BookmarkManagerConfigBuilder withBookmarksSupplier(BookmarkSupplier bookmarkSupplier) {
123+
this.bookmarkSupplier = bookmarkSupplier;
124+
return this;
125+
}
126+
127+
public BookmarkManagerConfig build() {
128+
return new BookmarkManagerConfig(this);
129+
}
130+
}
131+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver;
20+
21+
import org.neo4j.driver.internal.Neo4jBookmarkManager;
22+
23+
/**
24+
* Setups new instances of {@link BookmarkManager}.
25+
*/
26+
public interface BookmarkManagers {
27+
/**
28+
* Setups a new instance of bookmark manager that can be used in {@link org.neo4j.driver.Config.ConfigBuilder#withBookmarkManager(BookmarkManager)}.
29+
*
30+
* @param config the bookmark manager configuration
31+
* @return the bookmark manager
32+
*/
33+
static BookmarkManager defaultManager(BookmarkManagerConfig config) {
34+
return new Neo4jBookmarkManager(config.initialBookmarks(), config.updateListener(), config.bookmarkSupplier());
35+
}
36+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright (c) "Neo4j"
3+
* Neo4j Sweden AB [http://neo4j.com]
4+
*
5+
* This file is part of Neo4j.
6+
*
7+
* Licensed under the Apache License, Version 2.0 (the "License");
8+
* you may not use this file except in compliance with the License.
9+
* You may obtain a copy of the License at
10+
*
11+
* http://www.apache.org/licenses/LICENSE-2.0
12+
*
13+
* Unless required by applicable law or agreed to in writing, software
14+
* distributed under the License is distributed on an "AS IS" BASIS,
15+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
* See the License for the specific language governing permissions and
17+
* limitations under the License.
18+
*/
19+
package org.neo4j.driver;
20+
21+
import java.util.Set;
22+
23+
/**
24+
* Supplies additional bookmarks to {@link BookmarkManager} implementation provided by {@link BookmarkManagers#defaultManager(BookmarkManagerConfig)}.
25+
* <p>
26+
* Implementations must avoid calling driver.
27+
*/
28+
public interface BookmarkSupplier {
29+
/**
30+
* Supplies a set of bookmarks for a given database.
31+
*
32+
* @param database the database name
33+
* @return the set of bookmarks, must not be {@code null}
34+
*/
35+
Set<Bookmark> getBookmarks(String database);
36+
37+
/**
38+
* Supplies a set of bookmarks for all databases.
39+
*
40+
* @return the set of bookmarks, must not be {@code null}
41+
*/
42+
Set<Bookmark> getAllBookmarks();
43+
}

driver/src/main/java/org/neo4j/driver/Config.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ public class Config implements Serializable {
9898
private final int eventLoopThreads;
9999
private final String userAgent;
100100
private final MetricsAdapter metricsAdapter;
101+
private final BookmarkManager bookmarkManager;
101102

102103
private Config(ConfigBuilder builder) {
103104
this.logging = builder.logging;
@@ -119,6 +120,8 @@ private Config(ConfigBuilder builder) {
119120

120121
this.eventLoopThreads = builder.eventLoopThreads;
121122
this.metricsAdapter = builder.metricsAdapter;
123+
124+
this.bookmarkManager = builder.bookmarkManager;
122125
}
123126

124127
/**
@@ -252,6 +255,15 @@ public String userAgent() {
252255
return userAgent;
253256
}
254257

258+
/**
259+
* A {@link BookmarkManager} implementation for the driver to use.
260+
*
261+
* @return bookmark implementation or {@code null}.
262+
*/
263+
public BookmarkManager bookmarkManager() {
264+
return bookmarkManager;
265+
}
266+
255267
/**
256268
* Used to build new config instances
257269
*/
@@ -272,6 +284,7 @@ public static class ConfigBuilder {
272284
private MetricsAdapter metricsAdapter = MetricsAdapter.DEV_NULL;
273285
private long fetchSize = FetchSizeUtil.DEFAULT_FETCH_SIZE;
274286
private int eventLoopThreads = 0;
287+
private BookmarkManager bookmarkManager;
275288

276289
private ConfigBuilder() {}
277290

@@ -645,6 +658,19 @@ public ConfigBuilder withUserAgent(String userAgent) {
645658
return this;
646659
}
647660

661+
/**
662+
* Sets a {@link BookmarkManager} implementation for the driver to use.
663+
* <p>
664+
* By default, bookmark manager is effectively disabled.
665+
*
666+
* @param bookmarkManager bookmark manager implementation. Providing {@code null} effectively disables bookmark manager.
667+
* @return this builder.
668+
*/
669+
public ConfigBuilder withBookmarkManager(BookmarkManager bookmarkManager) {
670+
this.bookmarkManager = bookmarkManager;
671+
return this;
672+
}
673+
648674
/**
649675
* Extracts the driver version from the driver jar MANIFEST.MF file.
650676
*/

0 commit comments

Comments
 (0)