Repository navigation
Await as query for a Receipt #30
andrewzhurov
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I wanted to share an insight (perhaps not that surprising for some 😄) on how Await resembles a query for a Receipt's value.
E.g.,
behaves as a query for a Receipt where instruction is
bafy...getMailingListand result isok, selecting/pulling data that's underok.I wonder what values we could get by expanding on this idea, embracing Await as a way to query.
First of all, what if we'd have a more expressive DSL for "where" / pattern-matching?
Say we have sendEmail instruction that awaits on getMailingList instruction
{ "bafy...getMailingList": { "uri": "https://exmaple.com/mailinglist", "op": "crud/read" }, "bafy...getMailingList Task": { "run": {"/": "getMailingList"}, "meta": {"retries": 2} }, "bafy...getMailingList Task Invocation": { "task": {"/": "getMailingList Task"} }, "bafy...getMailingList Task Invocation Receipt": { "ran": {"/": "bafy...getMailingList Task Invocation"}, "out": {"ok": ["alice@mail.com", "bob@mail.com"]}, "iss": "Executor's DID" }, "bafy...sendEmail": { "uri": "mailto://alice@example.com", "op": "msg/send", "input": { "to": {"await/ok": {"/": "bafy...getMailingList"}}, "subject": "hello", "body": "world" } } }An alternative way to express the above await is to treat it as pattern-matching on Receipt,
we could express it as:
{"bafy...sendEmail": { "uri": "mailto://alice@example.com", "op": "msg/send", "input": { "to": {"await/ok": {"ran": {"task": {"run": {"/": "bafy...getMailingList"}}}, "out": {"ok": null}}}, "subject": "hello", "body": "world" } } }Interestingly, it allows us to pattern-match on any Receipt values that's been previously outside of our reach,
e.g., on
metafield of Task{"await/ok": {"ran": {"task": {"run": {"/": "bafy...getMailingList"}, "meta": {"retries": 2}}}, "out": {"ok": null}}}Which is equivalent to
{"await/ok": {"ran": {"task": {"/": "bafy...getMailingList Task"}}, "out": {"ok": null}}}or on
issof the Receipt{"await/ok": {"ran": {"/": "bafy...getMailingList Task"}, "out": {"ok": null}, "iss": "Executor's DID"}}and oh well, nothing stops us from specify it down to the exact Receipt!
{"await/ok": {"/": "bafy...getMailingList Task Invocation Receipt"}}And now to the "select" bit of query,
atm we have
await/okexpressing two things 1) await / query 2) select "ok"We could decouple the two!
{"await": {"select": ["out", "ok"], "where": {"/": "bafy...getMailingList Task Invocation Receipt"}}}And now we're able to pull arbitrary data out of those Receipts, say it's
iss{"await": {"select": ["iss"], "where": {"/": "bafy...getMailingList Task Invocation Receipt"}}}All this lands us a foot short from treating Receipts as graph data and implementing yet another graph querying engine over it.
What are the values out of a more expressive "where" and "select" is yet to be defined. 😄
And it comes with its costs, as now implementation of Promise Pipelines is more heavy.
Where previously implementations would simply filter Receipts by Instruction and "ok"/"error" fields, now they need to pattern-match Receipts with
where.Where previously they would simply select "ok"/"error"/"*", now they need to
getIn(Receipt, select)(ok this one is not that heavy :laugh:)Side-thought.
Interestingly, an Executor could attenuate Task down to its exact awaited Receipts before executing it.
Perhaps this may be an elegant way to "how capture exact Receipt awaited" that #22 rumbles about.
All reactions