Problem with wait wait functions in Volley library (PriorityBlockingQueue.java)

I have a problem with the functionality of pending requests in the volleyball library. Debugging led me to the AbstractQueue class in java.util, where an element is added (according to some values ​​in the method that indicate a successful addition to the queue) and at the same time it is not added (according to 0 elements in the queue, this does not change their value). The add method is synchronized. Below you can find a detailed description of the situation and my research. I will be very grateful if you look at them and share, if you have an idea of ​​what is happening.

I am trying to automatically retry requests for any error (for example, when there is no connection or the server name is incorrect). The request error handler adds the request back to the static singleton RequestQueue of my application.

RetriableRequestWraper.java

m_request = new StringRequest( method, url, new Response.Listener<String>() { @Override public void onResponse(String response) { handleResponse(response); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { handleError(volleyError); } }); public void handleError(VolleyError volleyError) { Log.d("Request: ", m_request.toString()); Log.d("handleError: ", volleyError.toString()); if(retriesCount<3) { executeRequest(); ++retriesCount; } else { retriesCount = 0; } } public void executeRequest() { RequestsManager.getInstance().executeRequest(m_request); } public void executeRequest(Request request) { Log.d("executeRequest ","m_requestQueue.add(request)"); m_requestQueue.add(request); } 

RequestManager.java

 public void executeRequest(Request request) { Log.d("executeRequest ","m_requestQueue.add(request)"); m_requestQueue.add(request); } 

This approach does not work, and when debugging inside the volley library, I got to the point that the request could not be added to the mCacheQueue class of the RequestQueue class, because the cacheKey from reuqest is present in the mWaitingRequests map. Thus, the request is added to the queue on the mWaitingRequests card corresponding to its key. When the previous request is completed, the new one is not added to the queue, although these lines are executed in the RequestQueue class:

 synchronized(this.mWaitingRequests) { String cacheKey1 = request.getCacheKey(); Queue waitingRequests1 = (Queue)this.mWaitingRequests.remove(cacheKey1); if(waitingRequests1 != null) { if(VolleyLog.DEBUG) { VolleyLog.v("Releasing %d waiting requests for cacheKey=%s.", new Object[]{Integer.valueOf(waitingRequests1.size()), cacheKey1}); } this.mCacheQueue.addAll(waitingRequests1); } } 

When debugging this line

 this.mCacheQueue.addAll(waitingRequests1); 

In AbstractQueue.java (the class in java.util), the element is added to the queue, the "changed" value is true, but during the hole, the "this" parameter continues to contain 0 elements.

  public boolean addAll(Collection<? extends E> c) { if (c == null) throw new NullPointerException("c == null"); if (c == this) throw new IllegalArgumentException("c == this"); boolean modified = false; for (E e : c) if (add(e)) modified = true; return modified; } 

Inside the sentence (E e), the PriorityBlockingQueue.java method program execution stops at line 453.

 l452 siftUpUsingComparator(n, e, array, cmp); l453 size = n+1; 

Obviously, the return value is true, but the item is not added. My debugger could not enter the method that adds the element - siftUpUsingComparator (n, e, array, cmp);

I am going to add a timer before repeating my request and build a new one. Therefore, I am not interested in a workaround; I want to understand what is happening in this situation and how. Do you have any ideas as to what might be causing this?

+5
source share
1 answer

The problem is that you are trying to add one instance of the request again to the queue to which it was added. This gets confused with the queue and the request itself, since it has states. For example, if you just turn on the markers, you will crash. The solution is to either use the default retry policy or clone the requests.

+1
source

Source: https://habr.com/ru/post/1238927/


All Articles