I am attempting to close a stream coming from an http request using Retrofit and rxjava, either because it timedOut, or because I need to change details that went into the request. Both appear to work perfectly, as when I cancel subscription I get the doOnCancel debug message and when doOnNext is completed I get the doOnTerminate message. I also do not receive inputLines from multiple threads. However, my thread count rises every single time either of the above actions happen. It appears that responsebody.close is not releasing their resources and therefore the thread is not dying (I also have gotten error messages along the lines of "OKHTTP leaked. did you close youre responseBody?")
Does anyone have any suggestions?
public boolean closeSubscription() {
flowableAlive = false;
subscription.cancel();
return true;
}
public void subscribeToFlowable() {
streamFlowable.observeOn(Schedulers.newThread()).subscribeOn(Schedulers.newThread())
.doOnTerminate(() -> log.debug("TERMINATED")).doOnCancel(() -> log.debug("FLOWABLE CANCELED"))
.subscribe(new Subscriber<ResponseBody>() {
#Override
public void onSubscribe(Subscription s) {
subscription = s;
subscription.request(Long.MAX_VALUE);
}
#Override
public void onNext(ResponseBody responseBody) {
log.debug("onNext called");
String inputLine;
try (InputStream inputStream = responseBody.byteStream()) {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
while (flowableAlive && ((inputLine = br.readLine()) != null)) {
log.debug("stream receive input line for thread " + name);
log.debug(inputLine);
}
} catch (IOException e) {
log.debug("error occurred");
log.debug(e.getMessage());
}
}
#Override
public void onError(Throwable t) {
log.debug("error");
flowableAlive = false;
}
#Override
public void onComplete() {
log.debug("completed");
closeSubscription();
flowableAlive = false;
}
});
}
The result of subscribe() is Disposable object. You should store it as a filed and call Disposable.dispose() on it later as shown here:
https://proandroiddev.com/disposing-on-android-the-right-way-97bd55cbf970
Tour OkHttp call will be interrupted properly because dispose() interrupts thread on which the call runs and OkHttp checks regularly if Thread was interrupted to stop transfer when that happened - it's called cooperative cancelling/interruption.
Im trying to implement windows phone 8.1 notification background task.
it is implemented with one bug!
the toast notification message will appear in the action center more than once. sometimes 9times.
here is my code:
public sealed class my_bg_notifier: IBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
var deferral = taskInstance.GetDeferral();
bool status = await notificationChecker.check();
if (status)
{
populateNotification(notificationChecker.count);
}
deferral.Complete();
}
}
I tried to debug so I put a breakpoint over the line status.
and I was surprised that it is called more than once and that is why my notification will pop-up more than one time.
and the message that is showed from the debugger breakpoint clearly states that there are multiple threads doing the same job simultaneously.
so i thought to prevent running the method by more than one thread by using a boolean flag as follow:
public sealed class my_bg_notifier: IBackgroundTask
{
private static bool isNotBusy = true;
public async void Run(IBackgroundTaskInstance taskInstance)
{
if (isNotBusy)
{
isNotBusy = false;
var deferral = taskInstance.GetDeferral();
bool status = await notificationChecker.check();
if (status)
{
populateNotification(notificationChecker.count);
}
deferral.Complete();
}
isNotBusy = true;
}
}
but again that didn't work.
my question is :
why would a background task run more than once by multiple thread simultanously.
and How can I block this behavioud? should I use lock keyword?
Okkkkk!!! It was my fault. In my code i registered the background task on each app launch without checking if it is already registered.
So i used code as below to check if my task is registered then no need to register it again.
var taskRegistered = false;
var exampleTaskName = "ExampleBackgroundTask";
foreach (var task in Background.BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
break;
}
}
Source: http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977055.aspx
I am using a separate thread to handle the processing of a file. The main thread holds the table to display to the user using a listView, and uses an AjaxSelfUpdatingTimer to refresh the list every second.
The problem is, after processing about 100 lines in my CSV file, I keep getting a no requestCyle exception:
Exception in thread "Thread-12" org.apache.wicket.WicketRuntimeException: No RequestCycle is currently set!
at org.apache.wicket.Component.getRequest(Component.java:1804)
at org.apache.wicket.markup.html.WebPage.dirty(WebPage.java:318)
at org.apache.wicket.Page.dirty(Page.java:249)
at org.apache.wicket.Page.componentStateChanging(Page.java:926)
at org.apache.wicket.Component.addStateChange(Component.java:3528)
at org.apache.wicket.Component.error(Component.java:1225)
at com.wicket.BulkLoadPage$BatchLoaderProcessingThread.processLine(BulkLoadPage.java:806)
at com.wicket.BulkLoadPage$BatchLoaderProcessingThread.run(BulkLoadPage.java:674)
at java.lang.Thread.run(Thread.java:662)
these are my runnable classes the thread calls:
class BatchLoaderProcessingThread implements Runnable
{
#Override
public void run()
{
processLine();
loaderFinished();
}
public void cancelThread()
{
cancelLoaderThread = true;
}
}
class BatchDeleteProcessingThread implements Runnable
{
#Override
public void run()
{
processLine();
deleterFinished();
}
public void cancelThread()
{
cancelDeleterThread = true;
}
}
I don't understand why the requestCycle would just go null.. How can I prevent this from happening?
Edit:
Commenting out feedback message do troubleshoot requestRecycle error, I receive this error:
java.io.IOException: Read error
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:220)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.read1(BufferedReader.java:185)
at java.io.BufferedReader.read(BufferedReader.java:261)
at java.io.BufferedReader.fill(BufferedReader.java:136)
Dec 30 13:14:31 ERROR BulkLoadPage-java.io.IOException: Read error
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at au.com.bytecode.opencsv.CSVReader.getNextLine(CSVReader.java:266)
at au.com.bytecode.opencsv.CSVReader.readNext(CSVReader.java:233)
at com..wicket.BulkLoadPage.processLine(BulkLoadPage.java:547)
at com..wicket.BulkLoadPage.access$0(BulkLoadPage.java:532)
at
com..wicket.BulkLoadPage$BatchLoaderProcessingThread.run(BulkLoadPage.java:1294)
at java.lang.Thread.run(Thread.java:662)
this error only occurs with the larger file as well. All of the lines inside the csv are duplicate only to mimic a large file.. so all lines are the same, and there shouldn't be an error caused directly from the file. Is there something else that I should be looking for that would cause this error from using another thread?
RequestCycle is a thread local singleton. If you're running a process in another thread that really means the RequestCycle singleton doesn't exist in your new thread.
The following example is placed on https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-1.4/browse
The idea is about holding the reference to the current RequestCycle, you cannot call RequestCycle.get() due to the thread local singleton doesn't exist in any other thread. This CustomRequestCycle implementation is ever waiting until the new thread notify its finishing. The counter of loops is just a protection to do not freeze the primary thread if the WaitingRunnable stops working/freezes.
RESULTS oF TESTS:
Check your logs for case 1, the separate thread is finishing very soon, RequestCycle doesn't wait for detaching
http://localhost:8080/wicket-examples14/wait?millis=10
DEBUG - CustomRequestCycle - Waiting until notify: 0
INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage
INFO - CustomRequestCycle - Notifier returned: Successfully finished
Check your logs for case 2, the separate thread is finishing in time, RequestCycle has to wait for detaching
http://localhost:8080/wicket-examples14/wait?millis=3000
DEBUG - CustomRequestCycle - Waiting until notify: 0
DEBUG - CustomRequestCycle - Waiting until notify: 1
DEBUG - CustomRequestCycle - Waiting until notify: 2
INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage
INFO - CustomRequestCycle - Notifier returned: Successfully finished
Check your logs for case 3, the separate thread is finishing on time, RequestCycle is already detached
http://localhost:8080/wicket-examples14/wait?millis=10000
DEBUG - CustomRequestCycle - Waiting until notify: 0
DEBUG - CustomRequestCycle - Waiting until notify: 1
DEBUG - CustomRequestCycle - Waiting until notify: 2
DEBUG - CustomRequestCycle - Waiting until notify: 3
DEBUG - CustomRequestCycle - Waiting until notify: 4
DEBUG - CustomRequestCycle - Waiting until notify: 5
DEBUG - CustomRequestCycle - Waiting until notify: 6
DEBUG - CustomRequestCycle - Waiting until notify: 7
INFO - CustomRequestCycle - Notifier returned: null
INFO - WaitingRunnableNotifier - Separate thread waiting finished cz.wicketstuff.enteam.wicket.examples14.request.ThreadWaitingPage
SOURCES:
WicketApplication
#Override
public RequestCycle newRequestCycle(Request request, Response response) {
return new CustomRequestCycle(this, (WebRequest)request, (WebResponse)response);
}
CustomRequestCycle
public class CustomRequestCycle extends WebRequestCycle implements INotifier<String> {
private static final Logger log = LoggerFactory.getLogger(CustomRequestCycle.class);
private long sleepTime = 1000L;
private long maxLoops = 8;
private boolean canDetach = true;
private String notifierResult;
public CustomRequestCycle(WicketApplication application, WebRequest request,
Response response) {
super(application, request, response);
}
public void notifyAny(String payload) {
notifierResult = payload;
canDetach = true;
}
#Override
public void detach() {
long counter = 0;
while(!canDetach && maxLoops > counter) {
log.debug("Waiting until notify: " + counter);
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// do nothing
}
counter++;
}
log.info("Notifier returned: " + notifierResult);
super.detach();
}
public static CustomRequestCycle get() {
return (CustomRequestCycle)RequestCycle.get();
}
/**
* #return the canDetach
*/
public boolean isCanDetach() {
return canDetach;
}
/**
* #param canDetach the canDetach to set
*/
public void setCanDetach(boolean canDetach) {
this.canDetach = canDetach;
}
}
WaitingRunnableNotifier
public class WaitingRunnableNotifier implements Runnable {
private static final Logger log = LoggerFactory.getLogger(WaitingRunnableNotifier.class);
private final long waitTime;
private RequestCycle requestCycle;
private INotifier<String> notifier;
public WaitingRunnableNotifier(RequestCycle requestCycle, long waitTime, INotifier<String> notifier) {
super();
this.notifier = notifier;
this.requestCycle = requestCycle;
this.waitTime = waitTime;
}
public void run() {
String message = null;
try {
try {
Thread.sleep(waitTime);
} catch (InterruptedException e) {
}
log.info("Separate thread waiting finished " + requestCycle.getResponsePageClass().getCanonicalName());
message = "Successfully finished";
} catch (Exception e) {
log.error("Exception during WaitingRunnableNotifier.run()", e);
message = "Exception: " + e.getMessage();
} finally {
notifier.notifyAny(message);
clean();
}
}
/**
* Clean object references
*/
private void clean() {
requestCycle = null;
notifier = null;
}
}
ThreadWaitingPage is a page with parameter 'millis'. There you can invoke the another thread and wait unitl it is finished.
public class ThreadWaitingPage extends WebPage {
private static final long serialVersionUID = 1L;
private final long millis;
public ThreadWaitingPage(final PageParameters parameters) {
super(parameters);
millis = parameters.getLong("millis");
add(new Label("millis", String.valueOf(millis)));
}
#Override
protected void onInitialize() {
super.onInitialize();
CustomRequestCycle requestCycle = CustomRequestCycle.get();
requestCycle.setCanDetach(false);
new Thread(new WaitingRunnableNotifier(requestCycle, millis, requestCycle)).start();
}
}
Ideally, you shouldn't be creating your own threads, the container should be left to do all that for you. Of course, this means you can't leave bulk processes running in the background between requests.
I've done something similar before (breaking the rule I just mentioned!) and the easiest way is to keep Wicket out of your own threads. If your threads populate a List for example, and your ajax timer callback extracts the records from the list and adds them to the list view.
The problem with list views though is you have to add the parent component to the ajax request target, meaning that the whole list view will be sent back in the ajax response, not just the new entries you've added but all the old ones as well, which would defeat the point of loading them incrementally.
As its only a CSV file, it might be better for you to use a data table, and write a data provider to open the file and read only the records for that request which should be much simpler.
I have temporarily fixed this issue by first loading the lines into a string ArrayList in the main thread and just read from that list inside the thread..
I don't really see any latency issues, so maybe this can be considered a good alternative? If it isn't please let me know, otherwise hopefully this helps someone else some day who struggles with this.
I have also posted my issue here:
http://apache-wicket.1842946.n4.nabble.com/MultiThreading-issues-with-Wicket-td4663325.html#a4663389
and was given some good resource links to review:
Multithreading in wicket:
http://javathoughts.capesugarbird.com/2008/04/spawning-thread-for-lengthy-operation.html
RequestCycle:
http://wicket.apache.org/guide/guide/chapter8.html
I want to implement a loading screen in blackberry. I try the code from following Support forum link using following code
PleaseWaitPopupScreen.showScreenAndWait(new Runnable() {
public void run() {
//**Segment 1** here i write the code for network call
}
}, "please wait");
// **Segment 2**:Here processing the data get from network call
the problem is the segment 2 works before completing the segment 1. I also try the following code
HorizontalFieldManager popHF = new HorizontalFieldManager();
popHF.add(new LabelField("Pls wait..."));
final PopupScreen waitScreen = new PopupScreen(popHF);
new Thread()
{
public void run()
{
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().pushScreen(waitScreen);
}
// **Segment 1**Here Some Network Call
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().popScreen(waitScreen);
}
}
}.start();
// **Segment 2**:Here processing the data get from network call
the same problem arises. Any help will be appreciated.
thanks
Actually it depends on what you're doing in segment 2. If there is no UI actions, then just move segment 2 inside the thread that makes http call. e.g.:
final PopupScreen waitScreen = new PopupScreen(popHF);
new Thread()
{
public void run()
{
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().pushScreen(waitScreen);
}
// **Segment 1**Here Some Network Call
// **Segment 2**:Here processing the data get from network call
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().popScreen(waitScreen);
}
}
}.start();
But if there are UI actions inside of segment 2, then call it on UI thread, right after you pop off the wait screen:
final PopupScreen waitScreen = new PopupScreen(popHF);
new Thread()
{
public void run()
{
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().pushScreen(waitScreen);
}
// **Segment 1**Here Some Network Call
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().popScreen(waitScreen);
// **Segment 2**:Here processing the data get from network call
}
}
}.start();
I have a HttpConnection thread class. when ı stop httpConnection, I show this messeage.
how should ı stop httpConnection??
Blackberry Output Console:
RuntimeException
blocking operation not permitted on event dispatch thread
net_rim_cldc-10
EventThreadCheck
throwException
0x3434
net_rim_cldc_io_tcp
Protocol
<private>
0x18B8
net_rim_cldc_io_tcp
Protocol
outputStreamClosed
0xB2D
net_rim_cldc_io_tcp
TcpOutputStream
close
0x40BF
net_rim_os-2
ClientProtocol
close
0x154E
CepVizyon-2
Http
cancel
0x174F
CepVizyon-2
Camera
cancel
0x6E7
CepVizyon
ViewCam
close
0xE79
net_rim_cldc-7
Screen
onClose
0x5DAC
net_rim_cldc-7
Screen
keyCharUnhandled
0x5C58
net_rim_cldc-9
MainScreen
keyCharUnhandled
0x23D7
net_rim_cldc-7
Screen
dispatchKeyEvent
0x51DB
net_rim_cldc-7
Screen
processKeyEvent
0x718D
net_rim_cldc-7
UiEngineImpl
processMessage
0x9E3C
net_rim_cldc-4
Application
processNextMessage
0x1073
net_rim_cldc-4
Application
enterEventDispatcher
0x775
CepVizyon-2
CepVizyonMain
main
0x1175
parts of My Connection class:
public abstract class Http extends Thread{
protected HttpConnection httpConnection;
HttpConnectionFactory factory;
protected static Base64 base64;
private boolean cancel = false;
/** bağlantının yapılcağı adres */
protected String url = "";
/** paremetre olarak gönderilecek data */
protected String queryString = "";
...
public void cancel() {
try {
if (httpConnection != null)
httpConnection.close();
if(factory!=null)
factory.cancel();
} catch (IOException ex) {
}
cancel = true;
}
part of my screen class:
public void close() {
super.close();
StaticVar.ActiveCam.cancel();
// CameraListScreen screen = new CameraListScreen();
// UiApplication.getUiApplication().pushScreen(screen);
//
}
and part of Camera Class/*ActiveCam's cancel is here/:
// finishes connection.
public void cancel() {
setConnected(false);
if (mjpeghttp != null) {
mjpeghttp.cancel();
//mjpeghttp.interrupt();
//mjpeghttp = null;
}
}
It looks like your HttpConnection is accessed from a background (non UI) thread which is good. However your UI calls close() directly which may block. You should consider spawning another thread to do the close().
You must work with screen only from event thread
//safely (recommended)
Application.getApplication().invokeLater(new Runnable() {
public void run() {
//your code here
}
});
or
//fast
synchronized(Application.getEventLock()) {
//your code here
}