<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<p>Hi Pranav,</p>
<p>I think your question touches upon an unresolved problem we have
with our system layering. We have discussed this before when I
wrote the first repository interfaces, but haven't really resolved
the issue at the time. Let's look at what kinds of code we have:</p>
<ul>
<li>Repository interfaces<br>
They define an interface for persistence in terms of application
level objects. The repository interfaces are not supposed to be
gorm specific. The idea is to be able to replace the
implementation in tests and to avoid coupling consumers to gorm.</li>
<li>Repository implementations<br>
They implement the repository implementations in a gorm-specific
way. They are free to convert app layer objects to a different
form. For example, we store work items as JSON in the db, which
only has very few data types (number, string, bool, etc.). The
repository implementations convert and validate the work item
fields according to a given work item type. <br>
</li>
<li>Gorm support stuff <br>
Stuff like models.Lifecycle, GormTransactionSupport, etc. This
is shared infrastructure for implementing repositories.</li>
</ul>
<p>Now that we have an overview, what problems can we run into and
how do we solve them?<br>
</p>
<ul>
<li>Problem 1: shared repository infrastructure in models package<br>
Solution: -> move infrastructure to a separate package</li>
<li>Problem 2: false cycle<br>
This problem can occur if we have multiple repositories in the
same package and have pairwise inverse dependencies: Think of
two packages foo and bar. We have repository foo.X depend on
bar.Y and repository bar.M depend on foo.N. Now we have a
package cycle, but it is not a REAL cycle in the code, we just
co-located two independent repositories in the same package<br>
Solution: -> separate repositories into different packages<br>
</li>
<li>Problem 3: real cycle<br>
In real life, there ARE cases where cyclic dependencies make
sense. Imaging an event service and a logging service: the event
service wants to log things, and the logging service wants to
send events. You usually need some kind of setup protocol to get
things going, but it's possible. The problem in our case is that
the compiler will complain if the two repositories are in
separate packages.<br>
Solution: -> move the two repository interfaces to a common
package and only depend on the interface of the other repository
in the implementation.</li>
</ul>
<p>/Thomas<br>
</p>
<br>
<div class="moz-cite-prefix">On 10/08/2016 05:25 AM, Pranav Gore
wrote:<br>
</div>
<blockquote
cite="mid:CADriryaQ9AK6xEUeB3Y2eoaCzHqF_Z_JBZbST5UkUGgXpZvp1A@mail.gmail.com"
type="cite">
<div dir="ltr">
<div>
<div>Hi Team Core,<br>
<br>
<b>Context/Background:-</b><br>
I am working on <a moz-do-not-send="true"
href="https://github.com/almighty/almighty-core/issues/244"
target="_blank">#244</a>. The task is to do <span
style="background-color:rgb(255,255,255)">`fields["system.creator"]=currentLoggedInUser</span>`.<br>
<br>
There, I want to call a method Locate from package "Token"
which returns current logged in user.<br>
While doing so I am facing cyclic import problem.<br>
<br>
<b>Reason:-</b> Work_item_repo is in package "models", it
wants to call Locate method from package "token".<br>
But "token" pachakge imports "account" package and "account"
package imports "models".<br>
Hence "models" package is unable to import "token" =>
cyclic dependency.<br>
<br>
<b>Debugging:-</b> When I was looking into "account"
package, what exactly it needs from "models" package is ONLY
"models.LifeCycle" and nothing else as of now.<br>
<br>
<b>Solutions:-</b> One quick possible/feasible solution is
to put models.LifeCycle into different new package of its
own, refactor and move on (IMO we should do this as first
step).<br>
<br>
Another is to write a middleware(as mentioned in <a
moz-do-not-send="true"
href="https://github.com/almighty/almighty-core/issues/244">#244</a>)
for injecting loggedInUser which will be in package
"middleware" and avoid cyclic import, <br>
<br>
Or redesigning to decouple models package into smaller
chunks ?<br>
</div>
<div><br>
PFA- I have attached output of `go list -f` on account,
models, token packages.<br>
<br>
Any input on this will be helpful :)<br>
</div>
<div><br>
<br>
</div>
Thanks,<br>
</div>
Pranav<br>
</div>
</blockquote>
<br>
</body>
</html>