Skip to content

Commit

Permalink
#296: first draft of client creation
Browse files Browse the repository at this point in the history
  • Loading branch information
petermasking committed Aug 23, 2024
1 parent e7d65d7 commit d299ff5
Show file tree
Hide file tree
Showing 10 changed files with 155 additions and 55 deletions.
16 changes: 1 addition & 15 deletions packages/jitar/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,8 @@ export
Teapot,
Unauthorized,
FileNotFound,
// ImplementationNotFound,
// InvalidParameterValue,
// InvalidSegmentFile,
// InvalidVersionNumber,
// MissingParameterValue,
// ModuleNotAccessible,
ModuleNotLoaded,
// NoWorkerAvailable,
// ProcedureNotAccessible,
// ProcedureNotFound,
// RepositoryNotAvailable,
// RuntimeNotAvailable,
// SegmentNotFound,
// UnknownParameter,
// startClient,
getClient
startClient
} from '@jitar/runtime';

export
Expand Down
18 changes: 17 additions & 1 deletion packages/runtime/src/RuntimeBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { Serializer, SerializerBuilder } from '@jitar/serialization';

import { ExecutionManager } from './execution';
import { RemoteRepository, LocalRepository, RemoteGateway, LocalGateway, RemoteWorker, LocalWorker, Proxy, Remote, RunnerService } from './services';
import { RemoteRepository, LocalRepository, RemoteGateway, LocalGateway, RemoteWorker, LocalWorker, Proxy, Remote, Client } from './services';
import { HealthManager } from './health';
import { MiddlewareManager } from './middleware';
import { SourceManager, ClassModuleLoader } from './source';
Expand Down Expand Up @@ -43,6 +43,13 @@ type ProxyConfiguration = ServiceConfiguration &

type StandaloneConfiguration = LocalWorkerConfiguration & LocalRepositoryConfiguration;

type ClientConfiguration =
{
remoteUrl: string;
segmentNames: string[];
middlewares: string[];
};

export default class RuntimeBuilder
{
#sourceManager: SourceManager;
Expand Down Expand Up @@ -130,6 +137,15 @@ export default class RuntimeBuilder
return new Proxy({ url, repository, runner });
}

async buildClient(configuration: ClientConfiguration): Promise<Client>
{
const gateway = this.buildRemoteGateway(configuration.remoteUrl);
const middlewareManager = await this.#buildMiddlewareManager(configuration.middlewares);
const executionManager = await this.#buildExecutionManager(configuration.segmentNames);

return new Client({ gateway, middlewareManager, executionManager });
}

#buildRemote(url: string): Remote
{
const serializer = this.#buildSerializer();
Expand Down
38 changes: 8 additions & 30 deletions packages/runtime/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,14 @@

import { LocalWorker, RemoteGateway } from './services';
import { SourceManager, ImportFunction, RemoteFileManager } from './source';
import type { Client } from './services';

let client: LocalWorker | undefined = undefined;
const resolvers: ((client: LocalWorker) => void)[] = [];
import RuntimeBuilder from './RuntimeBuilder';

// export async function startClient(remoteUrl: string, segmentNames: string[] = [], middlewares: string[] = []): Promise<LocalWorker>
// {
// const gateway = new RemoteGateway(remoteUrl);

// const worker = new LocalWorker(gateway);
// worker.segmentNames = new Set(segmentNames);
// worker.middlewareFiles = new Set(middlewares);

// await worker.start();

// client = worker;

// resolvers.forEach((resolve) => resolve(worker));
// resolvers.length = 0;

// return worker;
// }

export async function getClient(): Promise<LocalWorker>
export async function startClient(remoteUrl: string, importFunction: ImportFunction, segmentNames: string[] = [], middlewares: string[] = []): Promise<Client>
{
if (client === undefined)
{
return new Promise((resolve) =>
{
resolvers.push(resolve);
});
}
const fileManager = new RemoteFileManager(remoteUrl);
const sourceManager = new SourceManager(importFunction, fileManager);
const runtimeBuilder = new RuntimeBuilder(sourceManager);

return client;
return runtimeBuilder.buildClient({ remoteUrl, segmentNames, middlewares });
}
8 changes: 4 additions & 4 deletions packages/runtime/src/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@

import { ServerError } from './errors';
import { Runner } from './execution';

import Request from './execution/models/Request.js';
import ProcedureRuntime from './services/RunnerService.js';
import VersionParser from './execution/utils/VersionParser.js';

let _runtime: ProcedureRuntime;
let _runtime: Runner;

export class RuntimeNotAvailable extends ServerError
{
Expand All @@ -15,12 +15,12 @@ export class RuntimeNotAvailable extends ServerError
}
}

export function setRuntime(runtime: ProcedureRuntime): void
export function setRuntime(runtime: Runner): void
{
_runtime = runtime;
}

export function getRuntime(): ProcedureRuntime
export function getRuntime(): Runner
{
if (_runtime === undefined)
{
Expand Down
7 changes: 4 additions & 3 deletions packages/runtime/src/lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ export { MiddlewareManager, Middleware, NextHandler } from './middleware';
export { Gateway, LocalGateway, RemoteGateway, Proxy, Repository, LocalRepository, RemoteRepository, Worker, LocalWorker, RemoteWorker, Service, RunnerService } from './services';
export { File, Files, FileManager, FileNotFound, ImportFunction, ClassModuleLoader, SourceManager, ModuleNotLoaded } from './source';

export { default as RuntimeBuilder } from './RuntimeBuilder.js';
export { default as RuntimeBuilder } from './RuntimeBuilder';

export * from './client.js';
import './globals.js';
export { startClient } from './client';

import './globals';
57 changes: 57 additions & 0 deletions packages/runtime/src/services/Client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@

import { Request, Response, ExecutionManager, Runner } from '../execution';
import { MiddlewareManager, ProcedureRunner } from '../middleware';

import { setRuntime } from '../hooks.js';

import RemoteGateway from './gateway/RemoteGateway';

type Configuration =
{
gateway: RemoteGateway;
middlewareManager: MiddlewareManager; // object with all middleware loaded
executionManager: ExecutionManager; // object with all segments loaded
};

export default class Client implements Runner
{
#gateway: RemoteGateway;

#middlewareManager: MiddlewareManager;
#executionManager: ExecutionManager;

constructor(configuration: Configuration)
{
this.#gateway = configuration.gateway;

this.#middlewareManager = configuration.middlewareManager;
this.#executionManager = configuration.executionManager;

// TODO: Should be done when constructing the middleware manager
this.#middlewareManager.addMiddleware(new ProcedureRunner(this.#executionManager));

setRuntime(this);
}

run(request: Request): Promise<Response>
{
return this.#mustRunLocal(request)
? this.#runLocal(request)
: this.#runRemote(request);
}

#mustRunLocal(request: Request): boolean
{
return this.#executionManager.hasProcedure(request.fqn);
}

#runLocal(request: Request): Promise<Response>
{
return this.#middlewareManager.handle(request);
}

#runRemote(request: Request): Promise<Response>
{
return this.#gateway.run(request);
}
}
1 change: 1 addition & 0 deletions packages/runtime/src/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export { default as Worker } from './worker/Worker';
export { default as LocalWorker } from './worker/LocalWorker';
export { default as RemoteWorker } from './worker/RemoteWorker';

export { default as Client } from './Client';
export { default as Remote } from './Remote';

export { default as Service } from './Service';
Expand Down
4 changes: 2 additions & 2 deletions packages/runtime/src/source/SourceManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ export default class SourceManager
#import: ImportFunction;
#fileManager: FileManager;

constructor(moduleImporter: ImportFunction, fileManager: FileManager)
constructor(importFunction: ImportFunction, fileManager: FileManager)
{
this.#import = moduleImporter;
this.#import = importFunction;
this.#fileManager = fileManager;
}

Expand Down
1 change: 1 addition & 0 deletions packages/runtime/src/source/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export { default as Module } from './types/Module';
export { default as File } from './models/File';

export { default as ClassModuleLoader } from './utils/ClassModuleLoader';
export { default as RemoteFileManager } from './utils/RemoteFileManager';

export { default as SourceManager } from './SourceManager';
60 changes: 60 additions & 0 deletions packages/runtime/src/source/utils/RemoteFileManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@

import { NotImplemented } from '../../errors';

import FileManager from '../interfaces/FileManager';
import File from '../models/File';

export default class RemoteFileManager implements FileManager
{
#rootUrl: string;

constructor(rootUrl: string)
{
this.#rootUrl = rootUrl;
}

getRootLocation(): string
{
return this.#rootUrl;
}

getAbsoluteLocation(filename: string): string
{
return `${this.#rootUrl}/${filename}`;
}

getRelativeLocation(filename: string): string
{
throw new NotImplemented();
}

getType(filename: string): Promise<string>
{
throw new NotImplemented();
}

getContent(filename: string): Promise<Buffer | string>
{
throw new NotImplemented();
}

read(filename: string): Promise<File>
{
throw new NotImplemented();
}

write(filename: string, content: string): Promise<void>
{
throw new NotImplemented();
}

delete(filename: string): Promise<void>
{
throw new NotImplemented();
}

filter(pattern: string): Promise<string[]>
{
throw new NotImplemented();
}
}

0 comments on commit d299ff5

Please sign in to comment.