Allow cycles to be recorded as a TODO #353
Replies: 2 comments 10 replies
-
This idea makes a lot of sense to me. Most (all?) of us are coming from giant ball of mud monoliths, attempting to chunk things down into more manageable portions. As these "chunks" were previously all part of the same big ball of mud, they will naturally have plenty of circular dependencies as boundaries were never a thing until the chunking process began. Circular dependencies of this nature are big problems that we want to fix, but can live with "for now". They are a perfect fit for Anecdotally speaking, bringing visibility to circular dependencies will help teams prioritize decomposition work. If these problems are not visible, they aren't prioritized and therefore never done. Ok so now that I've established my high level agreement, I'll dive into some of the details presented with potentially more contentious opinions. Where?If a package participates in a circular dependency chain, then it owns the problem along with all other participating packages. Storing these violations in a global Loss of acyclic meaning for dependenciesAt GitHub, we currently report all actual dependencies and use Packwerk to identify and eliminate those we don't want and to ensure we don't add more that we don't intend. The package dependencies we have look like a mess in a graph, but we prefer to report the actual state of things. To do this, we actually don't run |
Beta Was this translation helpful? Give feedback.
-
While I agree it would be nice to have some kind of TODO list for cycles that exist in actual dependencies, I don't think we should have TODO list entries for the dependencies specified in It makes no sense whatsoever to me to have a desired end state that contains cycles.
We could still do that by highlighting cycles in actual dependencies somewhere. That doesn't require any changes to the acyclicity check on desired dependencies. I really think it is important to preserve a clean separation between current state and desired end state. Changing the desired end state changes what actual dependencies are listed in the package todo files. It makes no sense to me to derive that information from something that is closer to an actual state. To illustrate: If we listed all actual dependencies in |
Beta Was this translation helpful? Give feedback.
-
Summary
This discussion proposes storing cycles as a TODO item to permit more observable and gradual cycle reduction.
When, where, and how should the TODO be recorded?
bin/packwerk update-todo
.bin/packwerk validate
could change to make it clear we're talking about new cycles and that you can store new cycles as TODOs with update./.package_cycles_todo.yml
) should hold all of them.bin/packwerk validate
(slightly modified to be more serializable as YML) seems fine – is there an alternate format of cycles that is more useful?Advantages
Observability
Waste Reduction
bin/packs add_dependency
) that there is a validation (cycle) error. Then they remove the dependency until the next time someone else encounters the same issue. With this, there is much less waste since someone adds it once, uses their usualbin/packwerk validate
command, and can then commit the cycle TODO.More Gradual
Disadvantages
Loss of constraints and meaningfulness of
dependencies
The main thing I see now is that cycles in dependencies are possible, which was never possible before. It was kind of an interesting invariant that dependencies formed an acyclic graph, but I'm not sure if it was a useful invariant. This approach loosens this constraint and makes "violations" of that constraint visible. Furthermore, we could enable this via a flag in
packwerk.yml
so folks can keep the old behavior if they want.It could even be possible to have cycle detection itself be a checker that can be turned on/off per package, e.g.
enforce_acyclicity
(defaults to value ofenforce_dependencies
). If it's on, the package cannot be a part of any cycle. This could be an interesting way to allow a package to prevent this feature from causing entanglement.Noise from too many cycles
It's possible folks would use the cycle TODO list by just adding to it, as a shift from using the package TODO
I used a small script in Gusto's monolith to add all dependencies necessary to remove all dependency violations to establish an upper bound on cycles and saw there are still fewer cycles than dependency violations, so there should always be less noise by recording cycles (especially since I don't see folks adding all dependencies).
Feedback
Let me know what you think and what I might be missing!
Related discussions:
Beta Was this translation helpful? Give feedback.
All reactions