Skip to content

Commit a216025

Browse files
committed
Make newly created session return no bookmarks
1 parent adb446a commit a216025

File tree

5 files changed

+86
-59
lines changed

5 files changed

+86
-59
lines changed

CHANGELOG.md

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,42 @@
1616
Use `trusted_certificates` instead which expects `None` or a `list`. See the
1717
API documentation for more details.
1818
- `neo4j.time` module:
19-
- `Duration`
20-
- The constructor does not accept `subseconds` anymore.
21-
Use `milliseconds`, `microseconds`, or `nanoseconds` instead.
22-
- The property `subseconds` has been removed.
23-
Use `nanoseconds` instead.
24-
- The property `hours_minutes_seconds` has been removed.
25-
Use `hours_minutes_seconds_nanoseconds` instead.
26-
- For all math operations holds: they are element-wise on
27-
(`months`, `days`, `nanoseconds`).
28-
This affects (i.e., changes) the working of `//`, `%`, `/`, and `*`.
29-
- Years are equal to 12 months.
30-
- Weeks are equal to 7 days.
31-
- `seconds`, `milliseconds`, `microseconds`, and `nanoseconds` are
32-
implicitly converted to `nanoseconds` or `seconds` as fit.
33-
- Multiplication and division allow for floats but will always result in
34-
integer values (round to nearest even).
35-
- `Time`
36-
- The constructor does not accept `float`s for `second` anymore.
37-
Use `nanosecond` instead.
38-
- Ticks are now nanoseconds since midnight (`int`).
39-
- The property `ticks_ns` has been renamed to `ticks`.
40-
The old `ticks` is no longer supported.
41-
- The property`from_ticks_ns` has been renamed to `from_ticks`.
42-
The old `from_ticks` is no longer supported.
43-
- The property `second` returns an `int` instead of a `float`.
44-
Use `nanosecond` to get the sub-second information.
45-
- The property `hour_minute_second` has been removed.
46-
Use `hour_minute_second_nanosecond` instead.
47-
- `DateTime`
48-
- The property `hour_minute_second` has been removed.
49-
Use `hour_minute_second_nanosecond` instead.
50-
- The property `second` returns an `int` instead of a `float`.
51-
Use `nanosecond` to get the sub-second information.
19+
- `Duration`
20+
- The constructor does not accept `subseconds` anymore.
21+
Use `milliseconds`, `microseconds`, or `nanoseconds` instead.
22+
- The property `subseconds` has been removed.
23+
Use `nanoseconds` instead.
24+
- The property `hours_minutes_seconds` has been removed.
25+
Use `hours_minutes_seconds_nanoseconds` instead.
26+
- For all math operations holds: they are element-wise on
27+
(`months`, `days`, `nanoseconds`).
28+
This affects (i.e., changes) the working of `//`, `%`, `/`, and `*`.
29+
- Years are equal to 12 months.
30+
- Weeks are equal to 7 days.
31+
- `seconds`, `milliseconds`, `microseconds`, and `nanoseconds` are
32+
implicitly converted to `nanoseconds` or `seconds` as fit.
33+
- Multiplication and division allow for floats but will always result in
34+
integer values (round to nearest even).
35+
- `Time`
36+
- The constructor does not accept `float`s for `second` anymore.
37+
Use `nanosecond` instead.
38+
- Ticks are now nanoseconds since midnight (`int`).
39+
- The property `ticks_ns` has been renamed to `ticks`.
40+
The old `ticks` is no longer supported.
41+
- The property`from_ticks_ns` has been renamed to `from_ticks`.
42+
The old `from_ticks` is no longer supported.
43+
- The property `second` returns an `int` instead of a `float`.
44+
Use `nanosecond` to get the sub-second information.
45+
- The property `hour_minute_second` has been removed.
46+
Use `hour_minute_second_nanosecond` instead.
47+
- `DateTime`
48+
- The property `hour_minute_second` has been removed.
49+
Use `hour_minute_second_nanosecond` instead.
50+
- The property `second` returns an `int` instead of a `float`.
51+
Use `nanosecond` to get the sub-second information.
52+
- `Session.last_bookmark` returns `None` until the first bookmark has been
53+
received from the server. Previously, it returned the last bookmark of all
54+
the bookmarks passed on session creation.
5255

5356

5457
## Version 4.4

neo4j/_async/work/session.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ class AsyncSession(AsyncWorkspace):
8585
def __init__(self, pool, session_config):
8686
super().__init__(pool, session_config)
8787
assert isinstance(session_config, SessionConfig)
88-
self._bookmarks = tuple(session_config.bookmarks)
88+
self._bookmarks_in = tuple(session_config.bookmarks)
89+
self._bookmark_out = None
8990

9091
def __del__(self):
9192
if asyncio.iscoroutinefunction(self.close):
@@ -110,7 +111,8 @@ async def _connect(self, access_mode):
110111

111112
def _collect_bookmark(self, bookmark):
112113
if bookmark:
113-
self._bookmarks = [bookmark]
114+
self._bookmarks_in = bookmark,
115+
self._bookmark_out = bookmark
114116

115117
async def _result_closed(self):
116118
if self._auto_result:
@@ -217,16 +219,28 @@ async def run(self, query, parameters=None, **kwargs):
217219
await self._auto_result._run(
218220
query, parameters, self._config.database,
219221
self._config.impersonated_user, self._config.default_access_mode,
220-
self._bookmarks, **kwargs
222+
self._bookmarks_in, **kwargs
221223
)
222224

223225
return self._auto_result
224226

225227
async def last_bookmark(self):
226-
"""Return the bookmark received following the last completed transaction.
227-
Note: For auto-transaction (Session.run) this will trigger an consume for the current result.
228+
"""Return the bookmark received from the last completed transaction.
228229
229-
:returns: :class:`neo4j.Bookmark` object
230+
Bookmarks can be used to causally chain sessions. For example,
231+
if a session (``session1``) wrote something, that another session
232+
(``session2``) needs to read, use
233+
``session2 = driver.session(bookmarks=session1.last_bookmark())`` to
234+
achieve this.
235+
236+
A session automatically manages bookmarks, so this method is rarely
237+
needed. If you need causal consistency, try to run the relevant queries
238+
in the same session.
239+
240+
Note: For auto-transaction (Session.run) this will trigger a
241+
``consume`` for the current result.
242+
243+
:returns: str or None
230244
"""
231245
# The set of bookmarks to be passed into the next transaction.
232246

@@ -237,9 +251,7 @@ async def last_bookmark(self):
237251
self._collect_bookmark(self._transaction._bookmark)
238252
self._transaction = None
239253

240-
if len(self._bookmarks):
241-
return self._bookmarks[len(self._bookmarks)-1]
242-
return None
254+
return self._bookmark_out
243255

244256
async def _transaction_closed_handler(self):
245257
if self._transaction:
@@ -262,7 +274,7 @@ async def _open_transaction(self, *, access_mode, metadata=None,
262274
)
263275
await self._transaction._begin(
264276
self._config.database, self._config.impersonated_user,
265-
self._bookmarks, access_mode, metadata, timeout
277+
self._bookmarks_in, access_mode, metadata, timeout
266278
)
267279

268280
async def begin_transaction(self, metadata=None, timeout=None):

neo4j/_async/work/workspace.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def __init__(self, pool, config):
3333
self._connection_access_mode = None
3434
# Sessions are supposed to cache the database on which to operate.
3535
self._cached_database = False
36-
self._bookmarks = None
36+
self._bookmarks_in = None
3737

3838
def __del__(self):
3939
if asyncio.iscoroutinefunction(self.close):
@@ -74,14 +74,14 @@ async def _connect(self, access_mode):
7474
await self._pool.update_routing_table(
7575
database=self._config.database,
7676
imp_user=self._config.impersonated_user,
77-
bookmarks=self._bookmarks,
77+
bookmarks=self._bookmarks_in,
7878
database_callback=self._set_cached_database
7979
)
8080
self._connection = await self._pool.acquire(
8181
access_mode=access_mode,
8282
timeout=self._config.connection_acquisition_timeout,
8383
database=self._config.database,
84-
bookmarks=self._bookmarks
84+
bookmarks=self._bookmarks_in
8585
)
8686
self._connection_access_mode = access_mode
8787

neo4j/_sync/work/session.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ class Session(Workspace):
8585
def __init__(self, pool, session_config):
8686
super().__init__(pool, session_config)
8787
assert isinstance(session_config, SessionConfig)
88-
self._bookmarks = tuple(session_config.bookmarks)
88+
self._bookmarks_in = tuple(session_config.bookmarks)
89+
self._bookmark_out = None
8990

9091
def __del__(self):
9192
if asyncio.iscoroutinefunction(self.close):
@@ -110,7 +111,8 @@ def _connect(self, access_mode):
110111

111112
def _collect_bookmark(self, bookmark):
112113
if bookmark:
113-
self._bookmarks = [bookmark]
114+
self._bookmarks_in = bookmark,
115+
self._bookmark_out = bookmark
114116

115117
def _result_closed(self):
116118
if self._auto_result:
@@ -217,16 +219,28 @@ def run(self, query, parameters=None, **kwargs):
217219
self._auto_result._run(
218220
query, parameters, self._config.database,
219221
self._config.impersonated_user, self._config.default_access_mode,
220-
self._bookmarks, **kwargs
222+
self._bookmarks_in, **kwargs
221223
)
222224

223225
return self._auto_result
224226

225227
def last_bookmark(self):
226-
"""Return the bookmark received following the last completed transaction.
227-
Note: For auto-transaction (Session.run) this will trigger an consume for the current result.
228+
"""Return the bookmark received from the last completed transaction.
228229
229-
:returns: :class:`neo4j.Bookmark` object
230+
Bookmarks can be used to causally chain sessions. For example,
231+
if a session (``session1``) wrote something, that another session
232+
(``session2``) needs to read, use
233+
``session2 = driver.session(bookmarks=session1.last_bookmark())`` to
234+
achieve this.
235+
236+
A session automatically manages bookmarks, so this method is rarely
237+
needed. If you need causal consistency, try to run the relevant queries
238+
in the same session.
239+
240+
Note: For auto-transaction (Session.run) this will trigger a
241+
``consume`` for the current result.
242+
243+
:returns: str or None
230244
"""
231245
# The set of bookmarks to be passed into the next transaction.
232246

@@ -237,9 +251,7 @@ def last_bookmark(self):
237251
self._collect_bookmark(self._transaction._bookmark)
238252
self._transaction = None
239253

240-
if len(self._bookmarks):
241-
return self._bookmarks[len(self._bookmarks)-1]
242-
return None
254+
return self._bookmark_out
243255

244256
def _transaction_closed_handler(self):
245257
if self._transaction:
@@ -262,7 +274,7 @@ def _open_transaction(self, *, access_mode, metadata=None,
262274
)
263275
self._transaction._begin(
264276
self._config.database, self._config.impersonated_user,
265-
self._bookmarks, access_mode, metadata, timeout
277+
self._bookmarks_in, access_mode, metadata, timeout
266278
)
267279

268280
def begin_transaction(self, metadata=None, timeout=None):

neo4j/_sync/work/workspace.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def __init__(self, pool, config):
3333
self._connection_access_mode = None
3434
# Sessions are supposed to cache the database on which to operate.
3535
self._cached_database = False
36-
self._bookmarks = None
36+
self._bookmarks_in = None
3737

3838
def __del__(self):
3939
if asyncio.iscoroutinefunction(self.close):
@@ -74,14 +74,14 @@ def _connect(self, access_mode):
7474
self._pool.update_routing_table(
7575
database=self._config.database,
7676
imp_user=self._config.impersonated_user,
77-
bookmarks=self._bookmarks,
77+
bookmarks=self._bookmarks_in,
7878
database_callback=self._set_cached_database
7979
)
8080
self._connection = self._pool.acquire(
8181
access_mode=access_mode,
8282
timeout=self._config.connection_acquisition_timeout,
8383
database=self._config.database,
84-
bookmarks=self._bookmarks
84+
bookmarks=self._bookmarks_in
8585
)
8686
self._connection_access_mode = access_mode
8787

0 commit comments

Comments
 (0)