Documentation ¶
Index ¶
- Variables
- func FlushPath(ctx context.Context, rt *Root, pth string) (ipld.Node, error)
- func IsDir(fsn FSNode) bool
- func IsFile(fsn FSNode) bool
- func Mkdir(r *Root, pth string, opts MkdirOpts) error
- func Mv(r *Root, src, dst string) error
- func PutNode(r *Root, path string, nd ipld.Node) error
- type Directory
- func (d *Directory) AddChild(name string, nd ipld.Node) error
- func (d *Directory) Child(name string) (FSNode, error)
- func (d *Directory) Flush() error
- func (d *Directory) ForEachEntry(ctx context.Context, f func(NodeListing) error) error
- func (d *Directory) GetCidBuilder() cid.Builder
- func (d *Directory) GetNode() (ipld.Node, error)
- func (d *Directory) List(ctx context.Context) ([]NodeListing, error)
- func (d *Directory) ListNames(ctx context.Context) ([]string, error)
- func (d *Directory) Mkdir(name string) (*Directory, error)
- func (d *Directory) Path() string
- func (d *Directory) SetCidBuilder(b cid.Builder)
- func (d *Directory) Type() NodeType
- func (d *Directory) Uncache(name string)
- func (d *Directory) Unlink(name string) error
- type FSNode
- type File
- type FileDescriptor
- type Flags
- type MkdirOpts
- type NodeListing
- type NodeType
- type PubFunc
- type Republisher
- type Root
Constants ¶
This section is empty.
Variables ¶
var ErrClosed = errors.New("file closed")
var ErrDirExists = errors.New("directory already has entry by that name")
var ErrInvalidChild = errors.New("invalid child node")
var ErrIsDirectory = errors.New("error: is a directory")
TODO: Remove if not used.
var ErrNotExist = errors.New("no such rootfs")
TODO: Remove if not used.
var ErrNotYetImplemented = errors.New("not yet implemented")
Functions ¶
func Mkdir ¶
Mkdir creates a directory at 'path' under the directory 'd', creating intermediary directories as needed if 'mkparents' is set to true
func Mv ¶
Mv moves the file or directory at 'src' to 'dst' TODO: Document what the strings 'src' and 'dst' represent.
func PutNode ¶
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`.
Types ¶
type Directory ¶
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 ¶
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.
func (*Directory) AddChild ¶
AddChild adds the node 'nd' under this directory giving it the name 'name'
func (*Directory) ForEachEntry ¶
func (*Directory) GetCidBuilder ¶
GetCidBuilder gets the CID builder of the root node
func (*Directory) SetCidBuilder ¶
SetCidBuilder sets the CID builder
type FSNode ¶
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`.)
type File ¶
type File struct { RawLeaves bool // contains filtered or unexported fields }
File represents a file in the MFS, its logic its mainly targeted to coordinating (potentially many) `FileDescriptor`s pointing to it.
func NewFile ¶
NewFile returns a NewFile object with the given parameters. If the Cid version is non-zero RawLeaves will be enabled.
func (*File) Flush ¶
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?)
func (*File) GetNode ¶
GetNode returns the dag node associated with this file TODO: Use this method and do not access the `nodeLock` directly anywhere else.
func (*File) Size ¶
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 FileDescriptor ¶
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`).
type PubFunc ¶
PubFunc is the user-defined function that determines exactly what logic entails "publishing" a `Cid` value.
type Republisher ¶
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.
func NewRepublisher ¶
NewRepublisher creates a new Republisher object to republish the given root using the given short and long time intervals.
func (*Republisher) Close ¶
func (rp *Republisher) Close() error
func (*Republisher) Run ¶
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:
- When we receive the first update after publishing, we set a `longer` timer.
- When we receive any update, we reset the `quick` timer.
- 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 (*Republisher) Update ¶
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.
type Root ¶
type Root struct {
// contains filtered or unexported fields
}
Root represents the root of a filesystem tree.
func NewRoot ¶
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.
func (*Root) Flush ¶
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.
func (*Root) FlushMemFree ¶
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.
func (*Root) GetDirectory ¶
GetDirectory returns the root directory.