Java-Gaming.org Hi !
Featured games (83)
games approved by the League of Dukes
Games in Showcase (528)
Games in Android Showcase (127)
games submitted by our members
Games in WIP (594)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Stop frozen method  (Read 1572 times)
0 Members and 1 Guest are viewing this topic.
Offline Sammidysam
« Posted 2013-03-12 21:45:23 »

I originally posted this in my library's thread in Networking & Multiplayer, but this is a complicated issue that if anyone else encounters will likely want to find the answer easily, so I made this thread.  I was working today on fixing the issue where my auto-updater/patcher freezes when internet connection is lost in the middle of a download, and I came up with a solution that seemed to work.  The download would be run on a separate thread and if the thread takes longer to finish than expected the internet connection would be checked and if there is not internet then "return;" would be called in the method after something was printed to the console about how the download was aborted due to internet being lost.  This is the code:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
      ReadableByteChannel rbc = null;
      FileOutputStream fos = null;
      try {
//         creates file in temporary directory to be downloaded to, so that the main file isn't lost if the download is aborted
         File temp = File.createTempFile("tempFile", filePath.substring(filePath.lastIndexOf('.'), filePath.length()));
//         the file will be deleted upon exit unless the download is aborted mid-way
         temp.deleteOnExit();
         URL file = new URL(fileSite);
         URLConnection urlconnection = file.openConnection();
         urlconnection.setReadTimeout(5000);
         long size = urlconnection.getContentLength();
         rbc = Channels.newChannel(file.openStream());
         fos = new FileOutputStream(temp);
         long position = 0;
         if(usingChunks)
            while(position < size){
               if(!hasInternet)
                  return;
//               downloads chunkSize bytes and increases the position on the download accordingly
               final long finalPosition = position;
               final FileOutputStream finalFos = fos;
               final ReadableByteChannel finalRbc = rbc;
               Thread download = new Thread(new Runnable(){
                  public void run(){
                     try {
                        if(hasInternet)
                           finalFos.getChannel().transferFrom(finalRbc, finalPosition, chunkSize);
                     } catch (IOException e) {
                        e.printStackTrace();
                     }
                  }
               });
               download.start();
               long timeout = chunkSize;
               try {
                  download.join(timeout);
               } catch (InterruptedException e) {
                  ErrorLogger.logError(e);
                  return;
               }
               if(download.isAlive())
                  if(!isInternetReachable())
                     if(!hasInternetFallback()){
//                        this is a nested if because I only want to check internet if the above requirement works because checking internet takes some time
                        System.out.println("Internet connection lost");
                        hasInternet = false;
                        return;
                     }
               position += chunkSize;
//               position += fos.getChannel().transferFrom(rbc, position, chunkSize);
//               sets progress to the nearest tenth of the amount of bytes downloaded out of the total
               progress = Math.round((float)(100 * (float)position / (float)size) * (float)10) / (float)10;
               System.out.println(progress + "% done");
            }


The error is that if internet connection is lost the transferFrom method keeps running and running and running and running and running... It just doesn't stop.  I really wish it would throw an exception but it just keeps running.  This makes it so that when the checkForUpdate() method (the method from which the excerpt that is posted is from) tries to stop, the thread still running prevents the main method that called checkForUpdate() to advance further down the code line (which in my main method for testing would involve launching the extracted zip file's jar).  Do you know how I can fix this?  After searching on Google for an hour or two, I'm completely clueless.
Offline cubus

Junior Devvie


Medals: 2



« Reply #1 - Posted 2013-03-13 03:27:49 »

hi,

try this...

1  
2  
3  
URLConnection urlconnection = file.openConnection();
urlconnection.setReadTimeout(5000);
long size = urlconnection.getContentLength();


URLConnection's read-timeout is set to 0 by default, which means 'wait forever'.
Offline Sammidysam
« Reply #2 - Posted 2013-03-13 15:56:14 »

hi,

try this...

1  
2  
3  
URLConnection urlconnection = file.openConnection();
urlconnection.setReadTimeout(5000);
long size = urlconnection.getContentLength();


URLConnection's read-timeout is set to 0 by default, which means 'wait forever'.


No difference is made, after calling "return;" the method is still frozen.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline 65K
« Reply #3 - Posted 2013-03-13 16:32:23 »

The shown threading makes no sense to me. You first start a download thread, but then pause the further process until it died again. So, what was the reason to spawn a separate thread ? After it died, you ask if it is still alive, which is never the case, to decide what to do next.

Offline Sammidysam
« Reply #4 - Posted 2013-03-13 16:41:42 »

I thought that the join() method made the currently ran thread (the one running the while loop) wait for the thread download to die and if it didn't die within the timeout argument then the currently ran thread would carry on.  Then I would check if it is alive (normally it wouldn't be) and if it is then it didn't download in the expected time so I would confirm that there is indeed internet and if not I would quit the method.  It worked completely fine, as when internet connection was lost the console would print "Internet connection lost", so I believe it is programmed right.  It's just the transferFrom() method screwing it all up.
Offline 65K
« Reply #5 - Posted 2013-03-13 16:59:10 »

I did not recognize the timeout parameter maybe because you use the chunk size for it, instead of a time span ?
Still, it is a rather strange workaround to me to use a thread here. Broken connections should be notified by catching appropriate exceptions or setting connections timeouts. If that doesn't work, then there is another basic bug hiding out somewhere, I guess.

Offline Sammidysam
« Reply #6 - Posted 2013-03-13 17:08:34 »

As far as I know transferFrom does not seem to throw any exceptions when it can't connect to get the bytes, it seems to just keep trying and freeze.  Thus, I can't catch appropriate exceptions and connection timeouts don't seem to work.  Also, I used chunkSize as the timeout because I assume 1 byte a millisecond for a download is a slow internet speed today.  Maybe I should use another method instead of transferFrom to download so that it doesn't freeze, but I'm not sure if a different method won't freeze either.
Offline 65K
« Reply #7 - Posted 2013-03-13 17:39:27 »

Can't comment on transferFrom without trying, maybe you are feeding wrong positions or chunk sizes.
That timeout calculation assumption is weird, should definitely be replaced.

Offline Sammidysam
« Reply #8 - Posted 2013-03-13 17:57:45 »

Both position and chunkSize are correct throughout the download.  What would you rather have the timeout be?  I'd prefer to utilize chunkSize in some way so that the timeout relates to how long the download is, for example, if the file is 200 MB I don't want the timeout to be 1000 or 2000 because then it will check for internet when it shouldn't.
Offline sproingie

JGO Kernel


Medals: 202



« Reply #9 - Posted 2013-03-13 19:18:25 »

Might I go out on a limb and suggest a separate variable named something like, oh,
timeout
?
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Sammidysam
« Reply #10 - Posted 2013-03-14 01:25:50 »

I have made a separate long named timeout.  This doesn't solve the error however, it still freezes.
Offline deepthought
« Reply #11 - Posted 2013-03-14 02:28:10 »

 Huh
Why not just create the urlconmection, set the timeout, and then call tarnsferfrom with the whole content length?
It doesn't look like you're monitoring download progress anywhere.

jocks rule the highschools. GEEKS RULE THE WORLD MWAHAHAHA!!
captain failure test game
Offline Sammidysam
« Reply #12 - Posted 2013-03-15 01:55:26 »

It's in a while loop where it downloads chunkSize bytes each time in the loop and then calculates the percentage because it has retrieved from the URLConnection how big the file is.  There's also a method for downloading it all at once that I should try to apply that too and see if it works.
Offline Sammidysam
« Reply #13 - Posted 2013-03-16 23:41:01 »

I tested it without calculating percentages and it still freezes when internet is lost.  Does anyone have any ideas?  Maybe I need to rewrite the whole process of downloading.
Offline deepthought
« Reply #14 - Posted 2013-03-17 03:31:08 »

Could it be a problem with the transfer from method? Try using a byte buffer with .read()  and .write().

jocks rule the highschools. GEEKS RULE THE WORLD MWAHAHAHA!!
captain failure test game
Offline Sammidysam
« Reply #15 - Posted 2013-03-17 22:57:29 »

I thought that could be the problem and so I will try out that method.  I'll see how well it works and if it doesn't freeze then I will use that as my new download method.

EDIT: It still freezes so I will deem this as unsolvable for the time being.
Pages: [1]
  ignore  |  Print  
 
 
You cannot reply to this message, because it is very, very old.

 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

PocketCrafter7 (14 views)
2014-11-28 16:25:35

PocketCrafter7 (10 views)
2014-11-28 16:25:09

PocketCrafter7 (11 views)
2014-11-28 16:24:29

toopeicgaming1999 (76 views)
2014-11-26 15:22:04

toopeicgaming1999 (67 views)
2014-11-26 15:20:36

toopeicgaming1999 (17 views)
2014-11-26 15:20:08

SHC (30 views)
2014-11-25 12:00:59

SHC (28 views)
2014-11-25 11:53:45

Norakomi (32 views)
2014-11-25 11:26:43

Gibbo3771 (28 views)
2014-11-24 19:59:16
Understanding relations between setOrigin, setScale and setPosition in libGdx
by mbabuskov
2014-10-09 22:35:00

Definite guide to supporting multiple device resolutions on Android (2014)
by mbabuskov
2014-10-02 22:36:02

List of Learning Resources
by Longor1996
2014-08-16 10:40:00

List of Learning Resources
by SilverTiger
2014-08-05 19:33:27

Resources for WIP games
by CogWheelz
2014-08-01 16:20:17

Resources for WIP games
by CogWheelz
2014-08-01 16:19:50

List of Learning Resources
by SilverTiger
2014-07-31 16:29:50

List of Learning Resources
by SilverTiger
2014-07-31 16:26:06
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!