LoginSignup
1
1

More than 5 years have passed since last update.

OpenStack クライアントのタイムアウト

Posted at

OpenStackのCLI(コマンドラインインターフェース)の動作が予想と違っていたので調査した。

OpenStackのCLIにはタイムアウトの引数がある。例えばkeystoneの場合:

$ keystone --help
--timeout <seconds>       Set request timeout (in seconds).

デフォルトはタイムアウトしない設定になっている。

このtimeoutはCLIコマンド自体のタイムアウトではないし、もっと厳密に言うとリクエストのタイムアウトでもない。(Set request timeoutって書いてあるのに!)

結論から言うとOpenStackクライアントのtimeout設定はAPIコールの無通信時間のタイムアウトである。

OpenStackのクライアントライブラリのソースを追ってみた。OpenStackのクライアントライブラリのtimeoutパラメータはPythonのHTTPライブラリrequestsにそのまま渡される。

requestsのマニュアルには以下のような但し書きがある。

timeout is not a time limit on the entire response download; rather, an exception is raised if the server has not issued a response for timeout seconds (more precisely, if no bytes have been received on the underlying socket for timeout seconds). If no timeout is specified explicitly, requests do not time out.

実際に試してみるために、20秒おきに'.'を出力するサーバをつくる

$ ( echo "HTTP/1.0 200 OK"; echo; while true;do sleep 20;echo ".";done ) | nc -l 8080

タイムアウト10秒でリクエストすると正しくタイムアウトする。

$ python
>>> requests.request('GET', 'http://localhost:8080',timeout=10)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/api.py", line 53, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/sessions.py", line 608, in send
    r.content
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/models.py", line 737, in content
    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/models.py", line 667, in generate
    raise ConnectionError(e)
requests.exceptions.ConnectionError: HTTPConnectionPool(host='localhost', port=8080): Read timed out.

問題となるのは、タイムアウト値以下で間欠的なレスポンスを返すケースだろう

実際に試すために1秒ごとに'.'を出力するサーバをつくる。

$ ( echo "HTTP/1.0 200 OK"; echo; while true;do sleep 1;echo ".";done ) | nc -l 8080

以下のように、タイムアウト10秒でHTTPリクエストをしてもタイムアウトしない。

$ python
>>> import requests
>>> requests.request('GET', 'http://localhost:8080',timeout=10)
(ここでCtrl-Cまで停止)
^CTraceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/api.py", line 53, in request
    return session.request(method=method, url=url, **kwargs)
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/sessions.py", line 468, in request
    resp = self.send(prep, **send_kwargs)
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/sessions.py", line 608, in send
    r.content
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/models.py", line 737, in content
    self._content = bytes().join(self.iter_content(CONTENT_CHUNK_SIZE)) or bytes()
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/models.py", line 660, in generate
    for chunk in self.raw.stream(chunk_size, decode_content=True):
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/packages/urllib3/response.py", line 344, in stream
    data = self.read(amt=amt, decode_content=decode_content)
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/site-packages/requests/packages/urllib3/response.py", line 301, in read
    data = self._fp.read(amt)
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/httplib.py", line 612, in read
    s = self.fp.read(amt)
  File "/Users/tumf/.pyenv/versions/2.7.10/lib/python2.7/socket.py", line 384, in read
    data = self._sock.recv(left)
KeyboardInterrupt

OpenStackクライアントのtimeout設定は期待した時間にタイムアウトしないことがあることは頭に入れておきたい。

また、OpenStackのクライアントライブラリはタイムアウトはしないがデフォルトの挙動なので、CLIをバッチプロセス中に組み込むときにtimeout値を設定忘れるとそこで処理が停止したまま・・・なんてこともあるので同じく注意。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1