Hi Aleksander, I did a few tests, and this is what I learned:
1) Sending the provisional response definitely seems to mark the message for deletion, reclamation, whatever. I did a simple test of trying to send a final response from the main loop right after sending a 100 Trying and got the same "message could not be completed" message. So it has nothing to do with threading, and it definitely seems that stateless mode allows only for a single response. Is there any reason not to consider this a bug? Even though we are not dealing with transactions in stateless mode, a request is certainly able to have multiple provisional responses but only a single final one. 2) It does not appear that the stack automatically generates a 100 Trying in this case. I tested as you suggested, with a 2 second sleep in my clone task (allowing the main thread to continue running), but no 100 Trying was generated. 3) It appears that the main task must periodically yield the root object at times in order for a clone task to obtain it. I tried sending the response from my clone task, after first calling su_root_obtain, but the clone blocks forever on that call. This must be because my main thread is calling su_root_run and therefore has a lock/mutex on the root object. 4) In stateless mode, any retransmitted INVITEs that are received are sent up through the stack to my stateless callback, as expected. This means that my code by default would process the INVITE twice -- no big deal if I could generate 100 Trying responses since this would pretty much greatly mitigate the chance of receiving retransmissions in all but the case of network issues. Given point #3, what are the options for allowing clones to access the root object? As I mentioned in my earlier email, I don't view it as a particularly great solution if I have to release it every so many milliseconds in my main thread, because even that slight delay keeps clone tasks waiting to complete their work longer than necessary, and under serious load that would degrade performance. I guess if there are no other options I would keep with my current method of sending a reply message back to the root task and having all sending done from the main thread, as that seems to allow clones to perform more efficiently. As far as the choice of stateless vs stateful, I think I may play around with a stateful version to see what it is like, but I think stateless would be fine for my needs if I could figure out how to generate a 100 Trying. I'm really not forming a dialog anyways since each INVITE gets a final non-success response of one kind or another, so I'm not sure there is all that much value of having the stack manage transactions for me. Dave On Jan 4, 2010, at 9:32 AM, Aleksander Morgado wrote: > Hi Dave, > > Thanks Aleksander, I had actually seen your thread from some time ago and it > was what inspired me to take this general approach. So thanks twice! > > :-) > > > I have figured out some of my problem, and also have a few questions about > some of the suggestions below. First, after fiddling with my code, I see > that the problem only occurs if my main thread sends a 100 Trying using > msg_treply(). What I was doing is having the main thread receive the > message, discard it if is was an ACK or a response, respond with a final 501 > response if it was anything other than an INVITE, and if it was an INVITE > then first send a 100 Trying and then hand it off to a clone task via > su_msg_send. If I remove the sending of the 100 trying then everything works > (i.e., later the main thread is able to send a final response). The line > where I send the 100 trying in my main thread is simply: > > nta_msg_treply( nta, msg, SIP_100_TRYING, TAG_END() ) ; > > Is there any reason that sending a 100 Trying should prevent me from later > being able to send a final response on that same message object? > > If using a single-thread approach, does it also work ok? I mean, if you don't > use clone threads, and you send the 100 Trying first, and then the 200 OK, > all from the main thread, does it work? I am really not sure how the > stateless approach works with the non-final 100 reply. Maybe it is just that > you cannot send a non-final reply if you are using stateless approach. > > So, maybe the question is: is the message marked for removal when replied > with a provisional reply in a stateless approach? Actually... it is probably > something like that, as stateless approach doesn't know anything about > transactions, and a provisional reply is like a message inside the > transaction. > > > BTW, I would prefer to have the stack automatically send a 100 Trying to all > INVITEs, but I can't see how to do this with nta (I do see that there are > some nua tags that do this, but I assume I can't used those in nta). Is > there a way to do this? > > In fact, it is already done by the NTA agent. If your request processing > takes long enough, 100 Trying is automatically sent by the NTA agent, so you > don't need to take care of it. This happens for sure for stateful approach, > when using legs, but not sure for stateless approach. Moreover, it was added > some months ago an enhancement in the NTA to avoid sending the automatic 100 > Trying. You can try to spend a long time processing the request, maybe > forcing a sleep(10) in your code, and see if the NTA automatically replies > the 100 OK meanwhile. > > > Aleksander, I think I will try some of your suggestions, but had a few > questions: > > 1) In terms of obtaining and then releasing the root object from the clone, > you mention a scenario where the main thread should release/obtain if it is > doing other non-nta related stuff. In my case it is not doing any such other > stuff, just su_root_run(). Does that mean the clone will never be able to > obtain the root object, or that I need to do something to periodically > release the root object from the main thread (and that wouldn't be so great > if the clone had to wait even 100ms or so when it wanted to obtain the root). > > No, I don't think you need to do that. But, now that you say it, I am not > 100% sure... > > > 2) I chose stateless only because it seemed a bit simpler, but I may change > to using stateful. In your implementation did you simply create a single > default leg to use in the stateful mode, or did you explicitly create a leg > for each transaction? > > I started also with stateless approach in my code, and then just saw that > stateful was much better for my needs. In my implementation I have a default > leg for out-of-dialog transactions, and in the callback for that default leg > I would create a new specific leg for the dialog when needed. > > If you are processing INVITE requests, not forwarding them anywhere, you > should probably choose stateful approach, and create a new leg for each > generated dialog. Doing that you will be able to handle in-dialog requests > (like the BYE to terminate the dialog) directly in the specific leg created > for the dialog, for example, so no need to do it yourself. Also, not sure > about retransmissions, but if using a stateless approach, retransmissions of > same SIP message may be treated as different incoming messages, and not > filtered out by the NTA. > > > 3) How does stateless mode handle an incoming CANCEL? Does nta itself reply > with a 200 OK to the CANCEL and a 487 Request Terminated, or does the > application need to do that? > > > I believe you need to do that, but depending on what you actually are doing. > The example of stateless approach included in the sofia-sip documentation > says something about incoming CANCELs. In that example it says that, if you > are doing let's say a redirect server, you shouldn't process the CANCEL as > CANCELs will terminate transactions and your stateless approach doesn't know > anything about transactions. > > Cheers! > -Aleksander ------------------------------------------------------------------------------ This SF.Net email is sponsored by the Verizon Developer Community Take advantage of Verizon's best-in-class app development support A streamlined, 14 day to market process makes app distribution fast and easy Join now and get one step closer to millions of Verizon customers http://p.sf.net/sfu/verizon-dev2dev _______________________________________________ Sofia-sip-devel mailing list Sofia-sip-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/sofia-sip-devel