Cooperative multitasking and HTTP
I have now worked a few interfaces that make repeated requests to a server to complete a single task. Effectively I am relying on the request-queue on the HTTP server to implement cooperative multitasking, and this disturbs me somewhat.
It started with adding many people to a group in GroupServer. This task is slow because for each person a profile has to be created (touching on a couple of databases) and some emails are sent. When dealing with hundreds of new people the system was too slow for a single request, and would result in HTTP timeouts. To mitigate this, the system that adds people in bulk makes many smaller requests: it asks for a person to be added, waits for the response, and then adds the next person. This has a many benefits:
- Each request is relatively quick, so will avoid the dreaded HTTP timeout,
- The page coordinating all the requests can maintain a progress-bar, which is great for usability, and
- The server can respond to requests from other people, as their requests slip into the request-queue on the server between the requests to add each person.
This week I shipped the exact opposite interface: one that generates a CSV file based on the profile data of the group members. It also makes many requests (one per person). However, this time I crated a page that makes multiple requests because it gave the impression of being more responsive for the person exporting the profile data (progress bars are good that way) and to avoid the rest of the system being bogged down dealing with the request — rather than to avoid an HTTP timeout.
When I had finished, and I was admiring my handiwork, I realised that my goals were exactly that of multitasking: where one system handles multiple tasks. What I had implemented was a peculiar brand on cooperative multitasking (where the clients divide up there workload) that used the HTTP request queue.
This disturbs me somewhat, because the next logical step is preemtive multitasking, and that is hard. Tweaking the multitasking schedulers for Linux, for example, is a deep dark art practised by web-scale organisations. Thankfully I suspect that cooperative multitasking will serve me well for a while: MacOS only dropped it when MacOS X was introduced.
Another option to fufill your use case is to send one request to upload all the people. The server just saves the request and says "OK". Then the client can regulary poll the server to get a "processing status". This is what MailChimp does. That way if a user closes their browser down, the upload and process still occurs.