Thanks for your answers. I've implemented an Input representation more or less
like the code you sent. each time a new "chunk" or url is required, I scan the
Ranges first and if the ranges don't require data from that chunk, I just use a
dummy input stream to pass zeros. It's not perfect (perfect would not require
passing zeros), but in my cursory testing so far it works reasonably well, and
I suspect it will be more than adequate.
bjorn
On Apr 20, 2012, at 6:25 AM, Thierry Boileau wrote:
> Hello Bjorn,
>
> - 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 think that in your case the approach based on InputRepresentation is
> better, and should offer better performance.
> The aim of representations based on streams (such as InputRepresentation or
> OutputRepresentation) is to deliver the bytes of the Representation that are
> meant to be read (then written on a socket for example) via the stream
> returned by the "getStream()"method. InputRepresentation delivers the stream
> via an input stream, OutputRepresentation via output stream.
> Please feel free to ask for more details.
>
> - I am still confused as to what the bug was, and just what,exactly, I'm
> working around.
> I agree also, but it is linked to the usage of the OutputRepresentation.
>
> - 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.
> I've not tested it, I wonder if the RangeFilter really consumes the whole
> Representation. If this is the case, I think we should do better. I check
> that today.
> Regarding the usage of the "pre-joined" sequences, you can still check if the
> streams are really opened and read (I think the one from Guava should perform
> correctly, if not, you can complete the one I sent to you).
>
> Best regards,
> Thierry Boileau
>
>
> 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
>
>
>
>
>
-----------------------------
Bjorn Roche
http://www.xonami.com
Audio Collaboration
http://blog.bjornroche.com
------------------------------------------------------
http://restlet.tigris.org/ds/viewMessage.do?dsForumId=4447&dsMessageId=2950205