<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 30, 2015 at 4:45 PM, George Joseph <span dir="ltr"><<a href="mailto:george.joseph@fairview5.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=george.joseph@fairview5.com&cc=&bcc=&su=&body=','_blank','location=yes,menubar=yes,resizable=yes,width=800,height=600');return false;">george.joseph@fairview5.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Apr 30, 2015 at 3:59 PM, Joshua Colp <span dir="ltr"><<a href="mailto:jcolp@digium.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=jcolp@digium.com&cc=&bcc=&su=&body=','_blank','location=yes,menubar=yes,resizable=yes,width=800,height=600');return false;">jcolp@digium.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">George Joseph wrote:<br>
<br>
<snip><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
<br>
             What if contacts are stored in an external database? Your<br>
        proposal<br>
             would also have them going there as well. This would require an<br>
             explanation for deployers to know what is going on exactly<br>
        and what<br>
             they are. As well this means there would be a period of<br>
        time where<br>
             the permanent contacts would not be present if other<br>
        instances are<br>
             sharing the same database and one restarts.<br>
<br>
<br>
        They can't be today can they?  The dynamic ones are explicitly<br>
        mapped to<br>
        astdb and the permanent ones are explicitly placed in the aor based<br>
        container.  Can you even use sorcery.conf to map contacts<br>
        somewhere else<br>
        given that they're just strings in an aor?<br>
<br>
<br>
    You sure can.<br>
<br>
<br>
Who would even know they can do that besides you? :)<br>
</blockquote>
<br>
I believe there's a wiki page which details using PJSIP with realtime, and there's also the table in alembic.<br>
<br></blockquote><div><br></div><div>In general there is.  There aren't any specific instructions for contacts though. Permanent contacts specifically.  The ERD on the wiki shows contact but pjsip.conf.sample only mentions contacts in the context of aors.  There's no object mentioned.  If we took a poll, how many people would respond that they know they could define permanent contacts in realtime as separate objects. :)</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<snip><br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
             So. This is what I was originally trying to express when<br>
        you did the<br>
             wizard work, you've just gone about it in a different manner. I<br>
             think this is a rather specialized addition that could be<br>
        done in a<br>
             better way.<br>
<br>
             Right now sorcery wizards can't be programmatically added.<br>
        They just<br>
             can't. You have to do it from the sorcery.conf<br>
        configuration file.<br>
<br>
<br>
        Not true.  ast_sorcery_apply_wizard_mapping allows yo to add a<br>
        wizard to<br>
        any object type at run time.  That's what the config_wizard<br>
        does.  When<br>
        the object type registers, it adds a memory wizard to the object<br>
        type's<br>
        wizard list.  The config wizard then manipulates the memory wizard.<br>
<br>
<br>
    It adds a wizard but does not return a handle to it. It also doesn't<br>
    allow you to specify where to place it. It's always at the end.<br>
<br>
<br>
You don't need a handle, you have the wizard itself.  Correct on the order.<br>
</blockquote>
<br>
How? What I'm talking about is something like:<br></blockquote><div><br></div><div>You can get the wizard as a result of the wizard_mapped observer.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
int res;<br>
struct ast_sorcery_wizard *wizard;<br>
void *data;<br>
res = ast_sorcery_apply_explicit_wizard(sorcery, "endpoint", "memory", "", &wizard, &data);<br>
<br>
That function would explicit at a wizard to the front, and return the specific wizard interface and instance. Instant access to manipulate that specific instance with the CRUD interface and a guarantee of its position.<br>
<br></blockquote><div><br></div><div>Agreed and that's easy enough.  I'm not sure it helps any though.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
<br>
<br>
<br>
             What if they could be?<br>
             What if you could add a wizard that's marked as caching (so<br>
        it's<br>
             only queried) but still have a handle to it to<br>
        create/update/destroy?<br>
<br>
<br>
        You just described res_pjsip_config_wizard exactly.<br>
<br>
<br>
    Yes, except without having a direct handle and more control over<br>
    things you had to do it in an indirect manner.<br>
<br>
<br>
<br>
             Wrap that up in a higher level API like you want above and you<br>
             extend sorcery in a way that's useful in multiple ways.<br>
<br>
<br>
        Put the whole mutability thing aside for a minute.  I guess what I'm<br>
        suggesting that the default sorcery behavior could be an automatic<br>
        read/write cache in front of every sorcery wizard.  You can then<br>
        control<br>
        whether how writes are handled (if at all) by options you give<br>
        when you<br>
        register the object type, and options you give on CRUD calls.<br>
<br>
<br>
    I'm not a fan of automatic anything or complicating the sorcery core<br>
    any further. Higher level stuff built on top which has to be<br>
    explicitly done by users, yes.<br>
<br>
<br>
I think that's true in some cases but in others, you don't want "users"<br>
doing it 50 different ways where something carefully crafted at a lower<br>
level will do the trick.<br>
</blockquote>
<br>
No, I don't, but I also don't want the lower level sorcery core to become even more complex and have additional burden. Thin, simple (as much as possible), to the point. If higher level APIs exist which build on it to provide the functionality then I'm all for it.<br>
<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<br>
<br>
<br>
        For my contact scenario, I'd say writable cache and a writable<br>
        back end<br>
        (astdb by default).  When writing a new dynamic contact or<br>
        updating the<br>
        expiration, I'd say write-through.  When updating status, I'd say<br>
        cache-only.   For permanent contacts, it would always be cache-only.<br>
<br>
<br>
    So - stepping back and implementation details aside. What do we<br>
    need? In an ideal world how would the implementation work?<br>
<br>
<br>
Fair question.<br>
<br>
I want to CUD objects and decide whether the results of the operation<br>
should be temporary or persistent at the time I perform the operation.<br>
I don't want to have to create my own wizard some other specific<br>
implementation each time I need this capability.<br>
<br>
I want to dynamically create an object and not have to worry that the<br>
underlying wizard was res_sorcery_config and therefore doesn't support<br>
create.<br>
<br>
I want to update an object and call ast_sorcery_update without having to<br>
clone it.   It's my job to assess locking requirements.  It's sorcery's<br>
job to determine whether the object needs to be cloned.  A<br>
"get_for_update" might help there.  It could either lock it before<br>
giving it to you  or clone it before giving it to you.<br>
</blockquote>
<br>
This is even lower level then I was thinking of. Within the scope of contacts and contact status - what would be the best way for them to work?<br>
<br>
"When a contact status changes I need to be able to store this information"<br></blockquote><div><br></div><div>From who's perspective though?</div><div><br></div><div>When any contact is added, updated or deleted, I want the same observer to be called.  I don't want to have to code differently for permanent contacts vs dynamic contacts.<br></div><div><br></div><div><div>I want to create a temporary contact that sticks around until I delete it or Asterisk restarts.</div><div><br></div></div><div>I want to update a contact's status/rtt and indicate that the change should be discarded when Asterisk restarts.</div><div><br></div><div>I want to update expiration and indicate that the change should be permanent.</div><div><br></div><div>I don't want to care which wizards support CUD and which don't.</div><div><br></div><div><br></div></div></div></div></blockquote><div>Oh yeah.  I don't want a user to have to screw around with sorcery.conf to get basic behavior.</div><div><br></div><div> </div></div><br></div></div>