Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Links, paths, and anchors #453

Open
wants to merge 17 commits into
base: main
Choose a base branch
from
Open

Links, paths, and anchors #453

wants to merge 17 commits into from

Conversation

pdaoust
Copy link
Collaborator

@pdaoust pdaoust commented Jun 6, 2024

Resolves #467

Seeking review for:

  • Succinctness of prose -- do you get lost? Is there too much information, is the complex stuff (e.g., introducing how to get a hash for linking) introduced too early?
  • Correctness of code at first glance -- I have to confess I haven't tried compiling any of it yet.

Copy link

@mjbrisebois mjbrisebois left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great. I didn't know how to use the anchor functions until reading this.

!!! info Action hashes aren't certain until zome function lifecycle completes
When you get an action hash back from the host function that creates it, it doesn't mean the action is available on the DHT yet, or will ever be available. The action isn't written until the function that writes it completes, then passes the action to validation. If the function or the validation fail, the action will be discarded. And if it is successful, the action won't become fully available on the DHT until it's been published to a sufficient number of peers.

It's safer to share action hashes with other peers or cells in a callback called `post_commit()`. If your coordinator zome defines this callback, it'll be called after every successful function call within that zome.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This warning confused me. What is the less-safe way to share hashes? Also, when and why would I be sharing the hashes?

Is this about sending signals to other peers so they get the updates quicker?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this confused me too. In the context of linking to/from the action within the same zome call it was created there's no issue since all the actions will either be committed to the source chain or discarded atomically

src/pages/build/links-paths-and-anchors.md Outdated Show resolved Hide resolved
);
```

A link is considered dead once its creation action has one or more delete-link actions associated with it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might also copy the same disclaimer from the entries page: "deleting" a link just creates another action marking the link as deleted and does not actually delete any data. And that a future potential purge feature will not apply to links as they are only actions.


### Define a link type

Every link has a type that you define in an integrity zome, just like [an entry](/build/entries/#define-an-entry-type). Links are simple enough that they have no entry content. Instead, their data is completely contained in the actions that write them. Here's what a link creation action contains, in addition to the [common action fields](/build/working-with-data/#entries-actions-and-records-primary-data):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The phrasing of sentences 2-4 is a bit confusing to me. I might just say explicitly: "a link is commited to the source chain as an action with no associated entry"

);
```

Links can't be updated; they can only be created or deleted.
Copy link
Member

@mattyg mattyg Jun 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we give some clarifying rationale for why they can't be updated?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure... if only I knew why 🤣

);
```

A link is considered dead once its creation action has one or more delete-link actions associated with it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about using the term "dead" here -- in the web 2 context it usually means that a link's target is no longer hosted anywhere. I haven't seen the term used elsewhere in holochain, maybe we should just stick with "deleted"?

);
```

To get all live _and dead_ links, along with any deletion actions, use [`hdk::prelude::get_link_details`](https://docs.rs/hdk/latest/hdk/link/fn.get_link_details.html). This function has the same options as `get_links`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same note as above about the terms "dead" and "live"


### Count links

If all you need is a count of matching links, such as for an unread messages badge, use [`hdk::prelude::count_links`](https://docs.rs/hdk/latest/hdk/prelude/fn.count_links.html). It has a different input with more options for querying (we'll likely update the inputs of `get_links` and `count_links` to match `count_links` in the future).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth noting some gotchas with count_links: it goes to the network first, so if you end up asking 2 different peers with differing dht syncs you may get 2 different answers (which may be odd behavior if your unread messages badge shows a smaller number than before without you reading any messages). You may also get a different count as the number returned from get_links for the same reason.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, although I feel like there's an entire story about that re: eventual consistency everywhere.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's more than just that though since it doesn't go to your cache so you may have more links than you receive via count


While you can build this yourself, this is such a common pattern that the HDK implements it for you in the [`hdk::hash_path`](https://docs.rs/hdk/latest/hdk/hash_path/index.html) module. The implementation supports both anchors and **paths**, which are hierarchies of anchors.

!!! info Avoiding DHT hot spots
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same note as above -- I think hot spots could be expanded on in its own section

Copy link
Member

@mattyg mattyg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome stuff thanks for taking this on!

let hashes_of_all_first_letters = list_anchor_addresses(LinkTypes::MovieByFirstLetterAnchor, "movies_by_first_letter");
```

## Reference
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -88,7 +96,7 @@ use movie_integrity::*;

let movie = Movie {
title: "The Good, the Bad, and the Ugly",
director: "Sergio Leone"
director_hash: EntryHash::from_raw_36(vec![ /* hash of 'Sergio Leone' entry */ ]),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be useful to also show how to get /* hash of 'Sergio Leone' entry */, or is this covered elsewhere in the guide?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, there's a section on it elsewhere, although it's a bit long-winded. I might make it into its own article.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Practical docs for using Links
4 participants