Skip to content

Bump neo4j driver / Improve connection handling in CLI #3218

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 9 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
@@ -0,0 +1,13 @@
diff --git a/lib/pool/pool.js b/lib/pool/pool.js
index 659d80681ce11387e3d4eee645c5cbf3df7bcb30..bad49c310096fd02ecaddf907642aec78c44ced8 100644
--- a/lib/pool/pool.js
+++ b/lib/pool/pool.js
@@ -134,6 +134,8 @@ var Pool = /** @class */ (function () {
request.reject((0, neo4j_driver_core_1.newError)("Connection acquisition timed out in ".concat(_this._acquisitionTimeout, " ms. Pool status: Active conn count = ").concat(activeCount, ", Idle conn count = ").concat(idleCount, ".")));
}
}, _this._acquisitionTimeout);
+ // https://github.com/neo4j/neo4j-javascript-driver/pull/1196
+ timeoutId.unref();
request = new PendingRequest(key, acquisitionContext, config, resolve, reject, timeoutId, _this._log);
allRequests[key].push(request);
_this._processPendingAcquireRequests(address);
17 changes: 17 additions & 0 deletions .yarn/patches/neo4j-driver-core-npm-5.20.0-99216f6938.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
diff --git a/lib/transaction.js b/lib/transaction.js
index 8c97e77e79bc40856fc51c0f0d315fd6e4e5e763..1d16fcac7009d9c506bcdbabdef7890b2c8296f2 100644
--- a/lib/transaction.js
+++ b/lib/transaction.js
@@ -284,6 +284,12 @@ var Transaction = /** @class */ (function () {
// error will be "acknowledged" by sending a RESET message
// database will then forget about this transaction and cleanup all corresponding resources
// it is thus safe to move this transaction to a FAILED state and disallow any further interactions with it
+
+ if (this._state === _states.FAILED) {
+ // already failed, nothing to do
+ // if we call onError for each result again, we might run into an infinite loop, that causes an OOM eventually
+ return Promise.resolve(null)
+ }
this._state = _states.FAILED;
this._onClose();
this._results.forEach(function (result) {
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@
"luxon": "^3.4.3",
"mime": "beta",
"nanoid": "^4.0.2",
"neo4j-driver": "^5.14.0",
"neo4j-driver": "^5.20.0",
"p-retry": "^5.1.2",
"pako": "^2.1.0",
"pkg-up": "^4.0.0",
Expand Down Expand Up @@ -150,6 +150,8 @@
},
"resolutions": {
"cypher-query-builder/neo4j-driver": "^5.9.0",
"neo4j-driver-bolt-connection@npm:5.20.0": "patch:neo4j-driver-bolt-connection@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-bolt-connection-npm-5.20.0-1f7809f435.patch",
"neo4j-driver-core@npm:5.20.0": "patch:neo4j-driver-core@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-core-npm-5.20.0-99216f6938.patch",
"@apollo/server-plugin-landing-page-graphql-playground": "npm:empty-npm-package@*",
"@nestjs/cli/fork-ts-checker-webpack-plugin": "npm:empty-npm-package@*",
"@nestjs/cli/webpack": "npm:empty-npm-package@*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export class AuthenticationEdgeDBRepository
await this.db.waitForConnection({
forever: true,
maxTimeout: { seconds: 10 },
unref: true,
});
return await this.getRootUserId();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class AuthenticationRepository {
{
forever: true,
maxTimeout: { seconds: 10 },
unref: true,
},
async () => {
// Ensure the root user exists, if not keep waiting
Expand Down
3 changes: 3 additions & 0 deletions src/core/core.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { ExceptionNormalizer } from './exception/exception.normalizer';
import { GraphqlModule } from './graphql';
import { ResourceModule } from './resources/resource.module';
import { ScalarProviders } from './scalars.resolver';
import { ShutdownHookProvider } from './shutdown.hook';
import { TimeoutInterceptor } from './timeout.interceptor';
import { TracingModule } from './tracing';
import { ValidationModule } from './validation/validation.module';
Expand Down Expand Up @@ -46,6 +47,7 @@ import { WaitResolver } from './wait.resolver';
{ provide: APP_INTERCEPTOR, useClass: TimeoutInterceptor },
WaitResolver,
...ScalarProviders,
ShutdownHookProvider,
],
controllers: [CoreController],
exports: [
Expand All @@ -59,6 +61,7 @@ import { WaitResolver } from './wait.resolver';
EmailModule,
EventsModule,
ResourceModule,
ShutdownHookProvider,
TracingModule,
ValidationModule,
],
Expand Down
30 changes: 22 additions & 8 deletions src/core/database/database.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { Injectable } from '@nestjs/common';
import { entries, mapKeys } from '@seedcompany/common';
import { Connection, node, Query, relation } from 'cypher-query-builder';
import { LazyGetter } from 'lazy-get-decorator';
import { pickBy, startCase } from 'lodash';
import { Duration } from 'luxon';
import { defer, firstValueFrom, shareReplay, takeUntil } from 'rxjs';
import {
DuplicateException,
ID,
Expand All @@ -15,6 +18,7 @@ import {
import { AbortError, retry, RetryOptions } from '~/common/retry';
import { ConfigService } from '../config/config.service';
import { ILogger, Logger } from '../logger';
import { ShutdownHook } from '../shutdown.hook';
import { DbChanges } from './changes';
import {
createBetterError,
Expand Down Expand Up @@ -56,6 +60,7 @@ export class DatabaseService {
constructor(
private readonly db: Connection,
private readonly config: ConfigService,
private readonly shutdown$: ShutdownHook,
@Logger('database:service') private readonly logger: ILogger,
) {}

Expand Down Expand Up @@ -120,7 +125,20 @@ export class DatabaseService {
return q;
}

async getServerInfo(): Promise<ServerInfo> {
async getServerInfo() {
return await firstValueFrom(this.serverInfo$);
}
@LazyGetter() private get serverInfo$() {
return defer(() => this.queryServerInfo()).pipe(
takeUntil(this.shutdown$),
shareReplay({
refCount: false,
bufferSize: 1,
windowTime: Duration.from('3 mins').toMillis(),
}),
);
}
private async queryServerInfo(): Promise<ServerInfo> {
// @ts-expect-error Yes this is private, but we have a special use case.
// We need to run this query with a session that's not configured to use the
// database that may not exist.
Expand Down Expand Up @@ -171,22 +189,18 @@ export class DatabaseService {
if (!dbName || info.databases.some((db) => db.name === dbName)) {
return; // already exists or assuming default exists
}
await this.runAdminCommand('CREATE', dbName, info);
await this.runAdminCommand('CREATE', dbName);
}

async dropDb() {
const dbName = this.config.neo4j.database;
if (!dbName) {
return; // don't drop the default db
}
await this.runAdminCommand('DROP', dbName, await this.getServerInfo());
await this.runAdminCommand('DROP', dbName);
}

private async runAdminCommand(
action: 'CREATE' | 'DROP',
dbName: string,
_info: ServerInfo,
) {
private async runAdminCommand(action: 'CREATE' | 'DROP', dbName: string) {
// @ts-expect-error Yes this is private, but we have a special use case.
// We need to run this query with a session that's not configured to use the
// database we are trying to create.
Expand Down
4 changes: 3 additions & 1 deletion src/core/database/migration/migration.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ export class MigrationModule implements OnModuleInit {
) {}

async onModuleInit() {
const entryCmd = process.argv.join('');
if (
!this.config.dbAutoMigrate ||
process.argv.join('').includes('console')
entryCmd.includes('console') ||
entryCmd.includes('repl')
) {
return;
}
Expand Down
19 changes: 19 additions & 0 deletions src/core/shutdown.hook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { OnApplicationShutdown, Provider } from '@nestjs/common';
import { Observable, Subject } from 'rxjs';

export class ShutdownHook extends Observable<void> {}

class ShutdownHookImpl
extends Subject<void>
implements OnApplicationShutdown, ShutdownHook
{
onApplicationShutdown() {
this.next();
this.complete();
}
}

export const ShutdownHookProvider: Provider = {
provide: ShutdownHook,
useClass: ShutdownHookImpl,
};
50 changes: 34 additions & 16 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5430,7 +5430,7 @@ __metadata:
luxon: "npm:^3.4.3"
mime: "npm:beta"
nanoid: "npm:^4.0.2"
neo4j-driver: "npm:^5.14.0"
neo4j-driver: "npm:^5.20.0"
p-retry: "npm:^5.1.2"
pako: "npm:^2.1.0"
pkg-up: "npm:^4.0.0"
Expand Down Expand Up @@ -10311,32 +10311,50 @@ __metadata:
languageName: node
linkType: hard

"neo4j-driver-bolt-connection@npm:5.14.0":
version: 5.14.0
resolution: "neo4j-driver-bolt-connection@npm:5.14.0"
"neo4j-driver-bolt-connection@npm:5.20.0":
version: 5.20.0
resolution: "neo4j-driver-bolt-connection@npm:5.20.0"
dependencies:
buffer: "npm:^6.0.3"
neo4j-driver-core: "npm:5.14.0"
neo4j-driver-core: "npm:5.20.0"
string_decoder: "npm:^1.3.0"
checksum: 10c0/5e070a4b307473ffc51d90fc3423e173af3e8ce11b398feca5e86b22655e3ed8b113af8e13e1fae2e08a1bea24a00db84c0c6fbee37b6897589a15ebf712348b
checksum: 10c0/a60b51192a37a5c86b7fcdbac4ef56a647c3ebe8596ab813b7354188ee3659426f14aaad7fa1025ebc5e07eecabe89c8f2e33d95663c9cd8e49263c12c287c22
languageName: node
linkType: hard

"neo4j-driver-core@npm:5.14.0":
version: 5.14.0
resolution: "neo4j-driver-core@npm:5.14.0"
checksum: 10c0/e432a8e7054ba7ecd4d4767bcb0d5a8ea79c35235ae383c5b5fb6195920714e8c124659cc116493e60b86565f4a3ab7e32211f14ea175cb659451327e6309df6
"neo4j-driver-bolt-connection@patch:neo4j-driver-bolt-connection@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-bolt-connection-npm-5.20.0-1f7809f435.patch":
version: 5.20.0
resolution: "neo4j-driver-bolt-connection@patch:neo4j-driver-bolt-connection@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-bolt-connection-npm-5.20.0-1f7809f435.patch::version=5.20.0&hash=c7fd0b"
dependencies:
buffer: "npm:^6.0.3"
neo4j-driver-core: "npm:5.20.0"
string_decoder: "npm:^1.3.0"
checksum: 10c0/81c33ad9203a1d948deffca4d98b6ed162e46f9bdf1e2867fa4e9361a6e63c7b61208432d84ccd7ef9c0fcac7ff8b9e8ccc80226a28d102f195fe53d5d517347
languageName: node
linkType: hard

"neo4j-driver-core@npm:5.20.0":
version: 5.20.0
resolution: "neo4j-driver-core@npm:5.20.0"
checksum: 10c0/162ef4953bf04643c7d21b777b5cc0a9fb01aad7e9098bae5eb272de9d88d877808c43406f04db4c245306f501af31f7f5d9d3115f0f635758af394bae5fba17
languageName: node
linkType: hard

"neo4j-driver-core@patch:neo4j-driver-core@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-core-npm-5.20.0-99216f6938.patch":
version: 5.20.0
resolution: "neo4j-driver-core@patch:neo4j-driver-core@npm%3A5.20.0#~/.yarn/patches/neo4j-driver-core-npm-5.20.0-99216f6938.patch::version=5.20.0&hash=60e3d3"
checksum: 10c0/957b21375a430ae1973dac04adcdd2806595e5811c70ed46d2273f6df36c977ce94a7dedbf0dd2d7b5bf724ae06c1f86a29550ddabd6c532304257ecbe74a0c8
languageName: node
linkType: hard

"neo4j-driver@npm:^5.14.0, neo4j-driver@npm:^5.9.0":
version: 5.14.0
resolution: "neo4j-driver@npm:5.14.0"
"neo4j-driver@npm:^5.20.0, neo4j-driver@npm:^5.9.0":
version: 5.20.0
resolution: "neo4j-driver@npm:5.20.0"
dependencies:
neo4j-driver-bolt-connection: "npm:5.14.0"
neo4j-driver-core: "npm:5.14.0"
neo4j-driver-bolt-connection: "npm:5.20.0"
neo4j-driver-core: "npm:5.20.0"
rxjs: "npm:^7.8.1"
checksum: 10c0/e6b5def70af63a756c23e0e10153c95bf454b07540024bbe166b9b5bd954cfca0e79c2be101ec7bf1832d1a58650ac74acb330f903e40b3213a7727a83cb64d0
checksum: 10c0/1ed4cc3bcf4d0a5f6742aa5a2224ee1f1006ccedd5e62e3c15d612e4dd46d1ec67f1039a69aa008123da1ec74ff5369f760cb9e068b49b1624efbcdf622671a1
languageName: node
linkType: hard

Expand Down
Loading