<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 TRANSITIONAL//EN">
<HTML>
<HEAD>
  <META HTTP-EQUIV="Content-Type" CONTENT="text/html; CHARSET=UTF-8">
  <META NAME="GENERATOR" CONTENT="GtkHTML/4.2.3">
</HEAD>
<BODY>
Thanks for you help.<BR>
<BR>
On Thu, 2012-03-29 at 11:36 +0200, Miklos Tirpak wrote:
<BLOCKQUOTE TYPE=CITE>
<PRE>
On 03/29/2012 11:31 AM, Peter Dunkley wrote:
&gt; Hi,
&gt;
&gt; I have tried the fix and it worked. I tried it both with and without the
&gt; append_branch() call, and both cases worked. Is this what you would expect?

Yes. append_branch() is probably not important in your case because you 
do not modify the RURI and do not forward the request anywhere. It is 
safe to omit that, t_suspend() increases the branch number of the 
transaction automatically.

Miklos

&gt;
&gt; Thanks,
&gt;
&gt; Peter
&gt;
&gt; On Thu, 2012-03-29 at 11:01 +0200, Miklos Tirpak wrote:
&gt;&gt; Hi,
&gt;&gt;
&gt;&gt; I think the problem was in the check made by t_continue() which verifies
&gt;&gt; whether or not a new branch was added, the check ignored the pending
&gt;&gt; &quot;blind UAC&quot;, i.e. the new branch added by the subsequent t_suspend().
&gt;&gt; This explains why the first t_continue() killed the transaction and why
&gt;&gt; after the second t_suspend(). Thanks a lot for the logs!
&gt;&gt;
&gt;&gt; I have committed a fix into master
&gt;&gt; (9ae149ba25ee6467da1d95dd435995b9a59166a3), could you please try it?
&gt;&gt;
&gt;&gt; Miklos
&gt;&gt;
&gt;&gt; On 03/28/2012 04:52 PM, Peter Dunkley wrote:
&gt;&gt; &gt;  Hello again,
&gt;&gt; &gt;
&gt;&gt; &gt;  I took a quick look at the code in dset.c:append_branch(). This appears
&gt;&gt; &gt;  to update the global variable nr_branches, but the check in
&gt;&gt; &gt;  t_suspend.c:t_continue() is against t-&gt;nr_of_outgoings. There are no
&gt;&gt; &gt;  calls into the tm module in the PRESENCE_DISTRIBUTE and PRESENCE_ENQUEUE
&gt;&gt; &gt;  routes except for t_suspend(), so I suspect that the call to
&gt;&gt; &gt;  append_branch() didn't work because the updated nr_branches value was
&gt;&gt; &gt;  not used to update t-&gt;nr_of_outgoings. Should this be what happens?
&gt;&gt; &gt;
&gt;&gt; &gt;  Does this make sense? Is there a simple work-around for this?
&gt;&gt; &gt;
&gt;&gt; &gt;  Thanks,
&gt;&gt; &gt;
&gt;&gt; &gt;  Peter
&gt;&gt; &gt;
&gt;&gt; &gt;  On Wed, 2012-03-28 at 15:30 +0100, Peter Dunkley wrote:
&gt;&gt; &gt;&gt;  Hi,
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;  The append_branch() hasn't helped.
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;  Having looked a bit more closely, I think what I said at the end of my
&gt;&gt; &gt;&gt;  last email was not quite right.
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;  The t_continue() that kills the transaction is actually the first one.
&gt;&gt; &gt;&gt;  However, it only kills the transaction (causing a 500 to be sent)
&gt;&gt; &gt;&gt;  after it has been successfully suspended. What this means is that the
&gt;&gt; &gt;&gt;  second t_continue() seems to manage to resume the transaction (despite
&gt;&gt; &gt;&gt;  it having previously been killed), but at this point the presence APIs
&gt;&gt; &gt;&gt;  go wrong because the transaction cannot be statefully replied to. Here
&gt;&gt; &gt;&gt;  is some log content:
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;      1: Mar 28 12:02:28 pd-laptop-linux kamailio[16424]: INFO:
&gt;&gt; &gt;&gt;      &lt;script&gt;: presence: Found queued transaction [57508:831770136]
&gt;&gt; &gt;&gt;      2: Mar 28 12:02:28 pd-laptop-linux kamailio[16424]: INFO:
&gt;&gt; &gt;&gt;      &lt;script&gt;: PUBLISH: route[PRESENCE_DISTRIBUTE]
&gt;&gt; &gt;&gt;      3: Mar 28 12:02:28 pd-laptop-linux kamailio[16424]: INFO:
&gt;&gt; &gt;&gt;      &lt;script&gt;: Adding to queue: presenceWorker4
&gt;&gt; &gt;&gt;      4: Mar 28 12:02:28 pd-laptop-linux kamailio[16424]: WARNING:
&gt;&gt; &gt;&gt;      &lt;script&gt;: PUBLISH: route[PRESENCE_ENQUEUE]
&gt;&gt; &gt;&gt;      5: Mar 28 12:02:28 pd-laptop-linux kamailio[16424]: INFO:
&gt;&gt; &gt;&gt;      &lt;script&gt;: Suspended transaction for PUBLISH [57508:831770136]
&gt;&gt; &gt;&gt;      6: Mar 28 12:02:28 pd-laptop-linux kamailio[16424]: ERROR: tm
&gt;&gt; &gt;&gt;      [t_suspend.c:223]: branch == t-&gt;nr_of_outgoings
&gt;&gt; &gt;&gt;      7: Mar 28 12:02:28 pd-laptop-linux kamailio[16470]: ERROR: pua
&gt;&gt; &gt;&gt;      [pua_db.c:905]: no rows deleted
&gt;&gt; &gt;&gt;      8: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: WARNING:
&gt;&gt; &gt;&gt;      &lt;script&gt;: presenceWorker4: found queued transaction [57508:831770136]
&gt;&gt; &gt;&gt;      9: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: WARNING:
&gt;&gt; &gt;&gt;      &lt;script&gt;: PUBLISH: route[PRESENCE]: presenceWorker4
&gt;&gt; &gt;&gt;      10: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR: tm
&gt;&gt; &gt;&gt;      [t_reply.c:591]: ERROR: _reply_light: can't generate 200 reply
&gt;&gt; &gt;&gt;      when a final 500 was sent out
&gt;&gt; &gt;&gt;      11: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR: sl
&gt;&gt; &gt;&gt;      [sl.c:270]: failed to reply stateful (tm)
&gt;&gt; &gt;&gt;      12: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR:
&gt;&gt; &gt;&gt;      presence [presentity.c:154]: sending reply
&gt;&gt; &gt;&gt;      13: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR:
&gt;&gt; &gt;&gt;      presence [presentity.c:400]: sending 200OK
&gt;&gt; &gt;&gt;      14: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR:
&gt;&gt; &gt;&gt;      presence [publish.c:487]: when updating presentity
&gt;&gt; &gt;&gt;      15: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR: tm
&gt;&gt; &gt;&gt;      [t_reply.c:591]: ERROR: _reply_light: can't generate 500 reply
&gt;&gt; &gt;&gt;      when a final 500 was sent out
&gt;&gt; &gt;&gt;      16: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR: sl
&gt;&gt; &gt;&gt;      [sl.c:270]: failed to reply stateful (tm)
&gt;&gt; &gt;&gt;      17: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR:
&gt;&gt; &gt;&gt;      presence [utils_func.c:146]: sending 500 Server Internal Error reply
&gt;&gt; &gt;&gt;      18: Mar 28 12:02:28 pd-laptop-linux kamailio[16412]: ERROR:
&gt;&gt; &gt;&gt;      presence [publish.c:517]: failed to send error reply
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;  The scenario here is that pua_usrloc sends a PUBLISH to the local
&gt;&gt; &gt;&gt;  Kamailio instance. Line 7 is the pua module handling the 500 response
&gt;&gt; &gt;&gt;  sent by t_continue(). Lines 10 through 18 are presence getting the
&gt;&gt; &gt;&gt;  PUBLISH, handling it properly (updating the DB and so on), but then
&gt;&gt; &gt;&gt;  failing to respond, because a 500 has already been sent for the
&gt;&gt; &gt;&gt;  transaction.
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;  Thanks,
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;  Peter
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;&gt;  On Wed, 2012-03-28 at 14:44 +0100, Peter Dunkley wrote:
&gt;&gt; &gt;&gt;&gt;  Hi,
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  I am not relaying or replying to messages directly here - except in
&gt;&gt; &gt;&gt;&gt;  the error case. I am using the t_suspend()/t_continue() along with
&gt;&gt; &gt;&gt;&gt;  the presence and RLS APIs. So what I have is the following:
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;      #!substdef&quot;!PRESENCE_PROCESS_SLEEP!100000!g&quot;
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;mqueue&quot;,&quot;mqueue&quot;,&quot;name=presence&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;timer&quot;,&quot;name=presenceMaster;interval=PRESENCE_PROCESS_SLEEPu;mode=1;&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;exec&quot;,&quot;timer=presenceMaster;route=PRESENCE_MASTER_PROCESS&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;mqueue&quot;,&quot;mqueue&quot;,&quot;name=presenceWorker0&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;timer&quot;,&quot;name=presenceWorker0;interval=1u;mode=1;&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;exec&quot;,&quot;timer=presenceWorker0;route=PRESENCE_WORKER_PROCESS&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;mqueue&quot;,&quot;mqueue&quot;,&quot;name=presenceWorker1&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;timer&quot;,&quot;name=presenceWorker1;interval=1u;mode=1;&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;exec&quot;,&quot;timer=presenceWorker1;route=PRESENCE_WORKER_PROCESS&quot;)
&gt;&gt; &gt;&gt;&gt;      ...
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;mqueue&quot;,&quot;mqueue&quot;,&quot;name=presenceWorkern&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;timer&quot;,&quot;name=presenceWorkern;interval=1u;mode=1;&quot;)
&gt;&gt; &gt;&gt;&gt;      modparam(&quot;rtimer&quot;,&quot;exec&quot;,&quot;timer=presenceWorkern;route=PRESENCE_WORKER_PROCESS&quot;)
&gt;&gt; &gt;&gt;&gt;      ...
&gt;&gt; &gt;&gt;&gt;      route {
&gt;&gt; &gt;&gt;&gt;              ...
&gt;&gt; &gt;&gt;&gt;              # Some logic to determine this is a presence request (within or without dialog)
&gt;&gt; &gt;&gt;&gt;              $var(queue) =&quot;presence&quot;;
&gt;&gt; &gt;&gt;&gt;              route(PRESENCE_ENQUEUE);
&gt;&gt; &gt;&gt;&gt;              ...
&gt;&gt; &gt;&gt;&gt;      }
&gt;&gt; &gt;&gt;&gt;      ...
&gt;&gt; &gt;&gt;&gt;      route[PRESENCE_ENQUEUE] {
&gt;&gt; &gt;&gt;&gt;                      xlog(&quot;L_WARN&quot;,&quot;$rm: route[PRESENCE_ENQUEUE]\n&quot;);
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      if (!t_suspend()) {
&gt;&gt; &gt;&gt;&gt;                                      t_reply(&quot;500&quot;,&quot;Server Internal Error&quot;);
&gt;&gt; &gt;&gt;&gt;                                      xlog(&quot;L_ERR&quot;,&quot;Failed to suspend transaction for $rm\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                      exit;
&gt;&gt; &gt;&gt;&gt;                      }
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      xlog(&quot;L_INFO&quot;,&quot;Suspended transaction for $rm [$T(id_index):$T(id_label)]\n&quot;);
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      if (!mq_add(&quot;$var(queue)&quot;,&quot;$T(id_index)&quot;,&quot;$T(id_label)&quot;)) {
&gt;&gt; &gt;&gt;&gt;                                      t_reply(&quot;500&quot;,&quot;Server Internal Error&quot;);
&gt;&gt; &gt;&gt;&gt;                                      xlog(&quot;L_ERR&quot;,&quot;Failed to queue transaction for $rm [$T(id_index):$T(id_label)] on $var(queue)\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                      exit;
&gt;&gt; &gt;&gt;&gt;                      }
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      exit;
&gt;&gt; &gt;&gt;&gt;      }
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;      route[PRESENCE_MASTER_PROCESS] {
&gt;&gt; &gt;&gt;&gt;                      xlog(&quot;L_INFO&quot;,&quot;Running PRESENCE_MASTER_PROCESS\n&quot;);
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      while (mq_fetch(&quot;presence&quot;)) {
&gt;&gt; &gt;&gt;&gt;                                      $var(id_index) = (int) $mqk(presence);
&gt;&gt; &gt;&gt;&gt;                                      $var(id_label) = (int) $mqv(presence);
&gt;&gt; &gt;&gt;&gt;                                      xlog(&quot;L_INFO&quot;,&quot;presence: Found queued transaction [$var(id_index):$var(id_label)]\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                      t_continue(&quot;$var(id_index)&quot;,&quot;$var(id_label)&quot;,&quot;PRESENCE_DISTRIBUTE&quot;);
&gt;&gt; &gt;&gt;&gt;                      }
&gt;&gt; &gt;&gt;&gt;      }
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;      route[PRESENCE_DISTRIBUTE] {
&gt;&gt; &gt;&gt;&gt;                      xlog(&quot;L_WARN&quot;,&quot;$rm: route[PRESENCE_DISTRIBUTE]\n&quot;);
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      # Some algorithm to distribute traffic across queues...
&gt;&gt; &gt;&gt;&gt;              # Perhaps on request type (so we have a NOTIFIER that
&gt;&gt; &gt;&gt;&gt;              # sends NOTIFY requests in order), perhaps on some form
&gt;&gt; &gt;&gt;&gt;              # of hash...    I am experimenting with this...
&gt;&gt; &gt;&gt;&gt;                      $var(queue) =&quot;presenceWorker&quot;   + $var(queue_number);
&gt;&gt; &gt;&gt;&gt;                      xlog(&quot;L_INFO&quot;,&quot;Adding to queue: $var(queue)\n&quot;);
&gt;&gt; &gt;&gt;&gt;                      route(PRESENCE_ENQUEUE);
&gt;&gt; &gt;&gt;&gt;      }
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;      route[PRESENCE_WORKER_PROCESS] {
&gt;&gt; &gt;&gt;&gt;                      lock(&quot;pres&quot;);
&gt;&gt; &gt;&gt;&gt;                      $var(pres) = $shv(pres);
&gt;&gt; &gt;&gt;&gt;                      $shv(pres) = $shv(pres) + 1;
&gt;&gt; &gt;&gt;&gt;                      unlock(&quot;pres&quot;);
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      $var(queue) =&quot;presenceWorker&quot;   + $var(pres);
&gt;&gt; &gt;&gt;&gt;                      xlog(&quot;L_WARN&quot;,&quot;Starting process: $var(queue) (pid: $pp)\n&quot;);
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      while (1) {
&gt;&gt; &gt;&gt;&gt;                                      while (mq_fetch($var(queue))) {
&gt;&gt; &gt;&gt;&gt;                                                      $var(id_index) = (int) $mqk($var(queue));
&gt;&gt; &gt;&gt;&gt;                                                      $var(id_label) = (int) $mqv($var(queue));
&gt;&gt; &gt;&gt;&gt;                                                      xlog(&quot;L_WARN&quot;,&quot;$var(queue): found queued transaction [$var(id_index):$var(id_label)]\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                                      t_continue(&quot;$var(id_index)&quot;,&quot;$var(id_label)&quot;,&quot;PRESENCE&quot;);
&gt;&gt; &gt;&gt;&gt;                                      }
&gt;&gt; &gt;&gt;&gt;                                      usleep(PRESENCE_PROCESS_SLEEP);
&gt;&gt; &gt;&gt;&gt;                      }
&gt;&gt; &gt;&gt;&gt;      }
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;      route[PRESENCE] {
&gt;&gt; &gt;&gt;&gt;                      xlog(&quot;L_WARN&quot;,&quot;$rm: route[PRESENCE]: $var(queue)\n&quot;);
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;                      if (is_method(&quot;NOTIFY&quot;)) {
&gt;&gt; &gt;&gt;&gt;                                      xlog(&quot;L_INFO&quot;,&quot;Sending NOTIFY to RLS\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                      rls_handle_notify();
&gt;&gt; &gt;&gt;&gt;                      } else if (is_method(&quot;PUBLISH&quot;)) {
&gt;&gt; &gt;&gt;&gt;                                      xlog(&quot;L_INFO&quot;,&quot;Sending PUBLISH to Presence\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                      handle_publish();
&gt;&gt; &gt;&gt;&gt;                      } else if (is_method(&quot;SUBSCRIBE&quot;)) {
&gt;&gt; &gt;&gt;&gt;                                      xlog(&quot;L_INFO&quot;,&quot;Sending SUBSCRIBE to RLS\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                      $var(ret_code) = rls_handle_subscribe();
&gt;&gt; &gt;&gt;&gt;                                      if ($var(ret_code) == 10) {
&gt;&gt; &gt;&gt;&gt;                                                      xlog(&quot;L_INFO&quot;,&quot;     SUBSCRIBE not for RLS - sending to Presence\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                                      handle_subscribe();
&gt;&gt; &gt;&gt;&gt;                                      }
&gt;&gt; &gt;&gt;&gt;                      } else {
&gt;&gt; &gt;&gt;&gt;                                      xlog(&quot;L_ERR&quot;,&quot;Received non-(NOTIFY|PUBLISH|SUBSCRIBE) request from presence queue\n&quot;);
&gt;&gt; &gt;&gt;&gt;                                      t_reply(&quot;500&quot;,&quot;Server Internal Error&quot;);
&gt;&gt; &gt;&gt;&gt;                      }
&gt;&gt; &gt;&gt;&gt;              exit;
&gt;&gt; &gt;&gt;&gt;      }
&gt;&gt; &gt;&gt;&gt;      ...
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  Previously, I had just a single queue&quot;presence&quot;  which all of the
&gt;&gt; &gt;&gt;&gt;  presence worker process took requests from. This meant that
&gt;&gt; &gt;&gt;&gt;  t_suspend()/t_continue() was used just once and this worked (the
&gt;&gt; &gt;&gt;&gt;  presence/RLS APIs respond to the requests statefully). The reason for
&gt;&gt; &gt;&gt;&gt;  doing this in the first place is that I was getting problems with
&gt;&gt; &gt;&gt;&gt;  back-end RLS traffic all using a single TCP connection, which meant
&gt;&gt; &gt;&gt;&gt;  all the back-end presence requests were being handled by the same
&gt;&gt; &gt;&gt;&gt;  Kamailio process, which caused a bottleneck (using UDP causes a
&gt;&gt; &gt;&gt;&gt;  different set of problems under load and isn't really an option).
&gt;&gt; &gt;&gt;&gt;  Although the queue is a FIFO the fact that different processes could
&gt;&gt; &gt;&gt;&gt;  take different amounts of time means that things were happening out
&gt;&gt; &gt;&gt;&gt;  of order (Klaus and Anca have had a discussion about just this kind
&gt;&gt; &gt;&gt;&gt;  of issue with presence on the mailing list recently) and this is
&gt;&gt; &gt;&gt;&gt;  causing me problems.
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  What I have now (above) is presence requests being pulled from the
&gt;&gt; &gt;&gt;&gt;  TCP buffer and suspended as quickly as possible. A presenceMaster
&gt;&gt; &gt;&gt;&gt;  process then dequeues the request (continues it), performs some
&gt;&gt; &gt;&gt;&gt;  analysis to determine which worker should deal with it, and then
&gt;&gt; &gt;&gt;&gt;  suspends it again queuing it for the right worker. All of this works
&gt;&gt; &gt;&gt;&gt;  up until the t_continue() for the worker (in the
&gt;&gt; &gt;&gt;&gt;  PRESENCE_WORKER_PROCESS) is called. At this point the transaction is
&gt;&gt; &gt;&gt;&gt;  killed.
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  What I can't understand is why the first t_suspend()/t_continue()
&gt;&gt; &gt;&gt;&gt;  works here, but the second fails. My previous version of this (with
&gt;&gt; &gt;&gt;&gt;  the single queue and single t_suspend()/t_continue() call) worked
&gt;&gt; &gt;&gt;&gt;  fine, but it seems that the sequence of t_suspend(), t_continue(),
&gt;&gt; &gt;&gt;&gt;  t_suspend(), t_continue() - with no changes to or handling of the
&gt;&gt; &gt;&gt;&gt;  request in-between - fails.
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  Thanks,
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  Peter
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  On Wed, 2012-03-28 at 15:13 +0200, Miklos Tirpak wrote:
&gt;&gt; &gt;&gt;&gt;&gt;  Peter,
&gt;&gt; &gt;&gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  t_suspend() and t_continue() should work multiple times as long as they
&gt;&gt; &gt;&gt;&gt;&gt;  are executed sequentially after each other, i.e. there cannot be two
&gt;&gt; &gt;&gt;&gt;&gt;  branches suspended at the same time.
&gt;&gt; &gt;&gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  The error you get means to me that t_continue() executed the specified
&gt;&gt; &gt;&gt;&gt;&gt;  route block, but in that route, the request was neither replied nor a
&gt;&gt; &gt;&gt;&gt;&gt;  new branch was added. Hence, the transaction is hanging in memory and
&gt;&gt; &gt;&gt;&gt;&gt;  the module sees no pending branch that could return a reply later.
&gt;&gt; &gt;&gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  Make sure that in the route block executed by t_continue() there is
&gt;&gt; &gt;&gt;&gt;&gt;  either a t_reply() or you append a new branch and forward it with
&gt;&gt; &gt;&gt;&gt;&gt;  t_relay() (or append a new branch and call t_suspend() again). I think
&gt;&gt; &gt;&gt;&gt;&gt;  you also need to handle the failure of t_relay() and explicitly call
&gt;&gt; &gt;&gt;&gt;&gt;  t_reply() when t_relay() fails in this route.
&gt;&gt; &gt;&gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  Regards,
&gt;&gt; &gt;&gt;&gt;&gt;  Miklos
&gt;&gt; &gt;&gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  On 03/28/2012 02:21 PM, Daniel-Constantin Mierla wrote:
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   Hello,
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   I have been using it only once and didn't looked much deeper into the code.
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   Maybe Miklos (cc-ed) can give faster more details, afaik he is the
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   developer of that piece.
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   Cheers,
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   Daniel
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   On 3/28/12 1:13 PM, Peter Dunkley wrote:
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   Hi,
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   I am trying to use t_suspend()/t_continue() multiple times on the same
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   transaction. Calling t_suspend() more than once works, but the second
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   time I call t_continue() the transaction is killed and a 500 response
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   is sent. It is the&quot;if (branch == t-&gt;nr_of_outgoings)&quot;   check from the
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   code fragment below (from t_suspend.c:t_continue()) that results in
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   the transaction being killed - you can see the debug/error line I
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   added to determine this in the fragment.
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   Is using t_suspend()/t_continue() multiple times something that should
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   work?
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   Thanks,
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   Peter
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   if (t-&gt;uas.status&lt;   200) {
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   /* No final reply has been sent yet.
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   * Check whether or not there is any pending branch.
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   */
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   for ( branch = 0;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   branch&lt;   t-&gt;nr_of_outgoings;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   branch++
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   ) {
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   if ((t-&gt;uac[branch].request.buffer != NULL)
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   &amp;&amp;   (t-&gt;uac[branch].last_received&lt;   200)
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   )
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   break;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   }
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   if (branch == t-&gt;nr_of_outgoings) {
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   /* There is not any open branch so there is
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   * no chance that a final response will be received. */
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   ret = 0;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   LM_ERR(&quot;branch == t-&gt;nr_of_outgoings\n&quot;);
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   goto kill_trans;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   }
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   }
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   --
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   Peter Dunkley
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   Technical Director
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   Crocodile RCS Ltd
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   _______________________________________________
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   sr-dev mailing list
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   <A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>  &lt;<A HREF="mailto:sr-dev@lists.sip-router.org">mailto:sr-dev@lists.sip-router.org</A>&gt;   &lt;<A HREF="mailto:sr-dev@lists.sip-router.org">mailto:sr-dev@lists.sip-router.org</A>&gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;&gt;   <A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   --
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   Daniel-Constantin Mierla
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   Kamailio Advanced Training, April 23-26, 2012, Berlin, Germany
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;   <A HREF="http://www.asipto.com/index.php/kamailio-advanced-training/">http://www.asipto.com/index.php/kamailio-advanced-training/</A>
&gt;&gt; &gt;&gt;&gt;&gt;  &gt;
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;&gt;  _______________________________________________
&gt;&gt; &gt;&gt;&gt;  sr-dev mailing list
&gt;&gt; &gt;&gt;&gt;  <A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>  &lt;<A HREF="mailto:sr-dev@lists.sip-router.org">mailto:sr-dev@lists.sip-router.org</A>&gt;   &lt;<A HREF="mailto:sr-dev@lists.sip-router.org">mailto:sr-dev@lists.sip-router.org</A>&gt;
&gt;&gt; &gt;&gt;&gt;  <A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
&gt;&gt; &gt;&gt;&gt;
&gt;&gt; &gt;&gt;  _______________________________________________
&gt;&gt; &gt;&gt;  sr-dev mailing list
&gt;&gt; &gt;&gt;  <A HREF="mailto:sr-dev@lists.sip-router.org">sr-dev@lists.sip-router.org</A>  &lt;<A HREF="mailto:sr-dev@lists.sip-router.org">mailto:sr-dev@lists.sip-router.org</A>&gt;   &lt;<A HREF="mailto:sr-dev@lists.sip-router.org">mailto:sr-dev@lists.sip-router.org</A>&gt;
&gt;&gt; &gt;&gt;  <A HREF="http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev">http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev</A>
&gt;&gt; &gt;&gt;
&gt;&gt; &gt;  --
&gt;&gt; &gt;  Peter Dunkley
&gt;&gt; &gt;  Technical Director
&gt;&gt; &gt;  Crocodile RCS Ltd
&gt;&gt; &gt;
&gt;
&gt; --
&gt; Peter Dunkley
&gt; Technical Director
&gt; Crocodile RCS Ltd
&gt;
</PRE>
</BLOCKQUOTE>
<BR>
<TABLE CELLSPACING="0" CELLPADDING="0" WIDTH="100%">
<TR>
<TD>
<PRE>
-- 
Peter Dunkley
Technical Director
Crocodile RCS Ltd
</PRE>
</TD>
</TR>
</TABLE>
</BODY>
</HTML>