Java-Gaming.org    
Featured games (81)
games approved by the League of Dukes
Games in Showcase (489)
Games in Android Showcase (112)
games submitted by our members
Games in WIP (553)
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  
  URLConnection getContentLength()  (Read 1982 times)
0 Members and 1 Guest are viewing this topic.
Offline i30817

Junior Member





« Posted 2009-08-20 16:42:45 »

It takes a long time and i want to be able to interrupt it at will. I thought just using the thread trick to turn a synchronous method into a asynchronous one would work, but apparently it never throws interrupted exception. I guess i could ignore it (by replacing the interrupt for a break in that while.

Seems wrong though. Interrupting methods is such a bother in current PL's.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
            AssynchronousGetSize r = new AssynchronousGetSize(conn);

            Thread t = new Thread(r);
            t.start();

            while(t.isAlive()){
                if(p.isClosed()){
                    //closed in the ui
                   t.interrupt();
                }
                t.join(500);
            }
Offline h3ckboy

JGO Coder


Medals: 5



« Reply #1 - Posted 2009-08-20 16:51:48 »

waht is p?
Offline i30817

Junior Member





« Reply #2 - Posted 2009-08-20 17:06:50 »

My replacement for ProgressMonitor, since the jdk one likes to create components outside in the EDT (and yes the p.isClosed() internal variable is volatile).

edit, not that it need it in this case.

Edit: correction likes to create outside the EDT
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline ManaSink

Senior Newbie





« Reply #3 - Posted 2009-08-20 17:56:18 »


Try changing:

    t.interrupt();

to:

    conn.getInputStream().close();

or if conn is an instance of HttpURLConnection:

    conn.disconnect();



Offline pjt33
« Reply #4 - Posted 2009-08-21 10:49:40 »

It takes a long time and i want to be able to interrupt it at will.
Start at the start: why do you want to be able to interrupt it?
Offline i30817

Junior Member





« Reply #5 - Posted 2009-08-26 18:25:36 »

Because it takes a f**king long while before the application acknowledges my having pressed the cancel button if i don't?

Basically the whole method is this:

So the progress monitor knows it should close, because it popups right away after startViewInEDT in indeterminate state. I do this for obvious usability reasons. But, now having displayed the message i need to get the real size to setTotal(max) and at the same time ack a user pressing cancel during that interval. My pattern in these edt finangles is starting in the edt and offloading larger tasks into another Thread or ExecutorService, but not here since the ProgressMonitorStream hasa ProgressMonitor not the opposite (as i think is fitting) and  the ProgressMonitor hasa view (which may not be fitting but f**k it).
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  
    public static ProgressMonitorStream create(URL url, String message, Component parent) throws IOException {
        ProgressMonitor p = new ProgressMonitor(-1, message);
        try {
            p.startViewInEDT(parent);
            final URLConnection conn = url.openConnection();
            AsynchronousGetSize r = new AsynchronousGetSize(conn);

            Thread t = new Thread(r, "AsynchronousGetSizeThread");
            t.start();
            while(t.isAlive()){
                if(p.isClosed()){
                    //closed in the ui
                   t.interrupt();
                    throw new IOException("closed progress monitor while attempting to estabilish connection");
                }
                t.join(500);
            }
            int max = r.max;
            InputStream s = new BufferedInputStream(conn.getInputStream());
            p.setTotal(max);
            return new ProgressMonitorStream(s, max, p);
        } catch (Exception ex) {
            //close the dialog... (small window of opportunnity
           //where it doesn't close when a exception happens).
           p.close();
            throw new IOException(ex);
        }
    }


As you can see i'm currrently ignoring a in progress getContentLength if i don't care about it no more, after symbollically interrupting it- i remember reading that the old stream api doesn't respond to interrupts except the piped stream variants. Using a thread for this looks and feels awful especially considering the amount of threads my application already uses (hopefully none left hanging by now).
Offline i30817

Junior Member





« Reply #6 - Posted 2009-08-26 18:44:45 »

Folks i just noticed that this won't work if i call it on the edt.
Then the time consuming tasks are done before the dialog even shows because of the edt queue like nature. startViewInEDT justs calls invoke later showing the view.

The nature of the method should be to show the dialog the fastest possible in all situations where a progress monitor stream can be used.

Maybe i need a test in the startViewInEDT method?

if(isEDT){
 r.run();
}else{
 invokeLater(r);
}


(currently startViewInEDT uses invokeLater)

I noticed that the setVisible method is blocking... so the rest of the code never gets executed if i used that runnable in a invokeAndWait or called it directly. Including the code that would call close in the progress monitor (and dispose the view) if it went wrong of if the stream finished. So if i execute directly or use invokeAndWait, the edt is blocked. If i used invokeLater it is not blocked, but the view only displays after getcontentLenght and the rest of the code executes. Just another threading error.
(obviously reordering the statements so the arguments needed are available before calling startViewInEDT is not viable (what happens now if the whole method is called in the EDT). The view must start right then as soon as possible (but not block the rest of the code)).

So what i really need where to make this thread safe is call the whole function code out of the EDT if needed right? But - shit - as the method has a return that is not viable either. The caller would only get the input stream after the popup window was closed.

A notifier in a inputstream static factory saying this method shall not be called in the EDT seems to trust in my ability to read javadocs a bit too much.

3 threads already - edt, one to run this P.O.S. method and the aux turn into a synchronous method into a asynchronous method one.
Offline pjt33
« Reply #7 - Posted 2009-08-26 20:14:18 »

Because it takes a f**king long while before the application acknowledges my having pressed the cancel button if i don't?
So, because you're doing it in the EDT? You seem already to have worked out the solution, which is not to do anything expensive in the EDT. Spawn a thread which does the IO and uses SwingUtilities.invoke* to update the UI. Or pass state between the two using volatile fields or AtomicInteger etc.
Offline i30817

Junior Member





« Reply #8 - Posted 2009-08-26 20:15:12 »

No, that is not the problem. That is an hypothetical i (do) avoid.

I am trying to make it thread safe. Including being called from the edt. Which i don't, currently.
The problem in a nutshell, disregarding the asynchronous method thing:
setVisible is blocking.
The create method might be called anywhere (its only a creation of a input stream, no matter how special).
In the EDT the statements get reordered by invokelater - the view is only made visible after it knows the size in that code, but it should be reversed like if it isn't called in the EDT, so it takes a long time to display the view (doesn't stop execution - invoke later would stop it because of setVisible).

Thats it. I don't know how to avoid it, simply because setVisible is blocking (always). Maybe if i spin of the second part of the method - the one that sets the max size - into a runnable that runs conditionally off the edt if in it, and just return the input stream with a max size of 0 (the input stream size argument is for some statistics, download speed in particular - in fact i don't need this there - its just that it was tempting to use a already made superclass that had a hook and funcionality in the right place).

But that turns a already complex method i was hoping to simplify into hideous. Maybe i should just throw a Runtime exception, especially since the getInputStream method of HTTPURLConnection takes a long time to return (connect) if it is remote, so the method would probably run slowly.
Offline pjt33
« Reply #9 - Posted 2009-08-27 08:24:53 »

There are two ways round setVisible blocking. One is to not use a modal Dialog (or to fake your own with a JFrame - IIRC you can put an invisible component in the glasspane of the parent JFrame to which you can add a listener). The other is to make setVisible the last thing you do. If you hide the dialog in the new EDT then I think setVisible will return.

If that still doesn't make sense then please post a self-contained executable example, faking out the expensive network operation with a wait/sleep.
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.

TehJavaDev (18 views)
2014-08-28 18:26:30

CopyableCougar4 (26 views)
2014-08-22 19:31:30

atombrot (39 views)
2014-08-19 09:29:53

Tekkerue (36 views)
2014-08-16 06:45:27

Tekkerue (33 views)
2014-08-16 06:22:17

Tekkerue (22 views)
2014-08-16 06:20:21

Tekkerue (33 views)
2014-08-16 06:12:11

Rayexar (70 views)
2014-08-11 02:49:23

BurntPizza (47 views)
2014-08-09 21:09:32

BurntPizza (37 views)
2014-08-08 02:01:56
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

List of Learning Resources
by SilverTiger
2014-07-31 11:54:12

HotSpot Options
by dleskov
2014-07-08 01:59:08
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!