2011年 02月 13日


gerry++

2011年 02月 12日


建国記念の日、せっかくなので橿原神宮 (神話上で建国したことになっている神武天皇が祭神、橿原は建国の地ということになっていて、この神宮の創建は明治の、まぁ想像通りの時期です) にいってみた。とにかく右翼が多くて怖かったんだけど、外拝殿のところでそういう人ら並んで記念写真とってて「はい、チーズ」とかいっていたのがシュールだった。他もろもろ含めて面白かったけど、割と異様な雰囲気なので (祭なのでそういうもんだけど、それにしても)、あまり他人にはおすすめできない。

といってもそっちはメインではなくて、橿原考古学研究所附属博物館に展示されてる大型内行花文鏡を見たかったのでした。が、ピンポイントにその鏡は九州国立博物館に3月まで貸出中とのことで展示されておらず、小さい内行花文鏡しかありませんでした。日本最大の内行花文鏡は福岡で見れるみたいですけど遠すぎるので、鏡見るためにそのうちまた行きたいです。

JavaScript の哲学

  1. 小さいものは美しい
  2. 各スニペットが一つのことをうまくやるようにせよ
  3. できる限り最小限のプロトタイプを作れ
  4. コード量よりも移植のしやすさを選べ
  5. 単純なオブジェクトにデータを格納せよ
  6. 最小限のコードで最大限のことをすることに優位性を見出せ
  7. 効率と移植性を高めるためにコールバックを利用せよ
  8. 束縛するインターフェースは作るな
  9. 全てのスニペットは限りなく独立して動くようにせよ

Mike Gancarz の UNIX哲学の改変です

2011年 02月 11日

Chrome で XHR を abort() し続けるとそのうちリクエストが送信されなくなるのはどうにかならないのか

callback だけ無効にしてサーバサイドではちゃんとレスポンス返せってこと?

いまいち発生条件がつかめてないけど、ページロードしてからの累積回数で決まっているような気がしてならない。待ってても回復しない? というか abort() は自分でやってるんだから、余計なことしないでほしい。嫌なリクエストがくるならサーバ側ではじけばいいんだから……

以下のようなコードで再現する

上記の推測は間違っていて?、要は response body を待っている状態の XHR を abort() しても、Chrome はレスポンスを待ち続けるということらしい。HTTP ヘッダだけ先に送って body をストリームさせる場合にいろいろ困る。

#!/usr/bin/env corona
# vim:ft=perl:
use strict;
use warnings;
use Coro;
use Coro::Timer qw(sleep);

my $HTML = <<'EOF';
<!DOCTYPE html>
<html>
<title>test</title>

<h1>reproducing process</h1>
<ol>
	<li>Request to remote server
	<li>After requested, abort() it
	<li>Try requesting another xhr (but this waits until aborted xhr response)
</ol>

<textarea cols="140" rows="20" id="log"></textarea>

<script>
document.getElementById('log').value = "";
function log (m) {
	document.getElementById('log').value += m + "\n";
}

var seq = 1;
function req (time, callback) {
	log('req:'+seq++);
	var xhr = new XMLHttpRequest();
	xhr.open('GET', '/api/test?' + time, true);
	xhr.onreadystatechange = function () {
		log([ xhr.readyState, xhr.responseText ]);
		if (xhr.readyState == 4) callback();
	};
	xhr.send(null);
	return xhr;
}

function req_abort (time, callback) {
	var xhr = req(time, callback);
	// setup timeout to send request to remote surely.
	setTimeout(function () {
		log('abort');
		xhr.abort();
	}, 100);
	return req;
}

req(0, function () {
	req_abort(10, function () {
		req(1, function () { log('ok') }); // success after 10sec but should success after 1sec
	});
}); // success;


</script>
EOF

sub {
	my $env = shift;
	warn $env->{REQUEST_URI};
	my $sub = {
		'/' => sub {
			[ 200, [ 'Content-Type' => 'text/html' ], [ $HTML ] ];
		},
		'/api/test' => sub {
			sub {
				my $respond = shift;
				my $writer = $respond->([ 200, [ 'Content-Type' => 'application/json' ] ]);
				async {
					sleep $env->{QUERY_STRING};
					$writer->write('{ "ok": true }');
					$writer->close;
				};
			};
		},
	}->{$env->{PATH_INFO}};

	$sub ? $sub->() : [ 404, [ 'Content-Type' => 'text/plain' ], [ '404' ] ];
};

Chrome で 50x を数回受信すると throttle が有効になってリクエストを送信できなくなるが、どういった対策をうてばいいのか?

これは XHR にもあてはまってしまう。

マジでヤバい場合以外 50x を返さないということが必要になってしまう。バックエンドが応答できない場合特定のレスポンスを 200 で返したい、とかいうのは nginx でできるのか?

あるいはそもそも、1度 50x がでたらちゃんと待てばいいんだろうか?

gerry++

2011年 02月 10日