Skip to content

Commit b7ffc78

Browse files
authored
Move BookmarkManager at the session level
1 parent 1ccb037 commit b7ffc78

File tree

4 files changed

+69
-48
lines changed

4 files changed

+69
-48
lines changed

neo4j/bookmarks.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ type BookmarkManager interface {
4949
Forget(databases ...string)
5050
}
5151

52+
// BookmarkManagerConfig is an experimental API and may be changed or removed
53+
// without prior notice
5254
type BookmarkManagerConfig struct {
5355
// Initial bookmarks per database
5456
InitialBookmarks map[string]Bookmarks

neo4j/config.go

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,6 @@ type Config struct {
140140
// If a single large result is to be retrieved, this is the most performant
141141
// setting.
142142
FetchSize int
143-
// BookmarkManager defines a central point to externally supply bookmarks
144-
// and be notified of bookmark updates per database
145-
// Since 5.0
146-
// default: nil (no-op)
147-
BookmarkManager BookmarkManager
148143
}
149144

150145
func defaultConfig() *Config {
@@ -159,7 +154,6 @@ func defaultConfig() *Config {
159154
RootCAs: nil,
160155
UserAgent: UserAgent,
161156
FetchSize: FetchDefault,
162-
BookmarkManager: nil,
163157
}
164158
}
165159

neo4j/session_with_context.go

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -107,12 +107,12 @@ type SessionConfig struct {
107107
// to the correct cluster member (different databases may have different
108108
// leaders).
109109
ImpersonatedUser string
110-
// IgnoreBookmarkManager allows specific sessions to ignore the
111-
// globally-configured bookmark manager
112-
// Sessions with this setting will handle bookmarks as before the bookmark
113-
// manager was introduced
110+
// BookmarkManager defines a central point to externally supply bookmarks
111+
// and be notified of bookmark updates per database
112+
// This is experimental and may be changed or removed without prior notice
114113
// Since 5.0
115-
IgnoreBookmarkManager bool
114+
// default: nil (no-op)
115+
BookmarkManager BookmarkManager
116116
}
117117

118118
// FetchAll turns off fetching records in batches.
@@ -157,16 +157,12 @@ func newSessionWithContext(config *Config, sessConfig SessionConfig, router sess
157157
fetchSize = sessConfig.FetchSize
158158
}
159159

160-
configuredBookmarkManager := config.BookmarkManager
161-
if sessConfig.IgnoreBookmarkManager {
162-
configuredBookmarkManager = nil
163-
}
164160
return &sessionWithContext{
165161
config: config,
166162
router: router,
167163
pool: pool,
168164
defaultMode: idb.AccessMode(sessConfig.AccessMode),
169-
bookmarks: newSessionBookmarks(configuredBookmarkManager, sessConfig.Bookmarks),
165+
bookmarks: newSessionBookmarks(sessConfig.BookmarkManager, sessConfig.Bookmarks),
170166
databaseName: sessConfig.DatabaseName,
171167
impersonatedUser: sessConfig.ImpersonatedUser,
172168
resolveHomeDb: sessConfig.DatabaseName == "",

testkit-backend/backend.go

Lines changed: 61 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ type backend struct {
5353
wrLock sync.Mutex
5454
suppliedBookmarks map[string]neo4j.Bookmarks
5555
consumedBookmarks map[string]struct{}
56+
bookmarkManagers map[string]neo4j.BookmarkManager
5657
}
5758

5859
// To implement transactional functions a bit of extra state is needed on the
@@ -83,6 +84,7 @@ func newBackend(rd *bufio.Reader, wr io.Writer) *backend {
8384
recordedErrors: make(map[string]error),
8485
resolvedAddresses: make(map[string][]any),
8586
id: 0,
87+
bookmarkManagers: make(map[string]neo4j.BookmarkManager),
8688
suppliedBookmarks: make(map[string]neo4j.Bookmarks),
8789
consumedBookmarks: make(map[string]struct{}),
8890
}
@@ -448,9 +450,6 @@ func (b *backend) handleRequest(req map[string]any) {
448450
if data["connectionTimeoutMs"] != nil {
449451
c.SocketConnectTimeout = time.Millisecond * time.Duration(asInt64(data["connectionTimeoutMs"].(json.Number)))
450452
}
451-
if data["bookmarkManager"] != nil {
452-
c.BookmarkManager = neo4j.NewBookmarkManager(b.bookmarkManagerConfig(data["bookmarkManager"].(map[string]any)))
453-
}
454453
})
455454
if err != nil {
456455
b.writeError(err)
@@ -516,14 +515,35 @@ func (b *backend) handleRequest(req map[string]any) {
516515
if data["impersonatedUser"] != nil {
517516
sessionConfig.ImpersonatedUser = data["impersonatedUser"].(string)
518517
}
519-
if data["ignoreBookmarkManager"] != nil {
520-
sessionConfig.IgnoreBookmarkManager = data["ignoreBookmarkManager"].(bool)
518+
if data["bookmarkManagerId"] != nil {
519+
bmmId := data["bookmarkManagerId"].(string)
520+
bookmarkManager := b.bookmarkManagers[bmmId]
521+
if bookmarkManager == nil {
522+
b.writeError(fmt.Errorf("could not find bookmark manager with ID %s", bmmId))
523+
return
524+
}
525+
sessionConfig.BookmarkManager = bookmarkManager
521526
}
522527
session := driver.NewSession(ctx, sessionConfig)
523528
idKey := b.nextId()
524529
b.sessionStates[idKey] = &sessionState{session: session}
525530
b.writeResponse("Session", map[string]any{"id": idKey})
526531

532+
case "NewBookmarkManager":
533+
bookmarkManagerId := b.nextId()
534+
b.bookmarkManagers[bookmarkManagerId] = neo4j.NewBookmarkManager(
535+
b.bookmarkManagerConfig(bookmarkManagerId, data))
536+
b.writeResponse("BookmarkManager", map[string]any{
537+
"id": bookmarkManagerId,
538+
})
539+
540+
case "BookmarkManagerClose":
541+
bookmarkManagerId := data["id"].(string)
542+
delete(b.bookmarkManagers, bookmarkManagerId)
543+
b.writeResponse("BookmarkManager", map[string]any{
544+
"id": bookmarkManagerId,
545+
})
546+
527547
case "SessionClose":
528548
sessionId := data["sessionId"].(string)
529549
sessionState := b.sessionStates[sessionId]
@@ -1076,50 +1096,59 @@ func patchNumbersInMap(dictionary map[string]any) error {
10761096
return nil
10771097
}
10781098

1079-
func (b *backend) bookmarkManagerConfig(config map[string]any) neo4j.BookmarkManagerConfig {
1099+
func (b *backend) bookmarkManagerConfig(bookmarkManagerId string,
1100+
config map[string]any) neo4j.BookmarkManagerConfig {
1101+
10801102
var initialBookmarks map[string]neo4j.Bookmarks
10811103
if config["initialBookmarks"] != nil {
10821104
initialBookmarks = convertInitialBookmarks(config["initialBookmarks"].(map[string]any))
10831105
}
10841106
result := neo4j.BookmarkManagerConfig{InitialBookmarks: initialBookmarks}
10851107
supplierRegistered := config["bookmarksSupplierRegistered"]
10861108
if supplierRegistered != nil && supplierRegistered.(bool) {
1087-
result.BookmarkSupplier = &testkitBookmarkSupplier{supplierFn: b.supplyBookmarks}
1109+
result.BookmarkSupplier = &testkitBookmarkSupplier{
1110+
supplierFn: b.supplyBookmarks(bookmarkManagerId),
1111+
}
10881112
}
10891113
consumerRegistered := config["bookmarksConsumerRegistered"]
10901114
if consumerRegistered != nil && consumerRegistered.(bool) {
1091-
result.BookmarkUpdateNotifier = b.consumeBookmarks
1115+
result.BookmarkUpdateNotifier = b.consumeBookmarks(bookmarkManagerId)
10921116
}
10931117
return result
10941118
}
10951119

1096-
func (b *backend) supplyBookmarks(databases ...string) neo4j.Bookmarks {
1097-
if len(databases) > 1 {
1098-
panic("at most 1 database should be specified")
1099-
}
1100-
id := b.nextId()
1101-
msg := map[string]any{"id": id}
1102-
if len(databases) == 1 {
1103-
msg["database"] = databases[0]
1104-
}
1105-
b.writeResponse("BookmarksSupplierRequest", msg)
1106-
for {
1107-
b.process()
1108-
return b.suppliedBookmarks[id]
1120+
func (b *backend) supplyBookmarks(bookmarkManagerId string) func(...string) neo4j.Bookmarks {
1121+
return func(databases ...string) neo4j.Bookmarks {
1122+
if len(databases) > 1 {
1123+
panic("at most 1 database should be specified")
1124+
}
1125+
id := b.nextId()
1126+
msg := map[string]any{"id": id, "bookmarkManagerId": bookmarkManagerId}
1127+
if len(databases) == 1 {
1128+
msg["database"] = databases[0]
1129+
}
1130+
b.writeResponse("BookmarksSupplierRequest", msg)
1131+
for {
1132+
b.process()
1133+
return b.suppliedBookmarks[id]
1134+
}
11091135
}
11101136
}
11111137

1112-
func (b *backend) consumeBookmarks(database string, bookmarks neo4j.Bookmarks) {
1113-
id := b.nextId()
1114-
b.writeResponse("BookmarksConsumerRequest", map[string]any{
1115-
"id": id,
1116-
"database": database,
1117-
"bookmarks": bookmarks,
1118-
})
1119-
for {
1120-
b.process()
1121-
if _, found := b.consumedBookmarks[id]; found {
1122-
return
1138+
func (b *backend) consumeBookmarks(bookmarkManagerId string) func(string, neo4j.Bookmarks) {
1139+
return func(database string, bookmarks neo4j.Bookmarks) {
1140+
id := b.nextId()
1141+
b.writeResponse("BookmarksConsumerRequest", map[string]any{
1142+
"id": id,
1143+
"bookmarkManagerId": bookmarkManagerId,
1144+
"database": database,
1145+
"bookmarks": bookmarks,
1146+
})
1147+
for {
1148+
b.process()
1149+
if _, found := b.consumedBookmarks[id]; found {
1150+
return
1151+
}
11231152
}
11241153
}
11251154
}

0 commit comments

Comments
 (0)