From d1357e59ccb029b0b5f96360f16ae4801238a0dd Mon Sep 17 00:00:00 2001 From: Zeeshan Akram <97m.zeeshan@gmail.com> Date: Tue, 19 Jul 2022 16:39:49 +0500 Subject: [PATCH 1/5] changed BaseModel's createdAt & updatedAt field types --- package.json | 2 +- src/core/BaseModel.ts | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index b05e45a7..0d8039c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@joystream/warthog", - "version": "2.41.8", + "version": "2.41.9", "description": "Opinionated set of tools for setting up GraphQL backed by TypeORM", "main": "dist/index.js", "types": "dist/types/index.d.ts", diff --git a/src/core/BaseModel.ts b/src/core/BaseModel.ts index 4e700da9..73abb012 100644 --- a/src/core/BaseModel.ts +++ b/src/core/BaseModel.ts @@ -3,10 +3,8 @@ import { Field, ID, Int, InterfaceType, ObjectType } from 'type-graphql'; import { BeforeInsert, Column, - CreateDateColumn, PrimaryColumn, PrimaryGeneratedColumn, - UpdateDateColumn, VersionColumn, } from 'typeorm'; @@ -41,10 +39,10 @@ export abstract class BaseModel implements BaseGraphQLObject { @PrimaryColumn({ type: String }) id!: IDType; - @CreateDateColumn() createdAt!: Date; + @Column() createdAt!: Date; @Column() createdById!: IDType; - @UpdateDateColumn({ nullable: true }) + @Column({ nullable: true }) updatedAt?: Date; @Column({ nullable: true }) updatedById?: IDType; @@ -82,10 +80,10 @@ export abstract class BaseModelUUID implements BaseGraphQLObject { @PrimaryGeneratedColumn('uuid') id!: IDType; - @CreateDateColumn() createdAt!: Date; + @Column() createdAt!: Date; @Column() createdById!: IDType; - @UpdateDateColumn({ nullable: true }) + @Column({ nullable: true }) updatedAt?: Date; @Column({ nullable: true }) updatedById?: IDType; From 96ff04d0efba5d1371a2eac582c1dbb53bd51bdb Mon Sep 17 00:00:00 2001 From: Theophile Sandoz Date: Tue, 12 Mar 2024 13:08:26 +0100 Subject: [PATCH 2/5] Add a resolver timeout option --- README.md | 2 ++ src/middleware/DataLoaderMiddleware.ts | 42 +++++++++++++++++++------- 2 files changed, 33 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9c1666a6..e1846801 100644 --- a/README.md +++ b/README.md @@ -326,6 +326,8 @@ Almost all config in Warthog is driven by environment variables. The following i | WARTHOG_RESOLVERS_PATH | Where should Warthog look for resolvers | src/\*\*\/\*.resolver.ts | | WARTHOG_SUBSCRIPTIONS | Should we enable subscriptions and open a websocket port | false | | WARTHOG_VALIDATE_RESOLVERS | TypeGraphQL validation enabled? | false | +| WARTHOG_RESOLVER_TIMEOUT_MS | Highest time a resolver should take before timing out | _none_ | +| WARTHOG_RELATION_CONCURRENCY | Max number of relations a resolver can query in parallel | 30 | ## Field/Column Decorators diff --git a/src/middleware/DataLoaderMiddleware.ts b/src/middleware/DataLoaderMiddleware.ts index 04bf20ad..11c43de9 100644 --- a/src/middleware/DataLoaderMiddleware.ts +++ b/src/middleware/DataLoaderMiddleware.ts @@ -1,13 +1,10 @@ import * as DataLoader from 'dataloader'; +import { chunk } from 'lodash'; import { MiddlewareInterface, NextFn, ResolverData } from 'type-graphql'; import { Service } from 'typedi'; import { BaseContext } from '../core'; -interface Deleteable { - deletedAt?: string; -} - @Service() export class DataLoaderMiddleware implements MiddlewareInterface { async use({ context }: ResolverData, next: NextFn) { @@ -17,6 +14,9 @@ export class DataLoaderMiddleware implements MiddlewareInterface { loaders: {}, }; + const reqTimeout = Number(process.env.WARTHOG_RESOLVER_TIMEOUT_MS); + const abortSignal = reqTimeout ? AbortSignal.timeout(reqTimeout) : undefined; + const loaders = context.dataLoader.loaders; context.connection.entityMetadatas.forEach((entityMetadata) => { @@ -36,18 +36,38 @@ export class DataLoaderMiddleware implements MiddlewareInterface { if (Array.isArray(entities) && entities[0] && Array.isArray(entities[0])) { throw new Error('You must flatten arrays of arrays of entities'); } - return Promise.all( - entities.map((entity) => context.connection.relationLoader.load(relation, entity)) - ).then(function (results) { - return results.map(function (related) { - return relation.isManyToOne || relation.isOneToOne ? related[0] : related; - }); - }); + + const chunkSize = Number(process.env.WARTHOG_RELATION_CONCURRENCY) || 30; + return chunk(entities, chunkSize).reduce>( + async (prev, entityChunk) => { + const next = await prev; + + if (abortSignal?.aborted) { + throw new Error('Resolver timed out'); + } + + const results = await Promise.all( + entityChunk.map((entity) => + context.connection.relationLoader.load(relation, entity) + ) + ); + + next.push( + ...results.map((related) => + relation.isManyToOne || relation.isOneToOne ? related[0] : related + ) + ); + + return next; + }, + Promise.resolve([]) + ); }); } }); }); } + return next(); } } From 99f88db6f612faf8ac3ae4562b8d601c0d0c52ef Mon Sep 17 00:00:00 2001 From: Theophile Sandoz Date: Tue, 12 Mar 2024 13:09:30 +0100 Subject: [PATCH 3/5] Fix the missing `AbortSignal.timeout` type --- package.json | 5 ++++- tsconfig.json | 3 ++- yarn.lock | 8 ++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 0d8039c7..b6afc042 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,9 @@ "description": "Opinionated set of tools for setting up GraphQL backed by TypeORM", "main": "dist/index.js", "types": "dist/types/index.d.ts", + "engines": { + "node": ">=18" + }, "bin": { "warthog": "bin/warthog" }, @@ -107,7 +110,7 @@ "typedi": "^0.8.0", "typeorm": "https://github.com/Joystream/typeorm/releases/download/0.3.5/typeorm-v0.3.5.tgz", "typeorm-typedi-extensions": "^0.4.1", - "typescript": "^4.4" + "typescript": "^5.4.2" }, "devDependencies": { "@commitlint/cli": "^8.3.5", diff --git a/tsconfig.json b/tsconfig.json index 05355aea..42b6685c 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,6 +7,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "forceConsistentCasingInFileNames": true, + "ignoreDeprecations": "5.0", "keyofStringsOnly": true, "lib": [ "es2016", @@ -54,4 +55,4 @@ "src/**/*", "typings" ] -} +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 09347988..bc5fe04b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11459,10 +11459,10 @@ typescript-tuple@^2.2.1: dependencies: typescript-compare "^0.0.2" -typescript@^4.4: - version "4.5.4" - resolved "https://registry.npmjs.org/typescript/-/typescript-4.5.4.tgz#a17d3a0263bf5c8723b9c52f43c5084edf13c2e8" - integrity sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg== +typescript@^5.4.2: + version "5.4.2" + resolved "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz#0ae9cebcfae970718474fe0da2c090cad6577372" + integrity sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ== uc.micro@^1.0.1, uc.micro@^1.0.5: version "1.0.6" From 2f059e91dea4a30fc896e2e1be9e921167b03756 Mon Sep 17 00:00:00 2001 From: Theophile Sandoz Date: Wed, 10 Apr 2024 16:45:03 +0200 Subject: [PATCH 4/5] Move chunkSize const --- src/middleware/DataLoaderMiddleware.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/middleware/DataLoaderMiddleware.ts b/src/middleware/DataLoaderMiddleware.ts index 11c43de9..506e013d 100644 --- a/src/middleware/DataLoaderMiddleware.ts +++ b/src/middleware/DataLoaderMiddleware.ts @@ -15,6 +15,8 @@ export class DataLoaderMiddleware implements MiddlewareInterface { }; const reqTimeout = Number(process.env.WARTHOG_RESOLVER_TIMEOUT_MS); + const chunkSize = Number(process.env.WARTHOG_RELATION_CONCURRENCY) || 30; + const abortSignal = reqTimeout ? AbortSignal.timeout(reqTimeout) : undefined; const loaders = context.dataLoader.loaders; @@ -37,7 +39,6 @@ export class DataLoaderMiddleware implements MiddlewareInterface { throw new Error('You must flatten arrays of arrays of entities'); } - const chunkSize = Number(process.env.WARTHOG_RELATION_CONCURRENCY) || 30; return chunk(entities, chunkSize).reduce>( async (prev, entityChunk) => { const next = await prev; From 7ab0f00baece5d1499f1534a255a9ce5d47b58d9 Mon Sep 17 00:00:00 2001 From: Theophile Sandoz Date: Wed, 10 Apr 2024 16:45:53 +0200 Subject: [PATCH 5/5] Bump version to `2.42.0` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b6afc042..106ac928 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@joystream/warthog", - "version": "2.41.9", + "version": "2.42.0", "description": "Opinionated set of tools for setting up GraphQL backed by TypeORM", "main": "dist/index.js", "types": "dist/types/index.d.ts",