ID:2528707
 
Applies to:DM Language
Status: Open

Issue hasn't been assigned a status value.
As it stands now, it's super easy to absolutely choke the client with browse_rsc() calls, even if the files are tiny, and even if the client already has them loaded.

This is solely due to the fact that BYOND has to ask the client if they have each file individually, queuing up the calls and going through them one by one. This adds quite a bit of delay in the process. So when you recursively call it more than a few times you'll end up blocking browse() calls and other things that wait for browse_rsc() for a very long time (upwards of 20 minutes on 500 files, equaling less than 500kb in size).

Being able to push a list of files through browse_rsc() eg

src << browse_rsc(list('file1.dmi','file2.dmi'),list("file1.png","file2.png"))


To send the whole list of resources at once, without all the back and forth asking if they have each file. It would still queue/block calls, but only until the client has verified it did its job (which shouldn't take nearly as long since it's not having to tell the server after each file).
I don't know if this would solve our browse_rsc() woes, but it might help.

In-flight browse_rsc() calls block browse() calls. /tg/station uses a queue of browse_rsc() calls to work around this. Unfortunately each browse_rsc() call involves a non-negligible round trip delay, and the status bar and mouse cursor flicker until the queue completes. We solved this by creating spritesheets which combine what were once hundreds of browse_rsc() calls into one. Unfortunately browse_rsc() can only export the first frame of a .dmi file, so we have to send every .dmi file through an external process which strips metadata and re-transmit it, losing the bandwidth savings of simple .rsc extraction.

There's maybe three or four places in that process that the pressure could be let off and everything would be good.
It would definitely help your case, the solution I came up with was only pre-loading a few of the graphics in the big bunch, and loading the page dynamically as it scrolls, pre-loading the next few in the list as you go. But it's IE, so that's not the smoothest process and tends to go bonkers in the strangest ways.

So I had to go back to just living with people having broken images on pages the first time or two they opened them.
In response to Nadrew
Nadrew wrote:
So I had to go back to just living with people having broken images on pages the first time or two they opened them.

Here was our solution in client side jquery code to that problem (my code, can be used here)

function iconError(E) {
var that = this;
setTimeout(function() {
var attempts = $(that).data('reload_attempts');
if (typeof attempts === 'undefined' || !attempts) {
attempts = 1;
}
if (attempts > 50)
return;
var src = that.src;
that.src = null;
that.src = src+'#'+attempts;
$(that).data('reload_attempts', ++attempts);
}, 50);
}
$('img.icon').error(iconError);


This was used in our browse control based replacement to the default output control.

Basically it just keeps retrying to load the images every 50 milliseconds for up to 50 attempts by binding to the event that happens when an image with the icon class has an error.

This can be used even with the feature request because it allows you to just structure the browse call to come before the browse_rsc call and let the images just load in the background to make it seem more responsive.
I actually thought of something similar, but my javascript skills weren't really up to par to come up with that elegant of a solution. I'm *definitely* throwing that into our browser elements. We use them lots.

This would also work with a browse_rsc() flag to just not wait.

Thanks for the nice patch in the meantime :)
I'll need to throw jquery into what we're doing of course, which means I'll have to do this when I've got a little more tinker-time but I'll let you know how it turns out.