From 817790c41bfbcc5559cbcae35657942b7b150a13 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 21 Jan 2023 22:06:12 +0100 Subject: [PATCH 1/3] Support releasing actors. --- examples/stopping-actors.js | 31 ++++++++++++++ lib/actor-system/actor-message.ts | 10 +++++ lib/actor-system/actor-system.ts | 24 +++++++++++ lib/actor-system/actor.ts | 42 ++++++++++++++++--- lib/actor-system/materializer/materializer.ts | 2 + test/actor-system/actor-system.spec.ts | 24 +++++++++++ 6 files changed, 128 insertions(+), 5 deletions(-) create mode 100644 examples/stopping-actors.js diff --git a/examples/stopping-actors.js b/examples/stopping-actors.js new file mode 100644 index 0000000..2f9a10d --- /dev/null +++ b/examples/stopping-actors.js @@ -0,0 +1,31 @@ +let { Actor, ActorSystem, ActorSystemConfigurationBuilder } = require('../dist/index') + +class Clock extends Actor { + constructor(times, message) { + super() + + this.times = times + this.timer = this.schedule(1000, this.tick, [message]) + } + + async tick(message) { + console.log(this.times, "From clock ", this.id, " message:", message) + if (--this.times <= 0) { + this.cancel(this.timer) + } + } +} + +let system = ActorSystem.for(ActorSystemConfigurationBuilder.define() + .done()) + +const clock = system.actorOf(Clock, [10, "Actors are cool"]) + +setTimeout(() => { + system.releaseActor(clock) + console.log('Actor released, no more messages. Wait for 3 more seconds.') +}, 3000) + +setTimeout(() => { + system.free() +}, 6000) \ No newline at end of file diff --git a/lib/actor-system/actor-message.ts b/lib/actor-system/actor-message.ts index e7f35e1..de5dc18 100644 --- a/lib/actor-system/actor-message.ts +++ b/lib/actor-system/actor-message.ts @@ -5,6 +5,8 @@ * LICENSE file in the root directory of this source tree. */ +const RELEASE_ACTOR_MESSAGE = '' + type AnswerFunction = (r: any) => void export default class ActorMessage { @@ -23,4 +25,12 @@ export default class ActorMessage { this.resolve = resolve this.reject = reject } + + public isAReleaseMessage(): boolean { + return this.methodName == RELEASE_ACTOR_MESSAGE + } + + public static releaseActor(): ActorMessage { + return new ActorMessage(RELEASE_ACTOR_MESSAGE, [], null, null) + } } diff --git a/lib/actor-system/actor-system.ts b/lib/actor-system/actor-system.ts index ea68819..dc28521 100644 --- a/lib/actor-system/actor-system.ts +++ b/lib/actor-system/actor-system.ts @@ -8,6 +8,8 @@ import Fiber from '../fiber/fiber' import IProcessor from '../fiber/processor' import Mailbox from '../mailbox/mailbox' +import Message from '../mailbox/message' +import Topic from '../pubsub/topic' import { IActor } from './actor' import ActorMessage from './actor-message' import ActorProxy from './actor-proxy' @@ -77,6 +79,11 @@ export default class ActorSystem implements IProcessor { return proxy } + public releaseActor(actor: IActor): void { + const actorProxy = actor as any + this.mailbox.push(Message.of(actorProxy.ref.id, ActorMessage.releaseActor())) + } + /** * Looks for an existing actor in this actor system. If none exist, * it will try to resolve the actor, by id, with the provided resolvers. @@ -147,4 +154,21 @@ export default class ActorSystem implements IProcessor { instance.supervisor = this.supervisor instance.initialized() } + + private async releaseActorInternal(actor: IActor): Promise { + this.actors.delete(actor.id) // first remove, we don't want more references + + const actorSubscription = this.subscriptions.get(actor.id) + this.mailbox.removeSubscription(actorSubscription) // do not receive more messages + + this.subscriptions.delete(actor.id) + // unsubscribe from all topics + const subscribedTopics = (actor as any).topicSubscriptions as Map + const allUnsubs = Array.from(subscribedTopics.entries()).map(async ([value, key]) => { + const topic = await this.actorFor>(key) + topic.unsubscribe(value) + }) + + await Promise.all(allUnsubs) + } } diff --git a/lib/actor-system/actor.ts b/lib/actor-system/actor.ts index b3c20e0..31f048e 100644 --- a/lib/actor-system/actor.ts +++ b/lib/actor-system/actor.ts @@ -52,14 +52,25 @@ export default abstract class Actor implements IActor { return false } + let isBeingReleased = false this.busy = true const actorMessage = message.content try { - this.materializers.forEach((materializer) => materializer.onBeforeMessage(this, actorMessage)) - const result = await this.dispatchAndPromisify(actorMessage) + if (actorMessage.isAReleaseMessage()) { + isBeingReleased = true - actorMessage.resolve(result) + this.materializers.forEach((materializer) => materializer.onBeforeRelease(this)) + this.cancelAll() + await (this.system! as any).releaseActorInternal(this) + this.materializers.forEach((materializer) => materializer.onAfterRelease(this)) + } else { + this.materializers.forEach((materializer) => materializer.onBeforeMessage(this, actorMessage)) + const result = await this.dispatchAndPromisify(actorMessage) + + actorMessage.resolve(result) + } + } catch (ex) { this.materializers.forEach((materializer) => materializer.onError(this, actorMessage, ex)) const strategy = await this.supervisor!.supervise(this.self, ex, actorMessage) @@ -74,8 +85,10 @@ export default abstract class Actor implements IActor { return true } } finally { - this.busy = false - this.materializers.forEach((materializer) => materializer.onAfterMessage(this, actorMessage)) + if (!isBeingReleased) { + this.busy = false + this.materializers.forEach((materializer) => materializer.onAfterMessage(this, actorMessage)) + } } return true @@ -157,6 +170,21 @@ export default abstract class Actor implements IActor { }, 0) } + /** + * Cancel all scheduled actions created by #schedule or #scheduleOnce + * + * @see Actor#schedule + * @see Actor#scheduleOnce + */ + protected cancelAll(): void { + this.scheduled.forEach((value, key) => { + clearTimeout(value) + clearInterval(value) + + this.scheduled.delete(key) + }) + } + /** * Creates a child actor of this actor. The current actor will behave as the supervisor * of the created actor. @@ -203,4 +231,8 @@ export default abstract class Actor implements IActor { private initialized(): void { this.materializers.forEach((materializer) => materializer.onInitialize(this)) } + + private release(): void { + + } } diff --git a/lib/actor-system/materializer/materializer.ts b/lib/actor-system/materializer/materializer.ts index 89d160e..68eca82 100644 --- a/lib/actor-system/materializer/materializer.ts +++ b/lib/actor-system/materializer/materializer.ts @@ -13,4 +13,6 @@ export default interface IMaterializer { onBeforeMessage(actor: Actor, message: ActorMessage): void onAfterMessage(actor: Actor, message: ActorMessage): void onError(actor: Actor, message: ActorMessage, error: any): void + onBeforeRelease(actor: Actor): void + onAfterRelease(actor: Actor): void } diff --git a/test/actor-system/actor-system.spec.ts b/test/actor-system/actor-system.spec.ts index 1d8cb55..099fa72 100644 --- a/test/actor-system/actor-system.spec.ts +++ b/test/actor-system/actor-system.spec.ts @@ -11,6 +11,7 @@ import IMaterializer from '../../lib/actor-system/materializer/materializer' import NamedActor from './fixtures/named-actor' import SemaphoreActor from './fixtures/semaphore-actor' import waitFor from './fixtures/wait-for' +import sleep from './fixtures/sleep' import IResolver from '../../lib/actor-system/resolver/resolver' import { Actor } from '../../lib' @@ -30,12 +31,16 @@ describe('Actor System', () => { onBeforeMessage: jest.fn(), onError: jest.fn(), onInitialize: jest.fn(), + onBeforeRelease: jest.fn(), + onAfterRelease: jest.fn(), } secondMaterializer = { onAfterMessage: jest.fn(), onBeforeMessage: jest.fn(), onError: jest.fn(), onInitialize: jest.fn(), + onBeforeRelease: jest.fn(), + onAfterRelease: jest.fn(), } firstResolver = { resolveActorById: jest.fn(), @@ -183,4 +188,23 @@ describe('Actor System', () => { await waitFor(() => fnActor(5, 15)) expect(fn).toBeCalledWith(5, 15) }) + + describe('released actors', () => { + test('should call materializers before releasing', async () => { + const actor: NamedActor = actorSystem.actorOf(NamedActor, ['myReleasedActor']) + + try { + actorSystem.releaseActor(actor) + actorSystem.process() + await waitFor(() => sleep(10)) + } catch (e) { + // expected + } + + expect(firstMaterializer.onBeforeRelease).toHaveBeenCalled() + expect(secondMaterializer.onBeforeRelease).toHaveBeenCalled() + expect(firstMaterializer.onAfterRelease).toHaveBeenCalled() + expect(secondMaterializer.onAfterRelease).toHaveBeenCalled() + }) + }) }) From 0d5453415893bc33e9afe7b2851a2ca73c20cd24 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 21 Jan 2023 22:08:39 +0100 Subject: [PATCH 2/3] Clean up packages and upgrade --- lib/actor-system/actor-system.ts | 2 +- lib/actor-system/actor.ts | 9 +- package.json | 9 +- yarn.lock | 462 +++++++++++++++---------------- 4 files changed, 232 insertions(+), 250 deletions(-) diff --git a/lib/actor-system/actor-system.ts b/lib/actor-system/actor-system.ts index dc28521..7a02acc 100644 --- a/lib/actor-system/actor-system.ts +++ b/lib/actor-system/actor-system.ts @@ -82,7 +82,7 @@ export default class ActorSystem implements IProcessor { public releaseActor(actor: IActor): void { const actorProxy = actor as any this.mailbox.push(Message.of(actorProxy.ref.id, ActorMessage.releaseActor())) - } + } /** * Looks for an existing actor in this actor system. If none exist, diff --git a/lib/actor-system/actor.ts b/lib/actor-system/actor.ts index 31f048e..44643f7 100644 --- a/lib/actor-system/actor.ts +++ b/lib/actor-system/actor.ts @@ -67,10 +67,9 @@ export default abstract class Actor implements IActor { } else { this.materializers.forEach((materializer) => materializer.onBeforeMessage(this, actorMessage)) const result = await this.dispatchAndPromisify(actorMessage) - + actorMessage.resolve(result) } - } catch (ex) { this.materializers.forEach((materializer) => materializer.onError(this, actorMessage, ex)) const strategy = await this.supervisor!.supervise(this.self, ex, actorMessage) @@ -172,7 +171,7 @@ export default abstract class Actor implements IActor { /** * Cancel all scheduled actions created by #schedule or #scheduleOnce - * + * * @see Actor#schedule * @see Actor#scheduleOnce */ @@ -231,8 +230,4 @@ export default abstract class Actor implements IActor { private initialized(): void { this.materializers.forEach((materializer) => materializer.onInitialize(this)) } - - private release(): void { - - } } diff --git a/package.json b/package.json index 982c30b..d6f9094 100644 --- a/package.json +++ b/package.json @@ -43,13 +43,12 @@ "license": "MIT", "devDependencies": { "@faker-js/faker": "^7.6.0", - "@types/faker": "6.6.9", - "@types/jest": "29.2.5", + "@types/jest": "29.2.6", "@types/node": "18.11.18", - "@typescript-eslint/eslint-plugin": "5.48.1", - "@typescript-eslint/parser": "5.48.1", + "@typescript-eslint/eslint-plugin": "5.48.2", + "@typescript-eslint/parser": "5.48.2", "coveralls": "3.1.1", - "esbuild": "0.17.0", + "esbuild": "0.17.3", "eslint": "8.32.0", "eslint-config-standard": "17.0.0", "eslint-plugin-import": "^2.27.4", diff --git a/yarn.lock b/yarn.lock index 418b567..a1980f8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -139,12 +139,12 @@ integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== "@babel/helpers@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce" - integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA== + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.13.tgz#e3cb731fb70dc5337134cadc24cbbad31cc87ad2" + integrity sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg== dependencies: "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.7" + "@babel/traverse" "^7.20.13" "@babel/types" "^7.20.7" "@babel/highlight@^7.18.6": @@ -156,10 +156,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" - integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.13", "@babel/parser@^7.20.7": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.13.tgz#ddf1eb5a813588d2fb1692b70c6fce75b945c088" + integrity sha512-gFDLKMfpiXCsjt4za2JA9oTMn70CeseCehb11kRZgvd7+F67Hih3OHOK24cRrWECJ/ljfPGac6ygXAs/C8kIvw== "@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" @@ -268,10 +268,10 @@ "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" -"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.7", "@babel/traverse@^7.7.2": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.12.tgz#7f0f787b3a67ca4475adef1f56cb94f6abd4a4b5" - integrity sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ== +"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.13", "@babel/traverse@^7.7.2": + version "7.20.13" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473" + integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ== dependencies: "@babel/code-frame" "^7.18.6" "@babel/generator" "^7.20.7" @@ -279,7 +279,7 @@ "@babel/helper-function-name" "^7.19.0" "@babel/helper-hoist-variables" "^7.18.6" "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.7" + "@babel/parser" "^7.20.13" "@babel/types" "^7.20.7" debug "^4.1.0" globals "^11.1.0" @@ -298,115 +298,115 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@esbuild/android-arm64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.0.tgz#dd4c28274f08a16be95430d19fc0dab835fd2eae" - integrity sha512-77GVyD7ToESy/7+9eI8z62GGBdS/hsqsrpM+JA4kascky86wHbN29EEFpkVvxajPL7k6mbLJ5VBQABdj7n9FhQ== - -"@esbuild/android-arm@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.0.tgz#10d289617902f877a28f9f7913f4f54a4e699875" - integrity sha512-hlbX5ym1V5kIKvnwFhm6rhar7MNqfJrZyYTNfk6+WS1uQfQmszFgXeyPH2beP3lSCumZyqX0zMBfOqftOpZ7GA== - -"@esbuild/android-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.0.tgz#b0c124e434cec1a6551b400850458c860a30ecb4" - integrity sha512-TroxZdZhtAz0JyD0yahtjcbKuIXrBEAoAazaYSeR2e2tUtp9uXrcbpwFJF6oxxOiOOne6y7l4hx4YVnMW/tdFw== - -"@esbuild/darwin-arm64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.0.tgz#4a1b65e756cc29e8d68a5ace0a2eb1c63614a767" - integrity sha512-wP/v4cgdWt1m8TS/WmbaBc3NZON10eCbm6XepdVc3zJuqruHCzCKcC9dTSTEk50zX04REcRcbIbdhTMciQoFIg== - -"@esbuild/darwin-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.0.tgz#9a59890391f17cd3998d2c7959ea70a1aad28c93" - integrity sha512-R4WB6D6V9KGO/3LVTT8UlwRJO26IBFatOdo/bRXksfJR0vyOi2/lgmAAMBSpgcnnwvts9QsWiyM++mTTlwRseA== - -"@esbuild/freebsd-arm64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.0.tgz#3412ffa1703c991b4d562176881fb43a9ee6f7e3" - integrity sha512-FO7+UEZv79gen2df8StFYFHZPI9ADozpFepLZCxY+O8sYLDa1rirvenmLwJiOHmeQRJ5orYedFeLk1PFlZ6t8Q== - -"@esbuild/freebsd-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.0.tgz#427f2a07c997fb30f1a8906b070e28959f38f1e2" - integrity sha512-qCsNRsVTaC3ekwZcb2sa7l1gwCtJK3EqCWyDgpoQocYf3lRpbAzaCvqZSF2+NOO64cV+JbedXPsFiXU1aaVcIg== - -"@esbuild/linux-arm64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.0.tgz#0e32c6a6b290406b1203854c2d594987570dd66c" - integrity sha512-js4Vlch5XJQYISbDVJd2hsI/MsfVUz6d/FrclCE73WkQmniH37vFpuQI42ntWAeBghDIfaPZ6f9GilhwGzVFUg== - -"@esbuild/linux-arm@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.0.tgz#5a70a95bf336035884dee123b5453aeab9c608f3" - integrity sha512-Y2G2NU6155gcfNKvrakVmZV5xUAEhXjsN/uKtbKKRnvee0mHUuaT3OdQJDJKjHVGr6B0898pc3slRpI1PqspoQ== - -"@esbuild/linux-ia32@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.0.tgz#47baca8e733405a81952bcc475da1b8e5682915f" - integrity sha512-7tl/jSPkF59R3zeFDB2/09zLGhcM7DM+tCoOqjJbQjuL6qbMWomGT2RglCqRFpCSdzBx0hukmPPgUAMlmdj0sQ== - -"@esbuild/linux-loong64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.0.tgz#809398ca125ba3b57d4d12d261f2471ac32b1edb" - integrity sha512-OG356F7dIVVF+EXJx5UfzFr1I5l6ES53GlMNSr3U1MhlaVyrP9um5PnrSJ+7TSDAzUC7YGjxb2GQWqHLd5XFoA== - -"@esbuild/linux-mips64el@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.0.tgz#94b50097a3421ff538eb6a41cd4fb5db4c4993ff" - integrity sha512-LWQJgGpxrjh2x08UYf6G5R+Km7zhkpCvKXtFQ6SX0fimDvy1C8kslgFHGxLS0wjGV8C4BNnENW/HNy57+RB7iA== - -"@esbuild/linux-ppc64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.0.tgz#3a580bc8b494d3b273cf08a3bb0d893b31b786ae" - integrity sha512-f40N8fKiTQslUcUuhof2/syOQ+DC9Mqdnm9d063pew+Ptv9r6dBNLQCz4300MOfCLAbb0SdnrcMSzHbMehXWLw== - -"@esbuild/linux-riscv64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.0.tgz#bf75f769e5fa35d143bc5759520e4277b3a95bcc" - integrity sha512-sc/pvLexRvxgEbmeq7LfLGnzUBFi/E2MGbnQj3CG8tnQ90tWPTi+9CbZEgIADhj6CAlCCmqxpUclIV1CRVUOTw== - -"@esbuild/linux-s390x@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.0.tgz#ad6569476d6751cc9255fe059a5e074a08dd3e27" - integrity sha512-7xq9/kY0vunCL2vjHKdHGI+660pCdeEC6K6TWBVvbTGXvT8s/qacfxMgr8PCeQRbNUZLOA13G6/G1+c0lYXO1A== - -"@esbuild/linux-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.0.tgz#7e38c248b8c9f39240c0914872f93893bde7182a" - integrity sha512-o7FhBLONk1mLT2ytlj/j/WuJcPdhWcVpysSJn1s9+zRdLwLKveipbPi5SIasJIqMq0T4CkQW76pxJYMqz9HrQA== - -"@esbuild/netbsd-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.0.tgz#46e770aa6a14dad73d2cdf6a9521585eca1005ef" - integrity sha512-V6xXsv71b8vwFCW/ky82Rs//SbyA+ORty6A7Mzkg33/4NbYZ/1Vcbk7qAN5oi0i/gS4Q0+7dYT7NqaiVZ7+Xjw== - -"@esbuild/openbsd-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.0.tgz#5d4070663448db20d3de42f7a44a2c2dd0cac847" - integrity sha512-StlQor6A0Y9SSDxraytr46Qbz25zsSDmsG3MCaNkBnABKHP3QsngOCfdBikqHVVrXeK0KOTmtX92/ncTGULYgQ== - -"@esbuild/sunos-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.0.tgz#4a77dbf1691ce2fd9aba69f58248d46f3e28f98b" - integrity sha512-K64Wqw57j8KrwjR3QjsuzN/qDGK6Cno6QYtIlWAmGab5iYPBZCWz7HFtF2a86/130LmUsdXqOID7J0SmjjRFIQ== - -"@esbuild/win32-arm64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.0.tgz#9b7cb6839240cd4408fbca6565c6a08e277d73bb" - integrity sha512-hly6iSWAf0hf3aHD18/qW7iFQbg9KAQ0RFGG9plcxkhL4uGw43O+lETGcSO/PylNleFowP/UztpF6U4oCYgpPw== - -"@esbuild/win32-ia32@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.0.tgz#059a1651b830bfc188920487badd12a8e1b8f050" - integrity sha512-aL4EWPh0nyC5uYRfn+CHkTgawd4DjtmwquthNDmGf6Ht6+mUc+bQXyZNH1QIw8x20hSqFc4Tf36aLLWP/TPR3g== - -"@esbuild/win32-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.0.tgz#d2253fef7e7cd11f010f688fa4f5ebb2875f34c1" - integrity sha512-W6IIQ9Rt43I/GqfXeBFLk0TvowKBoirs9sw2LPfhHax6ayMlW5PhFzSJ76I1ac9Pk/aRcSMrHWvVyZs8ZPK2wA== +"@esbuild/android-arm64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.3.tgz#35d045f69c9b4cf3f8efcd1ced24a560213d3346" + integrity sha512-XvJsYo3dO3Pi4kpalkyMvfQsjxPWHYjoX4MDiB/FUM4YMfWcXa5l4VCwFWVYI1+92yxqjuqrhNg0CZg3gSouyQ== + +"@esbuild/android-arm@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.3.tgz#4986d26306a7440078d42b3bf580d186ef714286" + integrity sha512-1Mlz934GvbgdDmt26rTLmf03cAgLg5HyOgJN+ZGCeP3Q9ynYTNMn2/LQxIl7Uy+o4K6Rfi2OuLsr12JQQR8gNg== + +"@esbuild/android-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.3.tgz#a1928cd681e4055103384103c8bd34df7b9c7b19" + integrity sha512-nuV2CmLS07Gqh5/GrZLuqkU9Bm6H6vcCspM+zjp9TdQlxJtIe+qqEXQChmfc7nWdyr/yz3h45Utk1tUn8Cz5+A== + +"@esbuild/darwin-arm64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.3.tgz#e4af2b392e5606a4808d3a78a99d38c27af39f1d" + integrity sha512-01Hxaaat6m0Xp9AXGM8mjFtqqwDjzlMP0eQq9zll9U85ttVALGCGDuEvra5Feu/NbP5AEP1MaopPwzsTcUq1cw== + +"@esbuild/darwin-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.3.tgz#cbcbfb32c8d5c86953f215b48384287530c5a38e" + integrity sha512-Eo2gq0Q/er2muf8Z83X21UFoB7EU6/m3GNKvrhACJkjVThd0uA+8RfKpfNhuMCl1bKRfBzKOk6xaYKQZ4lZqvA== + +"@esbuild/freebsd-arm64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.3.tgz#90ec1755abca4c3ffe1ad10819cd9d31deddcb89" + integrity sha512-CN62ESxaquP61n1ZjQP/jZte8CE09M6kNn3baos2SeUfdVBkWN5n6vGp2iKyb/bm/x4JQzEvJgRHLGd5F5b81w== + +"@esbuild/freebsd-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.3.tgz#8760eedc466af253c3ed0dfa2940d0e59b8b0895" + integrity sha512-feq+K8TxIznZE+zhdVurF3WNJ/Sa35dQNYbaqM/wsCbWdzXr5lyq+AaTUSER2cUR+SXPnd/EY75EPRjf4s1SLg== + +"@esbuild/linux-arm64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.3.tgz#13916fc8873115d7d546656e19037267b12d4567" + integrity sha512-JHeZXD4auLYBnrKn6JYJ0o5nWJI9PhChA/Nt0G4MvLaMrvXuWnY93R3a7PiXeJQphpL1nYsaMcoV2QtuvRnF/g== + +"@esbuild/linux-arm@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.3.tgz#15f876d127b244635ddc09eaaa65ae97bc472a63" + integrity sha512-CLP3EgyNuPcg2cshbwkqYy5bbAgK+VhyfMU7oIYyn+x4Y67xb5C5ylxsNUjRmr8BX+MW3YhVNm6Lq6FKtRTWHQ== + +"@esbuild/linux-ia32@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.3.tgz#6691f02555d45b698195c81c9070ab4e521ef005" + integrity sha512-FyXlD2ZjZqTFh0sOQxFDiWG1uQUEOLbEh9gKN/7pFxck5Vw0qjWSDqbn6C10GAa1rXJpwsntHcmLqydY9ST9ZA== + +"@esbuild/linux-loong64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.3.tgz#f77ef657f222d8b3a8fbd530a09e40976c458d48" + integrity sha512-OrDGMvDBI2g7s04J8dh8/I7eSO+/E7nMDT2Z5IruBfUO/RiigF1OF6xoH33Dn4W/OwAWSUf1s2nXamb28ZklTA== + +"@esbuild/linux-mips64el@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.3.tgz#fa38833cfc8bfaadaa12b243257fe6d19d0f6f79" + integrity sha512-DcnUpXnVCJvmv0TzuLwKBC2nsQHle8EIiAJiJ+PipEVC16wHXaPEKP0EqN8WnBe0TPvMITOUlP2aiL5YMld+CQ== + +"@esbuild/linux-ppc64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.3.tgz#c157a602b627c90d174743e4b0dfb7630b101dbf" + integrity sha512-BDYf/l1WVhWE+FHAW3FzZPtVlk9QsrwsxGzABmN4g8bTjmhazsId3h127pliDRRu5674k1Y2RWejbpN46N9ZhQ== + +"@esbuild/linux-riscv64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.3.tgz#7bf79614bd544bd932839b1fcff6cf1f8f6bdf1a" + integrity sha512-WViAxWYMRIi+prTJTyV1wnqd2mS2cPqJlN85oscVhXdb/ZTFJdrpaqm/uDsZPGKHtbg5TuRX/ymKdOSk41YZow== + +"@esbuild/linux-s390x@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.3.tgz#6bb50c5a2613d31ce1137fe5c249ecadbecccdea" + integrity sha512-Iw8lkNHUC4oGP1O/KhumcVy77u2s6+KUjieUqzEU3XuWJqZ+AY7uVMrrCbAiwWTkpQHkr00BuXH5RpC6Sb/7Ug== + +"@esbuild/linux-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.3.tgz#aa140d99f0d9e0af388024823bfe4558d73fbbf9" + integrity sha512-0AGkWQMzeoeAtXQRNB3s4J1/T2XbigM2/Mn2yU1tQSmQRmHIZdkGbVq2A3aDdNslPyhb9/lH0S5GMTZ4xsjBqg== + +"@esbuild/netbsd-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.3.tgz#b6ae9948b03e4c95dc581c68358fb61d9d12a625" + integrity sha512-4+rR/WHOxIVh53UIQIICryjdoKdHsFZFD4zLSonJ9RRw7bhKzVyXbnRPsWSfwybYqw9sB7ots/SYyufL1mBpEg== + +"@esbuild/openbsd-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.3.tgz#cda007233e211fc9154324bfa460540cfc469408" + integrity sha512-cVpWnkx9IYg99EjGxa5Gc0XmqumtAwK3aoz7O4Dii2vko+qXbkHoujWA68cqXjhh6TsLaQelfDO4MVnyr+ODeA== + +"@esbuild/sunos-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.3.tgz#f1385b092000c662d360775f3fad80943d2169c4" + integrity sha512-RxmhKLbTCDAY2xOfrww6ieIZkZF+KBqG7S2Ako2SljKXRFi+0863PspK74QQ7JpmWwncChY25JTJSbVBYGQk2Q== + +"@esbuild/win32-arm64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.3.tgz#14e9dd9b1b55aa991f80c120fef0c4492d918801" + integrity sha512-0r36VeEJ4efwmofxVJRXDjVRP2jTmv877zc+i+Pc7MNsIr38NfsjkQj23AfF7l0WbB+RQ7VUb+LDiqC/KY/M/A== + +"@esbuild/win32-ia32@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.3.tgz#de584423513d13304a6925e01233499a37a4e075" + integrity sha512-wgO6rc7uGStH22nur4aLFcq7Wh86bE9cOFmfTr/yxN3BXvDEdCSXyKkO+U5JIt53eTOgC47v9k/C1bITWL/Teg== + +"@esbuild/win32-x64@0.17.3": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.3.tgz#2f69ea6b37031b0d1715dd2da832a8ae5eb36e74" + integrity sha512-FdVl64OIuiKjgXBjwZaJLKp0eaEckifbhn10dXWhysMJkWblg3OEEGKSIyhiD5RSgAya8WzP3DNkngtIg3Nt7g== "@eslint/eslintrc@^1.4.1": version "1.4.1" @@ -736,12 +736,12 @@ "@sinonjs/commons" "^1.7.0" "@types/babel__core@^7.1.14": - version "7.1.20" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359" - integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== + version "7.20.0" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" + integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" "@types/babel__generator" "*" "@types/babel__template" "*" "@types/babel__traverse" "*" @@ -768,13 +768,6 @@ dependencies: "@babel/types" "^7.3.0" -"@types/faker@6.6.9": - version "6.6.9" - resolved "https://registry.yarnpkg.com/@types/faker/-/faker-6.6.9.tgz#1064e7c46be58388fa326e2f918a4f02ab740a7a" - integrity sha512-Y9YYm5L//8ooiiknO++4Gr539zzdI0j3aXnOBjo1Vk+kTvffY10GuE2wn78AFPECwZ5MYGTjiDVw1naLLdDimw== - dependencies: - faker "*" - "@types/graceful-fs@^4.1.3": version "4.1.6" resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" @@ -801,10 +794,10 @@ dependencies: "@types/istanbul-lib-report" "*" -"@types/jest@29.2.5": - version "29.2.5" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.5.tgz#c27f41a9d6253f288d1910d3c5f09484a56b73c0" - integrity sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw== +"@types/jest@29.2.6": + version "29.2.6" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.2.6.tgz#1d43c8e533463d0437edef30b2d45d5aa3d95b0a" + integrity sha512-XEUC/Tgw3uMh6Ho8GkUtQ2lPhY5Fmgyp3TdlkTJs1W9VgNxs+Ow/x3Elh8lHQKqCbZL0AubQuqWjHVT033Hhrw== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -845,20 +838,20 @@ integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== "@types/yargs@^17.0.8": - version "17.0.19" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.19.tgz#8dbecdc9ab48bee0cb74f6e3327de3fa0d0c98ae" - integrity sha512-cAx3qamwaYX9R0fzOIZAlFpo4A+1uBVCxqpKz9D26uTF4srRXaGTTsikQmaotCtNdbhzyUH7ft6p9ktz9s6UNQ== + version "17.0.20" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.20.tgz#107f0fcc13bd4a524e352b41c49fe88aab5c54d5" + integrity sha512-eknWrTHofQuPk2iuqDm1waA7V6xPlbgBoaaXEgYkClhLOnB0TtbW+srJaOToAgawPxPlHQzwypFA2bhZaUGP5A== dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.1.tgz#deee67e399f2cb6b4608c935777110e509d8018c" - integrity sha512-9nY5K1Rp2ppmpb9s9S2aBiF3xo5uExCehMDmYmmFqqyxgenbHJ3qbarcLt4ITgaD6r/2ypdlcFRdcuVPnks+fQ== +"@typescript-eslint/eslint-plugin@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.2.tgz#112e6ae1e23a1dc8333ce82bb9c65c2608b4d8a3" + integrity sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg== dependencies: - "@typescript-eslint/scope-manager" "5.48.1" - "@typescript-eslint/type-utils" "5.48.1" - "@typescript-eslint/utils" "5.48.1" + "@typescript-eslint/scope-manager" "5.48.2" + "@typescript-eslint/type-utils" "5.48.2" + "@typescript-eslint/utils" "5.48.2" debug "^4.3.4" ignore "^5.2.0" natural-compare-lite "^1.4.0" @@ -866,72 +859,72 @@ semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/parser@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.48.1.tgz#d0125792dab7e232035434ab8ef0658154db2f10" - integrity sha512-4yg+FJR/V1M9Xoq56SF9Iygqm+r5LMXvheo6DQ7/yUWynQ4YfCRnsKuRgqH4EQ5Ya76rVwlEpw4Xu+TgWQUcdA== +"@typescript-eslint/parser@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.48.2.tgz#c9edef2a0922d26a37dba03be20c5fff378313b3" + integrity sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw== dependencies: - "@typescript-eslint/scope-manager" "5.48.1" - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/typescript-estree" "5.48.1" + "@typescript-eslint/scope-manager" "5.48.2" + "@typescript-eslint/types" "5.48.2" + "@typescript-eslint/typescript-estree" "5.48.2" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.48.1.tgz#39c71e4de639f5fe08b988005beaaf6d79f9d64d" - integrity sha512-S035ueRrbxRMKvSTv9vJKIWgr86BD8s3RqoRZmsSh/s8HhIs90g6UlK8ZabUSjUZQkhVxt7nmZ63VJ9dcZhtDQ== +"@typescript-eslint/scope-manager@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz#bb7676cb78f1e94921eaab637a4b5d596f838abc" + integrity sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw== dependencies: - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/visitor-keys" "5.48.1" + "@typescript-eslint/types" "5.48.2" + "@typescript-eslint/visitor-keys" "5.48.2" -"@typescript-eslint/type-utils@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.48.1.tgz#5d94ac0c269a81a91ad77c03407cea2caf481412" - integrity sha512-Hyr8HU8Alcuva1ppmqSYtM/Gp0q4JOp1F+/JH5D1IZm/bUBrV0edoewQZiEc1r6I8L4JL21broddxK8HAcZiqQ== +"@typescript-eslint/type-utils@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz#7d3aeca9fa37a7ab7e3d9056a99b42f342c48ad7" + integrity sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew== dependencies: - "@typescript-eslint/typescript-estree" "5.48.1" - "@typescript-eslint/utils" "5.48.1" + "@typescript-eslint/typescript-estree" "5.48.2" + "@typescript-eslint/utils" "5.48.2" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.1.tgz#efd1913a9aaf67caf8a6e6779fd53e14e8587e14" - integrity sha512-xHyDLU6MSuEEdIlzrrAerCGS3T7AA/L8Hggd0RCYBi0w3JMvGYxlLlXHeg50JI9Tfg5MrtsfuNxbS/3zF1/ATg== +"@typescript-eslint/types@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.2.tgz#635706abb1ec164137f92148f06f794438c97b8e" + integrity sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA== -"@typescript-eslint/typescript-estree@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.1.tgz#9efa8ee2aa471c6ab62e649f6e64d8d121bc2056" - integrity sha512-Hut+Osk5FYr+sgFh8J/FHjqX6HFcDzTlWLrFqGoK5kVUN3VBHF/QzZmAsIXCQ8T/W9nQNBTqalxi1P3LSqWnRA== +"@typescript-eslint/typescript-estree@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz#6e206b462942b32383582a6c9251c05021cc21b0" + integrity sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg== dependencies: - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/visitor-keys" "5.48.1" + "@typescript-eslint/types" "5.48.2" + "@typescript-eslint/visitor-keys" "5.48.2" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.1.tgz#20f2f4e88e9e2a0961cbebcb47a1f0f7da7ba7f9" - integrity sha512-SmQuSrCGUOdmGMwivW14Z0Lj8dxG1mOFZ7soeJ0TQZEJcs3n5Ndgkg0A4bcMFzBELqLJ6GTHnEU+iIoaD6hFGA== +"@typescript-eslint/utils@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.2.tgz#3777a91dcb22b8499a25519e06eef2e9569295a3" + integrity sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow== dependencies: "@types/json-schema" "^7.0.9" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.48.1" - "@typescript-eslint/types" "5.48.1" - "@typescript-eslint/typescript-estree" "5.48.1" + "@typescript-eslint/scope-manager" "5.48.2" + "@typescript-eslint/types" "5.48.2" + "@typescript-eslint/typescript-estree" "5.48.2" eslint-scope "^5.1.1" eslint-utils "^3.0.0" semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.48.1": - version "5.48.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.1.tgz#79fd4fb9996023ef86849bf6f904f33eb6c8fccb" - integrity sha512-Ns0XBwmfuX7ZknznfXozgnydyR8F6ev/KEGePP4i74uL3ArsKbEhJ7raeKr1JSa997DBDwol/4a0Y+At82c9dA== +"@typescript-eslint/visitor-keys@5.48.2": + version "5.48.2" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz#c247582a0bcce467461d7b696513bf9455000060" + integrity sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ== dependencies: - "@typescript-eslint/types" "5.48.1" + "@typescript-eslint/types" "5.48.2" eslint-visitor-keys "^3.3.0" acorn-jsx@^5.3.2: @@ -1031,7 +1024,7 @@ array.prototype.flat@^1.3.1: es-abstract "^1.20.4" es-shim-unscopables "^1.0.0" -array.prototype.flatmap@^1.3.0: +array.prototype.flatmap@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz#1aae7903c2100433cb8261cd4ed310aab5c4a183" integrity sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ== @@ -1213,9 +1206,9 @@ camelcase@^6.2.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001400: - version "1.0.30001445" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001445.tgz#cf2d4eb93f2bcdf0310de9dd6d18be271bc0b447" - integrity sha512-8sdQIdMztYmzfTMO6KfLny878Ln9c2M0fc7EH60IjlP4Dc4PiCy7K2Vl3ITmWgOyPgVQKa5x+UP/KqFsxj4mBg== + version "1.0.30001446" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001446.tgz#6d4ba828ab19f49f9bcd14a8430d30feebf1e0c5" + integrity sha512-fEoga4PrImGcwUUGEol/PoFCSBnSkA9drgdkxXkJLsUBOnJ8rs3zDv6ApqYXGQFOyMPsjh79naWhF4DAxbF8rw== caseless@~0.12.0: version "0.12.0" @@ -1518,33 +1511,33 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -esbuild@0.17.0: - version "0.17.0" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.0.tgz#fcf19373d1d546bdbec1557276284c0e6350380b" - integrity sha512-4yGk3rD95iS/wGzrx0Ji5czZcx1j2wvfF1iAJaX2FIYLB6sU6wYkDeplpZHzfwQw2yXGXsAoxmO6LnMQkl04Kg== +esbuild@0.17.3: + version "0.17.3" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.3.tgz#d9aa02a3bc441ed35f9569cd9505812ae3fcae61" + integrity sha512-9n3AsBRe6sIyOc6kmoXg2ypCLgf3eZSraWFRpnkto+svt8cZNuKTkb1bhQcitBcvIqjNiK7K0J3KPmwGSfkA8g== optionalDependencies: - "@esbuild/android-arm" "0.17.0" - "@esbuild/android-arm64" "0.17.0" - "@esbuild/android-x64" "0.17.0" - "@esbuild/darwin-arm64" "0.17.0" - "@esbuild/darwin-x64" "0.17.0" - "@esbuild/freebsd-arm64" "0.17.0" - "@esbuild/freebsd-x64" "0.17.0" - "@esbuild/linux-arm" "0.17.0" - "@esbuild/linux-arm64" "0.17.0" - "@esbuild/linux-ia32" "0.17.0" - "@esbuild/linux-loong64" "0.17.0" - "@esbuild/linux-mips64el" "0.17.0" - "@esbuild/linux-ppc64" "0.17.0" - "@esbuild/linux-riscv64" "0.17.0" - "@esbuild/linux-s390x" "0.17.0" - "@esbuild/linux-x64" "0.17.0" - "@esbuild/netbsd-x64" "0.17.0" - "@esbuild/openbsd-x64" "0.17.0" - "@esbuild/sunos-x64" "0.17.0" - "@esbuild/win32-arm64" "0.17.0" - "@esbuild/win32-ia32" "0.17.0" - "@esbuild/win32-x64" "0.17.0" + "@esbuild/android-arm" "0.17.3" + "@esbuild/android-arm64" "0.17.3" + "@esbuild/android-x64" "0.17.3" + "@esbuild/darwin-arm64" "0.17.3" + "@esbuild/darwin-x64" "0.17.3" + "@esbuild/freebsd-arm64" "0.17.3" + "@esbuild/freebsd-x64" "0.17.3" + "@esbuild/linux-arm" "0.17.3" + "@esbuild/linux-arm64" "0.17.3" + "@esbuild/linux-ia32" "0.17.3" + "@esbuild/linux-loong64" "0.17.3" + "@esbuild/linux-mips64el" "0.17.3" + "@esbuild/linux-ppc64" "0.17.3" + "@esbuild/linux-riscv64" "0.17.3" + "@esbuild/linux-s390x" "0.17.3" + "@esbuild/linux-x64" "0.17.3" + "@esbuild/netbsd-x64" "0.17.3" + "@esbuild/openbsd-x64" "0.17.3" + "@esbuild/sunos-x64" "0.17.3" + "@esbuild/win32-arm64" "0.17.3" + "@esbuild/win32-ia32" "0.17.3" + "@esbuild/win32-x64" "0.17.3" escalade@^3.1.1: version "3.1.1" @@ -1596,13 +1589,13 @@ eslint-plugin-es@^3.0.0: regexpp "^3.0.0" eslint-plugin-import@^2.27.4: - version "2.27.4" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.4.tgz#319c2f6f6580e1678d674a258ee5e981c10cc25b" - integrity sha512-Z1jVt1EGKia1X9CnBCkpAOhWy8FgQ7OmJ/IblEkT82yrFU/xJaxwujaTzLWqigewwynRQ9mmHfX9MtAfhxm0sA== + version "2.27.5" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" + integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== dependencies: array-includes "^3.1.6" array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.0" + array.prototype.flatmap "^1.3.1" debug "^3.2.7" doctrine "^2.1.0" eslint-import-resolver-node "^0.3.7" @@ -1812,11 +1805,6 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== -faker@*: - version "6.6.6" - resolved "https://registry.yarnpkg.com/faker/-/faker-6.6.6.tgz#e9529da0109dca4c7c5dbfeaadbd9234af943033" - integrity sha512-9tCqYEDHI5RYFQigXFwF1hnCwcWCOJl/hmll0lr5D2Ljjb0o4wphb69wikeJDz5qCEzXCoPvG6ss5SDP6IfOdg== - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1962,9 +1950,9 @@ get-caller-file@^2.0.5: integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== dependencies: function-bind "^1.1.1" has "^1.0.3" @@ -2758,9 +2746,9 @@ jest@29.3.1: jest-cli "^29.3.1" js-sdsl@^4.1.4: - version "4.2.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" - integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== + version "4.3.0" + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" + integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== js-tokens@^4.0.0: version "4.0.0" @@ -3213,9 +3201,9 @@ psl@^1.1.28: integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== punycode@^2.1.0, punycode@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.2.0.tgz#2092cc57cd2582c38e4e7e8bb869dc8d3148bc74" - integrity sha512-LN6QV1IJ9ZhxWTNdktaPClrNfp8xdSAYS0Zk2ddX7XsXZAxckMHPCBcHRo0cTcEIgYPRiGEkmji3Idkh2yFtYw== + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== qs@~6.5.2: version "6.5.3" From 0e4f10aa150332fb6242299429c27d2f995121c3 Mon Sep 17 00:00:00 2001 From: Kevin Date: Sat, 21 Jan 2023 22:37:43 +0100 Subject: [PATCH 3/3] Reject messages once an actor is released --- lib/actor-system/actor-proxy.ts | 29 +++++++++++++++++++++----- lib/actor-system/actor.ts | 6 +++--- test/actor-system/actor-proxy.spec.ts | 6 ++++-- test/actor-system/actor-system.spec.ts | 29 +++++++++++++++++++------- 4 files changed, 53 insertions(+), 17 deletions(-) diff --git a/lib/actor-system/actor-proxy.ts b/lib/actor-system/actor-proxy.ts index 65a18db..1d779d0 100644 --- a/lib/actor-system/actor-proxy.ts +++ b/lib/actor-system/actor-proxy.ts @@ -10,16 +10,35 @@ import Message from '../mailbox/message' import Actor, { IActor } from './actor' import ActorMessage from './actor-message' +class ActorHasBeenReleased { + private readonly id: string + private readonly message: ActorMessage + public readonly isActorReleased: boolean = true + + public constructor(id: string, message: ActorMessage) { + this.id = id + this.message = message + } + + public getMessage(): string { + return 'Actor ' + this.id + ' has been already released, but received message ' + JSON.stringify(this.message) + } +} + export default class ActorProxy { public static sendAndReturn( mailbox: Mailbox, - actorId: string, + actor: any, methodName: string, args: any[], ): Promise { - return new Promise((resolve, reject) => - mailbox.push(Message.of(actorId, ActorMessage.of(methodName, args, resolve, reject))), - ) + return new Promise((resolve, reject) => { + if (actor.isBeingReleased) { + reject(new ActorHasBeenReleased(actor.id, ActorMessage.of(methodName, args, null, null))) + } else { + return mailbox.push(Message.of(actor.id, ActorMessage.of(methodName, args, resolve, reject))) + } + }) } public static of(mailbox: Mailbox, actor: T): T { @@ -33,7 +52,7 @@ export default class ActorProxy { return allNames .map((name: string): [string, any] => [ name, - (...args: any[]): any => ActorProxy.sendAndReturn(mailbox, actor.id, name, args), + (...args: any[]): any => ActorProxy.sendAndReturn(mailbox, actor, name, args), ]) .reduce((result, [member, method]) => ({ ...result, [member]: method }), { ref: actor }) as any } diff --git a/lib/actor-system/actor.ts b/lib/actor-system/actor.ts index 44643f7..cf2e103 100644 --- a/lib/actor-system/actor.ts +++ b/lib/actor-system/actor.ts @@ -35,6 +35,7 @@ export default abstract class Actor implements IActor { private readonly scheduled: Map = new Map() private readonly topicSubscriptions: Map = new Map() private busy = false + private isBeingReleased = false protected constructor(id?: string) { this.id = id || uuid() @@ -52,13 +53,12 @@ export default abstract class Actor implements IActor { return false } - let isBeingReleased = false this.busy = true const actorMessage = message.content try { if (actorMessage.isAReleaseMessage()) { - isBeingReleased = true + this.isBeingReleased = true this.materializers.forEach((materializer) => materializer.onBeforeRelease(this)) this.cancelAll() @@ -84,7 +84,7 @@ export default abstract class Actor implements IActor { return true } } finally { - if (!isBeingReleased) { + if (!this.isBeingReleased) { this.busy = false this.materializers.forEach((materializer) => materializer.onAfterMessage(this, actorMessage)) } diff --git a/test/actor-system/actor-proxy.spec.ts b/test/actor-system/actor-proxy.spec.ts index 52b19a3..28f2561 100644 --- a/test/actor-system/actor-proxy.spec.ts +++ b/test/actor-system/actor-proxy.spec.ts @@ -66,6 +66,7 @@ describe('actor proxy', () => { const resultMessage = faker.datatype.uuid() const expectedResult = faker.datatype.uuid() const args = [faker.datatype.uuid(), faker.datatype.uuid()] + const actor = { id: actorId } actorMessageMock.of.mockImplementation((_, __, resolve, ___) => { resolve(expectedResult) @@ -73,7 +74,7 @@ describe('actor proxy', () => { }) messageMock.of.mockReturnValue(resultMessage) - const result = await ActorProxy.sendAndReturn(mailbox, actorId, methodName, args) + const result = await ActorProxy.sendAndReturn(mailbox, actor, methodName, args) expect(actorMessageMock.of).toBeCalledWith(methodName, args, expect.any(Function), expect.any(Function)) expect(messageMock.of).toBeCalledWith(actorId, resultActorMessage) @@ -88,6 +89,7 @@ describe('actor proxy', () => { const resultMessage = faker.datatype.uuid() const expectedResult = faker.datatype.uuid() const args = [faker.datatype.uuid(), faker.datatype.uuid()] + const actor = { id: actorId } actorMessageMock.of.mockImplementation((_, __, ___, reject) => { reject(expectedResult) @@ -95,7 +97,7 @@ describe('actor proxy', () => { messageMock.of.mockReturnValue(resultMessage) try { - await ActorProxy.sendAndReturn(mailbox, actorId, methodName, args) + await ActorProxy.sendAndReturn(mailbox, actor, methodName, args) fail() } catch (_) { // diff --git a/test/actor-system/actor-system.spec.ts b/test/actor-system/actor-system.spec.ts index 099fa72..b7219eb 100644 --- a/test/actor-system/actor-system.spec.ts +++ b/test/actor-system/actor-system.spec.ts @@ -193,18 +193,33 @@ describe('Actor System', () => { test('should call materializers before releasing', async () => { const actor: NamedActor = actorSystem.actorOf(NamedActor, ['myReleasedActor']) - try { - actorSystem.releaseActor(actor) - actorSystem.process() - await waitFor(() => sleep(10)) - } catch (e) { - // expected - } + actorSystem.releaseActor(actor) + actorSystem.process() + await waitFor(() => sleep(10)) expect(firstMaterializer.onBeforeRelease).toHaveBeenCalled() expect(secondMaterializer.onBeforeRelease).toHaveBeenCalled() expect(firstMaterializer.onAfterRelease).toHaveBeenCalled() expect(secondMaterializer.onAfterRelease).toHaveBeenCalled() }) + + test('should not received more messages once it has been released', async () => { + const actor: NamedActor = actorSystem.actorOf(NamedActor, ['myReleasedActor']) + + actorSystem.releaseActor(actor) + actorSystem.process() + + try { + console.log('first wait') + await waitFor(() => sleep(10)) + await waitFor(() => actor.sayHi()) + } catch (ex) { + expect(ex.getMessage()).toContain('has been already released, but received message') + expect(ex.isActorReleased).toBeTruthy() + return + } + + fail('Should have not been dispatched the message') + }) }) })