<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    <p>Very helpful indeed! Thank you for the insight Alex.</p>
    <p>The concern of "doing too much" is exactly what started
      conversation when we are expecrimenting with charm, because in our
      design we are using charm as a state-driven framework that
      interacts with external resources. So it's the sanity of these
      external resources we want to guard.</p>
    <p><br>
    </p>
    <br>
    <div class="moz-cite-prefix">On 07/28/2017 05:37 AM, Alex Kavanagh
      wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:CAO3V+OmPJ5F=ezke3==1ptDe4OqnLq-OkKfKwUiaJ_3pJ-qi5A@mail.gmail.com">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
      <div dir="ltr">Hi fengxia
        <div><br>
        </div>
        <div>As Cory says, it's much better to think of the set_state()
          and remove_state() as binary flags; in fact in the upcoming
          version, set_state becomes set_flag() and remove_state()
          becomes remove_flag()  -- although the existing functions will
          still exist for backwards compatibility.</div>
        <div><br>
        </div>
        <div>So a handler with a set of conditions built from flags
          (states) that evaluates to 'true' will always run on EVERY
          invocation of the charm; that's all of the charm hooks, plus
          relation hooks.</div>
        <div><br>
        </div>
        <div>This can often lead to a charm 'doing too much' during a
          hook invocation if you don't gate or otherwise detect that a
          charm doesn't need to do something.  I've had 'bugs' in the
          past where databases were set up multiple times because I
          didn't gate (by using a flag/state) the 'have I set up the
          database yet'.  Just something to watch for.</div>
        <div><br>
        </div>
        <div>Also, the update-status hook is a bit redundant now.  To
          get equivalent functionality without having to use a
          @hook('update-status') just use a
          @when_not("never-set-update-status") and it will always run on
          every hook invocation; it also means you can gate the 'update
          status' if certain other things haven't happened.</div>
        <div><br>
        </div>
        <div>And yes, in your example, you can use flags to 'make
          progress' in the charm life-cycle by using them to only run a
          bit of functionality once.  You can always do them in cycles
          too!</div>
        <div><br>
        </div>
        <div>Finally, remember that states are NOT shared amongst units
          of the same application; they are unique to each individual
          unit.  Juju is not aware that the charm is using reactive
          states.</div>
        <div><br>
        </div>
        <div>Hope this helps</div>
        <div>Cheers</div>
        <div>Alex.</div>
        <div><br>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Thu, Jul 27, 2017 at 9:09 PM,
          fengxia <span dir="ltr"><<a href="mailto:fxia1@lenovo.com"
              target="_blank" moz-do-not-send="true">fxia1@lenovo.com</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex">
            <div text="#000000" bgcolor="#FFFFFF">
              <p>Now thinking of it, I just realized that this concept
                of True state executing repeatedly is actually a good
                thing. <br>
              </p>
              <p><br>
              </p>
              <p>In many cases, there is a need to query external
                resource for its status. This is often implemented as a
                polling loop. So in charm, I can implement it as <br>
              </p>
              <p><br>
              </p>
              <p>@when("prep")</p>
              <p>def prep():</p>
              <p>    # are we there yet?</p>
              <p>    is_ready = prep_test()</p>
              <p>    if is_ready:</p>
              <p>        remove_state("prep")</p>
              <p>        set_state("do.sth")</p>
              <p>@when("do.sth")</p>
              <p>def do_sth():</p>
              <p>    # do this</p>
              <p>    pass</p>
              <p><br>
              </p>
              <p>    # move on</p>
              <p>    remove_state("do.sth")</p>
              <p>    set_state("next")<br>
              </p>
              <div>
                <div class="h5"> <br>
                  <div class="m_6829574904432859522moz-cite-prefix">On
                    07/27/2017 03:56 PM, Cory Johns wrote:<br>
                  </div>
                  <blockquote type="cite">
                    <div dir="ltr">fengxia,
                      <div><br>
                      </div>
                      <div>It's probably more enlightening to think of
                        them as "flags" rather than states.  (Indeed,
                        the next release of charms.reactive will
                        deprecate calling them states and will provide
                        set_flag, remove_flag, etc. functions instead.)</div>
                    </div>
                    <div class="gmail_extra"><br>
                      <div class="gmail_quote">On Thu, Jul 27, 2017 at
                        3:29 PM, fengxia <span dir="ltr"><<a
                            href="mailto:fxia1@lenovo.com"
                            target="_blank" moz-do-not-send="true">fxia1@lenovo.com</a>></span>
                        wrote:<br>
                        <blockquote class="gmail_quote" style="margin:0
                          0 0 .8ex;border-left:1px #ccc
                          solid;padding-left:1ex">
                          <div text="#000000" bgcolor="#FFFFFF">
                            <p>Alex,</p>
                            <p>Thank you for the detailed explanations
                              and examples.</p>
                            <p>After reading Tilman's and Cory's
                              replies, I think the confusion is at
                              continuous evaluation (thus execution) of
                              a True state. So a pair of @when and
                              @when_not will result in one of them being
                              executed over and over despite adding a
                              remove_state("myself") in the @when block.</p>
                            <p>I'm still trying to grasp the idea of
                              this "state" instead of treating it as an
                              event handler.</p>
                            <p>So for states, I usually draw a state
                              machine diagram. In this case, it feels
                              rather unnatural that all True states will
                              inherently loop to themselves. <br>
                            </p>
                            <p>But I don't what alternative is in
                              charm's context.<br>
                            </p>
                            <div>
                              <div class="m_6829574904432859522h5"> <br>
                                <div
                                  class="m_6829574904432859522m_921366770099927250moz-cite-prefix">On
                                  07/27/2017 04:13 AM, Alex Kavanagh
                                  wrote:<br>
                                </div>
                                <blockquote type="cite">
                                  <div dir="ltr">Hi
                                    <div class="gmail_extra"><br>
                                      <div class="gmail_quote">On Thu,
                                        Jul 27, 2017 at 2:37 AM, fengxia
                                        <span dir="ltr"><<a
                                            href="mailto:fxia1@lenovo.com"
                                            target="_blank"
                                            moz-do-not-send="true">fxia1@lenovo.com</a>></span>
                                        wrote:<br>
                                        <blockquote class="gmail_quote"
                                          style="margin:0 0 0
                                          .8ex;border-left:1px #ccc
                                          solid;padding-left:1ex">Hi
                                          Juju,<br>
                                          <br>
                                          Once I set a state,
                                          set_state("here"), I want to
                                          make sure its @when will only
                                          be executed ONCE (when "here"
                                          from False->True).<br>
                                          <br>
                                          So my thought is to
                                          remove_state("here") in its
                                          @when("here") code block. If I
                                          don't, will this @when be
                                          called multiple times if I
                                          don't reset this state? What's
                                          the good practice here?</blockquote>
                                        <div><br>
                                        </div>
                                        <div>You have a couple of
                                          options here depending on the
                                          nature of the handler.</div>
                                        <div><br>
                                        </div>
                                        <div>
                                          <ol>
                                            <li>If, in the lifetime of
                                              the unit's existence, the
                                              handler only has to
                                              execute ONCE.  (and I mean
                                              EVER), then there is a
                                              @only_once decorator that
                                              can be used.  It can be
                                              used in combination with
                                              other decorators to set up
                                              a condition, but it
                                              guarantees that the
                                              handler will only be
                                              called once.  However,
                                              what you probably want is
                                              ...<br>
                                            </li>
                                            <li>Use a @when_not('flag')
                                              and then set it the 'flag'
                                              in the body of the
                                              handler.</li>
                                          </ol>
                                          <div>The first would look
                                            something like:</div>
                                        </div>
                                        <div><br>
                                        </div>
                                        <div>@when('some-condition-flag')</div>
                                        <div>@only_once</div>
                                        <div>def
                                          do_something_only_once_when_so<wbr>me_condition_flag_is_set_for_<wbr>the_first_time():</div>
                                        <div>     ... do something once
                                          ...</div>
                                        <div><br>
                                        </div>
                                        <div>The second treats a flag as
                                          a 'have I done this yet'
                                          condition, and allows you to
                                          reset the flag at some other
                                          point in the charm's life
                                          cycle so that you can do it
                                          again.  'installed' is a good
                                          example of this:</div>
                                        <div><br>
                                        </div>
                                        <div>@when_not('installed-something<wbr>')</div>
                                        <div>def
                                          do_install_of_something():</div>
                                        <div>    ... do the installation
                                          ...</div>
                                        <div>    # when it is fully
                                          successful, set the
                                          installed-something flag. 
                                          Don't set it early as</div>
                                        <div>    # if it errors, a
                                          future handler invocation may
                                          be able to continue the
                                          installation.</div>
                                        <div>   
                                          set_state('installed-something<wbr>')</div>
                                        <div><br>
                                        </div>
                                        <div><br>
                                        </div>
                                        <div>@when(some other conditions
                                          indicating do an upgrade)</div>
                                        <div>def do_upgrade():</div>
                                        <div>     ... set upgrade
                                          sources, or other pre upgrade
                                          actions</div>
                                        <div>   
                                           remove_state('installed-somet<wbr>hing')</div>
                                        <div><br>
                                        </div>
                                        <div>In this situation,
                                          hopefully you can see that we
                                          can re-use
                                          'do_install_of_something()'
                                          when we do upgrades.</div>
                                        <div><br>
                                        </div>
                                        <div>I think it's useful to
                                          think about states (flags) as
                                          being a 'memory' that
                                          something has happened, and
                                          use them to either gate on not
                                          doing things again, or to
                                          trigger the next action is a
                                          graph of actions that need to
                                          take place to get the charm's
                                          payload to the desired
                                          operational state.  I tend to
                                          name them, and use them, to
                                          indicate when something has
                                          happened, rather than when it
                                          hasn't, and so tend to use
                                          @when_not('some-flag') on the
                                          handler that eventually sets
                                          that flag.</div>
                                        <div><br>
                                        </div>
                                        <div>Hope that this helps.</div>
                                        <div>Alex.</div>
                                        <blockquote class="gmail_quote"
                                          style="margin:0 0 0
                                          .8ex;border-left:1px #ccc
                                          solid;padding-left:1ex"><span
class="m_6829574904432859522m_921366770099927250HOEnZb"><font
                                              color="#888888"><br>
                                              <br>
                                              -- <br>
                                              Feng xia<br>
                                              Engineer<br>
                                              Lenovo USA<br>
                                              <br>
                                              Phone: <a
                                                href="tel:5088011794"
                                                value="+15088011794"
                                                target="_blank"
                                                moz-do-not-send="true">5088011794</a><br>
                                              <a
                                                href="mailto:fxia1@lenovo.com"
                                                target="_blank"
                                                moz-do-not-send="true">fxia1@lenovo.com</a><br>
                                                      <br>
                                              Lenovo.com<br>
                                              Twitter | Facebook |
                                              Instagram | Blogs | Forums<br>
                                              <br>
                                              <br>
                                              -- <br>
                                              Juju mailing list<br>
                                              <a
                                                href="mailto:Juju@lists.ubuntu.com"
                                                target="_blank"
                                                moz-do-not-send="true">Juju@lists.ubuntu.com</a><br>
                                              Modify settings or
                                              unsubscribe at: <a
                                                href="https://lists.ubuntu.com/mailman/listinfo/juju"
                                                rel="noreferrer"
                                                target="_blank"
                                                moz-do-not-send="true">https://lists.ubuntu.com/mailm<wbr>an/listinfo/juju</a><br>
                                            </font></span></blockquote>
                                      </div>
                                      <br>
                                      <br clear="all">
                                      <div><br>
                                      </div>
                                      -- <br>
                                      <div
                                        class="m_6829574904432859522m_921366770099927250gmail_signature"
                                        data-smartmail="gmail_signature">
                                        <div dir="ltr">Alex Kavanagh -
                                          Software Engineer
                                          <div>Cloud Dev Ops - Solutions
                                            & Product Engineering -
                                            Canonical Ltd</div>
                                        </div>
                                      </div>
                                    </div>
                                  </div>
                                </blockquote>
                                <br>
                                <pre class="m_6829574904432859522m_921366770099927250moz-signature" cols="72">-- 
Feng xia
Engineer
Lenovo USA

Phone: <a href="tel:%28508%29%20801-1794" value="+15088011794" target="_blank" moz-do-not-send="true">5088011794</a>
<a class="m_6829574904432859522m_921366770099927250moz-txt-link-abbreviated" href="mailto:fxia1@lenovo.com" target="_blank" moz-do-not-send="true">fxia1@lenovo.com</a>
        
Lenovo.com 
Twitter | Facebook | Instagram | Blogs | Forums
</pre>
                              </div>
                            </div>
                          </div>
                          <br>
                          --<br>
                          Juju mailing list<br>
                          <a href="mailto:Juju@lists.ubuntu.com"
                            target="_blank" moz-do-not-send="true">Juju@lists.ubuntu.com</a><br>
                          Modify settings or unsubscribe at: <a
                            href="https://lists.ubuntu.com/mailman/listinfo/juju"
                            rel="noreferrer" target="_blank"
                            moz-do-not-send="true">https://lists.ubuntu.com/mailm<wbr>an/listinfo/juju</a><br>
                          <br>
                        </blockquote>
                      </div>
                      <br>
                    </div>
                    <br>
                    <fieldset
                      class="m_6829574904432859522mimeAttachmentHeader"></fieldset>
                    <br>
                  </blockquote>
                  <br>
                  <pre class="m_6829574904432859522moz-signature" cols="72">-- 
Feng xia
Engineer
Lenovo USA

Phone: <a href="tel:%28508%29%20801-1794" value="+15088011794" target="_blank" moz-do-not-send="true">5088011794</a>
<a class="m_6829574904432859522moz-txt-link-abbreviated" href="mailto:fxia1@lenovo.com" target="_blank" moz-do-not-send="true">fxia1@lenovo.com</a>
        
Lenovo.com 
Twitter | Facebook | Instagram | Blogs | Forums
</pre>
                </div>
              </div>
            </div>
            <br>
            --<br>
            Juju mailing list<br>
            <a href="mailto:Juju@lists.ubuntu.com"
              moz-do-not-send="true">Juju@lists.ubuntu.com</a><br>
            Modify settings or unsubscribe at: <a
              href="https://lists.ubuntu.com/mailman/listinfo/juju"
              rel="noreferrer" target="_blank" moz-do-not-send="true">https://lists.ubuntu.com/<wbr>mailman/listinfo/juju</a><br>
            <br>
          </blockquote>
        </div>
        <br>
        <br clear="all">
        <div><br>
        </div>
        -- <br>
        <div class="gmail_signature" data-smartmail="gmail_signature">
          <div dir="ltr">Alex Kavanagh - Software Engineer
            <div>Cloud Dev Ops - Solutions & Product Engineering -
              Canonical Ltd</div>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
Feng xia
Engineer
Lenovo USA

Phone: 5088011794
<a class="moz-txt-link-abbreviated" href="mailto:fxia1@lenovo.com">fxia1@lenovo.com</a>
        
Lenovo.com 
Twitter | Facebook | Instagram | Blogs | Forums
</pre>
  </body>
</html>