winglang / wing

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

Brainsplit of inflight member fields between different functions #6738

Open asterkin opened 2 months ago

asterkin commented 2 months ago

I tried this:

pub struct Ticket { ticketCode: str; carPlate: str; rateName: str; }

pub class MockDataStore { inflight _tickets: MutMap;

inflight new(){
    this._tickets = MutMap<Ticket>{};
}

pub inflight storeTicket(ticket: Ticket): void {
    this._tickets.set(ticket.ticketCode, ticket);
}

pub inflight findTickets(carPlate: str, rateName: str): Set<Ticket> {
    let var result = MutSet<Ticket>[];
    log("{carPlate} {rateName} {this._tickets.size()}");
    for ticket in this._tickets.values() {
        log(Json.stringify(ticket));
        if ticket.carPlate == carPlate && ticket.rateName == rateName {
            result.add(ticket);
        }
    }
    return result.copy();
}

}

This happened:

bring cloud; bring expect; bring "./MockDataStore.w" as dataStore;

let _dataStore = new dataStore.MockDataStore(); let _carPlate = "6989GPJ"; let _rateName = "Green"; let _ticketCode = "0001";

let _buyTicket = new cloud.Function(inflight () => { let ticket = dataStore.Ticket { ticketCode: _ticketCode, carPlate: _carPlate, rateName: _rateName }; _dataStore.storeTicket(ticket); }) as "BuyTicket";

let _checkCar = new cloud.Function((inflight () => { let actual = _dataStore.findTickets(_carPlate, _rateName); let expected = Set[ dataStore.Ticket { ticketCode: _ticketCode, carPlate: _carPlate, rateName: _rateName } ]; log(Json.stringify(actual.toArray())); log(Json.stringify(expected.toArray())); expect.equal(actual, expected); })) as "CheckCar";

test "it will fail even in local" { _buyTicket.invoke(); _checkCar.invoke(); }

I expected this:

As a naive user, I might expect that it will work, at least locally. Using RAM-only mock implementations of DataStore objects is common in mainstream programming.

Is there a workaround?

Using Table instead, but that inflates the "stuff vs value" ratio.

Anything else?

The feature is not documented in https://www.winglang.io/docs/concepts/inflights#inflight-code. It works and is useful for keeping intermediate test results and understanding why and where it works and where it does not, requires a good understanding of how the Cloud Function memory is organized. For example, it would work for a Lambdalith local always, and remote sometimes depending on load (e.g. if because of load there are two instances of the same Cloud Function, it will not work). The same is true for a Container-based implementation.

It's a tough case of potentially leaky abstraction. I would probably remove it altogether. For keeping intermediate test results, resolving the https://github.com/winglang/wing/issues/6673 would be enough.

Wing Version

0.74.68

Node.js Version

22.1.0

Platform(s)

No response

Community Notes

asterkin commented 2 months ago

Apparently, the inflight member fields are documented in https://www.winglang.io/docs/language-reference#33-preflight-classes. I would recommend at least providing a clear reference from https://www.winglang.io/docs/concepts/inflights#inflight-code and a warning about potential brain split problems.