Writing a blog post to whine about a movie I disliked is not something that I would have expected myself to do. But since I seem to have a different perspective on this film than any of the other reviews that I read, here goes.
Spoilers ahead.
For me, the main conflict of this movie was the lobotomy awaiting the poor bleached-blond girl. I don't think she had a name besides "Baby Doll", so I'll have to stick with that. Baby Doll was faced with a horrifying, permanent physical and mental assault, and I badly wanted her to avoid this.
By the end of the movie, she had done essentially nothing to prevent it. She does not utter a single word in the "real world" segments of the film. Despite having the situation explicitly spelled out within earshot by Blue and her stepfather, she does not take any of the steps that a rational person would be expected to take. She doesn't tell the female "Polish" psychologist, who by any indication was genuinely interested in helping her. She does not try to explain the situation to the other orderlies or to Blue's boss, at least some of whom were bound to care about a violation of the law and of the asylum's policies. And when the time comes, she walks meekly into the operating room and lets herself be strapped in without a peep. What the fuck?
The point of the film is that escaping into a fantasy world is somehow empowering. How is it empowering? It didn't work, and it apparently distracted her from the obvious strategy of trying to rationally communicate with other human beings, which is how everything gets done in the real world last I checked.
Now, the Polish lady does mention that Baby Doll started a fire, and helped someone escape, etc. So apparently she was trying to influence the outcome in some way. I do not understand Baby Doll's strategy.
Was the asylum environment so toxic that no staff member would have entertained her story? No. There is every indication that at least the Polish doctor would have listened, since she gives Baby Doll an examination in one scene, and she would have investigated an allegation of repeated forgings of her signature, or at least not been surprised when she discovers it at the end of the film.
Was Baby Doll so psychologically damaged or socially crippled, either initially or due to some sort of PTSD effect, that she was unable to communicate with the people around her? After all, she's twenty years old and seems quite helpless, even before the asylum. Apparently she is not a complete vegetable if she helped another inmate escape.
So yeah. The other critiques that I read focused on the conspicuous identification of the female characters as sex objects, especially by themselves. I think that's a valid feminist response. The part I found more objectionable, which others have mentioned, is the silly thought that your imagination can somehow save you from oppression. Learning to cope with hardship is one thing, but seriously, by the end of the movie I was hoping for a prison riot and a lot of dominant male throats getting slit, not silent acquiescence.
I got hung up on the lobotomy to such an extent that it distracted me from the rest of the movie. It was so gruesome that it stayed in the back of my mind the whole time; it anchored me to the "real" storyline at the expense of the more enjoyable ones. Having come for the steampunk and short skirts, I found this disappointing.
Sunday, March 27, 2011
Thursday, January 13, 2011
HTTP chunks and onreadystatechange
One of the features of HTTP 1.1 is "chunked transfer encoding". Rather than send a Content-Length header followed by the entire document, it is possible to transmit the body as a series of chunks, each with their own content length declaration. This lets you start sending the beginning of the document before you know how long it's going to be.
It also makes Comet "streaming" possible, letting you trickle down data without the overhead of a full HTTP request for each message. This depends on your browser telling you when new chunks arrive. As you might guess, this isn't supported by Internet Explorer. But all other major browsers that I've tried (Firefox, Chrome, Safari) will fire multiple XMLHttpRequest onreadystatechange events (readyState == 3) as additional parts of the document are received.
Here's MochiWeb's implementation of chunked transfer encoding, which is pretty straightforward:
For each chunk, you send an integer size, followed by a newline, followed by that number of bytes of data, followed by another newline. On the client, the web browser stitches each segment together, appending the data to responseText.
When designing Kanaloa's streaming protocol, I initially took it for granted that each chunk would have its own onreadystatechange event. This made parsing the chunks simple; in my case, I just sent down a valid JSON array in each chunk, kept track of how much responseText I'd already seen on the client, and called JSON.parse on the difference.
The first thing I noticed was that sometimes single chunks would be split across multiple events. I theorized that this resulted from them being put into multiple TCP packets, and indeed limiting the chunk size to the typical TCP segment size seemed to fix this problem.
The next thing I noticed was that sometimes multiple chunks would be concatenated into the same event. This was also a problem, as JSON.parse needs a valid expression, and '["foo"]["bar"]' wasn't cutting it.
You can see both of these cases demonstrated here:
http://schwink.net/blog/chunker/client/
The small chunks are often concatenated, and the large chunks are split.
I took a look at the TCP packets in Wireshark, and am struct by two things. First, the small messages do in fact arrive as their own separate TCP packets. So the browser is stitching them together into the same event in some cases. They arrive at roughly equal intervals in the case I examined.
Secondly, in the cases where a chunk is split across multiple events, the event boundaries do correspond with the packet boundaries.
So I think we can conclude that the browser simply reads in incoming packets into its responseText buffer, and fires onreadystatechange for each. If your script is still running from the previous event, it just makes the responseText available to you when you get that field, rather than wait to send another event later.
This sort of begs the question whether we could construct a scenario where additional text gets appended to responseText without you being notified, or where it changes between multiple reads to that field by the same JavaScript thread. But I've just about had my fill of this topic for now : )
In the end I had to do what I'd been hoping to avoid from the start, and write my own logic to split the response, rather than trust the events to delineate them. The result may be the world's simplest and least featureful JSON parser, whose only job is to split a string into substrings that encode JSON arrays, which can in turn be properly deserialized. But it seems to work, and because it leaves unterminated arrays untouched, I can now also receive messages of arbitrary size that span multiple chunks.
It also makes Comet "streaming" possible, letting you trickle down data without the overhead of a full HTTP request for each message. This depends on your browser telling you when new chunks arrive. As you might guess, this isn't supported by Internet Explorer. But all other major browsers that I've tried (Firefox, Chrome, Safari) will fire multiple XMLHttpRequest onreadystatechange events (readyState == 3) as additional parts of the document are received.
Here's MochiWeb's implementation of chunked transfer encoding, which is pretty straightforward:
%% @spec write_chunk(iodata()) -> ok%% @doc Write a chunk of a HTTP chunked response. If Data is zero length,%% then the chunked response will be finished.write_chunk(Data) ->case Request:get(version) ofVersion when Version >= {1, 1} ->Length = iolist_size(Data),send([io_lib:format("~.16b\r\n", [Length]), Data, <<"\r\n">>]);_ ->send(Data)end.
For each chunk, you send an integer size, followed by a newline, followed by that number of bytes of data, followed by another newline. On the client, the web browser stitches each segment together, appending the data to responseText.
When designing Kanaloa's streaming protocol, I initially took it for granted that each chunk would have its own onreadystatechange event. This made parsing the chunks simple; in my case, I just sent down a valid JSON array in each chunk, kept track of how much responseText I'd already seen on the client, and called JSON.parse on the difference.
The first thing I noticed was that sometimes single chunks would be split across multiple events. I theorized that this resulted from them being put into multiple TCP packets, and indeed limiting the chunk size to the typical TCP segment size seemed to fix this problem.
The next thing I noticed was that sometimes multiple chunks would be concatenated into the same event. This was also a problem, as JSON.parse needs a valid expression, and '["foo"]["bar"]' wasn't cutting it.
You can see both of these cases demonstrated here:
http://schwink.net/blog/chunker/client/
The small chunks are often concatenated, and the large chunks are split.
I took a look at the TCP packets in Wireshark, and am struct by two things. First, the small messages do in fact arrive as their own separate TCP packets. So the browser is stitching them together into the same event in some cases. They arrive at roughly equal intervals in the case I examined.
Secondly, in the cases where a chunk is split across multiple events, the event boundaries do correspond with the packet boundaries.
So I think we can conclude that the browser simply reads in incoming packets into its responseText buffer, and fires onreadystatechange for each. If your script is still running from the previous event, it just makes the responseText available to you when you get that field, rather than wait to send another event later.
This sort of begs the question whether we could construct a scenario where additional text gets appended to responseText without you being notified, or where it changes between multiple reads to that field by the same JavaScript thread. But I've just about had my fill of this topic for now : )
In the end I had to do what I'd been hoping to avoid from the start, and write my own logic to split the response, rather than trust the events to delineate them. The result may be the world's simplest and least featureful JSON parser, whose only job is to split a string into substrings that encode JSON arrays, which can in turn be properly deserialized. But it seems to work, and because it leaves unterminated arrays untouched, I can now also receive messages of arbitrary size that span multiple chunks.
Subscribe to:
Posts (Atom)