From 35917ea65e3ada833f8dff42515021b7e2f991c5 Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 19 Sep 2023 18:38:26 +0200 Subject: [PATCH] negotiate: support un/match notifications Depending on the flag at the head of the sample given to the library, it may poke the underlying agent with a %negotiate-notification whenever we match or unmatch with a specific gill. --- desk/lib/negotiate.hoon | 75 +++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/desk/lib/negotiate.hoon b/desk/lib/negotiate.hoon index 587e406915..6c75f95fab 100644 --- a/desk/lib/negotiate.hoon +++ b/desk/lib/negotiate.hoon @@ -9,6 +9,8 @@ :: usage :: :: to use this library, you must supply it with three things: +:: - a flag specifying whether the inner agent should be notified of version +:: negotiation events (matching & unmatching of external agents) :: - a map of, per protocol your agent exposes, a version noun :: - a map of, per agent name, a map of, per protocol, the version we expect :: call this library's +agent arm with those three arguments, and then call @@ -38,6 +40,14 @@ :: where we now do have matching versions. in upgrade scenarios, changing :: the library arguments should generally suffice. :: +:: if the flag at the start of the sample is set to true then, whenever we +:: start to match or stop matching with a specific gill, we send a poke to +:: the inner agent, marked %negotiate-notification, containing both a flag +:: indicating whether we now match, and the gill for which the notification +:: applies. +:: (the initial state, of not having negotiated at all, counts as "not +:: matching".) +:: :: if an agent was previously using epic, it can trivially upgrade into :: this library by making the following changes: :: - change its own epic version number @@ -68,10 +78,8 @@ |= [=bowl:gall =gill:gall] ?=(%match (read-status bowl gill)) :: -::TODO want to +notify-me to subscribe to self about heed changes -:: ++ agent - |= [our-versions=(map protocol version) =our=config] + |= [notify=? our-versions=(map protocol version) =our=config] ^- $-(agent:gall agent:gall) |^ agent :: @@ -102,19 +110,22 @@ :: negotiation where needed. :: ++ inflate + |= knew=(unit config) ^- (quip card _state) =* boat=boat:gall wex.bowl :: establish subs from .want where versions match :: - =/ open=(list card) - %- zing - %+ turn ~(tap by want) - |= [=gill:gall m=(map wire path)] - ?. (match gill) ~ - %+ murn ~(tap by m) - |= [=wire =path] - ?. (~(has by boat) [wire gill]) ~ :: already established - (some %pass wire %agent gill %watch path) + =/ [open=(list card) news=(set gill:gall)] + %+ roll ~(tap by want) + |= $: [=gill:gall m=(map wire path)] + [open=(list card) news=(set gill:gall)] + == + ?. (match gill) [open news] + %+ roll ~(tap by m) + |= [[=wire =path] =_open =_news] + ?: (~(has by boat) [wire gill]) [open news] :: already established + :_ (~(put by news) gill) + [[%pass wire %agent gill %watch path] open] :: manage subs for new or non-matching gills :: =^ [init=(set [gill:gall protocol]) kill=(set [=wire =gill:gall])] want @@ -149,6 +160,17 @@ (~(put in kill) [wire gill]) $(need t.need) :: + =/ notes=(list card) + ?. notify ~ + ?~ knew ~ + %+ murn ~(tap in `(set gill:gall)`(~(run in ~(key by heed)) head)) + |= =gill:gall + ^- (unit card) + =/ did=? (match(know u.knew) gill) + =/ now=? (match gill) + ?: =(did now) ~ + `(notify-inner now gill) + :: =^ inis state =| caz=(list card) =/ inz=(list [gill:gall protocol]) ~(tap in init) @@ -157,6 +179,7 @@ =^ car state (negotiate i.inz) $(caz (weld car caz), inz t.inz) :_ state + %+ weld notes %+ weld open %+ weld inis %+ turn ~(tap in kill) @@ -269,14 +292,29 @@ `[%give %fact [/~/negotiate/version/[protocol]]~ %noun !>(version)] :: ++ heed-changed - |= [for=[gill:gall protocol] new=version] + |= [for=[=gill:gall protocol] new=version] ^- (quip card _state) =/ hav=(unit version) ~| %unrequested-heed (~(got by heed) for) ?: =(`new hav) [~ state] - =. heed (~(put by heed) for `new) - inflate + =/ did=? &(notify (match gill.for)) + =. heed (~(put by heed) for `new) + :: we may need to notify the inner agent + :: + =/ nos=(list card) + ?. notify ~ + =/ now=? (match gill.for) + ?: =(did now) ~ + [(notify-inner now gill.for)]~ + =^ caz state (inflate ~) + [(weld caz nos) state] + :: + ++ notify-inner + |= event=[match=? =gill:gall] + ^- card + :+ %pass /~/negotiate/notify + [%agent [our dap]:bowl %poke %negotiate-notification !>(event)] :: ++ watch-version |= [=gill:gall =protocol] @@ -353,7 +391,7 @@ ?. ?=([[%negotiate *] *] q.ole) =. ours our-versions =. know our-config - =^ caz state inflate:up + =^ caz state (inflate:up ~) =^ cards inner (on-load:og ole) =^ cards state (play-cards:up cards) [(weld caz cards) this] @@ -365,8 +403,9 @@ ?: =(ours our-versions) ~ (ours-changed:up ours our-versions) =. ours our-versions + =/ knew know =. know our-config - =^ caz2 state inflate:up + =^ caz2 state (inflate:up `knew) =^ cards inner (on-load:og ile) =^ cards state (play-cards:up cards) [:(weld caz1 caz2 cards) this] @@ -395,6 +434,8 @@ :: ~| wire=t.t.wire ?+ t.t.wire ~|([%negotiate %unexpected-wire] !!) + [%notify ~] [~ this] + :: [%heed @ @ @ ~] =/ for=[gill:gall protocol] =* w t.t.t.wire