2009年12月15日火曜日

Shindig + Partuzaでキャッシュさせない設定

Shindig + Partuzaで開発するならキャッシュ機能をオフにしないと不便。
Shindig,Partuzaの両方ともキャッシュに関する設定があるので、両方ともオフにする。

Shindig (PHP版)

cache_timeを0に設定する。


$ cat /path/to/shindig/php/config/local.php
'PartuzaService',
'activity_service' => 'PartuzaService',
'app_data_service' => 'PartuzaService',
'messages_service' => 'PartuzaService',
'oauth_lookup_service' => 'PartuzaOAuthLookupService',
'extension_class_paths' => '/Library/WebServer/Documents/partuza/Shindig',
'cache_time' => 0,
);


Partuza


こちらもcache_timeを0に設定する。


$ cd /path/to/partuza/html/
$ diff -u config.php.org config.php
--- config.php.org 2009-12-15 12:27:12.000000000 +0900
+++ config.php 2009-12-15 12:25:25.000000000 +0900
@@ -20,7 +20,7 @@

$config = array(
// Language to use, used for gettext / setenv LC_ALL
-'language' => 'en_US',
+'language' => 'ja_JP',

// prefix of where partuza lives, empty means it's /
'web_prefix' => '',
@@ -58,7 +58,7 @@
// If you use CacheStorageMemcache as caching backend, change these to the memcache server settings
'cache_host' => 'localhost',
'cache_port' => 11211,
-'cache_time' => 24 * 60 * 60,
+'cache_time' => 0,

2009年12月14日月曜日

デフォルトのストレージエンジンをInnoDBにする

LeopardにdmgからインストールしたMySQLのデフォルトのストレージエンジンがMyISAMだってことに最近気付いた。
デフォルトのストレージエンジンを変更するにはmy.cnfでdefault-storage-engineを指定すればOK


$ sudo vi /etc/my.cnf
$ cat /etc/my.cnf
[mysqld]
default-storage-engine=InnoDB


mysqlを再起動して、実際にInnoDBになったか確認


$ mysql -uroot
mysql> create database foo;
mysql> use foo
mysql> create table bar(id int not null);
mysql> show table status bar ¥G
*************************** 1. row ***************************
Table: bar
Create Table: CREATE TABLE `bar` (
`id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

2009年12月3日木曜日

MySQL 主キーの追加・削除

忘れるのでメモ

主キーの追加


ALTER TABLE テーブル名 ADD PRIMARY KEY (カラム名1[,カラム名2...]);


主キーの削除


ALTER TABLE テーブル名 DROP PRIMARY KEY


削除時下のようなエラーがでたら制約を疑う

OperationalError: (1025, "Error on rename of './foo/#sql-b6f_3958' to './foo/bar' (errno: 150)")


制約を確認


mysql> SHOW CREATE TABLE foo;

2009年11月24日火曜日

AmazonRDSでslow queryを出力するようにする方法

AmazonRDSは、デフォルトの設定ではslow queryを出力するようになっていない。
また、MySQLが動いているサーバにアクセスすることができないので、slow queryをログファイルに出力したとしてもそれを閲覧する術がない。
RDSでも採用されているMySQL 5.1からは、slow queryをテーブルに保存できるようになったので、それを使う。

方針

  • ログはテーブル(mysql.slow_log)に出力する。

  • 実行に1秒以上かかったクエリを記録する

  • 100行以上を読み込んだクエリを記録する



普通なら以下のオプションをmy.cnfに設定すればOK。


[mysqld]
slow_query_log = ON
long_query_time = 1.000
log_output = TABLE
min_examined_row_limit=100


RDSの場合は、db-parameter-groupを作成し、パラメータを編集し、db-instanceに適用する。
今回はacme-param-grpというdb-parameter-groupを作成し、acmeというdb-instanceに適用する。

db-parameter-groupを作成

$ rds-create-db-parameter-group acme-param-grp -e MySQL5.1 -d "parameter group for acme"


db-parameter-groupのパラメータを編集
(log_outputはデフォルトでTABLEになっているので設定しない。設定しようとしてもできない)


$ rds-modify-db-parameter-group acme-param-grp \
--parameters="name=slow_query_log, value=ON, method=immediate" \
--parameters="name=long_query_time, value=1, method=immediate" \
--parameters="name=min_examined_row_limit, value=100, method=immediate"


methodに指定できる値はimmediate もしくは pending-reboot

編集したパラメータの確認

$ rds-describe-db-parameters acme-param-grp --source user
DBPARAMETER long_query_time 1 user integer dynamic true
DBPARAMETER min_examined_row_limit 100 user integer dynamic true
DBPARAMETER slow_query_log 1 user boolean dynamic true


sourceに指定できる値はuser 、system、 engine-default

db-parameter-groupをdb-instanceに適用

$ rds-modify-db-instance acme --db-parameter-group-name=acme-param-grp


db-instanceを再起動

$ rds-reboot-db-instance acme


db-instanceにdb-parameter-groupが適用されているか確認

$ rds-describe-db-instances
DBINSTANCE acme 2009-11-04T10:59:28.860Z db.m1.large mysql5.1 100 xxxx available acme.xxxxxxx.us-east-1.rds.amazonaws.com 3306 us-east-1d 1
SECGROUP xxxx active
PARAMGRP acme-param-grp in-sync


PARAMGRPがacme-param-grpになっていて、ステータスがin-syncになっていればOK。

さらにmysqlにアクセスしパラメータが有効になっているか確認する。


mysql > show global variables like 'slow_query_log';
+----------------+-------+
| Variable_name | Value |
+----------------+-------+
| slow_query_log | ON |
+----------------+-------+
1 row in set (0.00 sec)

mysql> show global variables like 'long_query_time';
+-----------------+----------+
| Variable_name | Value |
+-----------------+----------+
| long_query_time | 1.000000 |
+-----------------+----------+
1 row in set (0.00 sec)

mysql> show global variables like 'min_examined_row_limit';
+------------------------+-------+
| Variable_name | Value |
+------------------------+-------+
| min_examined_row_limit | 100 |
+------------------------+-------+
1 row in set (0.00 sec)

2009年11月20日金曜日

Python 今日覚えたこと

utf-8な文字列を内部で扱う形式にデコードする際、


unicode_str = utf8_data.decode('utf-8')

とするとutf8_dataにデコードできないバイト列があった場合、UnicodeDecodeErrorの例外をだす。


UnicodeDecodeError: 'utf8' codec can't decode byte 0xb4 in position 1: unexpected code byte


デコードできない文字列を削除してしまっていいのなら'ignore'を引数で渡してやればよい。


unicode_str = utf8_data.decode('utf-8', 'ignore')


さらにdecodeよりunicodeの方が高速らしい。


unicode_str = unicode(utf8_data, "utf-8", 'ignore')


エンコード、デコードの概念はPerlと同じなので理解しやすかった。

参考
http://snippets.hachinos.net/lang/python/user/piro_suke/3/
http://d.hatena.ne.jp/methane/20090816/1250433407

2009年11月18日水曜日

saveをオーバーライドする時はforce_insert、force_updateを渡す

Djangoでdjango.db.Modelsのsaveメソッドをオーバーライドする際


def save(self):


とすると、create()とget_or_create()で以下のようなエラーを吐いた。


TypeError: save() got an unexpected keyword argument 'force_insert'


saveにforce_insert,force_updateを渡すようにしないといけないらしい。
正解はこう


def save(self, force_insert=False, force_update=False):


http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges


create() and get_or_create() will never update existing objects ¶

In [8670] a change was made to both create() and get_or_create() that affects people in two ways:

Firstly, if you have a custom save() method on your model and it is going to be called using create() or get_or_create(), you should make sure you accept the force_insert parameter (best to accept force_update as well, just like django.db.models.base.Model.save()). You don't have to do anything with these parameters, just pass them through to the Model.save() method.

2009年11月17日火曜日

urllib2でgzipされたデータを扱う

ここに書いてあった。
http://diveintomark.org/projects/misc/httpgzip.py.txt

StringIOよりcStringIOのが高速でよいと聞いたのでそちらを使ってみる。
それ以外はまるパクリ。



import urllib2, gzip, cStringIO

def get(uri):
request = urllib2.Request(uri)
request.add_header("Accept-encoding", "gzip")
usock = urllib2.urlopen(request)
data = usock.read()
if usock.headers.get('content-encoding', None) == 'gzip':
data = gzip.GzipFile(fileobj=cStringIO.StringIO(data)).read()
return data

if __name__ == '__main__':
import sys
uri = sys.argv[1:] and sys.argv[1] or 'http://mixi.jp/'
print get(uri)

2009年11月13日金曜日

MySQL 外部キー制約の追加、削除

忘れるのでメモ

MySQL 5.1で確認した。

外部キー制約の確認

SHOW CREATE TABLE テーブル名;


show create table bbs_thread;


外部キー制約の追加

ALTER TABLE テーブル名 ADD FOREIGN KEY (制約を張りたいカラム) REFERENCES 張りたいテーブル(張りたいカラム);


alter table bbs_thread add foreign key (creator_id) references accounts_user(id);



外部キー制約の削除

ALTER TABLE テーブル名 DROP FOREIGN KEY 制約名;


ALTER TABLE bbs_thread drop foreign key creator_id_refs_id_75448b6c;

2009年11月11日水曜日

Leopardでcapistrano

Leopardにはデフォルトでcapistranoが入っているが、バージョンが古いので、更新する

$ sudo gem install capistrano

複数環境にデプロイできるように。capistrano-extをインストールする

$ sudo gem install capistrano-ext

2009年10月26日月曜日

LeopardにPILをpipでインストール

$ pip install PIL

とすると
IOError: [Errno 2] No such file or directory: '/Path/to/build/PIL/setup.py'
というエラーがでてインストールできない。

ソースのURLを指定してインストール。

$ pip install http://effbot.org/downloads/Imaging-1.1.6.tar.gz

Jpeg support not availableとログに出た場合は、
jpegを利用できるようにするために、libjpegをインストール

$ wget http://www.ijg.org/files/jpegsrc.v7b.tar.gz
$ tar zxvf jpegsrc.v7b.tar.gz
$ cd jpeg-7
$ ./configure
$ make && sudo make install

そんでもいっかいpip

$ pip install http://effbot.org/downloads/Imaging-1.1.6.tar.gz

JPEG support ok とでればOK。

2009年10月22日木曜日

safari3でjTemplatesがうまく動かない問題を解決

jTemplatesのsetTemplateElementメソッドを使ってテンプレートをロードする際、テンプレートに日本語が含まれていると、safari3では何も表示されないという問題に遭遇。
jQuery,jTemplatesのバージョンはそれぞれ現在最新の、1.3.2と0.7.8。

原因を調べるため、jquery-jtemplates.jsを見てみると、なんのことはない、replaceの正規表現がうまくマッチせず、テンプレート内のコメント部分の除去がうまくいってないだけだった。

具体的にはjquery-jtemplates.jsの中のjQuery.fn.setTemplateElement内にある下のコード。

s = s.replace(/^<\!\[CDATA\[([\s\S]*)\]\]>$/im,'$1');
s = s.replace(/^<\!--([\s\S]*)-->$/im, '$1');


これがsafari3だとうまくマッチせず、<!--と-->が除去されず、そのままコメント扱いになり、表示されていなかった。

とりあえず、上記コードを下記のように修正することで対応した。


s = s.replace(/^<\!\[CDATA\[/m, '').replace(/\]\]>$/m, '').replace(/^<\!--/m, '').replace(/-->$/m, '');

2009年9月14日月曜日

mixiアプリの表示領域(高さ)を調整する最適な方法

mixiアプリの開発をはじめてからずっと表示領域(高さ)の調節に悩まされていたのですが、下記の記述でうまく調整されるようになりました。

gadgets.window.adjustHeight($(document).height());


$(document).height()でjQueryを使ってdocumentの高さを取得し、
コンテナの提供するgadgets.window.adjustHeightに渡すようにしています。


そもそも、gadgets.window.adjustHeightは引数を渡さず実行すると、表示領域の高さを自動調整してくれるはずなので、引数なしで呼びだせばそれでOKなはずなのですが、これが結構うまく動作してくれません。
その結果コンテンツが全て画面に入りきらずに、スクロールバーが表示されてしまい、見づらいし、使いずらいということになってしまいます。

ここで問題なのが、開発環境と本番環境で挙動が異なるということで、
僕の場合ローカルの開発環境(Partuza+Shindig)では高さの自動調整がうまく行くのに、mixi上で動作させると高さがうまく調整されずスクロールバーがでてしまうという現象になやみました。

そこで上記の解決策です。jQueryで高さを取得することで、コンテナに依存しなくなるので、開発環境でも本番環境でも同じ挙動を得ることができるようになりました。

コンテナが成熟してくればこの手の問題はある程度解決していくとは思いますが、コンテナ毎の微妙な差異というのは少なからず残るのではないかと思います。

そのため、今回のようにコンテナに依存しないような方法を取るというのは、様々なプラットフォームで動かすアプリを作る時には考えなければいけないなと思います。

2009年6月4日木曜日

10日でおぼえるPython入門教室

CMSコミュニケーションズの寺田さんから「10日でおぼえるPython入門教室」を献本いただきました!
どうもありがとうございます!!

ちょうど僕の中で「Python」が熱くなっていたところだったんです!
まさにベストなタイミング!

10日目にはGoogle App Engineの使い方の解説もあるみたい。
これからじっくり読んでみます。


10日でおぼえる Python 入門教室
穂苅 実紀夫 寺田 学 中西 直樹 堀田 直孝 永井 孝
翔泳社
売り上げランキング: 5963




2009年3月14日土曜日

OpenPNE flipclip小窓スクリプト 新URL対応版

FlipClpリニューアルに伴って、クリップのURLを下記のように変更しました。

旧URL
>

http://www.flipclpi.net/{userid}/{clip_no}
<

新URL
>

http://www.flipclpi.net/{clip_no}
<

旧URLから新URLへはリダイレクトするようにしているので旧URLはそのままにしておいて問題ないのですが、クリップのURLを正規表現でマッチさせてごにょごにょしたりしている場合、新URLだとマッチせずうまく動かないってことがおこっちゃってます。

OpenPNEの小窓機能もそのひとつで、新URLを貼り付けるとうまくURLがマッチせず、動画が表示されなくなってしまってます。
OpenPNEの中の人が対応してくれると思いますが、取り急ぎ、新URLでも動くものをのっけておきます。
以下のflipclip.net.js、www.flipclip.net.jsをダウンロードして、public_html/cmd/に上書きコピーすればOKです。

>

OpenPNE flipclip小窓スクリプト 新URL対応版
flipclip.net.js
www.flipclip.net.js
<









2009年3月11日水曜日

FlipClipがリニューアルしました!

FlipClipがリニューアルしました。

詳しい内容はこちら
http://blog.flipclip.net/2009/03/post_57.html

今回のリニューアルで体感できるほど、サイトのレスポンスが上がったと思います。

今までサービス全体のレスポンスを下げていた、全レコードに対する検索を見直すことで、DBの負荷が50〜100分の1になりました。

レコードの検索に対して、様々な場面を想定して、柔軟に条件を指定検索できるような実装をしてしまっていたのが、DBのレスポンスを悪くして、サイトを重くしていた主な原因であり、反省する点です。

今回の件で、「なんでもできる」ものは「なんにもできない」のと同じだってことを痛感しました。
リーンな開発を心がけようと心に誓いました。







2009年2月13日金曜日

DjangoXPython

僕のとなりの席の露木さんがDjangoの本を書きました!

「ディージャンゴ」じゃないよ「ジャンゴ」だよ。

Googleも使ってるPythonのフレームワークで、優秀なadmin機能が標準装備されていたり、テンプレートの継承ができたりします。

僕もDjangoに(露木さんに?)インスパイアされてテンプレートの継承っぽいことができるTTのプラグイン書いて、FlipClipで使ってます。


Django×Python
posted with amazlet at 09.02.12
露木 誠
技術評論社
売り上げランキング: 5011