permaweb / aos

An operating system for AO: The hyper parallel computer
https://ao.g8way.io
Other
68 stars 46 forks source link

feat(token-blueprint): make response messages easier to identify #290

Open dvinubius opened 2 months ago

dvinubius commented 2 months ago

Problem

Response - Type messages have no straightforward way to be matched as such.

e.g.

It difficult to elegantly implement handlers for all of these responses in the same process, due to the asymmetry (peculiarity) of how the checks need to be performed.

In case of Balances it's most extreme, meaning that I can only match a Balances response by the fact that it has none of the other tags.

Solution

Any response-type message be tagged as follows:

ao.send({
  Target = msg.From,
  ["Response-For"] = <Name-Of-The-Action>,
  -- ...
})

This way, responses are matched by msg.From as follows

Handlers.utils.hasMatchingTag("Response-For", "Info")

Handlers.utils.hasMatchingTag("Response-For", "Balance")

Handlers.utils.hasMatchingTag("Response-For", "Balances")

No breaking change

This change is attractive especially since it doesn't break any existing implementations of processes which interact with the token process.

Potentially a good standard

I think this is intuitive to use and could serve as a general pattern for all AO processes. Including it in something as essential as the token blueprint can help in establishing the standard.

hitwill commented 2 months ago

Great point. Maybe this should be lower-level, so that any message on AO carries a: msg. From (already implemented - shows the process that originated the message) msg.Subject (the name of the handler that sent the message)

Or maybe better, if a handler receives something like x-echo = some-string any message it sends out should include the echo message

twilson63 commented 1 month ago

The best way forward is to use Reference and X-Reference

When a message is Sent a Reference number is provide, the returning message can send it back using X-Reference

dvinubius commented 1 month ago

@twilson63 This doesn't solve the problem of simplifying the code that identifies what a specific message is about.

It's a way to do it, for sure, but the code becomes harder to work with, I think.

That's because there are no semantics in the number value from Reference. My understanding is, we generally want to handle messages based on semantic tags, not on numbers for which a process tracks the semantics itself.

I mean, in a Reference based approach a process would have to explicitly manage a mapping between expected reference numbers of incoming messages and their associated handling paths. This is an overhead that is better avoided, IMO. It would also require a "switch"-type message handler for "various" incoming messages.

Keep in mind, one of the messages I mentioned in the problem statement is 'Balances' where the response has no semantic tag at all to identify it. Then, this rather ugly "switch"-type handler becomes a necessity.

-- map msg reference numbers to response types ('Balance', 'Balances', 'Info')
References = References or {}

Handlers.add(
  "response",
  function() return true, -- match all messages
  function(msg)
    local responseType = References[msg["X-Reference"]]
    if responseType == 'Balance' then
    -- ...
    elseif responseType == 'Balances' then
    -- ...
    elseif responseType == 'Info' then
    -- ...
    else
    -- error
    end
  end
)

Maybe there is a better way to do this based on Reference, that you had in mind?

dvinubius commented 1 month ago

@twilson63 I think you suggest using the X-Reference like this?

Screenshot 2024-07-25 at 16 16 25

That's much better in terms of how the code is written, indeed.

Sorry for the confusion, I'm looking into applying this now.