danzel/Leaflet.utfgrid — pull request #28 by aliceh75 (2014-09-08 11:20:33+00:00)
Title: Implemented a queue for the tile requests (#2)

Hello,

Here is an implementation of a queue for tile requests. I have re-generated the files in `dist/` only to notice they were not in sync with the code in `src/` ! So when looking at the diffs, check the diffs with the file in `src/`.

Motivation for the implementation:

- Limit the number of requests sent at once. Browsers prioritize javascript/json requests, so in my use cases the visual tiles did not get loaded until all the utfgrid tiles were loaded. When these take a non-trivial time to generate, this delays the visual tiles noticeably. Chrome/FF send at most 8 concurrent requests by default (not sure about IE), so I have set this to a (configurable) default of 4 concurrent utfgrid requests. This ensures that there is 4 available slots for image tiles;

- Cancel loading requests. By limiting the number of concurrent requests, we can also ensure that if a tile has gone out of view before it even started loading then we can simply drop it from the queue. My implementation also cancels loading tiles after the ajax request was made. In Chrome, this works for JSON tiles but not JSON-P tiles. This provides an additional performance boost if the tile server detects dropped connections (not a trivial problem. I assume many won't; but the one I implemented for this project does if the connection gets dropped while in the server queue).

Implementation notes:
- Rather than directly sending the requests, `_loadTileP` and `_loadTile` call `_queue_request` to add the request to the queue. `_queue_request` is called with the key of the tile (ie. `__`) and a function to be called when the request should be initiated. The function should return an object that has an `abort` method, that can be used to cancel requests;

- Request callbacks must invoke `_finish_request(key)`;

- Requests are stored as objects in `_request`, indexed by the request key. The request object defines:
- `callback`, the function that is called to start the actual request;
- `handler`, the object returned by the callback function ;
- `timeout`, a timeout id used to track request timeouts. The timeout starts when the request is initiated, and will abort the request if triggered before `_finish_request` is called.

- Every time a new request is added, and every time a request finishes or is aborted (via timeout or by being moved out of view) `_process_queued_requests` is called. This ensures that we are always processing as many requests as possible (and no request is left un-processed);

- The queue is filo queue. As users pan the map, newer requests are likely to be more important, while older requests are more likely to get dropped.