import "github.com/ipfs/go-mfs"
dir.go fd.go file.go inode.go ops.go options.go repub.go root.go
TODO: Remove if not used.
TODO: Remove if not used.
TODO: Document this function and link its functionality with the republisher.
IsDir checks whether the FSNode is dir type
IsFile checks whether the FSNode is file type
Mkdir creates a directory at 'path' under the directory 'd', creating intermediary directories as needed if 'mkparents' is set to true
Mv moves the file or directory at 'src' to 'dst' TODO: Document what the strings 'src' and 'dst' represent.
PutNode inserts 'nd' at 'path' in the given mfs TODO: Rename or clearly document that this is not about nodes but actually MFS files/directories (that in the underlying representation can be considered as just nodes). TODO: Document why are we handling IPLD nodes in the first place when we are actually referring to files/directories (that is, it can't be any node, it has to have a specific format). TODO: Can this function add directories or just files? What would be the difference between adding a directory with this method and creating it with `Mkdir`.
type Directory struct {
// contains filtered or unexported fields
}
TODO: There's too much functionality associated with this structure, let's organize it (and if possible extract part of it elsewhere) and document the main features of `Directory` here.
func NewDirectory(ctx context.Context, name string, node ipld.Node, parent parent, dserv ipld.DAGService) (*Directory, error)
NewDirectory constructs a new MFS directory.
You probably don't want to call this directly. Instead, construct a new root using NewRoot.
AddChild adds the node 'nd' under this directory giving it the name 'name'
Child returns the child of this directory by the given name
GetCidBuilder gets the CID builder of the root node
SetCidBuilder sets the CID builder
FSNode abstracts the `Directory` and `File` structures, it represents any child node in the MFS (i.e., all the nodes besides the `Root`). It is the counterpart of the `parent` interface which represents any parent node in the MFS (`Root` and `Directory`). (Not to be confused with the `unixfs.FSNode`.)
DirLookup will look up a file or directory at the given path under the directory 'd'
Lookup extracts the root directory and performs a lookup under it. TODO: Now that the root is always a directory, can this function be collapsed with `DirLookup`? Or at least be made a method of `Root`?
File represents a file in the MFS, its logic its mainly targeted to coordinating (potentially many) `FileDescriptor`s pointing to it.
NewFile returns a NewFile object with the given parameters. If the Cid version is non-zero RawLeaves will be enabled.
TODO: Tight coupling with the `FileDescriptor`, at the very least this should be an independent function that takes a `File` argument and automates the open/flush/close operations. TODO: Why do we need to flush a file that isn't opened? (the `OpenWriteOnly` seems to implicitly be targeting a closed file, a file we forgot to flush? can we close a file without flushing?)
GetNode returns the dag node associated with this file TODO: Use this method and do not access the `nodeLock` directly anywhere else.
func (fi *File) Open(flags Flags) (_ FileDescriptor, _retErr error)
Size returns the size of this file TODO: Should we be providing this API? TODO: There's already a `FileDescriptor.Size()` that through the `DagModifier`'s `fileSize` function is doing pretty much the same thing as here, we should at least call that function and wrap the `ErrNotUnixfs` with an MFS text.
Type returns the type FSNode this is
type FileDescriptor interface { io.Reader CtxReadFull(context.Context, []byte) (int, error) io.Writer io.WriterAt io.Closer io.Seeker Truncate(int64) error Size() (int64, error) Flush() error }
One `File` can have many `FileDescriptor`s associated to it (only one if it's RW, many if they are RO, see `File.desclock`). A `FileDescriptor` contains the "view" of the file (through an instance of a `DagModifier`), that's why it (and not the `File`) has the responsibility to `Flush` (which crystallizes that view in the `File`'s `Node`).
MkdirOpts is used by Mkdir
PubFunc is the user-defined function that determines exactly what logic entails "publishing" a `Cid` value.
type Republisher struct { TimeoutLong time.Duration TimeoutShort time.Duration RetryTimeout time.Duration // contains filtered or unexported fields }
Republisher manages when to publish a given entry.
NewRepublisher creates a new Republisher object to republish the given root using the given short and long time intervals.
func (rp *Republisher) Close() error
func (rp *Republisher) Run(lastPublished cid.Cid)
Run contains the core logic of the `Republisher`. It calls the user-defined `pubfunc` function whenever the `Cid` value is updated to a *new* value. The complexity comes from the fact that `pubfunc` may be slow so we need to batch updates.
Algorithm:
1. When we receive the first update after publishing, we set a `longer` timer. 2. When we receive any update, we reset the `quick` timer. 3. If either the `quick` timeout or the `longer` timeout elapses, we call `publish` with the latest updated value.
The `longer` timer ensures that we delay publishing by at most `TimeoutLong`. The `quick` timer allows us to publish sooner if it looks like there are no more updates coming down the pipe.
Note: If a publish fails, we retry repeatedly every TimeoutRetry.
func (rp *Republisher) Update(c cid.Cid)
Update the current value. The value will be published after a delay but each consecutive call to Update may extend this delay up to TimeoutLong.
func (rp *Republisher) WaitPub(ctx context.Context) error
WaitPub waits for the current value to be published (or returns early if it already has).
type Root struct {
// contains filtered or unexported fields
}
Root represents the root of a filesystem tree.
func NewRoot(parent context.Context, ds ipld.DAGService, node *dag.ProtoNode, pf PubFunc) (*Root, error)
NewRoot creates a new Root and starts up a republisher routine for it.
Flush signals that an update has occurred since the last publish, and updates the Root republisher. TODO: We are definitely abusing the "flush" terminology here.
FlushMemFree flushes the root directory and then uncaches all of its links. This has the effect of clearing out potentially stale references and allows them to be garbage collected. CAUTION: Take care not to ever call this while holding a reference to any child directories. Those directories will be bad references and using them may have unintended racy side effects. A better implemented mfs system (one that does smarter internal caching and refcounting) shouldnt need this method. TODO: Review the motivation behind this method once the cache system is refactored.
GetDirectory returns the root directory.
Package mfs imports 18 packages (graph) and is imported by 65 packages. Updated 2020-05-19. Refresh now. Tools for package owners.