<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>