From 76cd5be6154d81439e561f5c74cdec169bcb9593 Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Tue, 25 Jun 2024 19:58:08 +0900 Subject: [PATCH 1/2] Upgrade TGrid version, and change interfaces --- package.json | 6 +- src/MutexAcceptor.ts | 73 +++++++++---------- src/MutexConnector.ts | 55 ++++++-------- src/MutexServer.ts | 19 ++--- src/client/RemoteBarrier.ts | 2 +- src/client/RemoteConditionVariable.ts | 20 +++-- src/client/RemoteLatch.ts | 2 +- src/client/RemoteMutex.ts | 4 +- src/client/RemoteSemaphore.ts | 4 +- src/server/ProviderCapsule.ts | 9 --- src/server/ProviderGroup.ts | 9 ++- src/server/components/IComponent.ts | 9 ++- src/server/components/ServerBarrier.ts | 19 +++-- .../components/ServerConditionVariable.ts | 23 +++--- src/server/components/ServerLatch.ts | 17 +++-- src/server/components/ServerMutex.ts | 57 ++++++++------- src/server/components/ServerSemaphore.ts | 35 +++++---- src/server/components/SolidComponent.ts | 33 +++++---- src/server/global/GlobalBase.ts | 22 +++--- src/server/providers/ProviderBase.ts | 9 ++- test/index.ts | 28 +++---- test/internal/ConnectionFactory.ts | 2 +- test/manual/remote-mutex.ts | 5 +- test/mutextes/test_mutex_disconnections.ts | 2 +- test/mutextes/test_mutex_locks.ts | 2 +- test/semaphores/test_semaphore_acquires.ts | 2 +- .../test_semaphore_disconnections.ts | 4 +- test/test_destructors.ts | 2 +- 28 files changed, 239 insertions(+), 235 deletions(-) delete mode 100644 src/server/ProviderCapsule.ts diff --git a/package.json b/package.json index 3768083..d0b1c27 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mutex-server", - "version": "0.5.0", + "version": "0.6.0", "description": "Mutex Server using WebSocket", "main": "lib/index.js", "typings": "lib/index.d.ts", @@ -70,11 +70,11 @@ "ts-patch": "^3.1.2", "tslib": "^2.6.2", "typedoc": "^0.25.12", - "typescript": "^5.4.2", + "typescript": "5.4.5", "typescript-transform-paths": "^3.4.7" }, "dependencies": { - "tgrid": "^0.10.0", + "tgrid": "^1.0.1", "tstl": "^3.0.0" }, "files": [ diff --git a/src/MutexAcceptor.ts b/src/MutexAcceptor.ts index a92e97e..98838db 100644 --- a/src/MutexAcceptor.ts +++ b/src/MutexAcceptor.ts @@ -1,6 +1,5 @@ -import { Driver, WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; -import { ProviderCapsule } from "./server/ProviderCapsule"; import { ProviderGroup } from "./server/ProviderGroup"; /** @@ -30,11 +29,11 @@ import { ProviderGroup } from "./server/ProviderGroup"; * @template Provider Type of additional features provided for the remote client. * @author Jeongho Nam - https://github.com/samchon */ -export class MutexAcceptor { +export class MutexAcceptor
{ /** * @hidden */ - private base_: WebAcceptor>; + private base_: WebSocketAcceptor; /** * @hidden @@ -48,7 +47,7 @@ export class MutexAcceptor { * @hidden */ private constructor( - base: WebAcceptor>, + base: WebSocketAcceptor, group: ProviderGroup, ) { this.base_ = base; @@ -58,10 +57,10 @@ export class MutexAcceptor { /** * @internal */ - public static create( - base: WebAcceptor>, + public static create
( + base: WebSocketAcceptor, group: ProviderGroup, - ) { + ): MutexAcceptor
{ return new MutexAcceptor(base, group); } @@ -159,32 +158,32 @@ export class MutexAcceptor { return this.base_.state; } - /** - * Get Driver for [RFC](https://github.com/samchon/tgrid#13-remote-function-call). - * - * If remote client provides custom features for this `mutex-server`, you can utilize - * those features thorugh returned `Driver` object by this method. To use this method, you - * should define the `Controller` template argument, a type of interface who is defining - * additionla features provided from the remote client. - * - * The returned object `Driver` makes to call remote functions, defined in the `Controller` - * and provided by `Provider` in the remote client, possible. In other words, callling a - * function in the `Driver`, it means to call a matched function in the remote - * client's `Provider` object. - * - * - `Controller`: Definition only - * - `Driver`: [Remote Function Call](https://github.com/samchon/tgrid#13-remote-function-call) - * - * @template Controller An interface for provided features (functions & objects) from the remote client (`Provider`). - * @template UseParametric Whether to convert type of function parameters to be compatible with their pritimive. - * @return A `Driver` for the [RFC](https://github.com/samchon/tgrid#13-remote-function-call). - */ - public getDriver< - Controller extends object, - UseParametric extends boolean = false, - >(): Driver { - return this.base_.getDriver(); - } + // /** + // * Get Driver for [RFC](https://github.com/samchon/tgrid#13-remote-function-call). + // * + // * If remote client provides custom features for this `mutex-server`, you can utilize + // * those features thorugh returned `Driver` object by this method. To use this method, you + // * should define the `Controller` template argument, a type of interface who is defining + // * additionla features provided from the remote client. + // * + // * The returned object `Driver` makes to call remote functions, defined in the `Controller` + // * and provided by `Provider` in the remote client, possible. In other words, callling a + // * function in the `Driver`, it means to call a matched function in the remote + // * client's `Provider` object. + // * + // * - `Controller`: Definition only + // * - `Driver`: [Remote Function Call](https://github.com/samchon/tgrid#13-remote-function-call) + // * + // * @template Controller An interface for provided features (functions & objects) from the remote client (`Provider`). + // * @template UseParametric Whether to convert type of function parameters to be compatible with their pritimive. + // * @return A `Driver` for the [RFC](https://github.com/samchon/tgrid#13-remote-function-call). + // */ + // public getDriver< + // Controller extends object, + // UseParametric extends boolean = false, + // >(): Driver { + // return this.base_.getDriver(); + // } /* ---------------------------------------------------------------- HANDSHAKES @@ -196,8 +195,8 @@ export class MutexAcceptor { * * @param provider An object providing additional features for the remote client. If you don't have plan to proivde any additional feature, assign `null`. */ - public async accept(provider: Provider): Promise { - await this.base_.accept({ group: this.group_, provider: provider }); + public async accept(): Promise { + await this.base_.accept(this.group_); this.base_.join().then(() => this.group_.destructor()); } @@ -221,5 +220,5 @@ export namespace MutexAcceptor { /** * Current state of the {@link MutexAcceptor} */ - export import State = WebAcceptor.State; + export import State = WebSocketAcceptor.State; } diff --git a/src/MutexConnector.ts b/src/MutexConnector.ts index a2e0b27..71be770 100644 --- a/src/MutexConnector.ts +++ b/src/MutexConnector.ts @@ -1,11 +1,11 @@ -import { Driver, Promisive, WebConnector } from "tgrid"; +import { Driver, WebSocketConnector } from "tgrid"; import { RemoteBarrier } from "./client/RemoteBarrier"; import { RemoteConditionVariable } from "./client/RemoteConditionVariable"; import { RemoteLatch } from "./client/RemoteLatch"; import { RemoteMutex } from "./client/RemoteMutex"; import { RemoteSemaphore } from "./client/RemoteSemaphore"; -import { ProviderCapsule } from "./server/ProviderCapsule"; +import { ProviderGroup } from "./server/ProviderGroup"; /** * Mutex server connector for client. @@ -41,16 +41,16 @@ import { ProviderCapsule } from "./server/ProviderCapsule"; * @template Provider Type of additional features provided for the remote server. If no plan to provide anything, declare `null`. * @author Jeongho Nam - https://github.com/samchon */ -export class MutexConnector { +export class MutexConnector
{ /** * @hidden */ - private base_: WebConnector; + private connector_: WebSocketConnector; /** * @hidden */ - private controller_: Driver>; + private driver_: Driver; /* ----------------------------------------------------------- CONSTRUCTORS @@ -61,9 +61,9 @@ export class MutexConnector { * @param header Initial data sending to the remote server after connection. Hope to use it as an activation tool. * @param provider Additional feature provided for the remote server. If don't plan to provide anything to the remote server, assign `null`. */ - public constructor(header: Header, provider: Provider) { - this.base_ = new WebConnector(header, provider); - this.controller_ = this.base_.getDriver(); + public constructor(header: Header) { + this.connector_ = new WebSocketConnector(header, null); + this.driver_ = this.connector_.getDriver(); } /** @@ -84,7 +84,7 @@ export class MutexConnector { * @throw WebError when server does not accept your connection until timeout. */ public connect(url: string, timeout?: number): Promise { - return this.base_.connect(url, { timeout }); + return this.connector_.connect(url, { timeout }); } /** @@ -105,7 +105,7 @@ export class MutexConnector { * @throw DomainError when the connection is not online. */ public async close(): Promise { - await this.base_.close(); + await this.connector_.close(); } /** @@ -136,7 +136,7 @@ export class MutexConnector { public join(at: Date): Promise; public join(param?: number | Date): Promise { - return this.base_.join(param! as Date); + return this.connector_.join(param! as Date); } /* ----------------------------------------------------------- @@ -146,7 +146,7 @@ export class MutexConnector { * Get connection url. */ public get url(): string | undefined { - return this.base_.url; + return this.connector_.url; } /** @@ -162,14 +162,14 @@ export class MutexConnector { * - `CLOSED`: The connection is offline. */ public get state(): MutexConnector.State { - return this.base_.state; + return this.connector_.state; } /** * Get header. */ public get header(): Header { - return this.base_.header; + return this.connector_.header; } /** @@ -192,11 +192,8 @@ export class MutexConnector { * @template UseParametric Whether to convert type of function parameters to be compatible with their pritimive. * @return A `Driver` for the [RFC](https://github.com/samchon/tgrid#13-remote-function-call). */ - public getDriver< - Controller extends object, - UseParametric extends boolean = false, - >(): Promisive { - return this.controller_.provider as any; + public getDriver(): Driver { + return this.driver_; } /* ----------------------------------------------------------- @@ -216,7 +213,7 @@ export class MutexConnector { */ public getConditionVariable(key: string): Promise { return RemoteConditionVariable.create( - this.controller_.group.condition_variables, + this.driver_.condition_variables, key, ); } @@ -234,7 +231,7 @@ export class MutexConnector { * @return A {@link RemoteMutex} object. */ public getMutex(key: string): Promise { - return RemoteMutex.create(this.controller_.group.mutexes, key); + return RemoteMutex.create(this.driver_.mutexes, key); } /** @@ -254,11 +251,7 @@ export class MutexConnector { * @return A {@link RemoteSemaphore} object. */ public getSemaphore(key: string, count: number): Promise { - return RemoteSemaphore.create( - this.controller_.group.semaphores, - key, - count, - ); + return RemoteSemaphore.create(this.driver_.semaphores, key, count); } /** @@ -278,7 +271,7 @@ export class MutexConnector { * @return A {@link RemoteBarrier} object. */ public getBarrier(key: string, count: number): Promise { - return RemoteBarrier.create(this.controller_.group.barriers, key, count); + return RemoteBarrier.create(this.driver_.barriers, key, count); } /** @@ -298,11 +291,7 @@ export class MutexConnector { * @return A {@link RemoteLatch} object. */ public getLatch(identifier: string, count: number): Promise { - return RemoteLatch.create( - this.controller_.group.latches, - identifier, - count, - ); + return RemoteLatch.create(this.driver_.latches, identifier, count); } } @@ -313,5 +302,5 @@ export namespace MutexConnector { /** * Current state of the {@link MutexConnector} */ - export import State = WebConnector.State; + export import State = WebSocketConnector.State; } diff --git a/src/MutexServer.ts b/src/MutexServer.ts index e8ef222..f71a4fb 100644 --- a/src/MutexServer.ts +++ b/src/MutexServer.ts @@ -3,10 +3,9 @@ * @module msv */ //----------------------------------------------------------- -import { WebServer } from "tgrid"; +import { WebSocketServer } from "tgrid"; import { MutexAcceptor } from "./MutexAcceptor"; -import { ProviderCapsule } from "./server/ProviderCapsule"; import { ProviderGroup } from "./server/ProviderGroup"; import { GlobalGroup } from "./server/GlobalGroup"; @@ -40,7 +39,7 @@ export class MutexServer { /** * @hidden */ - private server_: WebServer>; + private server_: WebSocketServer; /** * @hidden @@ -68,7 +67,7 @@ export class MutexServer { public constructor(key: string, cert: string); public constructor(key?: string, cert?: string) { - this.server_ = new WebServer(key!, cert!); + this.server_ = new WebSocketServer(key!, cert!); this.components_ = new GlobalGroup(); } @@ -97,15 +96,11 @@ export class MutexServer { */ public open( port: number, - handler: (acceptor: MutexAcceptor) => Promise, + handler: (acceptor: MutexAcceptor
) => Promise, ): Promise { return this.server_.open(port, async (base) => { - let group: ProviderGroup = new ProviderGroup(this.components_, base); - let acceptor: MutexAcceptor = MutexAcceptor.create( - base, - group, - ); - + const group: ProviderGroup = new ProviderGroup(this.components_, base); + const acceptor: MutexAcceptor
= MutexAcceptor.create(base, group); await handler(acceptor); }); } @@ -153,5 +148,5 @@ export namespace MutexServer { /** * Current state of the {@link MutexServer} */ - export import State = WebServer.State; + export import State = WebSocketServer.State; } diff --git a/src/client/RemoteBarrier.ts b/src/client/RemoteBarrier.ts index 59ac17d..4c944d0 100644 --- a/src/client/RemoteBarrier.ts +++ b/src/client/RemoteBarrier.ts @@ -85,7 +85,7 @@ export class RemoteBarrier { * @return Whether succeeded to waiting in the given time. */ public async wait_until(at: Date): Promise { - let ms: number = at.getTime() - Date.now(); + const ms: number = at.getTime() - Date.now(); return await this.wait_for(ms); } diff --git a/src/client/RemoteConditionVariable.ts b/src/client/RemoteConditionVariable.ts index 501262f..6af7d1c 100644 --- a/src/client/RemoteConditionVariable.ts +++ b/src/client/RemoteConditionVariable.ts @@ -88,11 +88,10 @@ export class RemoteConditionVariable { * * This method is equivalent to: ```typescript - let at: Date = new Date(Date.now() + ms); - while (!await predicator()) - { - if (!await this.wait_until(at)) - return await predicator(); + const at: Date = new Date(Date.now() + ms); + while (!await predicator()) { + if (!await this.wait_until(at)) + return await predicator(); } return true; ``` @@ -110,7 +109,7 @@ export class RemoteConditionVariable { ms: number, predicator?: RemoteConditionVariable.Predicator, ): Promise { - let at: Date = new Date(Date.now() + ms); + const at: Date = new Date(Date.now() + ms); return this.wait_until(at, predicator!); } @@ -127,10 +126,9 @@ export class RemoteConditionVariable { * * This method is equivalent to: ```typescript - while (!await predicator()) - { - if (!await this.wait_until(at)) - return await predicator(); + while (!await predicator()) { + if (!await this.wait_until(at)) + return await predicator(); } return true; ``` @@ -167,7 +165,7 @@ export class RemoteConditionVariable { * @hidden */ private async _Wait_until(at: Date): Promise { - let ms: number = at.getTime() - Date.now(); + const ms: number = at.getTime() - Date.now(); return await this.controller_.wait_for(this.name_, ms); } diff --git a/src/client/RemoteLatch.ts b/src/client/RemoteLatch.ts index 049e5b3..af71b94 100644 --- a/src/client/RemoteLatch.ts +++ b/src/client/RemoteLatch.ts @@ -105,7 +105,7 @@ export class RemoteLatch { * @return Whether succeeded to waiting in the given time. */ public async wait_until(at: Date): Promise { - let ms: number = at.getTime() - Date.now(); + const ms: number = at.getTime() - Date.now(); return await this.wait_for(ms); } diff --git a/src/client/RemoteMutex.ts b/src/client/RemoteMutex.ts index 889d816..ce285eb 100644 --- a/src/client/RemoteMutex.ts +++ b/src/client/RemoteMutex.ts @@ -125,7 +125,7 @@ export class RemoteMutex { * @return Whether succeeded to monopoly the mutex or not. */ public async try_lock_until(at: Date): Promise { - let ms: number = at.getTime() - Date.now(); + const ms: number = at.getTime() - Date.now(); return await this.try_lock_for(ms); } @@ -237,7 +237,7 @@ export class RemoteMutex { * @return Whether succeeded to share the mutex or not. */ public async try_lock_shared_until(at: Date): Promise { - let ms: number = at.getTime() - Date.now(); + const ms: number = at.getTime() - Date.now(); return await this.try_lock_shared_for(ms); } diff --git a/src/client/RemoteSemaphore.ts b/src/client/RemoteSemaphore.ts index 4e77678..d22607b 100644 --- a/src/client/RemoteSemaphore.ts +++ b/src/client/RemoteSemaphore.ts @@ -48,7 +48,7 @@ export class RemoteSemaphore { name: string, count: number, ): Promise { - let max: number = await controller.emplace(name, count); + const max: number = await controller.emplace(name, count); return new RemoteSemaphore(controller, name, max); } @@ -149,7 +149,7 @@ export class RemoteSemaphore { * @return Whether succeded to acquire or not. */ public async try_acquire_until(at: Date): Promise { - let ms: number = at.getTime() - Date.now(); + const ms: number = at.getTime() - Date.now(); return await this.try_acquire_for(ms); } diff --git a/src/server/ProviderCapsule.ts b/src/server/ProviderCapsule.ts deleted file mode 100644 index 6680a66..0000000 --- a/src/server/ProviderCapsule.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { ProviderGroup } from "./ProviderGroup"; - -/** - * @internal - */ -export interface ProviderCapsule { - group: ProviderGroup; - provider: T; -} diff --git a/src/server/ProviderGroup.ts b/src/server/ProviderGroup.ts index f71b257..70cd878 100644 --- a/src/server/ProviderGroup.ts +++ b/src/server/ProviderGroup.ts @@ -1,4 +1,4 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { Joiner } from "./components/internal/Joiner"; import { GlobalGroup } from "./GlobalGroup"; @@ -24,7 +24,10 @@ export class ProviderGroup { public readonly barriers: BarriersProvider; public readonly latches: LatchesProvider; - public constructor(group: GlobalGroup, acceptor: WebAcceptor) { + public constructor( + group: GlobalGroup, + acceptor: WebSocketAcceptor, + ) { this.disolvers_ = new List(); this.condition_variables = new ConditionVariablesProvider( @@ -61,7 +64,7 @@ export class ProviderGroup { } public async destructor(): Promise { - for (let joiner of this.disolvers_) + for (const joiner of this.disolvers_) if (joiner !== undefined) await joiner(); await this.condition_variables.destructor(); diff --git a/src/server/components/IComponent.ts b/src/server/components/IComponent.ts index cdbec0d..fa4ce1a 100644 --- a/src/server/components/IComponent.ts +++ b/src/server/components/IComponent.ts @@ -1,9 +1,12 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal */ export interface IComponent { - _Insert_acceptor(acceptor: WebAcceptor): void; - _Erase_acceptor(acceptor: WebAcceptor): boolean; + _Insert_acceptor(acceptor: WebSocketAcceptor): void; + _Erase_acceptor( + acceptor: WebSocketAcceptor, + ): boolean; } diff --git a/src/server/components/ServerBarrier.ts b/src/server/components/ServerBarrier.ts index 098a0be..da3a104 100644 --- a/src/server/components/ServerBarrier.ts +++ b/src/server/components/ServerBarrier.ts @@ -1,9 +1,10 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { List } from "tstl"; import { IComponent } from "./IComponent"; import { ServerConditionVariable } from "./ServerConditionVariable"; import { Joiner } from "./internal/Joiner"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -24,11 +25,15 @@ export class ServerBarrier implements IComponent { this.count_ = size; } - public _Insert_acceptor(acceptor: WebAcceptor): void { + public _Insert_acceptor( + acceptor: WebSocketAcceptor, + ): void { this.cv_._Insert_acceptor(acceptor); } - public _Erase_acceptor(acceptor: WebAcceptor): boolean { + public _Erase_acceptor( + acceptor: WebSocketAcceptor, + ): boolean { return this.cv_._Erase_acceptor(acceptor); } @@ -36,7 +41,7 @@ export class ServerBarrier implements IComponent { WAITORS --------------------------------------------------------- */ public wait( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return this.cv_.wait(acceptor, disolver); @@ -44,7 +49,7 @@ export class ServerBarrier implements IComponent { public wait_for( ms: number, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return this.cv_.wait_for(ms, acceptor, disolver); @@ -54,7 +59,7 @@ export class ServerBarrier implements IComponent { ARRIVERS --------------------------------------------------------- */ public async arrive(n: number): Promise { - let completed: boolean = (this.count_ += n) <= this.size_; + const completed: boolean = (this.count_ += n) <= this.size_; if (completed === false) return; this.count_ %= this.size_; @@ -62,7 +67,7 @@ export class ServerBarrier implements IComponent { } public async arrive_and_wait( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { await this.arrive(1); diff --git a/src/server/components/ServerConditionVariable.ts b/src/server/components/ServerConditionVariable.ts index 1ddf210..1558cba 100644 --- a/src/server/components/ServerConditionVariable.ts +++ b/src/server/components/ServerConditionVariable.ts @@ -1,9 +1,10 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { List, sleep_for } from "tstl"; import { LockType } from "tstl/lib/internal/thread/LockType"; import { SolidComponent } from "./SolidComponent"; import { Joiner } from "./internal/Joiner"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -13,12 +14,12 @@ export class ServerConditionVariable extends SolidComponent { WAITORS --------------------------------------------------------- */ public wait( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return new Promise((resolve) => { // ENROLL TO THE RESOLVERS - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: resolve, lockType: LockType.HOLD, @@ -34,12 +35,12 @@ export class ServerConditionVariable extends SolidComponent { public wait_for( ms: number, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return new Promise((resolve) => { // ENROLL TO THE RESOLVERS - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: resolve, lockType: LockType.KNOCK, @@ -74,7 +75,7 @@ export class ServerConditionVariable extends SolidComponent { if (this.queue_.empty()) return; // POP THE FIRST ITEM - let it: List.Iterator = this.queue_.begin(); + const it: List.Iterator = this.queue_.begin(); this.queue_.erase(it); // DO RESOLVE @@ -85,22 +86,22 @@ export class ServerConditionVariable extends SolidComponent { if (this.queue_.empty()) return; // COPY RESOLVERS - let ordinaryResolvers: Resolver[] = [...this.queue_]; - let copiedResolvers: Resolver[] = ordinaryResolvers.map((resolver) => ({ + const ordinaryResolvers: Resolver[] = [...this.queue_]; + const copiedResolvers: Resolver[] = ordinaryResolvers.map((resolver) => ({ ...resolver, })); // CLEAR OLD ITEMS this.queue_.clear(); - for (let resolver of ordinaryResolvers) resolver.destructor!(); + for (const resolver of ordinaryResolvers) resolver.destructor!(); // DO NOTIFY - for (let resolver of copiedResolvers) this._Notify(resolver, false); + for (const resolver of copiedResolvers) this._Notify(resolver, false); } private _Notify(resolver: Resolver, discard: boolean): void { // RESERVE HANDLER - let handler = resolver.handler!; + const handler = resolver.handler!; // DISCARD FOR SEQUENCE if (discard === true) resolver.destructor!(); diff --git a/src/server/components/ServerLatch.ts b/src/server/components/ServerLatch.ts index 63ae934..4c2da17 100644 --- a/src/server/components/ServerLatch.ts +++ b/src/server/components/ServerLatch.ts @@ -1,9 +1,10 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { List } from "tstl"; import { IComponent } from "./IComponent"; import { ServerConditionVariable } from "./ServerConditionVariable"; import { Joiner } from "./internal/Joiner"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -20,11 +21,15 @@ export class ServerLatch implements IComponent { this.count_ = size; } - public _Insert_acceptor(acceptor: WebAcceptor): void { + public _Insert_acceptor( + acceptor: WebSocketAcceptor, + ): void { this.cv_._Insert_acceptor(acceptor); } - public _Erase_acceptor(acceptor: WebAcceptor): boolean { + public _Erase_acceptor( + acceptor: WebSocketAcceptor, + ): boolean { return this.cv_._Erase_acceptor(acceptor); } @@ -32,7 +37,7 @@ export class ServerLatch implements IComponent { WAITORS --------------------------------------------------------- */ public async wait( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { if (this._Try_wait() === false) return this.cv_.wait(acceptor, disolver); @@ -44,7 +49,7 @@ export class ServerLatch implements IComponent { public async wait_for( ms: number, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { if (this._Try_wait() === true) return true; @@ -64,7 +69,7 @@ export class ServerLatch implements IComponent { } public async arrive_and_wait( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { await this.count_down(1); diff --git a/src/server/components/ServerMutex.ts b/src/server/components/ServerMutex.ts index 94e28b4..0b76f2a 100644 --- a/src/server/components/ServerMutex.ts +++ b/src/server/components/ServerMutex.ts @@ -1,4 +1,4 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { List, sleep_for, OutOfRange, Pair } from "tstl"; import { AccessType } from "tstl/lib/internal/thread/AccessType"; import { LockType } from "tstl/lib/internal/thread/LockType"; @@ -6,6 +6,7 @@ import { LockType } from "tstl/lib/internal/thread/LockType"; import { SolidComponent } from "./SolidComponent"; import { Disolver } from "./internal/Disolver"; import { Joiner } from "./internal/Joiner"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -25,7 +26,7 @@ export class ServerMutex extends SolidComponent { } protected _Insert_resolver(resolver: Resolver): List.Iterator { - let it: List.Iterator = super._Insert_resolver(resolver); + const it: List.Iterator = super._Insert_resolver(resolver); resolver.iterator = it; return it; @@ -35,12 +36,12 @@ export class ServerMutex extends SolidComponent { WRITE LOCK --------------------------------------------------------- */ public lock( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return new Promise((resolve) => { // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: this.writing_++ === 0 && this.reading_ === 0 ? null : resolve, accessType: AccessType.WRITE, lockType: LockType.HOLD, @@ -59,14 +60,14 @@ export class ServerMutex extends SolidComponent { } public async try_lock( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { // LOCKABLE ? if (this.writing_ !== 0 || this.reading_ !== 0) return false; // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: null, accessType: AccessType.WRITE, lockType: LockType.KNOCK, @@ -86,12 +87,12 @@ export class ServerMutex extends SolidComponent { public try_lock_for( ms: number, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return new Promise((resolve) => { // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: this.writing_++ === 0 && this.reading_ === 0 ? null : resolve, accessType: AccessType.WRITE, lockType: LockType.KNOCK, @@ -118,7 +119,9 @@ export class ServerMutex extends SolidComponent { }); } - public async unlock(acceptor: WebAcceptor): Promise { + public async unlock( + acceptor: WebSocketAcceptor, + ): Promise { //---- // VALIDATION //---- @@ -132,7 +135,7 @@ export class ServerMutex extends SolidComponent { ); // IN LOCAL AREA - let local: SolidComponent.LocalArea | null = + const local: SolidComponent.LocalArea | null = this._Get_local_area(acceptor); if ( local === null || @@ -147,7 +150,7 @@ export class ServerMutex extends SolidComponent { // RELEASE //---- // DESTRUCT TOP RESOLVER - let top: Resolver = local.queue.front(); + const top: Resolver = local.queue.front(); this.queue_.erase(top.iterator!); top.destructor!(); @@ -161,12 +164,12 @@ export class ServerMutex extends SolidComponent { READ LOCK --------------------------------------------------------- */ public lock_shared( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return new Promise((resolve) => { // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: this.writing_ === 0 ? null : resolve, accessType: AccessType.READ, lockType: LockType.HOLD, @@ -186,13 +189,13 @@ export class ServerMutex extends SolidComponent { } public async try_lock_shared( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { if (this.writing_ !== 0) return false; // CONSTRUCT RESOLVER - let it = this._Insert_resolver({ + const it = this._Insert_resolver({ handler: null, accessType: AccessType.READ, lockType: LockType.KNOCK, @@ -212,12 +215,12 @@ export class ServerMutex extends SolidComponent { public try_lock_shared_for( ms: number, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: List.Iterator, ): Promise { return new Promise((resolve) => { // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: this.writing_ === 0 ? null : resolve, accessType: AccessType.READ, lockType: LockType.KNOCK, @@ -243,7 +246,9 @@ export class ServerMutex extends SolidComponent { }); } - public async unlock_shared(acceptor: WebAcceptor): Promise { + public async unlock_shared( + acceptor: WebSocketAcceptor, + ): Promise { //---- // VALIDATION //---- @@ -257,7 +262,7 @@ export class ServerMutex extends SolidComponent { ); // IN LOCAL AREA - let local: SolidComponent.LocalArea | null = + const local: SolidComponent.LocalArea | null = this._Get_local_area(acceptor); if ( local === null || @@ -272,7 +277,7 @@ export class ServerMutex extends SolidComponent { // RELEASE //---- // DESTRUCT THE RESOLVER - let top: Resolver = local.queue.front(); + const top: Resolver = local.queue.front(); this.queue_.erase(top.iterator!); top.destructor!(); @@ -289,10 +294,10 @@ export class ServerMutex extends SolidComponent { if (this.queue_.empty() === true) return; // GATHER THE NEXT STEPS - let currentType: AccessType = this.queue_.front().accessType; - let pairList: Pair[] = []; + const currentType: AccessType = this.queue_.front().accessType; + const pairList: Pair[] = []; - for (let resolver of this.queue_) { + for (const resolver of this.queue_) { // STOP WHEN DIFFERENT ACCESS TYPE COMES if (resolver.accessType !== currentType) break; // RESERVE HANDLER @@ -306,20 +311,20 @@ export class ServerMutex extends SolidComponent { } // CALL THE HANDLERS - for (let pair of pairList) + for (const pair of pairList) if (pair.second === LockType.HOLD) pair.first(); else pair.first(true); } private _Cancel(it: List.Iterator): void { // POP HANDLER & DESTRUCT - let handler: Function = it.value.handler!; + const handler: Function = it.value.handler!; this.queue_.erase(it); it.value.destructor!(); // CHECK THE PREVIOUS HANDLER - let prev: List.Iterator = it.prev(); + const prev: List.Iterator = it.prev(); if (prev.equals(this.queue_.end()) === false && prev.value.handler === null) this._Release(); diff --git a/src/server/components/ServerSemaphore.ts b/src/server/components/ServerSemaphore.ts index 1915810..651d531 100644 --- a/src/server/components/ServerSemaphore.ts +++ b/src/server/components/ServerSemaphore.ts @@ -1,9 +1,10 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { List, sleep_for, OutOfRange, Pair } from "tstl"; import { LockType } from "tstl/lib/internal/thread/LockType"; import { SolidComponent } from "./SolidComponent"; import { Disolver } from "./internal/Disolver"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -30,14 +31,14 @@ export class ServerSemaphore extends SolidComponent { ACQUIRANCES --------------------------------------------------------- */ public acquire( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: Disolver, ): Promise { return new Promise((resolve) => { - let success: boolean = this.acquiring_ < this.max_; + const success: boolean = this.acquiring_ < this.max_; // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: success ? null : resolve, lockType: LockType.HOLD, acceptor: acceptor, @@ -59,14 +60,14 @@ export class ServerSemaphore extends SolidComponent { } public async try_acquire( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: Disolver, ): Promise { // ACQUIRABLE ? if (this.acquiring_ >= this.max_) return false; // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: null, lockType: LockType.HOLD, acceptor: acceptor, @@ -84,14 +85,14 @@ export class ServerSemaphore extends SolidComponent { public async try_acquire_for( ms: number, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolver: Disolver, ): Promise { return new Promise((resolve) => { - let success: boolean = this.acquiring_ < this.max_; + const success: boolean = this.acquiring_ < this.max_; // CONSTRUCT RESOLVER - let it: List.Iterator = this._Insert_resolver({ + const it: List.Iterator = this._Insert_resolver({ handler: success ? null : resolve, lockType: LockType.KNOCK, acceptor: acceptor, @@ -110,7 +111,7 @@ export class ServerSemaphore extends SolidComponent { resolve(true); } else sleep_for(ms).then(() => { - let success: boolean = it.value.handler === null; + const success: boolean = it.value.handler === null; if (success === false) this._Cancel(it); resolve(success); @@ -120,7 +121,7 @@ export class ServerSemaphore extends SolidComponent { private _Cancel(it: List.Iterator): void { // POP THE LISTENER - let handler: Function = it.value.handler!; + const handler: Function = it.value.handler!; this.queue_.erase(it); it.value.destructor!(); @@ -134,7 +135,7 @@ export class ServerSemaphore extends SolidComponent { --------------------------------------------------------- */ public async release( n: number, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, ): Promise { //---- // VALIDATION @@ -154,7 +155,7 @@ export class ServerSemaphore extends SolidComponent { ); // IN LOCAL AREA - let local: SolidComponent.LocalArea | null = + const local: SolidComponent.LocalArea | null = this._Get_local_area(acceptor); if (local === null || local.queue.empty() === true) throw new OutOfRange( @@ -172,8 +173,10 @@ export class ServerSemaphore extends SolidComponent { this.acquiring_ -= n; local.aggregate.acquring -= n; + // eslint-disable-next-line let count: number = 0; for ( + // eslint-disable-next-line let it = local.queue.begin(); it.equals(local.queue.end()) === false; @@ -185,9 +188,9 @@ export class ServerSemaphore extends SolidComponent { } // RESERVE HANDLERS - let pairList: Pair[] = []; + const pairList: Pair[] = []; - for (let resolver of this.queue_) + for (const resolver of this.queue_) if (resolver.handler !== null) { pairList.push(new Pair(resolver.handler!, resolver.lockType)); resolver.handler = null; @@ -197,7 +200,7 @@ export class ServerSemaphore extends SolidComponent { } // CALL HANDLERS - for (let pair of pairList) + for (const pair of pairList) if (pair.second === LockType.HOLD) pair.first(); else pair.first(true); } diff --git a/src/server/components/SolidComponent.ts b/src/server/components/SolidComponent.ts index 461ccac..61852c1 100644 --- a/src/server/components/SolidComponent.ts +++ b/src/server/components/SolidComponent.ts @@ -1,9 +1,10 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { HashMap, HashSet, List } from "tstl"; import { LockType } from "tstl/lib/internal/thread/LockType"; import { IComponent } from "./IComponent"; import { Disolver } from "./internal/Disolver"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -15,11 +16,12 @@ export abstract class SolidComponent< { protected queue_: List; protected local_areas_: HashMap< - WebAcceptor, + WebSocketAcceptor, SolidComponent.LocalArea >; - private acceptors_: HashSet> = new HashSet(); + private acceptors_: HashSet> = + new HashSet(); /* --------------------------------------------------------- CONSTRUCTORS @@ -29,11 +31,15 @@ export abstract class SolidComponent< this.local_areas_ = new HashMap(); } - public _Insert_acceptor(acceptor: WebAcceptor): void { + public _Insert_acceptor( + acceptor: WebSocketAcceptor, + ): void { this.acceptors_.insert(acceptor); } - public _Erase_acceptor(acceptor: WebAcceptor): boolean { + public _Erase_acceptor( + acceptor: WebSocketAcceptor, + ): boolean { this.acceptors_.erase(acceptor); return this.acceptors_.empty(); } @@ -46,8 +52,9 @@ export abstract class SolidComponent< // LOCAL QUEUE //---- // FIND OR EMPLACE + // eslint-disable-next-line let mit: HashMap.Iterator< - WebAcceptor, + WebSocketAcceptor, SolidComponent.LocalArea > = this.local_areas_.find(resolver.acceptor); if (mit.equals(this.local_areas_.end()) === true) @@ -56,14 +63,14 @@ export abstract class SolidComponent< aggregate: resolver.aggregate, }).first; else { - for (let key in resolver.aggregate) + for (const key in resolver.aggregate) (mit.second.aggregate as Record)[key] += resolver.aggregate[key]; resolver.aggregate = mit.second.aggregate; } // INSERT NEW ITEM - let lit: List.Iterator = mit.second.queue.insert( + const lit: List.Iterator = mit.second.queue.insert( mit.second.queue.end(), resolver, ); @@ -71,7 +78,7 @@ export abstract class SolidComponent< //---- // GLOBAL QUEUE //---- - let ret: List.Iterator = this.queue_.insert( + const ret: List.Iterator = this.queue_.insert( this.queue_.end(), resolver, ); @@ -88,10 +95,10 @@ export abstract class SolidComponent< } protected _Get_local_area( - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, ): SolidComponent.LocalArea | null { - let it: HashMap.Iterator< - WebAcceptor, + const it: HashMap.Iterator< + WebSocketAcceptor, SolidComponent.LocalArea > = this.local_areas_.find(acceptor); return it.equals(this.local_areas_.end()) === false ? it.second : null; @@ -111,7 +118,7 @@ export namespace SolidComponent { lockType: LockType; // ASSET FFOR CLIENT - acceptor: WebAcceptor; + acceptor: WebSocketAcceptor; aggregate: AggregateT; disolver: Disolver; diff --git a/src/server/global/GlobalBase.ts b/src/server/global/GlobalBase.ts index fea43c2..5aba08f 100644 --- a/src/server/global/GlobalBase.ts +++ b/src/server/global/GlobalBase.ts @@ -1,7 +1,8 @@ -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { HashMap } from "tstl"; import { IComponent } from "../components/IComponent"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -18,17 +19,20 @@ export abstract class GlobalBase { public emplace( name: string, param: Param, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, ): Ret { - let it: HashMap.Iterator = this.dict_.find(name); - if (it.equals(this.dict_.end()) === true) - it = this.dict_.emplace(name, this._Create_component(param)).first; - it.second._Insert_acceptor(acceptor); - - return this._Returns(it.second); + // eslint-disable-next-line + const component: ComponentT = this.dict_.take(name, () => + this._Create_component(param), + ); + component._Insert_acceptor(acceptor); + return this._Returns(component); } - public erase(name: string, acceptor: WebAcceptor): void { + public erase( + name: string, + acceptor: WebSocketAcceptor, + ): void { if (this.dict_.get(name)._Erase_acceptor(acceptor) === true) this.dict_.erase(name); } diff --git a/src/server/providers/ProviderBase.ts b/src/server/providers/ProviderBase.ts index 6e08c08..0b2b37d 100644 --- a/src/server/providers/ProviderBase.ts +++ b/src/server/providers/ProviderBase.ts @@ -3,11 +3,12 @@ * @module msv */ //----------------------------------------------------------- -import { WebAcceptor } from "tgrid"; +import { WebSocketAcceptor } from "tgrid"; import { List, HashSet, OutOfRange } from "tstl"; import { GlobalBase } from "../global/GlobalBase"; import { Joiner } from "../components/internal/Joiner"; +import { ProviderGroup } from "../ProviderGroup"; /** * @internal @@ -18,7 +19,7 @@ export abstract class ProviderBase< Ret, > { protected readonly global_: GlobalT; - protected readonly acceptor_: WebAcceptor; + protected readonly acceptor_: WebSocketAcceptor; private readonly disolvers_: List; private readonly names_: HashSet; @@ -29,7 +30,7 @@ export abstract class ProviderBase< --------------------------------------------------------- */ public constructor( global: GlobalT, - acceptor: WebAcceptor, + acceptor: WebSocketAcceptor, disolvers: List, remoteName: string, ) { @@ -42,7 +43,7 @@ export abstract class ProviderBase< } public destructor(): void { - for (let name of this.names_) this.erase(name); + for (const name of this.names_) this.erase(name); } protected createDisolver(): List.Iterator { diff --git a/test/index.ts b/test/index.ts index 89e599d..d04e676 100644 --- a/test/index.ts +++ b/test/index.ts @@ -29,10 +29,10 @@ async function iterate( server: MutexServer, path: string, ): Promise { - let fileList: string[] = await fs.promises.readdir(path); + const fileList: string[] = await fs.promises.readdir(path); for (let file of fileList) { - let currentPath: string = `${path}/${file}`; - let stats: fs.Stats = await fs.promises.lstat(currentPath); + const currentPath: string = `${path}/${file}`; + const stats: fs.Stats = await fs.promises.lstat(currentPath); if ( stats.isDirectory() === true && @@ -47,7 +47,7 @@ async function iterate( ) continue; - let external: IModule = await import( + const external: IModule = await import( currentPath.substr(0, currentPath.length - 3) ); for (let key in external) { @@ -73,23 +73,19 @@ async function main(): Promise { // OPEN SERVER let server: MutexServer = new MutexServer(); await server.open(PORT, async (acceptor) => { - if (acceptor.header.password === HEADER.password) - await acceptor.accept(null); + if (acceptor.header.password === HEADER.password) await acceptor.accept(); else await acceptor.reject(); }); // CONNECTION-FACTORY TO THE SERVER let sequence: number = 0; - let connectorList: MutexConnector[] = []; - - let factory: ConnectionFactory = async () => { - let connector: MutexConnector = new MutexConnector( - { - uid: ++sequence, - ...HEADER, - }, - null, - ); + const connectorList: MutexConnector[] = []; + + const factory: ConnectionFactory = async () => { + const connector: MutexConnector = new MutexConnector({ + uid: ++sequence, + ...HEADER, + }); await connector.connect(URL); connectorList.push(connector); diff --git a/test/internal/ConnectionFactory.ts b/test/internal/ConnectionFactory.ts index 6302548..945c8d1 100644 --- a/test/internal/ConnectionFactory.ts +++ b/test/internal/ConnectionFactory.ts @@ -3,5 +3,5 @@ import { MutexConnector } from "mutex-server"; import { IActivation } from "./IActivation"; export interface ConnectionFactory { - (): Promise>; + (): Promise>; } diff --git a/test/manual/remote-mutex.ts b/test/manual/remote-mutex.ts index 202a07f..ebe903f 100644 --- a/test/manual/remote-mutex.ts +++ b/test/manual/remote-mutex.ts @@ -6,9 +6,8 @@ const PORT = 37119; async function client(index: number, character: string): Promise { // CONNECT TO THE SERVER - const connector: msv.MutexConnector = new msv.MutexConnector( + const connector: msv.MutexConnector = new msv.MutexConnector( PASSWORD, - null, ); await connector.connect(`ws://127.0.0.1:${PORT}`); @@ -34,7 +33,7 @@ async function main(): Promise { // OPEN SERVER const server: MutexServer = new MutexServer(); await server.open(PORT, async (acceptor) => { - if (acceptor.header === PASSWORD) await acceptor.accept(null); + if (acceptor.header === PASSWORD) await acceptor.accept(); else await acceptor.reject(); }); diff --git a/test/mutextes/test_mutex_disconnections.ts b/test/mutextes/test_mutex_disconnections.ts index 148e71e..50afd2e 100644 --- a/test/mutextes/test_mutex_disconnections.ts +++ b/test/mutextes/test_mutex_disconnections.ts @@ -8,7 +8,7 @@ async function test_disconnection( factory: ConnectionFactory, index: number, ): Promise { - const connector: MutexConnector = await factory(); + const connector: MutexConnector = await factory(); const mutex: RemoteMutex = await connector.getMutex( "test_mutex_disconnection", ); diff --git a/test/mutextes/test_mutex_locks.ts b/test/mutextes/test_mutex_locks.ts index 0bde2ba..48abc7a 100644 --- a/test/mutextes/test_mutex_locks.ts +++ b/test/mutextes/test_mutex_locks.ts @@ -16,7 +16,7 @@ const MAGNIFIER: number = 3; export async function test_mutex_locks( factory: ConnectionFactory, ): Promise { - const connector: MutexConnector = await factory(); + const connector: MutexConnector = await factory(); const mutex: RemoteMutex = await connector.getMutex("remote_mutex"); // TEST COMMON FEATURES diff --git a/test/semaphores/test_semaphore_acquires.ts b/test/semaphores/test_semaphore_acquires.ts index 47aaec9..3ddf733 100644 --- a/test/semaphores/test_semaphore_acquires.ts +++ b/test/semaphores/test_semaphore_acquires.ts @@ -14,7 +14,7 @@ export async function test_semaphore_acquires( //---- // TEST MUTEX FEATURES //---- - const connector: MutexConnector = await factory(); + const connector: MutexConnector = await factory(); const mutex: RemoteSemaphore = await connector.getSemaphore( "test_semaphore_acquires_binary", 1, diff --git a/test/semaphores/test_semaphore_disconnections.ts b/test/semaphores/test_semaphore_disconnections.ts index ae6f72a..1d91ec9 100644 --- a/test/semaphores/test_semaphore_disconnections.ts +++ b/test/semaphores/test_semaphore_disconnections.ts @@ -10,7 +10,7 @@ async function acquire_and_disconnect( factory: ConnectionFactory, ms: number, ): Promise { - const connector: MutexConnector = await factory(); + const connector: MutexConnector = await factory(); const semaphore: RemoteSemaphore = await connector.getSemaphore( "test_semaphore_disconnections", 0, @@ -29,7 +29,7 @@ async function acquire_and_disconnect( export async function test_semaphore_disconnections( factory: ConnectionFactory, ): Promise { - const connector: MutexConnector = await factory(); + const connector: MutexConnector = await factory(); const semaphore: RemoteSemaphore = await connector.getSemaphore( "test_semaphore_disconnections", MAX, diff --git a/test/test_destructors.ts b/test/test_destructors.ts index e88282a..8f96ff6 100644 --- a/test/test_destructors.ts +++ b/test/test_destructors.ts @@ -4,7 +4,7 @@ import { IActivation } from "./internal/IActivation"; import { ConnectionFactory } from "./internal/ConnectionFactory"; async function test(factory: ConnectionFactory): Promise { - let connector: MutexConnector = await factory(); + let connector: MutexConnector = await factory(); let mutex: RemoteMutex = await connector.getMutex("test_destructors"); await mutex.lock_shared(); From d027b4aff868833c5894afc9df3eb3f8e4bdabf9 Mon Sep 17 00:00:00 2001 From: Jeongho Nam Date: Tue, 25 Jun 2024 20:33:33 +0900 Subject: [PATCH 2/2] Exact interfaces --- package.json | 2 +- src/MutexAcceptor.ts | 47 +++------------------- src/MutexConnector.ts | 79 ++++++++++++------------------------- src/MutexServer.ts | 21 ++++------ test/index.ts | 15 +++---- test/manual/remote-mutex.ts | 2 +- test/test_destructors.ts | 4 +- 7 files changed, 50 insertions(+), 120 deletions(-) diff --git a/package.json b/package.json index d0b1c27..8b8c78c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mutex-server", - "version": "0.6.0", + "version": "0.6.1", "description": "Mutex Server using WebSocket", "main": "lib/index.js", "typings": "lib/index.d.ts", diff --git a/src/MutexAcceptor.ts b/src/MutexAcceptor.ts index 98838db..8f06fa6 100644 --- a/src/MutexAcceptor.ts +++ b/src/MutexAcceptor.ts @@ -8,7 +8,7 @@ import { ProviderGroup } from "./server/ProviderGroup"; * - available only in NodeJS. * * The {@link MutexAcceptor} is a communicator class interacting with the remote client, through - * websocket and [RFC](https://github.com/samchon/tgrid#13-remote-function-call) protocol, in the + * websocket and [RPC](https://tgrid.com/docs/remote-procedure-call/) protocol, in the * `mutex-server`. The {@link MutexAcceptor} objects are always created by the {@link MutexServer} * class, whenever a remote client connects to the `mutex-server`. * @@ -16,17 +16,12 @@ import { ProviderGroup } from "./server/ProviderGroup"; * method. If you {@link accept} the connection, the interaction would be started and the client * can access to critical component sections of this `mutex-server`. * - * Also, when declaring this {@link MutexAcceptor} type, you've to define two template arguments, - * *Header* and *Provider*. The *Header* type repersents an initial data gotten from the remote - * client after the connection. I hope you and client not to omit it and utilize it as an - * activation tool to enhance security. - * - * The second template argument *Provider* represents the additional features provided for the - * remote client. If you don't have any plan to provide additional feature to the remote client, - * just declare it as `null` + * Also, when declaring this {@link MutexAcceptor} type, you've to define one template argument, + * *Header*. The *Header* type repersents an initial data gotten from the remote client after + * the connection. I hope you and client not to omit it and utilize it as an activation tool + * to enhance security. * * @template Header Type of the header containing initial data. - * @template Provider Type of additional features provided for the remote client. * @author Jeongho Nam - https://github.com/samchon */ export class MutexAcceptor
{ @@ -73,11 +68,6 @@ export class MutexAcceptor
{ * acquired and tried would be automatically unlocked and cancelled by this `mutex-server`. * Also, remote critical section components had assigned to the client would be returned, too. * - * In addition, the disconnection destories all [RFC](https://github.com/samchon/tgrid#13-remote-function-call)s - * between the remote client. Therefore, if the remote client is providing custom features to - * your `mutex-server` and there're uncompleted method calls to the `Provider` through - * `Driver`, {@link RuntimeError} exceptions would be thrown. - * * @param code Closing code. * @param reason Reason why. * @throw DomainError when the connection is not online. @@ -158,33 +148,6 @@ export class MutexAcceptor
{ return this.base_.state; } - // /** - // * Get Driver for [RFC](https://github.com/samchon/tgrid#13-remote-function-call). - // * - // * If remote client provides custom features for this `mutex-server`, you can utilize - // * those features thorugh returned `Driver` object by this method. To use this method, you - // * should define the `Controller` template argument, a type of interface who is defining - // * additionla features provided from the remote client. - // * - // * The returned object `Driver` makes to call remote functions, defined in the `Controller` - // * and provided by `Provider` in the remote client, possible. In other words, callling a - // * function in the `Driver`, it means to call a matched function in the remote - // * client's `Provider` object. - // * - // * - `Controller`: Definition only - // * - `Driver`: [Remote Function Call](https://github.com/samchon/tgrid#13-remote-function-call) - // * - // * @template Controller An interface for provided features (functions & objects) from the remote client (`Provider`). - // * @template UseParametric Whether to convert type of function parameters to be compatible with their pritimive. - // * @return A `Driver` for the [RFC](https://github.com/samchon/tgrid#13-remote-function-call). - // */ - // public getDriver< - // Controller extends object, - // UseParametric extends boolean = false, - // >(): Driver { - // return this.base_.getDriver(); - // } - /* ---------------------------------------------------------------- HANDSHAKES ---------------------------------------------------------------- */ diff --git a/src/MutexConnector.ts b/src/MutexConnector.ts index 71be770..570fcf4 100644 --- a/src/MutexConnector.ts +++ b/src/MutexConnector.ts @@ -1,4 +1,4 @@ -import { Driver, WebSocketConnector } from "tgrid"; +import { WebSocketConnector } from "tgrid"; import { RemoteBarrier } from "./client/RemoteBarrier"; import { RemoteConditionVariable } from "./client/RemoteConditionVariable"; @@ -11,7 +11,7 @@ import { ProviderGroup } from "./server/ProviderGroup"; * Mutex server connector for client. * * The {@link MutexConnector} is a communicator class who can connect to a remote `mutex-server` - * and interact with it through websocket and [RFC](https://github.com/samchon/tgrid#13-remote-function-call) + * and interact with it through websocket and [RPC](https://tgrid.com/docs/remote-procedure-call/) * protocol. * * You can connect to the websocket `mutex-server` using {@link connect} method. After the @@ -28,17 +28,12 @@ import { ProviderGroup } from "./server/ProviderGroup"; * - {@link getBarrier} * - {@link getLatch} * - * Also, when declaring this {@link MutexConnector} type, you've to define two template arguments, - * *Header* and *Provider*. The *Header* type repersents an initial data sending to the remote - * `mutex-server` after connection. I hope you not to omit it and utilize it as an activation tool - * to enhance security. - * - * The second template argument *Provider* represents the custom features provided for the remote - * `mutex-server`. If you don't have any plan to provide any feature to the `mutex-server`, just - * declare it as `null`. + * Also, when declaring this {@link MutexConnector} type, you've to define one template argument, + * *Header*. The *Header* type repersents an initial data sending to the remote `mutex-server` + * after connection. I hope you not to omit it and utilize it as an activation tool to + * enhance security. * * @template Header Type of the *header* containing initial data. - * @template Provider Type of additional features provided for the remote server. If no plan to provide anything, declare `null`. * @author Jeongho Nam - https://github.com/samchon */ export class MutexConnector
{ @@ -47,11 +42,6 @@ export class MutexConnector
{ */ private connector_: WebSocketConnector; - /** - * @hidden - */ - private driver_: Driver; - /* ----------------------------------------------------------- CONSTRUCTORS ----------------------------------------------------------- */ @@ -59,11 +49,9 @@ export class MutexConnector
{ * Initializer Constructor. * * @param header Initial data sending to the remote server after connection. Hope to use it as an activation tool. - * @param provider Additional feature provided for the remote server. If don't plan to provide anything to the remote server, assign `null`. */ public constructor(header: Header) { this.connector_ = new WebSocketConnector(header, null); - this.driver_ = this.connector_.getDriver(); } /** @@ -97,11 +85,6 @@ export class MutexConnector
{ * tried to get locks through the remote critical section components by calling their methods, * those methods would throw {@link RuntimeError} exceptions. * - * Also, the disconnection destories all [RFC](https://github.com/samchon/tgrid#13-remote-function-call)s - * between the remote server. Therefore, if you or server has an additional `Provider` and - * there're uncompleted method calls to the `Provideer` through the `Driver`, - * {@link RuntimeError} exceptions would be thrown. - * * @throw DomainError when the connection is not online. */ public async close(): Promise { @@ -172,33 +155,9 @@ export class MutexConnector
{ return this.connector_.header; } - /** - * Get Driver for [RFC](https://github.com/samchon/tgrid#13-remote-function-call). - * - * If your target {@link MutexServer} provides additional features, you can utilize those - * features through returned `Driver` object by this method. To use this method, you should - * define the `Controller` template argument, a type of interface who is defining additional - * features provided from the remote server. - * - * The returned object `Driver` makes to call remote functions, defined in the `Controller` - * and provided by `Provider` in the remote server, possible. In other words, callling a - * function in the `Driver`, it means to call a matched function in the remote - * server's `Provider` object. - * - * - `Controller`: Definition only - * - `Driver`: [Remote Function Call](https://github.com/samchon/tgrid#13-remote-function-call) - * - * @template Controller An interface for provided features (functions & objects) from the remote system (`Provider`). - * @template UseParametric Whether to convert type of function parameters to be compatible with their pritimive. - * @return A `Driver` for the [RFC](https://github.com/samchon/tgrid#13-remote-function-call). - */ - public getDriver(): Driver { - return this.driver_; - } - /* ----------------------------------------------------------- - THREAD COMPONENTS - ----------------------------------------------------------- */ + THREAD COMPONENTS + ----------------------------------------------------------- */ /** * Get remote condition variable. * @@ -213,7 +172,7 @@ export class MutexConnector
{ */ public getConditionVariable(key: string): Promise { return RemoteConditionVariable.create( - this.driver_.condition_variables, + this.connector_.getDriver().condition_variables, key, ); } @@ -231,7 +190,7 @@ export class MutexConnector
{ * @return A {@link RemoteMutex} object. */ public getMutex(key: string): Promise { - return RemoteMutex.create(this.driver_.mutexes, key); + return RemoteMutex.create(this.connector_.getDriver().mutexes, key); } /** @@ -251,7 +210,11 @@ export class MutexConnector
{ * @return A {@link RemoteSemaphore} object. */ public getSemaphore(key: string, count: number): Promise { - return RemoteSemaphore.create(this.driver_.semaphores, key, count); + return RemoteSemaphore.create( + this.connector_.getDriver().semaphores, + key, + count, + ); } /** @@ -271,7 +234,11 @@ export class MutexConnector
{ * @return A {@link RemoteBarrier} object. */ public getBarrier(key: string, count: number): Promise { - return RemoteBarrier.create(this.driver_.barriers, key, count); + return RemoteBarrier.create( + this.connector_.getDriver().barriers, + key, + count, + ); } /** @@ -291,7 +258,11 @@ export class MutexConnector
{ * @return A {@link RemoteLatch} object. */ public getLatch(identifier: string, count: number): Promise { - return RemoteLatch.create(this.driver_.latches, identifier, count); + return RemoteLatch.create( + this.connector_.getDriver().latches, + identifier, + count, + ); } } diff --git a/src/MutexServer.ts b/src/MutexServer.ts index f71a4fb..7fd8a8e 100644 --- a/src/MutexServer.ts +++ b/src/MutexServer.ts @@ -16,26 +16,21 @@ import { GlobalGroup } from "./server/GlobalGroup"; * * The {@link MutexServer} is a class who can open an `mutex-server`. Clients connecting to the * `mutex-server` would communicate with this server through {@link MutexAcceptor} objects using - * websocket and [RFC](https://github.com/samchon/tgrid#13-remote-function-call) protocol. + * websocket and [RPC](https://tgrid.com/docs/remote-procedure-call/) protocol. * * To open the `mutex-server`, call the {@link open} method with your custom callback function * which would be called whenever a {@link MutexAcceptor} has been newly created by a client's * connection. * - * Also, when declaring this {@link MutexServer} type, you've to define two template arguments, - * *Header* and *Provider*. The *Header* type repersents an initial data gotten from the remote - * client after the connection. I hope you and client not to omit it and utilize it as an - * activation tool to enhance security. - * - * The second template argument *Provider* represents the additional features provided for the - * remote client. If you don't have any plan to provide additional feature to the remote client, - * just declare it as `null`. + * Also, when declaring this {@link MutexServer} type, you've to define one template argument, + * *Header*. The *Header* type repersents an initial data gotten from the remote client after + * the connection. I hope you and client not to omit it and utilize it as an activation tool + * to enhance security. * * @template Header Type of the *header* containing initial data. - * @template Provider Type of additional features provided for the remote client. * @author Jeongho Nam - https://github.com/samchon */ -export class MutexServer { +export class MutexServer
{ /** * @hidden */ @@ -112,8 +107,8 @@ export class MutexServer { * Therefore, clients who are using the {@link MutexConnector} class, they can't use the * remote critical section components more. * - * Also, closing the server means that all of the [RFC](https://github.com/samchon/tgrid#13-remote-function-call)s - * between the server and had connected clients would be destroied. Therefore, all of the [RFC](https://github.com/samchon/tgrid#13-remote-function-call)s + * Also, closing the server means that all of the [RPC](https://tgrid.com/docs/remote-procedure-call/)s + * between the server and had connected clients would be destroied. Therefore, all of the [RPC](https://tgrid.com/docs/remote-procedure-call/)s * that are not returned (completed) yet would ge {@link RuntimeError} exception. */ public close(): Promise { diff --git a/test/index.ts b/test/index.ts index d04e676..ccf1784 100644 --- a/test/index.ts +++ b/test/index.ts @@ -14,7 +14,7 @@ const HEADER = { password: "some_password" }; interface IModule { [key: string]: ( factory: ConnectionFactory, - server: MutexServer, + server: MutexServer, ) => Promise; } @@ -26,7 +26,7 @@ async function measure(job: () => Promise): Promise { async function iterate( factory: ConnectionFactory, - server: MutexServer, + server: MutexServer, path: string, ): Promise { const fileList: string[] = await fs.promises.readdir(path); @@ -71,7 +71,7 @@ async function main(): Promise { console.log("=========================================================="); // OPEN SERVER - let server: MutexServer = new MutexServer(); + const server: MutexServer = new MutexServer(); await server.open(PORT, async (acceptor) => { if (acceptor.header.password === HEADER.password) await acceptor.accept(); else await acceptor.reject(); @@ -104,9 +104,10 @@ async function main(): Promise { console.log(` - elapsed time: ${time} ms`); // MEMORY USAGE - let memory: NodeJS.MemoryUsage = process.memoryUsage(); - for (let property in memory) { - let amount: number = memory[property as keyof NodeJS.MemoryUsage] / 10 ** 6; + const memory: NodeJS.MemoryUsage = process.memoryUsage(); + for (const property in memory) { + const amount: number = + memory[property as keyof NodeJS.MemoryUsage] / 10 ** 6; console.log(` - ${property}: ${amount} MB`); } console.log("----------------------------------------------------------\n"); @@ -114,7 +115,7 @@ async function main(): Promise { //---- // TERMINATE //---- - for (let connector of connectorList) + for (const connector of connectorList) if (connector.state === MutexConnector.State.OPEN) await connector.close(); await server.close(); diff --git a/test/manual/remote-mutex.ts b/test/manual/remote-mutex.ts index ebe903f..438b0e6 100644 --- a/test/manual/remote-mutex.ts +++ b/test/manual/remote-mutex.ts @@ -31,7 +31,7 @@ async function client(index: number, character: string): Promise { async function main(): Promise { // OPEN SERVER - const server: MutexServer = new MutexServer(); + const server: MutexServer = new MutexServer(); await server.open(PORT, async (acceptor) => { if (acceptor.header === PASSWORD) await acceptor.accept(); else await acceptor.reject(); diff --git a/test/test_destructors.ts b/test/test_destructors.ts index 8f96ff6..d7cce19 100644 --- a/test/test_destructors.ts +++ b/test/test_destructors.ts @@ -16,9 +16,9 @@ async function test(factory: ConnectionFactory): Promise { export async function test_destructors( factory: ConnectionFactory, - server: MutexServer, + server: MutexServer, ): Promise { - let promises: Promise[] = []; + const promises: Promise[] = []; for (let i: number = 0; i < 4; ++i) promises.push(test(factory)); await Promise.all(promises);