<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">Wow you don't make this easy on us ;)<br>
      <br>
      Killing the thread/thread pool is probably a bad idea.&nbsp; It may be
      cleaner to make the anonymous runner classes in RestAdatper into
      static classes which implement Runnable and provide a cancel
      method.&nbsp; In the RestAdapter you could do some bookkeeping to
      provide references to the Threads so you can call cancel on each
      one which is currently running.<br>
      <br>
      Also, the LoaderAdapters will need a different solution (but
      theirs is MUCH easier, you just call cancelLoader and implement
      onCancel in the Loader implementations).<br>
      <br>
      Summers<br>
      <br>
      PS bookkeeping is one of my favorite words.<br>
      <br>
      <br>
      On 08/14/2013 03:36 PM, Yavuz Selim YILMAZ wrote:<br>
    </div>
    <blockquote
      cite="mid:59B896C9-A770-45B4-8536-F1BC581F2DA7@buffalo.edu"
      type="cite">
      <meta http-equiv="Content-Type" content="text/html;
        charset=ISO-8859-1">
      <div>Hi all,</div>
      <div><br>
      </div>
      <div>I am working on AGDROID-11 [<a moz-do-not-send="true"
          href="https://issues.jboss.org/browse/AGDROID-11">https://issues.jboss.org/browse/AGDROID-11</a>].
        As suggested on the JIRA, I started with investigating how
        AeroGear iOS handles pipe cancel operation.</div>
      <div><br>
      </div>
      <div>-----------------------------------------------------------------------</div>
      <div>---- Skip if you don't want to verify my iOS tracking ----</div>
      <div>-----------------------------------------------------------------------</div>
      <div>------------------------------ Start
        ---------------------------------</div>
      <div>-----------------------------------------------------------------------</div>
      <div><br>
      </div>
      <div>First, here is what I could track on the iOS side (please
        correct me if there's any mistake):</div>
      <div><br>
      </div>
      <div>- AGRESTPipe cancel method simply calls the
        cancelAllOperations on its restClient's operationQueue [1].</div>
      <div>- AGRESTPipe's restClient is a AGHttpClient [2].</div>
      <div>- AGHttpClient is a AFHttpClient [3].</div>
      <div>- AFHttpClient's operationQueue is a NSOperationQueue [4].</div>
      <div>- Calling cancelAllOperations on NSOperationQueue sends
        cancel message to all Operations in the queue [5]. If the
        operation is still in the queue (waiting to be executed), they
        are not being executed. If the operation is alread started to
        it's execution, it's up to the "Operation" how to respond to
        cancel message.</div>
      <div>- Sending cancel message to operations sets their isCancelled
        flag. Any custom NSOperation extension is recommended to handle
        this cancel operation [6].</div>
      <div>- AGHttpClient creates the operation by calling
        HTTPRequestOperationWithRequest [7], which is AFHttpClient
        method. It creates either custom (AFImage, AFJSON,
        AFPropertyList, AFXML) operation [8] or AFHttpRequestOperation
        [9]. All custom operations are AFHttpRequestOperation, which is
        a AFURLConnectionOperation [10].</div>
      <div>- AFURLConnectionOperation implements cancel method [11] and
        simply cancels the operation's NSURLConnection, the connection
        is cancelled and no delegate is called [12].</div>
      <div>- Then AFURLConnectionOperation calls its delegate method
        manually to finish the operation [13].</div>
      <div>- The delegate handles the case [14] and finishes the
        operation [15].</div>
      <div><br>
      </div>
      <div>-----------------------------------------------------------------------</div>
      <div>------------------------------- End
        ---------------------------------</div>
      <div>-----------------------------------------------------------------------</div>
      <div>---- Skip if you don't want to verify my iOS tracking ----</div>
      <div>-----------------------------------------------------------------------</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>Simply, what I understand is, operation itself is responsible
        to handle the cancel message sent by any pipe implementation.
        And on the Android side, the operations are runnables [16, 17,
        18, 19] as far as I could interpret. So, these runnables should
        be able to handle cancel messages which means they should catch
        or throw the thrown InterruptedException.</div>
      <div><br>
      </div>
      <div>So, the problem is, find a way to send cancel message to the
        tasks, and handle the cancel message on the tasks.</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>HOW TO SEND CANCEL MESSAGE TO THE TASKS?</div>
      <div><br>
      </div>
      <div>1ST PROPOSAL:</div>
      <div><br>
      </div>
      <div>RestAdapter is using ThreadPoolExecutor [20]. So, one way to
        send cancel message to all running and queued runnables is to
        call shutDownNow on the ThreadPoolExecutor [21]. It has some
        limitations. First, shut down destroys the ThreadPoolExecutor,
        so it needs to be recreated. Second, the current
        ThredPoolExecutor is static, means it will cancel all pipes if
        it is shut down, so it needs to be an instance variable instead
        of static.</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>2ND PROPOSAL:</div>
      <div><br>
      </div>
      <div>Instead of calling THREAD_POOL_EXECUTOR.execute(), if we call
        THREAD_POOL_EXECUTOR.submit() [22], then it returns a Future
        representing the task. Future has cancel() [23], which prevents
        running the task if it is not started, and interrupts the task
        if it is currently running. Therefore, if we have a collection
        of &lt;Future&gt; in RestAdapter (i.e. pipe), then we can cancel
        the operations by iterating over the collection and calling
        cancel() on each Future. In this case, at some point, we need to
        clean &lt;Future&gt; collection to get rid of the already
        cancelled tasks.</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>HOW TO HANDLE THE CANCEL MESSAGE ON THE TASKS?</div>
      <div><br>
      </div>
      <div>I could only come up with a single solution, which is, adding
        another catch block to each of the runnables [16, 17, 18, 19].
        Here is what it will look like:</div>
      <div><br>
      </div>
      <div>try {</div>
      <div>&nbsp; &nbsp; this.result = ...</div>
      <div>} catch (InterruptedException e) {</div>
      <div>&nbsp; &nbsp; return; // don't call the callbacks, may need to check
        the cause of the interrupt???</div>
      <div>} catch (Exception e) {</div>
      <div>&nbsp; &nbsp; Log.e(TAG, e.getMessage(), e);</div>
      <div>&nbsp; &nbsp; this.exception = e;</div>
      <div>}</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>So, I would like to hear what you think about my solution,
        and if you have any corrections, better solutions, comments,
        anything... All are most welcome.</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>Kind regards,</div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div><br>
      </div>
      <div>--- REFERENCES ---</div>
      <div>[1] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/pipeline/AGRESTPipe.m#L283">https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/pipeline/AGRESTPipe.m#L283</a></div>
      <div>[2] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/pipeline/AGRESTPipe.m#L71">https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/pipeline/AGRESTPipe.m#L71</a></div>
      <div>[3] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/core/AGHttpClient.h#L21">https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/core/AGHttpClient.h#L21</a></div>
      <div>[4] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m#L189">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m#L189</a></div>
      <div>[5] <a moz-do-not-send="true"
href="http://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html#//apple_ref/occ/instm/NSOperationQueue/cancelAllOperations">http://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Reference/NSOperationQueue_class/Reference/Reference.html#//apple_ref/occ/instm/NSOperationQueue/cancelAllOperations</a></div>
      <div>[6] <a moz-do-not-send="true"
href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004591-RH2-SW18">http://developer.apple.com/library/mac/documentation/Cocoa/Reference/NSOperation_class/Reference/Reference.html#//apple_ref/doc/uid/TP40004591-RH2-SW18</a></div>
      <div>[7] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/core/AGHttpClient.m#L158">https://github.com/aerogear/aerogear-ios/blob/master/AeroGear-iOS/AeroGear-iOS/core/AGHttpClient.m#L158</a></div>
      <div>[8] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m#L554">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m#L554</a></div>
      <div>[9] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m#L560">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPClient.m#L560</a></div>
      <div>[10] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPRequestOperation.h#L29">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFHTTPRequestOperation.h#L29</a></div>
      <div>[11] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L548">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L548</a></div>
      <div>[12] <a moz-do-not-send="true"
href="http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/occ/instm/NSURLConnection/cancel">http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLConnection_Class/Reference/Reference.html#//apple_ref/occ/instm/NSURLConnection/cancel</a></div>
      <div>[13] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L573">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L573</a></div>
      <div>[14] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L760">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L760</a></div>
      <div>[15] <a moz-do-not-send="true"
href="https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L540">https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLConnectionOperation.m#L540</a></div>
      <div><br>
      </div>
      <div>[16] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L119">https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L119</a></div>
      <div>[17] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L146">https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L146</a></div>
      <div>[18] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L170">https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L170</a></div>
      <div>[19] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L198">https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L198</a></div>
      <div>[20] <a moz-do-not-send="true"
href="https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L50">https://github.com/aerogear/aerogear-android/blob/master/src/org/jboss/aerogear/android/impl/pipeline/RestAdapter.java#L50</a></div>
      <div>[21] <a moz-do-not-send="true"
href="http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html#shutdownNow%28%29">http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html#shutdownNow()</a></div>
      <div>[22] <a moz-do-not-send="true"
href="http://developer.android.com/reference/java/util/concurrent/AbstractExecutorService.html#submit%28java.lang.Runnable%29">http://developer.android.com/reference/java/util/concurrent/AbstractExecutorService.html#submit(java.lang.Runnable)</a></div>
      <div>[23] <a moz-do-not-send="true"
href="http://developer.android.com/reference/java/util/concurrent/Future.html#cancel%28boolean%29">http://developer.android.com/reference/java/util/concurrent/Future.html#cancel(boolean)</a></div>
      <div>
        <div style="color: rgb(0, 0, 0); font-family: Helvetica;
          font-size: medium; font-style: normal; font-variant: normal;
          font-weight: normal; letter-spacing: normal; line-height:
          normal; orphans: 2; text-align: -webkit-auto; text-indent:
          0px; text-transform: none; white-space: normal; widows: 2;
          word-spacing: 0px; -webkit-text-size-adjust: auto;
          -webkit-text-stroke-width: 0px; "><br
            class="Apple-interchange-newline">
          ---</div>
        <div style="color: rgb(0, 0, 0); font-family: Helvetica;
          font-size: medium; font-style: normal; font-variant: normal;
          font-weight: normal; letter-spacing: normal; line-height:
          normal; orphans: 2; text-align: -webkit-auto; text-indent:
          0px; text-transform: none; white-space: normal; widows: 2;
          word-spacing: 0px; -webkit-text-size-adjust: auto;
          -webkit-text-stroke-width: 0px; ">Yavuz Selim Yilmaz</div>
        <div style="color: rgb(0, 0, 0); font-family: Helvetica;
          font-size: medium; font-style: normal; font-variant: normal;
          font-weight: normal; letter-spacing: normal; line-height:
          normal; orphans: 2; text-align: -webkit-auto; text-indent:
          0px; text-transform: none; white-space: normal; widows: 2;
          word-spacing: 0px; -webkit-text-size-adjust: auto;
          -webkit-text-stroke-width: 0px; ">SUNY at Buffalo</div>
        <div style="color: rgb(0, 0, 0); font-family: Helvetica;
          font-size: medium; font-style: normal; font-variant: normal;
          font-weight: normal; letter-spacing: normal; line-height:
          normal; orphans: 2; text-align: -webkit-auto; text-indent:
          0px; text-transform: none; white-space: normal; widows: 2;
          word-spacing: 0px; -webkit-text-size-adjust: auto;
          -webkit-text-stroke-width: 0px; ">Computer Science and
          Engineering</div>
        <div style="color: rgb(0, 0, 0); font-family: Helvetica;
          font-size: medium; font-style: normal; font-variant: normal;
          font-weight: normal; letter-spacing: normal; line-height:
          normal; orphans: 2; text-align: -webkit-auto; text-indent:
          0px; text-transform: none; white-space: normal; widows: 2;
          word-spacing: 0px; -webkit-text-size-adjust: auto;
          -webkit-text-stroke-width: 0px; ">PhD Candidate</div>
      </div>
      <br>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">_______________________________________________
aerogear-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:aerogear-dev@lists.jboss.org">aerogear-dev@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/aerogear-dev">https://lists.jboss.org/mailman/listinfo/aerogear-dev</a></pre>
    </blockquote>
    <br>
  </body>
</html>