Previously, when the refresh-rate timer activated, and the thread from
the previous activation was still running, we would kill it and start
a new one. For low refresh rates, on slower machines, nodes, or network
connections, this could cause the update to never conclude.
Here we add a timeout-time to eth-watcher's config. If the refresh-rate
timer activates, and a thread exists, but hasn't been running for at
least the specified timeout-time yet, we simply take no action, and wait
for the next refresh timer.
Note that we opted for "at least timeout-time", instead of killing &
restarting directly after the specified timeout-time has passed, to
avoid having to handle an extra timer flow.
In the +on-load logic, we configure the timeout-time for existing
watchdogs as six times the refresh-rate. We want to set
azimuth-tracker's timeout-time to ~m30, and don't care much about other,
less-likely-to-be-active use cases of eth-watcher.
During the #2607 upgrade, strictly local collections got left out of the
listening set. (Because they did not have any outgoing subscriptions.)
This led to personal collections not being available on the frontend.
Here, we add upgrade logic for adding those back to our listening set again.
If a user had explicitly left a personal collection (instead of deleted it, for
whatever reason), they will have to leave it again. This case seems much more
rare than the "my collection is gone" one.
(Re)subscribing gets us a %contacts update, containing the full set of
contacts as it currently exists.
Previously, we would fully delete our local state, only to recreate it
using the data from the update.
Now, we never delete existing data, instead only creating if we don't
have it yet, and adding, removing or recreating contacts if they
changed.
In the future, we'll want an easy way to turn two contacts into an %edit
diff, to let us apply correct semantics to individual contacts, too.
Instead, %bundle and %add if we don't have the group locally yet,
or %add and %remove whatever the difference is between the local group
and the group as specified in the %path update.
In both, we make clear that the wire is always of the /@/group/^ form,
and alias the "group path" portion of the wire for clarity.
For kick, more obviously reuse the same wire, don't reconstruct it.
For watch-nack, only delete from the synced map if the source of the
watch-nack is still relevant. While we don't expect this to be relevant
considering current mode of operation, this does protect us against
strange cases.
Instead of going purely off metadata, we now track the collections we're
listening to, and allow the user to remove collections from that list.
This allows us to remove/ignore collections, without mutilating group
assocations locally.
We were taking care not to re-add something to our data store if we
already had it in there, but were still sending out an update
regardless.
With this, we only send out an update if we weren't previously aware
of the content.
If chats with identical resource paths were created, that would result
in chat-hook seeing updates twice.
These "/mailbox wire sub to local chat-store" subscriptions aren't
created by the current logic anymore, and as such any existing ones
should be eradicated.
* origin/m/chat-groupify-extra:
chat-view: %delete even without association
frontend: apply ec6c2ed69 to link, publish, groups
chat fe: clarify copy
chat fe: support adding chat to existing group
chat fe: invite search with/out ships
chat-view: allow %groupify into existing group
chat-view: add docs for %create action
Signed-off-by: Jared Tobin <jared@tlon.io>
Previously, running %delete had a hard dependency on a (metadata-store)
association being present for the chat. If a remotely-hosted chat got
deleted, that would delete the association, preventing us from deleting
the chat for ourselves.
Now, we simply neglect to do related metadata deletions if no
association was present in the first place.
In many cases running without %force is insufficient because ford
crashes while unsubscribing. This should fix some cases of OTAs being
received but not processed.
Downgrades unmanaged chat paths to their uglified versions, as used by
web chat. Removes "group-based" indicators and makes them implicit in
shorter paths instead.
Under mysterious conditions, chat-cli might get into a state where its
rendering width is set to zero. This makes sure we set it back to 80
if that's the case.
This commit is mostly just precaution.
It was filling the number.envelope prior to adding the envelope to the
mailbox, but wasn't actually including that change in the %message(s)
update that was getting sent out.
This makes +append-envelope return both the updated mailbox _and_ the
modified envelope, which we then use in our outgoing update.
During upgrade, we gassed _in_ a map, instead of _by_, causing it to use
set-style sorting, leading to incorrect lookups.
This fixes that upgrade logic, and re-builds the map for existing instances.
Was using "manual" scries, and incorrect ones at that. Would crash, causing
subscriptions to not go through. Now uses the helper function and correct paths.
Re-enables chat creation, touches up invite logic, and makes everything
work with the new "un/managed" attribute of chats.
Changes the +target type, so requires state transition. We use that
opportunity to clean up our messages mirror (memory reclamation).
"Unmanaged" chats should work the same as they did before.
Group-based chats are secondary citizens, but supported by prepending
"group " to whatever target you want to use. ie:
;join group ~marzod/secret-club :: join a group-based chat
;group ~marzod/secret-club :: target a group-based chat
The latter case should be rarely needed, as glyphs remember this
attribute of their bound target.
Creating a group alongside a chat is supported through:
;create village-with-group /cool-kids
You can then invite to that group (and by extension the associated chat)
by doing:
;invite group /cool-kids ~rinsed-walrus
chat: ota attempt
chat: ota triggers chat-store to tell chat-hook to send cards to update chat-store's state
contact-view: commented out avatars and base64
chat: cleaned up commits
- finds resources & displays details using metadata-store
- supports creating new collections for groups
- supports creating new collections with new unmanaged group
- supports receiving invites for new (unmanaged) collections
In order to track & respond to all group-related metadata, hooks may
want to subscribe to the metadata-store in response to group creation.
In that case it is possible that there are no entries for the group-path
in group-indices yet.
This makes us fall back to the empty set in case group-indices has no
entry for the group-path yet.
The previous Tile.png for the Dojo module (Soto) was a stylized rendering of "barcen" and could be seen as confusing. Fixing up the image to appear more *actually* glyph-like.
In order to track & respond to all app-related metadata, hooks may want to
subscribe to the metadata-store as the first thing they do on-init. In that case
it is exceedingly likely that there are no entries for the app-name in
app-indices yet.
This makes us fall back to the empty set in case app-indices has no entry for
the app-name yet.
Basically, this PR includes a collection of edits made to the headers across each of our OS1 modules.
I flattened the font sizing, fixed edge margins/padding, and fixed some button copy in the case of the Contacts app.
If we don't host a group, we can't (locally) delete it, but we do still
have a permission-hook entry we want to clean up. This does that
deletion, but still relies on the permission-hook logic to clean it up
in the local group case.
Permissions for the new group need to be exposed to the members of those
new groups. This makes the on-migrate logic poke the permission-hook for
that.
This temporary, upgrade-oriented logic depends on two assumptions:
- If the metadata-store is not running, we are still in the process of
applying the upgrade.
- If the above is true, all chats are /~host/name, all groups are
/~/~host/name, and they have a strict one-to-one relation.
Armed with those assumptions, we can deduce groups from chats and vice
versa without depending on the metadata-store, allowing us to carry on
as if it were already running.
If we %add-owned, then we add an entry to the access-control jug matching the
data we put into the synced map. When a permission gets deleted, we remove it
from synced, but previously neglected to clean up the matching access-control
entry.
This ensures that if a permission was deleted, and we had it registered as
owned, that the relevant access-control entry is removed from state.
We want to move from group/permission paths of the form /chat/~host/name
to /~/~host/name, merging the ./read and ./write permission paths into a
single permission matching the group path.
(The leading /~ signifies an "unmanaged" group, one used by apps
internally, and not explicitly exposed to the user as a contacts group.)
This upgrade logic does roughly the following, for every chat path, to
accomplish the migration:
1. delete ./read and ./write groups associated with the chat
2. create a new group containing an approximate "uni" of the old groups
3. register the chat + new group with the metadata-store
4. hook the group up to its matching permission set
Note that because existing groups are hooked up through the
permission-group-hook, doing step 1 deletes the associated permissions.
Step 4 then re-establishes that relation for the newly created group.
The logic here scries into the metadata-store, and as such depends on
that having been started prior to this upgrade process.
When permissions change, find out which chats are impacted (on the
assumption that permission paths are group paths), then perform actions
wrt that chat accordingly.
When a chat is interacted with, find out which groups the chat is
associated with, then use those to perform permission checks. If the
check passes for any group, permission is granted.