Thanks for your help, I'll give this a shot. A few points:
- Are you suggesting that I return an InputRepresentation instead of an
OutputRepresentation? That seems counterintuitive, it seems like I should
always be returning some sort of OutputRepresentation because I am outputing
data to the client. Terminology wise, my intuition tells me an input
representation would be for data coming in from the client. I don't see this
distinction documented anywhere, though.
- I am still confused as to what the bug was, and just what,exactly, I'm
working around.
- The reason I don't want to use one of the "canned" or "pre-joined" sequences
is performance: why am I reading 10 URLs off if the user requested data from
only one of them? Ultimately, my goal is not not have to read data that is
going to be dumped anyway.
- I still don't see how to bypass the content range stuff. The docs allude to
this being possible in several places, so I kindof assumed it could be done,
but I don't see it documented explicitly, so maybe not. At the very least, of
course, I can read the range info, determine what will not be read and fill in
zeros for that information. That approach is still a lot better than reading
all the data from a remote URL.
bjorn
On Apr 18, 2012, at 12:07 PM, Thierry Boileau wrote:
> Hello Bjorn,
>
> >By messing with the code you sent, this seems to be a function of setting
> >the representation size. If I set the size, it's fine, if not, it sends the
> >whole thing regardless of content-range, which seems like a bug.
> Thanks for discovering a bug inside the RangeFilter class.
>
> Then, I've found that the problem is due to the usage of the
> OutputRepresentation in order to gather the several instances of InputStream.
> I propose you to use an InputRepresentation instead.
> First, I've set up a InputStream class that composes the several InputStream
> (this implementation is only a "quick" code):
>
> private static class CompositeInputStream extends InputStream {
> private Iterator<URL> urlIt = null;
> private InputStream is = null;
>
> public CompositeInputStream(Vector<URL> urls) throws IOException {
> urlIt = urls.iterator();
> if (urlIt.hasNext()) {
> is = urlIt.next().openStream();
> }
> }
>
> @Override
> public int read() throws IOException {
> // read each input stream until exhaustion
> int r = is.read();
>
> boolean goOn = (r == -1);
> while (goOn) {
> // choose the next one until exhaustion
> if (urlIt.hasNext()) {
> is = urlIt.next().openStream();
> r = is.read();
> goOn = (r == -1);
> } else {
> goOn = false;
> }
> }
>
> return r;
> }
> }
>
> Then, I simple return the InputRepresentation:
> return new InputRepresentation(new CompositeInputStream(urls));
>
> I hope this will help you.
>
> Best regards,
> Thierry Boileau
>
>
>
> On Apr 11, 2012, at 2:14 PM, Bjorn Roche wrote:
>
>>
>> On Apr 11, 2012, at 1:50 PM, Thierry Boileau wrote:
>>
>>> Hi Bjorn,
>>>
>>> that's right, I primarily use the restlet 2.1 version, which does not
>>> support this constructor I think. I'm not sure this has an impact.
>>>
>>
>> Well when I use the setter I get the same thing (throws exception) as when I
>> pass that value to the constructor.
>>
>> Also, it looks like the range is being ignored -- I am getting the full
>> document back rather than part.
>
> By messing with the code you sent, this seems to be a function of setting the
> representation size. If I set the size, it's fine, if not, it sends the whole
> thing regardless of content-range, which seems like a bug.
>
>> Can you send me build instructions (pom or ant file?) for your code if you
>> have it? I am testing with curl, maybe there is an issue with one of our
>> tests?
>
> I've figured out how to build (I am an idiot with building)... and I can't
> reproduce the exception.
>
> bjorn
>
>>
>> Finally, is it possible to avoid the range processing on just some calls for
>> greater efficiency?
>>
>> bjorn
>>
>>> Best regards,
>>> Thierry Boileau
>>>
>>> Thierry,
>>>
>>> The first thing I noticed in your code is that you are using the
>>> OutputRepresentation constructor that does not take an expectedSize
>>> argument, so I took that out and the exception goes away. At the moment my
>>> tests are still failing, so I'll look into that some more.
>>>
>>> bjorn
>>>
>>> On Apr 11, 2012, at 12:39 PM, Thierry Boileau wrote:
>>>
>>>> Hi Bjorn,
>>>>
>>>> I send you a sample test code (server + client) based on your code that
>>>> works for me. But I notice that my app sends only 15000 bytes... Can you
>>>> tell us the metrics of your tests?
>>>>
>>>> Not 100% sure of the question.. do you mean container? I am not using
>>>> jetting. My initialization code looks like this:
>>>> Component component = new Component();
>>>> component.getServers().add(Protocol.HTTP, PORT);
>>>> component.getDefaultHost().attach(new
>>>> com.xonami.rest.server.ApiApplication());
>>>> component.start();
>>>>
>>>> Is that what you wanted?
>>>> I wanted to know if the application is served using some "server"
>>>> extensions such as jetty (org.restlet.ext.jetty.jar) or simple
>>>> (org.restlet.ext.simple.jar), or inside a servlet container.
>>>>
>>>>
>>>> also, in the code I sent it looks like it was not "hanging" but rather
>>>> pausing for a moment and then throwing this exception:
>>>>
>>>> java.io.IOException: Timeout while writing to the queue-based output stream
>>>> at org.restlet.engine.io.PipeStream$2.write(PipeStream.java:106)
>>>> at java.io.OutputStream.write(OutputStream.java:99)
>>>> at
>>>> com.xonami.rest.server.media.RawMediaStateWithIdResource$1.write(RawMediaStateWithIdResource.java:158)
>>>> at org.restlet.engine.io.BioUtils$2.run(BioUtils.java:394)
>>>> at org.restlet.service.TaskService$1$1.run(TaskService.java:130)
>>>> at
>>>> java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>>> at
>>>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>>> at java.lang.Thread.run(Thread.java:680)
>>>>
>>>> thanks, I try to reproduce this error. Or, if may ask you, can you provide
>>>> a reproductible sample test code?
>>>>
>>>> Best regards,
>>>> Thierry Boileau
>>>>
>>>> -----------------------------
>>>> Bjorn Roche
>>>> http://www.xonami.com
>>>> Audio Collaboration
>>>> http://blog.bjornroche.com
>>>>
>>>> ------------------------------------------------------
>>>> http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2947368
>>>>
>>>> <testRange.zip>
>>>
>>>
>>> -----------------------------
>>> Bjorn Roche
>>> http://www.xonami.com
>>> Audio Collaboration
>>> http://blog.bjornroche.com
>>>
>>>
>>>
>>>
>>>
>>
>> -----------------------------
>> Bjorn Roche
>> http://www.xonami.com
>> Audio Collaboration
>> http://blog.bjornroche.com
>>
>>
>>
>>
>
>
> -----------------------------
> Bjorn Roche
> http://www.xonami.com
> Audio Collaboration
> http://blog.bjornroche.com
>
>
>
>
>
-----------------------------
Bjorn Roche
http://www.xonami.com
Audio Collaboration
http://blog.bjornroche.com
------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2949907