<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 4, 2013 at 3:53 PM, David M. Lee <span dir="ltr"><<a href="mailto:dlee@digium.com" target="_blank">dlee@digium.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div class="im"><div>On Dec 4, 2013, at 3:08 PM, Matthew Jordan <<a href="mailto:mjordan@digium.com" target="_blank">mjordan@digium.com</a>> wrote:</div>
<br></div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote"><div class="im">On Wed, Dec 4, 2013 at 2:56 PM, David M. Lee <span dir="ltr"><<a href="mailto:dlee@digium.com" target="_blank">dlee@digium.com</a>></span> wrote:<br>

</div><div class="im"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><div>
<br>Let’s be consistent and create a ChannelOriginated event. We can guarantee that this will be the first event for originated channels. It will have the appArgs and channel information, similar to the StasisStart event. The application can put a unique identifier in the application’s arguments in order to associate the originated channel with a request.</div>

</div></blockquote><div><br>This is basically what we have today, where you specify a UUID 
through a channel variable and then look for that identifier in 
subsequent events. This feels like a hack, not a solution.</div></div></div></div></div></blockquote><div><br></div>That depends on your point of view. Complicating the process of origination for these sorts of event ordering issues feels like more of a hack to me. Adding events and information to events to aid in coordination feels more natural.<br>
</div></div></blockquote><div><br></div><div>Information that ties events together is fine. However, as a user of the system, I would expect that the unique ID of the "thing" - whatever it is - is the only unique ID that either (a) I need to provide or (b) is provided to me by the system. Having two unique IDs - one that is returned by the system that acts as a handle to the resource and another user provided one to tie the responses back to the events feels wrong.<br>
<br></div><div>From a client perspective, it's more stuff to track and more things you have to use to tie things together. That's annoying and increases the processing burden on the client.<br><br></div><div>From a server implementation perspective - depending on the implementation - you can constrain your system if you require channels to have added metadata to function properly (from the client perspective). Each variable set requires a channel lookup in the channels container, which locks that container. If you're originating a lot of calls simultaneously, you're throwing a lot of extra locking into the mix that shouldn't strictly be necessary.<br>
<br></div><div>Furthermore, if you allow a client to supply the unique ID, you run into a lot of side issues we've historically not had to worry about, since the unique ID was generated by Asterisk. Maximum field lengths, implicit knowledge that the ID was created with the object, etc. These can all be worked around, but we'd still have to go through and work through all of the assumptions consumers of objects make about the type/nature of the various object's unique IDs.<br>
</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br></div><div>Giving it some thought, this problem may be more pervasive than we realized. You can get the same response/event ordering issues with playbacks and recordings. Going forward, any resource that 1) can be created via ARI and 2) has events associated with it could run into this same problem. If we follow this same pattern, then much of the API will be broken down into two-stage create/do-it invocations. Which *really* feels wrong to me.</div>
</div></blockquote><div><br></div><div>I can see that. Which adds credence to having the user supply the unique ID of the thing. I do think that channels are the most likely culprit of this problem - although as Matt DiMeo pointed out in another thread, this happens with playbacks as well.<br>
<br></div><div>For everything but channel unique IDs having a user supply the unique ID could possible work - the fact that channel unique IDs have historically been more than just a random number is what complicates the picture. There's probably a path forward to fixing linked ID propagation, as the rules for propagating the linked ID are based on channel creation time which can be extracted from another field - but people have always relied on the channel unique ID being a timestamp for a lot of things. There's a laundry list of e-mails on the -dev/-user lists where people have shown dialplans extracting the channel unique ID (or AMI/AGI scripts) to determine when the channel was created. We'll break a lot of people if we break that scheme - and if we allow a user to supply the ID, we've implicitly broken that scheme.<br>
<br></div><div>There's also the inevitable errors that will occur if someone supplies the same identifier twice. Hilarity will definitely ensue.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div style="word-wrap:break-word"><div><br></div><div>I think to come up with the correct solution we’ll have to think about how the API will be used by different programming environments.</div><div><br></div><div>There’s simple synchronous environments. In these environments, you actually don’t have a problem. In these environments, HTTP clients only offer synchronous interfaces that block until a response is received. You wouldn’t process any received events on the WebSocket until you’re done processing the response to your HTTP request. This works great for small, simple applications. But it won’t scale.</div>
<div><br></div><div>To scale, you need to build an asynchronous/event driven application (Node.js, Twisted, Akka, etc.). In these environments, you already have to deal with the asynchronous coordination of events. Because it’s such a part of problem of building these applications, the frameworks give you tools to help deal with coordination problems (futures, promises, deferrers, etc.).</div>
<div><br></div><div>What worries me will be the in-between land of multi-threaded applications. If you have one thread processing the WebSocket, and ARI invocations happening on a different thread, you’ll definitely find yourself in the land of things happening on one thread before you expect them to. And the frameworks aren’t very helpful in dealing with this, either.</div>
<br clear="all"></div></blockquote><div><br></div><div>I think we need to aim for those situations. The days of someone using Asterisk in a simple synchronous environment are pretty long behind us. <br></div></div><br>-- <br>
<div dir="ltr"><div>Matthew Jordan<br></div><div>Digium, Inc. | Engineering Manager</div><div>445 Jan Davis Drive NW - Huntsville, AL 35806 - USA</div><div>Check us out at: <a href="http://digium.com" target="_blank">http://digium.com</a> & <a href="http://asterisk.org" target="_blank">http://asterisk.org</a></div>
</div>
</div></div>