Skip to content

Introduce Bookmark Manager #974

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

Merged
merged 43 commits into from
Sep 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
fe1fe4a
Introduce Bookmark Manager
bigmontz Aug 1, 2022
d6945b1
Support BMM during routing
bigmontz Aug 2, 2022
e4b1efe
Adjusting tests
bigmontz Aug 3, 2022
7c7281d
Fixing driver
bigmontz Aug 3, 2022
7ff597c
Add tests to bookmark-manager.ts
bigmontz Aug 3, 2022
16d49cf
Add tests to driver.ts
bigmontz Aug 3, 2022
309ea34
Partially revert "Support BMM during routing"
bigmontz Aug 3, 2022
3a672ea
only update when bookmark arrive
bigmontz Aug 3, 2022
0ff3311
Explicity ignore bookmark manager when ignoreBookmarkManager is true
bigmontz Aug 4, 2022
a3d168b
Add test for session run
bigmontz Aug 4, 2022
0a0b56b
Add test for begin transaction
bigmontz Aug 4, 2022
a968d32
Add tests for commit tx
bigmontz Aug 4, 2022
1c4a4df
Add tests rxSessions
bigmontz Aug 4, 2022
3799568
Add iterator capabilities to Bookmarks
bigmontz Aug 4, 2022
2ed6501
Update docs
bigmontz Aug 5, 2022
733251f
Optimization:MinimalBookmarksSet
bigmontz Aug 8, 2022
b497248
Add BookmarkManager.forget() method
bigmontz Aug 8, 2022
9c1baa1
Add support for testing extensions
bigmontz Aug 9, 2022
179c2e4
Add support for testing extensions
bigmontz Aug 9, 2022
c562e66
Addressing issues detected in the ADR
bigmontz Aug 11, 2022
f4c5c3e
Adjust testkit protocol naming
bigmontz Aug 11, 2022
e388304
Docs
bigmontz Aug 11, 2022
748a8d0
Fix deno issues
bigmontz Aug 11, 2022
9d07673
Avoiding BookmarkManager interface instantiation
bigmontz Aug 11, 2022
66786d7
@ts-ingore Error contructor
bigmontz Aug 11, 2022
0ac2b57
Fix typo
bigmontz Aug 11, 2022
9354389
Apply suggestions from code review
bigmontz Aug 19, 2022
d0cebe3
Apply suggestions from code review
bigmontz Aug 19, 2022
4a138c1
Tweak the interface for not returning duplication
bigmontz Aug 19, 2022
3381818
Update packages/core/src/bookmark-manager.ts
bigmontz Aug 19, 2022
5e26a26
AsyncBookmarkManager
bigmontz Aug 19, 2022
973a61c
SortedEqual
bigmontz Aug 19, 2022
2022527
Do not sent configured bookmarks after receive bookmarks
bigmontz Aug 19, 2022
baff600
Moving configuration to the session
bigmontz Aug 23, 2022
902a286
Testkit: bookmark manager in the session
bigmontz Aug 24, 2022
bea5884
Skipping tests
bigmontz Aug 24, 2022
19694bf
BookmarkManagerClose
bigmontz Aug 29, 2022
f8a4f1e
Enable Rx support StartSubTest
bigmontz Aug 31, 2022
4eb39af
Unskipping tests
bigmontz Aug 31, 2022
bdc483d
remove un-necessary logs
bigmontz Aug 31, 2022
a7bdd3c
Wait for BEGIN be send before send RUN, COMMIT or ROLLBACK
bigmontz Sep 1, 2022
0fe6ccd
addressing pr comments
bigmontz Sep 1, 2022
28cd7cf
Fix test name
bigmontz Sep 1, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ export default class RoutingConnectionProvider extends PooledConnectionProvider
const routingTable = await this._freshRoutingTable({
accessMode,
database: context.database,
bookmarks: bookmarks,
bookmarks,
impersonatedUser,
onDatabaseNameResolved: (databaseName) => {
context.database = context.database || databaseName
Expand Down
187 changes: 187 additions & 0 deletions packages/core/src/bookmark-manager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/**
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [http://neo4j.com]
*
* This file is part of Neo4j.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* Interface for the piece of software responsible for keeping track of current active bookmarks accross the driver.
* @interface
* @since 5.0
* @experimental
*/
export default class BookmarkManager {
/**
* @constructor
* @private
*/
private constructor () {
throw new Error('Not implemented')
}

/**
* Method called when the bookmarks get updated when a transaction finished.
*
* This method will be called when auto-commit queries finish and when explicit transactions
* get commited.
*
* @param {string} database The database which the bookmarks belongs to
* @param {Iterable<string>} previousBookmarks The bookmarks used when starting the transaction
* @param {Iterable<string>} newBookmarks The new bookmarks received at the end of the transaction.
* @returns {void}
*/
async updateBookmarks (database: string, previousBookmarks: Iterable<string>, newBookmarks: Iterable<string>): Promise<void> {
throw new Error('Not implemented')
}

/**
* Method called by the driver to get the bookmarks for one specific database
*
* @param {string} database The database which the bookmarks belong to
* @returns {Iterable<string>} The set of bookmarks
*/
async getBookmarks (database: string): Promise<Iterable<string>> {
throw new Error('Not implemented')
}

/**
* Method called by the driver for getting all the bookmarks.
*
* This method should return all bookmarks for all databases present in the BookmarkManager.
*
* @returns {Iterable<string>} The set of bookmarks
*/
async getAllBookmarks (): Promise<Iterable<string>> {
throw new Error('Not implemented')
}

/**
* Forget the databases and its bookmarks
*
* This method is not called by the driver. Forgetting unused databases is the user's responsibility.
*
* @param {Iterable<string>} databases The databases which the bookmarks will be removed for.
*/
async forget (databases: Iterable<string>): Promise<void> {
throw new Error('Not implemented')
}
}

export interface BookmarkManagerConfig {
initialBookmarks?: Map<string, Iterable<string>>
bookmarksSupplier?: (database?: string) => Promise<Iterable<string>>
bookmarksConsumer?: (database: string, bookmarks: Iterable<string>) => Promise<void>
}

/**
* @typedef {Object} BookmarkManagerConfig
*
* @since 5.0
* @experimental
* @property {Map<string,Iterable<string>>} [initialBookmarks@experimental] Defines the initial set of bookmarks. The key is the database name and the values are the bookmarks.
* @property {function([database]: string):Promise<Iterable<string>>} [bookmarksSupplier] Called for supplying extra bookmarks to the BookmarkManager
* 1. supplying bookmarks from the given database when the default BookmarkManager's `.getBookmarks(database)` gets called.
* 2. supplying all the bookmarks when the default BookmarkManager's `.getAllBookmarks()` gets called
* @property {function(database: string, bookmarks: Iterable<string>): Promise<void>} [bookmarksConsumer] Called when the set of bookmarks for database get updated
*/
/**
* Provides an configured {@link BookmarkManager} instance.
*
* @since 5.0
* @experimental
* @param {BookmarkManagerConfig} [config={}]
* @returns {BookmarkManager}
*/
export function bookmarkManager (config: BookmarkManagerConfig = {}): BookmarkManager {
const initialBookmarks = new Map<string, Set<string>>()

config.initialBookmarks?.forEach((v, k) => initialBookmarks.set(k, new Set(v)))

return new Neo4jBookmarkManager(
initialBookmarks,
config.bookmarksSupplier,
config.bookmarksConsumer
)
}

class Neo4jBookmarkManager implements BookmarkManager {
constructor (
private readonly _bookmarksPerDb: Map<string, Set<string>>,
private readonly _bookmarksSupplier?: (database?: string) => Promise<Iterable<string>>,
private readonly _bookmarksConsumer?: (database: string, bookmark: Iterable<string>) => Promise<void>
) {

}

async updateBookmarks (database: string, previousBookmarks: Iterable<string>, newBookmarks: Iterable<string>): Promise<void> {
const bookmarks = this._getOrInitializeBookmarks(database)
for (const bm of previousBookmarks) {
bookmarks.delete(bm)
}
for (const bm of newBookmarks) {
bookmarks.add(bm)
}
if (typeof this._bookmarksConsumer === 'function') {
await this._bookmarksConsumer(database, [...bookmarks])
}
}

private _getOrInitializeBookmarks (database: string): Set<string> {
let maybeBookmarks = this._bookmarksPerDb.get(database)
if (maybeBookmarks === undefined) {
maybeBookmarks = new Set()
this._bookmarksPerDb.set(database, maybeBookmarks)
}
return maybeBookmarks
}

async getBookmarks (database: string): Promise<Iterable<string>> {
const bookmarks = new Set(this._bookmarksPerDb.get(database))

if (typeof this._bookmarksSupplier === 'function') {
const suppliedBookmarks = await this._bookmarksSupplier(database) ?? []
for (const bm of suppliedBookmarks) {
bookmarks.add(bm)
}
}

return [...bookmarks]
}

async getAllBookmarks (): Promise<Iterable<string>> {
const bookmarks = new Set<string>()

for (const [, dbBookmarks] of this._bookmarksPerDb) {
for (const bm of dbBookmarks) {
bookmarks.add(bm)
}
}
if (typeof this._bookmarksSupplier === 'function') {
const suppliedBookmarks = await this._bookmarksSupplier() ?? []
for (const bm of suppliedBookmarks) {
bookmarks.add(bm)
}
}

return bookmarks
}

async forget (databases: Iterable<string>): Promise<void> {
for (const database of databases) {
this._bookmarksPerDb.delete(database)
}
}
}
Loading