<html>
 <body>
  <div style="font-family: Verdana, Arial, Helvetica, Sans-Serif;">
   <table bgcolor="#f9f3c9" width="100%" cellpadding="8" style="border: 1px #c9c399 solid;">
    <tr>
     <td>
      This is an automatically generated e-mail. To reply, visit:
      <a href="https://reviewboard.asterisk.org/r/4215/">https://reviewboard.asterisk.org/r/4215/</a>
     </td>
    </tr>
   </table>
   <br />










<blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
 <p style="margin-top: 0;">On December 4th, 2014, 4:08 p.m. MST, <b>Kevin Harwell</b> wrote:</p>
 <blockquote style="margin-left: 1em; border-left: 2px solid #d0d0d0; padding-left: 10px;">
  



<table width="100%" border="0" bgcolor="white" style="border: 1px solid #C0C0C0; border-collapse: collapse; margin: 2px padding: 2px;">
 <thead>
  <tr>
   <th colspan="4" bgcolor="#F0F0F0" style="border-bottom: 1px solid #C0C0C0; font-size: 9pt; padding: 4px 8px; text-align: left;">
    <a href="https://reviewboard.asterisk.org/r/4215/diff/7/?file=69340#file69340line1268" style="color: black; font-weight: bold; text-decoration: underline;">branches/12/main/sorcery.c</a>
    <span style="font-weight: normal;">

     (Diff revision 7)

    </span>
   </th>
  </tr>
 </thead>

 <tbody style="background-color: #e4d9cb; padding: 4px 8px; text-align: center;">
  <tr>

   <td colspan="4"><pre style="font-size: 8pt; line-height: 140%; margin: 0; ">static int sorcery_observer_notify_loaded(void *obj, void *arg, int flags)</pre></td>

  </tr>
 </tbody>



 
 

 <tbody>

  <tr>
    <th bgcolor="#f0f0f0" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">1062</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
    <th bgcolor="#f0f0f0" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">1256</font></th>
    <td bgcolor="#ffffff" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
  </tr>

 </tbody>


 
 

 <tbody>

  <tr>
    <th bgcolor="#e9eaa8" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">1063</font></th>
    <td bgcolor="#fdfebc" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="tb">  </span><span class="k">if</span> <span class="p">(</span><span class="n">invocation</span> <span class="o">&&</span> <span class="n">ast_taskprocessor_push</span><span class="p">(</span><span class="n">type</span><span class="o">-></span><span class="n">serializer</span><span class="p">,</span> <span class="n">sorcery_observers_notify_loaded</span><span class="p">,</span> <span class="n">invocation</span><span class="p">))</span> <span class="p">{</span></pre></td>
    <th bgcolor="#e9eaa8" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">1257</font></th>
    <td bgcolor="#fdfebc" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="n">NOTIFY_INSTANCE_OBSERVERS</span><span class="p">(</span><span class="n">details</span><span class="o">-></span><span class="n">sorcery</span><span class="o">-></span><span class="n">observers</span><span class="p">,</span> <span class="n">object_type_loaded</span><span class="p">,</span></pre></td>
  </tr>

  <tr>
    <th bgcolor="#e9eaa8" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">1064</font></th>
    <td bgcolor="#fdfebc" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="tb">  </span><span class="tb">  </span><span class="n">ao2_cleanup</span><span class="p">(</span><span class="n">invocation</span><span class="p">);</span></pre></td>
    <th bgcolor="#e9eaa8" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2">1258</font></th>
    <td bgcolor="#fdfebc" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="tb">  </span><span class="n">details</span><span class="o">-></span><span class="n">sorcery</span><span class="o">-></span><span class="n">module_name</span><span class="p">,</span> <span class="n">details</span><span class="o">-></span><span class="n">sorcery</span><span class="p">,</span> <span class="n">type</span><span class="o">-></span><span class="n">name</span><span class="p">,</span> <span class="n">details</span><span class="o">-></span><span class="n">reload</span><span class="p">);</span></pre></td>
  </tr>

 </tbody>


 
 

 <tbody>

  <tr>
    <th bgcolor="#ebb1ba" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">1065</font></th>
    <td bgcolor="#ffc5ce" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="tb">  </span><span class="p">}</span></pre></td>
    <th bgcolor="#ebb1ba" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2"></font></th>
    <td bgcolor="#ffc5ce" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
  </tr>

  <tr>
    <th bgcolor="#ebb1ba" style="border-right: 1px solid #C0C0C0;" align="right"><font size="2">1066</font></th>
    <td bgcolor="#ffc5ce" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "><span class="tb">   </span><span class="p">}</span></pre></td>
    <th bgcolor="#ebb1ba" style="border-left: 1px solid #C0C0C0; border-right: 1px solid #C0C0C0;" align="right"><font size="2"></font></th>
    <td bgcolor="#ffc5ce" width="50%"><pre style="font-size: 8pt; line-height: 140%; margin: 0; "></pre></td>
  </tr>

 </tbody>

</table>

  <pre style="white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">This particular observer's invocation was pushed to the taskprocessor.  Do the replacement(s)/new observers need to be as well?  What are the implications of not doing so? For instance, what if one is long running or expected to be ran in another thread. But if you schedule all on the task processor then that might be a problem for the "loading" types.  Thoughts?</pre>
 </blockquote>





</blockquote>
<pre style="margin-left: 1em; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">The existing observers remain intact - as pushes to the taskprocessor.  The new observers don't replace any existing observer are purposefully invoked synchronously.

The existing observers are more fine grained to include object level create, update and delete and it makes sense (maybe) for them to be run asynchronously.  I'm not sure whether there's any benefit to them being asynchronous but there's no functionality that needs them to be synchronous so there's no point in messing with them.

The new observers are more coarse grained (no lower than object type as opposed to object) and are generally not called again once asterisk has finished loading or re-loading.  The first use case for them though is the new pjsip config wizard which does require the observers to be synchronous.  For instance, the pattern for sorcery use is to call ast_sorcery_object_register, register a bunch of fields, then call ast_sorcery_load_object.  If the registered observer is still running in the background when the main thread does the load on that same object type, things are going to get ugly because the registered observer is doing things that will affect the load.







</pre>
<br />




<p>- George</p>


<br />
<p>On December 3rd, 2014, 10:36 a.m. MST, George Joseph wrote:</p>








<table bgcolor="#fefadf" width="100%" cellspacing="0" cellpadding="8" style="background-image: url('https://reviewboard.asterisk.org/static/rb/images/review_request_box_top_bg.ab6f3b1072c9.png'); background-position: left top; background-repeat: repeat-x; border: 1px black solid;">
 <tr>
  <td>

<div>Review request for Asterisk Developers and Joshua Colp.</div>
<div>By George Joseph.</div>


<p style="color: grey;"><i>Updated Dec. 3, 2014, 10:36 a.m.</i></p>









<div style="margin-top: 1.5em;">
 <b style="color: #575012; font-size: 10pt;">Repository: </b>
Asterisk
</div>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Description </h1>
 <table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">Interface for the global sorcery observer

/*! \brief Callback after an instance is created */
void (*instance_created)(const char *name, struct ast_sorcery *sorcery);

/*! \brief Callback after an wizard is registered */
void (*wizard_registered)(const char *name, const struct ast_sorcery_wizard *wizard);

/*! \brief Callback before a wizard is unregistered */
void (*wizard_unregistered)(const char *name, const struct ast_sorcery_wizard *wizard);

/*! \brief Callback before an instance is destroyed */
void (*instance_destroyed)(const char *name, struct ast_sorcery *sorcery);


Interface for the sorcery instance observer

/*! \brief Callback before instance is loaded/reloaded */
void (*instance_loading)(const char *name, const struct ast_sorcery *sorcery,
   int reloaded);

/*! \brief Callback after instance is loaded/reloaded */
void (*instance_loaded)(const char *name, const struct ast_sorcery *sorcery,
   int reloaded);

/*! \brief Callback after a wizard is mapped to an object_type */
void (*wizard_mapped)(const char *name, struct ast_sorcery *sorcery,
   const char *object_type, struct ast_sorcery_wizard *wizard, const char *wizard_args,
   void *wizard_data);

/*! \brief Callback after any obect_type is registered */
void (*object_type_registered)(const char *name, struct ast_sorcery *sorcery,
   const char *object_type);

/*! \brief Callback before any obect_type is loaded/reloaded */
void (*object_type_loading)(const char *name, const struct ast_sorcery *sorcery,
   const char *object_type, int reloaded);

/*! \brief Callback after any obect_type is loaded/reloaded */
void (*object_type_loaded)(const char *name, const struct ast_sorcery *sorcery,
   const char *object_type, int reloaded);


Interface for the sorcery wizard observer

/*! \brief Callback before a wizard is loaded/reloaded for any type */
void (*wizard_loading)(const char *name, const struct ast_sorcery_wizard *wizard,
   const char *object_type, int reloaded);

/*! \brief Callback after a wizard is loaded/reloaded for any type */
void (*wizard_loaded)(const char *name, const struct ast_sorcery_wizard *wizard,
   const char *object_type, int reloaded);


Add the following observer add/remove APIs

int ast_sorcery_global_observer_add(const struct ast_sorcery_global_observer *callbacks);
void ast_sorcery_global_observer_remove(const struct ast_sorcery_global_observer *callbacks);
int ast_sorcery_instance_observer_add(struct ast_sorcery *sorcery,
        const struct ast_sorcery_instance_observer *callbacks);
void ast_sorcery_instance_observer_remove(struct ast_sorcery *sorcery,
        const struct ast_sorcery_instance_observer *callbacks);
int ast_sorcery_wizard_observer_add(struct ast_sorcery_wizard *wizard,
        const struct ast_sorcery_wizard_observer *callbacks);
void ast_sorcery_wizard_observer_remove(struct ast_sorcery_wizard *wizard,
        const struct ast_sorcery_wizard_observer *callbacks);


Expose the following apply mapping APIs for future use...

enum ast_sorcery_apply_result __ast_sorcery_apply_wizard_mapping(struct ast_sorcery *sorcery,
                const char *type, const char *module, const char *name, const char *data, unsigned int caching);
#define ast_sorcery_apply_wizard_mapping(sorcery, type, name, data, caching) \
        __ast_sorcery_apply_wizard_mapping((sorcery), (type), AST_MODULE, (name), (data), (caching));


</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Testing </h1>
<table width="100%" bgcolor="#ffffff" cellspacing="0" cellpadding="10" style="border: 1px solid #b8b5a0">
 <tr>
  <td>
   <pre style="margin: 0; padding: 0; white-space: pre-wrap; white-space: -moz-pre-wrap; white-space: -pre-wrap; white-space: -o-pre-wrap; word-wrap: break-word;">All existing unit tests pass.
Additional sorcery units tests were added for the new observers.
Testsuite testing resulted in no new failures.
</pre>
  </td>
 </tr>
</table>


<h1 style="color: #575012; font-size: 10pt; margin-top: 1.5em;">Diffs</b> </h1>
<ul style="margin-left: 3em; padding-left: 0;">

 <li>branches/12/tests/test_sorcery.c <span style="color: grey">(428890)</span></li>

 <li>branches/12/main/sorcery.c <span style="color: grey">(428890)</span></li>

 <li>branches/12/include/asterisk/test.h <span style="color: grey">(428890)</span></li>

 <li>branches/12/include/asterisk/sorcery.h <span style="color: grey">(428890)</span></li>

</ul>

<p><a href="https://reviewboard.asterisk.org/r/4215/diff/" style="margin-left: 3em;">View Diff</a></p>







  </td>
 </tr>
</table>








  </div>
 </body>
</html>