-
Notifications
You must be signed in to change notification settings - Fork 8
Description
During the Proof of Concept (PoC) phase, specific Client implementation classes were created through the resource type's buildClient method, while specific Infra implementation classes were registered in the Registry and then retrieved by querying the Registry based on platform and engine type. Both of these methods introduced additional cognitive load for SDK developers, requiring an understanding of the specific creation methods and adding extra logic to Pluto's implementation. Simplification in this area could be explored.
// Resource Client
export class Queue implements Resource {
constructor(name: string, opts?: QueueOptions) {
name;
opts;
throw new Error(
"Cannot instantiate this class, instead of its subclass depending on the target runtime."
);
}
public static buildClient(name: string, opts?: QueueClientOptions): QueueClient {
const rtType = process.env["RUNTIME_TYPE"];
switch (rtType) {
case runtime.Type.AWS:
return new aws.SNSQueue(name, opts);
case runtime.Type.K8s:
return new k8s.RedisQueue(name, opts);
case runtime.Type.Simulator:
if (!process.env.PLUTO_SIMULATOR_URL) throw new Error("PLUTO_SIMULATOR_URL doesn't exist");
return simulator.makeSimulatorClient(process.env.PLUTO_SIMULATOR_URL!, name);
default:
throw new Error(`not support this runtime '${rtType}'`);
}
}
}
// Resource Infra
export function register(reg: Registry) {
reg.register(runtime.Type.AWS, engine.Type.pulumi, Router, aws.ApiGatewayRouter);
reg.register(runtime.Type.AWS, engine.Type.pulumi, KVStore, aws.DynamoKVStore);
reg.register(runtime.Type.AWS, engine.Type.pulumi, Queue, aws.SNSQueue);
reg.register(runtime.Type.AWS, engine.Type.pulumi, Schedule, aws.CloudWatchSchedule);
reg.register(runtime.Type.AWS, engine.Type.pulumi, "FnResource", aws.Lambda);
reg.register(runtime.Type.AWS, engine.Type.pulumi, Tester, aws.Tester);
}We can place the logic for selecting the specific implementation class within the constructor, allowing SDK developers to manage this process. By eliminating Registry and buildClient, Pluto would no longer have to add extra logic for handling type conversion and could instead focus solely on maintaining user code.
We'd like to instantiate the implementation classes asynchronously, which can help cut down on package loading costs. This process will be encapsulated within an asynchronous function, often referred to as a 'lazy importing' function. However, in JavaScript, it's not feasible to call an async function within a constructor.
So we've come up with a solution where each resource has an abstract base class at the root of the infra SDK and includes a static async method named createInstance. This method serves to create instances of resource infrastructure implementation classes based on the target platform and engine.
Not only does this strategy streamline operations, but it also allows SDK developers to concentrate more effectively on their tasks.
The stipulation is that the parameters for both the client implementation class and infrastructure implementation class of a resource, along with those of the createInstance method from its base class, must all be consistent.
abstract class Queue {
public static async createInstance(name, opts) {
if (currentPlatform == "AWS") {
return new SNSQueue(name, opts);
} else if (...) {
// ...
}
}
}
class SNSQueue {
public subscribe(handler: any) {
// do something...
}
}