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

check for cycles #4

Open
3 tasks
agarwal opened this issue Apr 10, 2015 · 6 comments
Open
3 tasks

check for cycles #4

agarwal opened this issue Apr 10, 2015 · 6 comments
Milestone

Comments

@agarwal
Copy link
Member

agarwal commented Apr 10, 2015

Symbolic links lead to the possibility of cycles. Cycles are not necessarily wrong, so we don't consider them ill-formed at construction time. However, some operations will lead to an infinite loop, so we need to check for them in:

  • resolve_links
  • the proposed reify function
  • maybe in normalize also??
@agarwal agarwal changed the title check for cycles in resolve_links check for cycles Jul 30, 2015
@pveber
Copy link
Contributor

pveber commented Nov 11, 2015

Indeed not all loops are a problem. If we view a one-step resolution of a path (choose a link, and replace it by its target) as a rewriting, then we have a problem with paths such that there is no finite sequence of rewritings that leads to a link-free path. In 8f1749f we detect such cases at link creation and define them as broken links. Note that the detection is easy because all rewriting sequences are confluent.

As a result, resolve is now cycle-safe (normalize was safe to begin with because we don't normalize the target of a link), as well as typ_of and equal.

As for reify and fold, that's a different story since we have to "discover" a path and build it incrementally.

@agarwal
Copy link
Member Author

agarwal commented Nov 12, 2015

Can you give examples of links that are supposed to be ruled out by 8f1749f. I considered that x in the following two cases might be, but both return ``Ok`.

utop # let x = Item.link (name_exn "foo") (Item (Item.file (name_exn "foo")));;
val x : [ `Broken of (rel, link) item | `Ok of (rel, file) item ] =
  `Ok (Link ("foo", Item (File "foo")))
utop # let l =
  match Item.link (name_exn "foo") (Item (Item.file (name_exn "bar"))) with
  | `Broken _ -> assert false
  | `Ok x -> x;;
val l : (rel, file) item = Link ("foo", Item (File "bar"))

utop # let x = Item.link (name_exn "foo") (Item l);;
val x : [ `Broken of (rel, link) item | `Ok of (rel, file) item ] =                             
  `Ok (Link ("foo", Item (Link ("foo", Item (File "bar")))))

@pveber
Copy link
Contributor

pveber commented Nov 13, 2015

These examples are not cyclic but certainly wrong since they imply the existence of two different objects with the same path. However I think this verification is more on of the filesystem duty, isn't it? At the very least in both cases you can eventually resolve the links to a file, the only problem is that you can't build a tree directory with those paths.

What I mean by cyclic in this issue really boils down to cyclic ocaml values.

@agarwal agarwal added this to the release 0.1 milestone Nov 25, 2015
pveber added a commit that referenced this issue Dec 4, 2015
With this, we adopt the simple (and more common) design where paths
which are cyclic ocaml values are *not* supported and *not*
checked. In particular, some functions may not terminate when
called with such values.

This answers issue #4, which dealt with possible non termination of
functions of the pure library: all legal paths are acyclic ocaml
values, and as our functions on `Path.t` values in the pure library
simply traverse them, there is no risk of infinite loop, hence no
particular precaution to take.

Note that there is no danger of non-termination when dealing with the
file system either:
  - either the functions in async-unix do their job by traversing a
    `Path.t` value, which guarantees termination
  - either they can discover symbolic links whose resolution run
    an infinite computation by just asking the filesystem, which
    considers such links as ill-defined and marks them as broken.
@pveber
Copy link
Contributor

pveber commented Dec 4, 2015

See the commit above, saying:

we adopt the simple (and more common) design where paths which are cyclic ocaml values are not supported and not checked. In particular, some functions may not terminate when called with such values.

This answers issue #4, which dealt with possible non termination of functions of the pure library: all legal paths are acyclic ocaml values, and as our functions on Path.t values in the pure library simply traverse them, there is no risk of infinite loop, hence no particular precaution to take.

Note that there is no danger of non-termination when dealing with the file system either:

  • either the functions in async-unix do their job by traversing a
    Path.t value, which guarantees termination
  • either they can discover symbolic links whose resolution run
    an infinite computation by just asking the filesystem, which
    considers such links as ill-defined and marks them as broken.

@agarwal
Copy link
Member Author

agarwal commented Dec 10, 2015

IIUC correctly, you are saying we entirely can do away with our own logic for testing for cycles, except indirectly by outsourcing the work to a system call that figures it out for us. Can you confirm. If so, I can close this issue.

pveber added a commit that referenced this issue Dec 15, 2015
With merging this branch, we now have implementations for [reify] and
[fold] that can cope with cycles. The first one does so by counting on
the file system to detect cases where a step-by-step discovery of link
targets would loop forever; the second one uses [reify] and a set of
visited nodes to avoid infinte loops.
@pveber
Copy link
Contributor

pveber commented Dec 15, 2015

Comment from 1d80c25:

"By merging this branch, we have implementations for [reify] and
[fold] that can cope with cycles. The first one does so by counting on
the file system to detect cases where a step-by-step discovery of link
targets would loop forever; the second one uses [reify] and a set of
visited nodes to avoid infinite loops."

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

No branches or pull requests

2 participants