Ubuntu serverに入れてるDropboxが変なメッセージを出すようになった
ちょっと前くらいからこんなメッセージが出るようになった
$ Unable to monitor entire Dropbox folder hierarchy. Please run "echo 100000 | sudo tee /proc/sys/fs/inotify/max_user_watches" and restart Dropbox to correct the problem.
わけもわからず言われるがままコマンド叩いてたんだけど、毎日ログインVM起動する度に表示されてていい加減鬱陶しくなったので調べた。
/proc/sys/fs/inotify/max_user_watches とは
引用の引用
/proc インターフェース
以下のインターフェースは、inotify で消費されるカーネルメモリの総量を制限するの
に使用できる:/proc/sys/fs/inotify/max_queued_events
このファイルの値は、アプリケーションが inotify_init(2) を呼び出すときに使用さ
れ、対応する inotify インスタンスについてキューに入れられるイベントの数の上限
を設定する。この制限を超えたイベントは破棄されるが、 IN_Q_OVERFLOW イベントが
常に生成される。/proc/sys/fs/inotify/max_user_instances
1 つの実ユーザ ID に対して生成できる inotify インスタンスの数の上限を指定す
る。/proc/sys/fs/inotify/max_user_watches
作成可能な監視対象の数の実 UID 単位の上限を指定する。
だそうです。要するに監視対象のファイル数が上限をオーバーしたってことか。
/etc/sysctl.conf
/proc/sys/fs/inotify/max_user_wathces は直接書き換えても再起動の度にリセットされるらしいので、/etc/sysctl.conf を編集する
こいつはカーネルパラメータを設定するファイルだそうです。そんな事言われたらインフラ知識からっきしな僕は怖くて手が震えてしまうんですががが。
[ThinkIT] 第5回:カーネルをチューニングする (1/4)
管理者権限で開く。
$ sudo vi /etc/sysctl.conf
以下の行を追加する
fs.inotify.max_user_watches = 100000
追加後にこの設定を反映させるために以下のコマンドを叩く
$ sudo sysctl -p
これでたぶん直ったはず。
コミット時にpdb消し忘れてないかチェックするhg hook
チェック用のスクリプト
こんな感じのスクリプト作成
#!/usr/bin/env python import os import sys COMMAND = r"find . -name '*.py' | xargs grep -lr '{pattern}'" INFO = '{filename}: pdb found.' def check(pattern): return os.popen(COMMAND.format(pattern=pattern)).readlines() def display_warning(lines): for line in lines: print >> sys.stderr, INFO.format(filename=line.strip('\n')) def check_pdb(*args, **kwargs): lines = check('pdb.set_trace') if lines: display_warning(lines) sys.exit(1)
~/.hgext/hookpdb/check.py みたいな感じで配置。
試してみる
pdb仕込みっぱなしのファイルがある状態でコミットしようとすると…
$ hg ci ./hoge.py: pdb found. transaction abort! rollback completed note: commit message saved in .hg/last-message.txt
うん、できてる。けど、ファイル多いともっさりがキニナルような…
追記
@kk6 こんな感じでコミットに含まれるファイルだけチェックするようにしたら速くなるんじゃないですかね。 URL
2012-09-13 02:30:15 via Saezuri to @kk6
ありがとうございますありがとうございます!
描き直してみました。
#!/usr/bin/env python import os import sys from fnmatch import fnmatch COMMAND = r"grep -l {pattern} {file}" INFO = '{filename}: debugger found.' PATTERNS = ['pdb.set_trace', 'import debug'] def check(repo, file, patterns): patterns = ['-e "{ptn}"'.format(ptn=pattern) for pattern in patterns] pattern = ' '.join(patterns) file = os.path.join(repo.root, file) return os.popen(COMMAND.format(pattern=pattern, file=file)).read() def display_warning(lines): for line in lines: print >> sys.stderr, INFO.format(filename=line.strip('\n')) def get_pyfiles(repo, node): return [f for f in repo[node].files() if fnmatch(f, '*.py')] def check_pdb(ui, repo, hooktype, node=None, source=None, **kwargs): lines = [f for f in get_pyfiles(repo, node) if check(repo, f, PATTERNS)] if lines: display_warning(lines) sys.exit(1)
さらにさらに修正
ゆとりな僕はpdbよりもdebugモジュールを使いがちなのでパターンを複数受け取れるように修正しました。もうGistでやれよと思います。
インスタンスに動的にメソッドを追加する
追記:
記事を公開してからおんなじような記事あったりするかなと思ってググったら2年前にIanさんがほとんど同じ内容書いてた。
Pythonでメソッドをクラスまたはインスタンスに動的に追加する - Ian Lewis
しかも僕その記事はてブしてたよ…
Interactive Shell で色々試してる時なんかにインスタンスにメソッドを追加したくなる時がある。
>>> class Person(object): ... def __init__(self, name): ... self._name = name ... >>> alice = Person("Alice") >>> bob = Person("Bob")
こんなクラスがあって、幾つかインスタンスを作っているとする。で、self._nameを取得するメソッドが欲しくなったとしよう。
>>> def get_name(self): ... return self._name
これを単純にインスタンスのメンバーとして代入してもうまくいかない
>>> alice.get_name = get_name >>> alice.get_name() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: get_name() takes exactly 1 argument (0 given)
これはalice.get_nameがただの関数だから。インスタンスメソッドではない。
>>> type(alice.get_name)
<type 'function'>
コレジャナイので一旦消します。
>>> del alice.get_name
さて、じゃあどうすればいいかというと
>>> Person.get_name = get_name
というようにクラスの方に追加してやる。ただ、これだと当然ながら全てのインスタンスに影響が出る
>>> alice.get_name() 'Alice' >>> bob.get_name() 'Bob'
影響が出るというか、実はaliceもbobもget_nameなんて持ってない。持ってないんだけど、クラスの方を見に行ったらそっちにあったからそれを呼び出してるだけ。
>>> del alice.get_name Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: get_name >>> alice.__dict__ {'_name': 'Alice'}
というわけでまあこれでいいんだけど、もしある特定のインスタンスにだけ設定したいなんて場合にはどうすればいいか…というのが今回の本題。結論としては、types.MethodTypeを使う。
>>> del Person.get_name >>> import types >>> alice.get_name = types.MethodType(get_name, alice) >>> alice.get_name() 'Alice' >>> bob.get_name() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'Person' object has no attribute 'get_name'
第一引数にメソッドとして登録したい関数、第二引数にインスタンスを渡してやると、それらを紐付けてくれる。これでaliceはget_nameメソッドを持ってるけど、bobは持っていないという状態にすることができる。用途が思いつかないけど気になったから調べてみただけ。