(Advanced) Conditional Subgraph Execution
There will be times when you actually only want to execute some portion of the graph upon satisfying some condition.
In this case, you may inject the node to a procedure expecting a provider<future<...>>
so that you may conditionally
trigger execution yourself after checking the condition:
graph function getHomepage(userId : UserId) -> future<Homepage> {
root homepage <- renderPage(@basePage, @maybeUpgradeBanner);
node basePage <- getBasePageFromDB();
node maybeUpgradeBanner
<- getOptionalUpgradeBannerFromDB(
@userIsPremium,
@upgradeBanner # <-- "Lazy Subgraph" injection requested.
);
node userIsPremium <- checkPremiumFromDB(userId);
node upgradeBanner <- getUpgradeBannerFromDB();
}
...
function getOptionalUpgradeBannerFromDB(
alreadyPremium: boolean,
getUpgradeBannerPromDBProvider: provider<future<Upgrade>>
) -> Optional<future<Upgrade>> {
if (already premium) {
return Nothing;
}
return getUpgradeBannerFromDBProvider();
}
Read closely above. The function shown requests an arg of type provider<future<Upgrade>>
which is injected as a
lazy subgraph rooted at node upgradeBanner
. In this way, the subgraph of the getHomepage(...)
graph is only run
sometimes, upon satisfying the condition that the user is not already a "premium" member.
Note on Usage of Optional
in Above Example:
If you read the above example very closely, you may have noticed that the return type of the
getOptionalUpgradeBannerFromDB(...)
is Optional<future<Upgrade>>
but yet the two return statements in the
function are return Nothing;
and return getUpgradeBannerFromDBProvider();
, neither of which reference Optional
.
This is making use of a type system feature upcoming very soon in the language but not yet available, the oneof<...>
type. I've done this to make a less distracting example, but for now, until oneof<...>
is available, you would
actually need to do a workaround to define your own quasi Optional
perhaps looking something like:
# Impl of `Optional` before `oneof<...>` type system support.
alias Optional : tuple<boolean, future<Upgrade>, NothingType>
As a preview, for anyone very interested in what the definition of this more convenient Optional
in the example above
would look like making use of the in-development oneof<...>
type:
# Impl of `Optional` using `oneof<...>`.
alias Optional<T> : oneof<T, !! NothingType>
Stay tuned for updates on oneof<...>
support.