Closed Chriscbr closed 11 months ago
I think it's a cool idea!
How about
register new cloud.Logger() as singleton in scope // scope can be global or some resource
// when we want to use the singleton somewhere:
let logger = singleton of cloud.Logger // option to also add from scope (which can only be this resource or one of its parents)
Hi,
This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!
Hi,
This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!
VPCs could be a good use case for this kind of feature.
Hi,
This issue hasn't seen activity in 60 days. Therefore, we are marking this issue as stale for now. It will be closed after 7 days. Feel free to re-open this issue when there's an update or relevant information to be added. Thanks!
This came up in @ainvoner's work when trying to ensure that a Terraform provider is only added once to the app.
Here's a solution for a "barrier" pattern we came up with:
class Foo {
init() {
let once = (key: str): bool => {
let root = std.Node.of(this).root;
if root.node.tryGetContext(key) == nil {
return false;
} else {
root.node.setContext(key, true);
return true;
}
};
if once("71299E76-8666-44AC-8B78-9FCA29B4EA70") {
new dnsimple.provider.DnsimpleProvider();
}
}
}
Explanation:
The once(key)
function returns true
only once for each key
. It adds a context key to the root construct to track this.
Perhaps we can add something like util.once(key)
that implements this. BUT... We'll have a problem accessing this
from within this static function, so maybe the API can be util.once(scope, key)
and then the usage would be:
if util.once(this, "foo") {
// singleton!
}
Original proposal by @Chriscbr:
let logger = instanceof(cloud.Logger);
let orders = instanceof(OrderDatabase);
In CDK there is a common pattern where you use Class.of(scope)
to automatically obtain a unique instance of some construct given a scope. For example, in AWS CDK you can use Stack.of(this).region
to get the AWS region you're in. there are also cases when you want a resource to be reused in many places, and requiring the resource to be passed as a prop to every other resource can be cumbersome.
With Wing we could offer this as a syntactic sugar.
We might also need a way to register an instance if one doesn't already exist (or perhaps this should happen implicitly?)
let logger = new cloud.Logger();
register(logger); // don't love this syntax
Tried to build a singleton bucket for the simulator, ran into issues. See here for details https://github.com/skorfmann/wing-sim-singleton
and here's a related slack thread https://winglang.slack.com/archives/C048QCN2XLJ/p1699878030297609?thread_ts=1699877019.443519&cid=C048QCN2XLJ
Ideas?
Congrats! :rocket: This was released in Wing 0.48.12.
Summary
Support for singleton resource patterns built into the Wing language
Feature Spec
See alternative proposal here.
Use Cases
One-of resources used throughout your entire application, like a database, or a logger, etc.
Implementation Notes
Based on how
Stack.of
orApp.of
is implemented in the AWS CDK (https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/core/lib/stack.ts) or howLogger.of
is implemented in the Wing SDK.Component
Language Design