winglang / wing

A programming language for the cloud ☁️ A unified programming model, combining infrastructure and runtime code into one language ⚡
https://winglang.io
Other
5.02k stars 197 forks source link

Builtin support for singleton resources #513

Closed Chriscbr closed 11 months ago

Chriscbr commented 1 year ago

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 or App.of is implemented in the AWS CDK (https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/core/lib/stack.ts) or how Logger.of is implemented in the Wing SDK.

Component

Language Design

ShaiBer commented 1 year 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)
github-actions[bot] commented 1 year ago

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!

github-actions[bot] commented 1 year ago

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!

Chriscbr commented 1 year ago

VPCs could be a good use case for this kind of feature.

github-actions[bot] commented 1 year ago

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!

eladb commented 1 year ago

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!
}
eladb commented 1 year ago

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
skorfmann commented 11 months ago

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?

monadabot commented 11 months ago

Congrats! :rocket: This was released in Wing 0.48.12.