Plain Irc Bot の略。
概要
インストール方法
- リポジトリのlib/pib.scmをもらってきて、適当な場所に設置する
- リポジトリのsample/*.scmをもらってきて、適当に書き換え、実行する
もしくは
wget http://d.tir.jp/pib-0.3.1.tgz
gauche-package install pib-0.3.1.tgz
但し、これでインストールされるのはpibモジュールだけなので、結局、別途sample/*.scmを参照する必要有り。
リポジトリ
同梱のサンプルの詳細
どのスクリプトも、設定部分を適切に書き換える必要があります。
基本的に、stdout/stderrには何も出力しませんが、エラーが発生した時はstderrに表示するので、バックグラウンド実行時でも、一応stderrのログを取っておいた方がいいでしょう。
- つまり、一時的に実行するなら「./logger.scm」でフォアグラウンド実行、止めたくなったらctrl+C
- 本格的に実行するなら、「./logger.scm >> std.log 2>&1 &」でバックグラウンド実行して放置
logger.scm
- ロギング機能と、INVITEに対応するのみ。最もシンプル。
- 生成されるログについては、make-basic-irc-loggerの項目を参照。
ircbot.scm
- ベースにした、 http://homepage3.nifty.com/oatu/gauche/try.html#ircbot とほぼ同等。
- echo 'PRIVMSG #channel :メッセージ' > ./ircbot.pipe
- とか流し込む。発言以外にも、任意のircコマンドが送信可能。
- ※ircbot.pipeはFIFOの為、botプロセスがいない時に流し込むとstuckします。.qmailから流し込んだりする際には注意しないと、大量のqmailプロセスが溜まる事になります。
- FIFO(named pipe)対応の為、ちょっとトリッキーなコードになっている。
- 子スレッドを用意し、そこで受信メッセージをひたすら捨てている。ロギングは:logging-handlerが行う為、受信メッセージをトリガにして動作する挙動を行わないのなら、捨ててしまって問題無い(捨てないと溜まる一方なので、捨てる必要性はある)。
- 親スレッドはひたすらFIFOのメッセージを待ち、受け取ったらircサーバに送信するのみ。
- 生成されるログについては、make-basic-irc-loggerの項目を参照。
repl.scm
- 他人の発言を見て、特定部分の文字列をreadし、evalし、その結果をprintする事を繰り返す。
- 危険。セキュリティホールになる。
- スクリプトの*allowed-hosts*のところに、発言評価機能対象にしたいユーザのhostname(/who nickしたら出てくる@以降の部分)を記述してください。この設定が無いと、評価対象外になります。
- repl.scmに定義されている、「*expr-prefix*で始まり、*expr-suffix*で終わる」発言をすると、その間に書かれているS式がevalされる。その結果はNOTICEとして返される。
- デフォルトでは、*expr-prefix*には「(eval! '」が、*expr-suffix*には「)」が定義されている為、「(eval! '(+ 1 2))」と発言すると「(+ 1 2)」が評価される事になる。
- このeval時の(current-input-port)や(current-output-port)等は、repl.scmを実行したプロセスのstdin/stdout/stderrになっている点に注意する事。
- 同様に、eval時の環境は、(interaction-environment)とかではなくrepl.scmの環境になっている点に注意。必要なら変更する事。
- 生成されるログについては、make-basic-irc-loggerの項目を参照。
cliirc
- まだ未作成。
- command line interface irc client。
- シェルから直接「JOIN '#channel'」とか「MSG 'ああああ'」とか入力する。
- 自分の愛用しているシェルのキーバインドや履歴機能等がそのまま使える。履歴保存ファイル等はデフォルトと違うファイルにした方が吉。
- カレントチャンネル等はシェルの環境変数に保持する。
- ログはlogger.scm同等のログをmultitail等を使って別screenで表示するのが前提。
- 問題点は、日付が変わるとログファイルも変わってしまう事。どうする?
ライセンス
BSD風
使い方詳細
※基本的に、rfc:1459( http://www.haun.org/kent/lib/rfc1459-irc-ja.html )準拠です。
- 最近のircサーバは拡張されているようで、rfc1459よりも広い範囲の設定が可能なようですが(例:nickは15文字ぐらい使用可能、nickにアンダーバーも使用可能)、rfc1459自体はその辺をサポートしていないので(nickは9文字まで、nickにアンダーバーは使用不可)、rfc1459を越える設定を行う場合は、自己責任でお願いします(一応、それらしく動くように実装してはいる筈……)。
event書式
このモジュールでは、ircサーバとの送受信に使うmessageは、「event書式」(仮名)で扱います。event書式とは、以下のフォーマットのlistです。
'(timestamp mode prefix command . params)
- timestampは、送信/受信日時を特定する文字列。送信前の(つまり、irc-send-event!に渡す)eventでは、これは#fにしておく。
- modeは、送信か受信かを特定するシンボル。'sendまたは'recv。これも送信前のeventでは、#fにしておく。
- prefixは、ircサーバによって付与される、該当messageの関連者を示す文字列。これも送信前のeventでは、#fにしておく。
- commandは、ircコマンドを示すシンボル、または、ircレスポンスを示す最大三桁の数値。
- paramsは、commandに与えられる引数。
モジュールのuse
(use pib)
ircサーバに接続する
(with-irc
"irc.server.name" ; ircサーバ名またはip
6667 ; ircサーバのport番号
:irc-server-encoding "iso-2022-jp" ; ircサーバのencoding設定(デフォルトutf-8)
:irc-server-pass "hoge" ; ircサーバのパスワード(デフォルト#f)
:base-nick "nick" ; nick指定(既に使われていた場合は自動で変更される)
:username "hoge" ; username指定(デフォルト:base-nick流用)
:realname "fuge" ; realname指定(デフォルト:username流用)
:flood-protection-interval 1000000 ; 連続send時の自動ウェイト間隔(デフォルト900000)
:logging-handler (lambda (event) ...) ; 送受信messageロギング用ハンドラ(デフォルト#f)
main-thunk)
- 設定されたパラメータで、ircサーバに接続し、main-thunkを実行する。
- main-thunkが返り値を返したり、エラー例外を投げたり、外側の継続を実行して大域脱出したりすると、自動的にircサーバの接続を終了する。
- 尚、main-thunk内での継続を保存しておいての再突入には対応していない。
- with-ircが実行されると、子スレッドが二つ(送信用と受信用)作られる。
- ircメッセージの送信及び受信は、どちらも非同期に行われる。後述の送受信を行う為の手続きは、内部キューにデータを追加したり、取り出したりしているだけで、実際の送受信は、送信用スレッド/受信用スレッドが非同期に行っている。
- main-thunkの実行は親スレッドで行われるが、:logging-handlerの実行は送信用スレッドと受信用スレッドの両方によって行われる(これが問題になる場合があるので要注意!)。
- :logging-handlerに指定する手続きは、引数として「event書式のlist」「eof」「エラーオブジェクト」のどれかを受け取るものとする。前述の通り、複数スレッドから実行される為、スレッド安全かつport競合しないようにする必要がある。
- 後述のmake-basic-irc-logger手続きによって、簡易ロギング手続きを生成できるので、それを使うのが手軽。
- with-irc内では、PINGに対して自動的にPONGが返される(これは受信用スレッドが勝手に行う)。
with-irc内で利用可能な手続き
これらの手続きは、with-irc外では利用できない。
irc-recv-event!
(let1 event (irc-recv-event! . opt-timeout)
...)
- 内部の受信キューから、溜まっているircイベントを一つ取り出す。
- もし受信キューが空なら、受信するまでtimeoutで指定された秒数だけ待つ。
- デフォルト値は0。#fが指定されたら受信するまでずっと待つ。
- ※待っている間はシグナル(SIGINT, SIGTERM含む)が処理されません!よって、同時にシグナルの処理が必要な場合は、timeoutを小さく指定してループするか、別スレッドを用意してそっちでシグナルを処理するかする必要があります。
- timeoutした場合は#fが返される。
- ircサーバから不正なデータが送信され、正しくeventが構築できなかった場合は、エラー例外オブジェクト(condition?述語で#tが返るオブジェクト)が返される。
- ircサーバと(gauche-character-encoding)が一致しない時に、誰かが不正なマルチバイト文字になる発言をした際に、これが返される場合がある
- ircサーバから切断された場合は、#<eof>が返される。
- #<eof>が返された後にまたirc-recv-event!を実行した場合、エラー例外が投げられる。
- よって、with-ircに渡されたmain-thunkは、これを検出したなら、その後に適切なタイミングでプロセスを終了する必要がある。
- 要するに、返り値が何なのかをちゃんと確認し、それに応じた処理を行う必要がある。
irc-send-event!
(irc-send-event! '(#f #f #f PRIVMSG "#channel" "こんにちわ"))
- ircサーバにevent形式のircメッセージ(コマンド)を一つ送る。
- eventのtimestamp, mode, prefixは、設定されていても無視される。
- eventが不正な場合はエラー例外を投げる。
- この手続きは、内部の送信キューにeventを追加するだけで、実際の送信は送信用スレッドが行う。よって、送信が成功したかどうかはこの手続きでは分からない。
- 送信したコマンドがircサーバでエラーと判定された場合は、エラーのレスポンスが送られてくるので、そっちで判別する必要がある。つまり、何にせよ非同期になる。
- eventが充分に大きく、送信時に512byteを越える場合は、適当な長さで512byte以下になるように末尾が切り捨てられる(マルチバイト安全)。
- これが嫌な場合は、後述のsend-event-split-last-paramを使い、送信前に自分自身で分割する必要がある。
irc-send!
(irc-send! '(PRIVMSG "#channel" "こんにちわ"))
- irc-send-event!のラッパー。上の例は、irc-send-event!のところの例と完全に等価。
get-recv-cv
(let1 cv (get-recv-cv)
...)
- 内部の受信用キューにデータが追加されるとcondition-variable-broadcast!が実行されるcondition-variableを取得する。
- このcondition-variableは、内部でirc-recv-event!がtimeout待ちをするのに使われているが、他の条件との複合条件待ちの為に使用してよい。
get-current-nick
(let1 nick (get-current-nick)
...)
event->reply-to
(let1 channel (event->reply-to event)
...)
- 特定の受信eventから、「それに対して返事をする際には、どこに返事をすべきか」を得る手続き。
- 受信eventが、「返事をするのに向いていない」ものの場合は、#fが返される。
- 頻出パターンの「誰かの発言に反応して、それに対する返事を発言する」という機能を作る際に利用できる。
- 通常、PRIVMSGの場合は、(car (event->params event))でチャンネル名が取れる。しかし、チャンネル経由の発言ではなく、nick直指定の発言だった場合、(car (event->params event))で取得できるのは自分のnickになってしまい、ここに返信すると、自分に対して発言してしまう事になる。この場合は相手の発言のprefixからnickを切り出して、そこに返事をする必要がある。この手続きはその切り出し作業を行ってくれる。
send-event-split-last-param
(receive (chopped-event remainder) (send-event-split-last-param event)
...)
- 送信用eventが大きい場合、ircプロトコルの制約の512byte以下になるように、自動的に末尾が切り捨てられるが、それが嫌な場合は、自分でこの手続きに通して、分割する必要がある。マルチバイト安全。
- 返り値は以下のパターンになる。
- 送信時に512byte未満になるeventだった → (values 元のevent #f)
- 送信時に512byte以上になるeventだった → (values 最後のparamsが切り詰められ、512byte未満で送信可能になったevent 切り詰められた分の文字列)
- 送信時に512byte以上になるeventだけど、paramsが'()だった → エラー例外
- 送信時に512byte以上になるeventだった、最後のparamsを切り詰めて短くしようとしたけど、空文字列にしても512byte以上だった → エラー例外
- この手続きは結構重い。また、あまり厳密に512byte直前にはしない(少し多めに切り詰めてしまう)。
eventに対するアクセサ
event->timestamp
event->mode
event->prefix
event->command
event->params
その他のユーティリティ手続き
message->event
(let1 event (message->event message . opt-send?)
...)
- ircプロトコルのmessage書式("PRIVMSG #ch :hello\r\n" 等)を、event書式に変換する。
- message書式の末尾改行はあってもなくてもok(つまり、read-lineで取得したものでもok)。
- この手続き自体は、encoding変換は行わない点に注意。必要なら自前でencoding変換を行う必要有り。
- オプショナル引数に#tを渡すと、送信用eventを生成する(つまり、元messageのprefix等は無視される)。デフォルトは#f。
- messageが不正な場合は、エラー例外が投げられる。
event->message
(let1 message (event->message event . opt-send?)
...)
- eventを、ircプロトコルのmessage書式(\r\n末尾の一行)に変換する。
- この手続き自体は、encoding変換は行わない点に注意。必要なら自前でencoding変換を行う必要有り。
- オプショナル引数に#tを渡すと、送信用messageを生成する(つまり、元eventのprefix等は無視される)。デフォルトは#f。
- eventが不正な場合は、エラー例外が投げられる。
valid-nick?
(unless (valid-nick? nick)
...)
make-basic-irc-logger
(with-irc
...
...
:logging-handler (make-basic-irc-logger "/path/to/logdir" . opt-fallback-channame)
main-thunk)
- 簡易ロガー生成高階手続き。
- 指定されたディレクトリ内に、チャンネル名またはnick名のディレクトリを作り、その中に日付指定のログファイルを作り、そこに一行ずつ、S式書式のログを追記していく。
- ついでに、このディレクトリ内に「latest」という名前のシンボリックリンクも作る。リンク先は最新のログファイル。
- ログファイルの日本語encodingは、(gauche-character-encoding)固定。
- オプショナル引数は、チャンネル/nick指定の無いircメッセージ(例えば、MOTDやPING等)を書き込むディレクトリ名。デフォルトは"#"。
- この手続きが生成するログファイルは、read-line後にread-from-stringする事で、元のevent書式に復元できる。
- 但し、ログファイル中にはeof及びエラーオブジェクトの行も存在する可能性がある為、read-from-stringする部分はguardしておき、それらを検出した方が無難。
- 直接file-portをreadしても問題無い筈だが、前述の通り、eof及びエラーオブジェクトが出現する事に備えてguardしておく必要はやっぱりある。
make-thread/report-error
(let1 thread (make-thread/report-error thunk)
...)
- make-thread手続きの代用品。
- 生成したスレッドがエラー例外で終了する際に、(standard-error-port)にスタックトレースを出力するようになる。それ以外はmake-threadと同じ。
バッドノウハウ
- チャンネル名及びnickの大文字小文字がcase insensitiveな時と、case sensitiveな時がある
- 既存チャンネルにJOINする時や、nickをWHOISする時は、case insensitiveな扱いになるようだ(しかし、RFC1459には該当する記載無し。ircサーバ側の独自拡張?)。
- 新しいチャンネルを作成(JOIN)する時や、NICKコマンドでnickを変更する時は、case sensitiveな扱いになるようだ(これもRFC1459に記載無し)。
- 現在のところ、make-basic-irc-loggerが生成するロギング手続きは、チャンネル名及びnickを、常にcase sensitiveに扱っている(主に、書き出すディレクトリ名に使っている為)。しかし、これでは、同じ名前で大文字小文字が違うだけのチャンネル名/nickのディレクトリが複数できてしまい、その際に内容も分散してしまう。これは嫌なのでなんとかしたい。
- しかし、どうすれば良い?最初は、ディレクトリ名だけは常に小文字にするようにすれば大丈夫だろう、と軽く考えていて、実際、ロギング目的の為だけならそれで問題なさそうだ、が、この問題は、もうちょっと奥の方で大きい影響があるように思えてならない。
- とりあえず仮の修正として、make-basic-irc-loggerのみ、常に小文字にする対応を行う。
- irc-recv-event!でタイムアウトを0以外(#f含む)にした場合、その待ち時間中にシグナル(SIGINTとかSIGTERMとか)が流れても、待ち状態が終了されるまでシグナル処理が行われないので、タイムアウトは短めに設定してループさせるか、irc-recv-event!は子スレッドを作ってそっちでやらせた方が良い。
- 頻出パターンの「他人の発言を受けて、それに返事をする」ものを実装する際に、「返信先」を取得する際に、通常のチャンネル経由の時と、直にnickにメッセージが送られてきた時とで、返信先(チャンネル/nick)の取得方法が違う。
- event->reply-to手続きを用意したので、これを使うのが楽。
- 受信したメッセージは、ces-convertを使って(gauche-character-encoding)に通してから、更に(cut string-incomplete->complete <> :omit)を通している。ircサーバからのメッセージが文字化けしている時は、ここに何か問題がある?
- ロギングハンドラとirc-recv-event!、どっちを使うべきか
- ロギングハンドラに渡されるeventオブジェクトは、基本的にあらゆるeventが渡される(PING/PONG、433(NICK変更失敗)、NICK自動調整時の送信event等も含む)。irc-recv-event!は、前述のPING、433は含まれない。
- ロギングハンドラは送信スレッドと受信スレッドで実行され、スレッド安全である必要がある。irc-recv-event!は、呼び出したスレッドで実行が完結している(内部キューから取り出すだけなので)。
- ロギングハンドラ内で重い処理をする場合、stuckしてしまう可能性があるかも知れない。irc-recv-event!は構造上stuckしない。
- ロギングハンドラだけを使って、irc-recv-event!を全く使わない場合でも、(別スレッド等を用意して、そっちで?)キューにデータが溜まらないように捨てる必要がある。
作った感想
- 当初予定していたよりもずっと複雑な構造になった。
- irc-recv-event!は実は不要だった?
- ……と最初は思っていたが、ある程度複雑なirc用botを作る場合、もしこの機構が無ければ、結局自前で実装しなくてはならなくなるようなので、最終的には用意しておいて損は無かった筈。ただ、そういう意味ならば、以下のチャンネル管理機構も用意しておくレベルだったとは思う。
- 当初は本当にPING/PONGの面倒を見るだけのモジュールにして、NICKやUSERコマンドも自前でやってもらうようにする予定だったが、結局実装してしまった。
- bot本人のみnick管理を内部でやっているが、これをやる場合、チャンネル管理、及び、チャンネル参加者のnickも内部でやった方が、同じ方式で管理できる分、よいような気はする(けど面倒なのでやっていない)。
- これらの要素を考慮に入れて再設計すれば結構スマートになると思うが、面倒なのでそこまではしない予定。
TODO
以下はなんとかするかもしれない項目
- make-basic-irc-loggerにオプショナル引数を渡して、「ログチャンネルを分ける/分けない」「日付でファイルを分ける/分けない」を設定可能にする
- ircサーバと(gauche-character-encoding)が一致しない時に、誰かが不正なマルチバイト文字になる発言をした際に、readに失敗してエラーオブジェクトが返される時がある
- 可能なら、誰かが不正なマルチバイト文字になる発言をしても、(cut string-incomplete->complete <> :omit)を通すなりして、読めなくてもいいのでevent書式を返してほしい(エラーオブジェクトじゃなく)。
- freenodeで動作確認を取る?
- thread-join!とかに渡せる「秒数」は整数じゃなくて、実数もいけるので、わざわざ整数にして渡している部分を直す
以下は基本的に実装されません(実装する必要性に迫られてから実装する為)。
- ircbot.scmで、プロセスが起動していない時にFIFOに流し込もうとするとブロックしてしまうので、なんとか対策を考える
- irc-recv-event!を使わない時用に、内部キューにeventを追加しないオプション
- 或いは、irc-recv-event!自体をオプショナルにして、ロギングハンドラと統合してしまうか?
- 結構仕様が変わるので、もう少しよく考えた方がいい。
- ある程度heavyに使う場合、この仕組みは結局必要になるので、このままでいいという結論になった
- JOINしているチャンネル及びチャンネル参加者(とそのnick)の内部管理
- 自分自身のprefix記憶
- with-irc内部で継続を保存し、外から中に再突入できるようにする事(中から外に緊急脱出する方は既に実装済)
- コマンド数値を文字列に変換するテーブルを提供
- 終了処理時に、受信スレッド回りがあまり綺麗でないのをどうにかする?
- ロギング専用スレッドを作る?
- irc-send-event!のsync実行オプション対応
- 引数チェックの強化
- cthreads対応
- sample/cliirc作成
履歴とメモ等
0.3.1
0.3.0
- 接続断を検出する為に、一定時間おきに、ダミーのPONGをサーバに投げ返すようにする
- この実装は非常にexperimentalなので、ある程度動作検証した後に、パラメータをいじれるようにしたバージョンを出し直す事
0.2.4
- make-basic-irc-loggerが生成するチャンネル名及びnick名のディレクトリは、常に小文字化した状態で生成するようにする
0.2.3
- make-basic-irc-loggerのfallback-channameのデフォルト値を"AUTH"から"#"に変更する
0.2.2
- ロギングハンドラをguardするのをやめる(ロギングハンドラがエラーを出しても、make-thread/report-errorでエラーが表示されるので)
0.2.1
0.2.0
- ※event形式のcommand部分は、文字列ではなくシンボルとする事にした(大きな変更)
- 後方互換性の為に、irc-send!及びirc-send-event!には、これまで通り文字列のcommandを指定してもいいものとする
- irc-recv-event!及びロギングハンドラの判定部分は後方互換性が取られない事に注意!
- event->reply-toの処理を書き直す
- 受信eventかつ、KICK PRIVMSG NOTICE MODE INVITEの時のみに適用されるようになった
- make-basic-irc-loggerの、ログ保存ディレクトリの判定にevent->reply-toを使わずに、自前で判定手続きを用意する
- この修正に伴い、「JOIN #hoge,#fuge」等の、コンマ区切りで複数の対象を取るコマンドは、両方のディレクトリに同じ内容のログが記録されるようになった
- 同時に、チャンネル区分のある数値replyのいくつかが、チャンネル毎ディレクトリの方に保存されるようにもなった
- make-basic-irc-loggerにて、eventがeofまたはエラーオブジェクトだった場合の処理をやや強化した
- ircサーバとのtcp接続が切られた時の判定を正しく行えるように直した
0.1.6
- nick変更回りの修正に伴い、get-current-nickとevent->reply-toが不正確になる可能性が出てきたので、正確に取得できるように直す
- この修正に伴い、やっぱりwith-irc時にvalid-nick?を通すように戻す
0.1.5
- 0.1.4でnick変更が柔軟になったので、with-irc時にvalid-nick?を通すのはやめる
0.1.4
- nick変更時の処理をより厳密かつ柔軟に
- 子スレッドがエラー終了する際にも、stderrにスタックトレースを出すようにする
- 上を実現する為のmake-thread/report-error手続きをユーティリティ手続きとして提供
0.1.3
- NICKコマンド手動実行時にcurrent-nickを変更するように
- 現在のnickが9文字より長い時に仮対応
0.1.2
- :flood-protection-intervalが#fの時にも対応
0.1.1
- sample/ircbot.scmをシンプルに書き直した
- 標準ロギング手続きのcommand判定が肥大化してきたので、テーブル化
- 標準ロギング手続きのチャンネル判定に、PING/PONGの例外判定を追加
- event->channelを廃止し、event->reply-toを新設
- sample/repl.scmを、event->reply-toを使うように修正
- send-event-split-last-paramを実装
- これまで、irc-send-event!及びirc-send!は、messageが512byteを越えた時にエラー例外を通知していたが、単に黙って512byteを越える分を切り捨てるように修正
0.1.0
0.0.0で問題となっていた部分は大体解決された。
未実装部分が多いが、どうしても実装する必要性に迫られてから実装する事にする。
0.1.0以降で可能なら解決したい点は以下の通り。
- 「他人の発言を聞いて、それに対する返事をする」というインターフェースは頻出パターンだが、この「他人の発言」がチャンネル経由の時と、直接nick個人に対するメッセージの時で、「返事の応答先を求める」方法が違う。これを統一的に扱えるインターフェースが欲しい。
- しかし、どういう構造がベストなのかが不明。
- 最低でも「受信したeventから、返信先を取り出す手続き」ぐらいは用意する。
- irc-recv-event!にタイムアウトを設定した際に、シグナルの処理がされない問題を、どうにかして解決したい。
- 他には?
0.0.0
とりあえず動作する状態になった。
しかし、色々と問題点がある為、それらを解決したバージョンを作る必要がある。
- スレッドの使い方が上手くない
- まともにスレッドを使ったのは初めてなので、まあ仕方が無い。が、もう少しマシになるように考え直す
- ロックが怪しい
- 特にport回り。今はコメントアウトしてあるが、もう少し考える必要がある
- インターフェースに提供できるcvが必要
- 表面上はまあまあ綺麗なインターフェースになったが、これだけでは利用側で待ちたい時に困る。ユーザに提供するcvを用意して、内部でまめにcvにシグナルを送り、ユーザは任意のところで適当なmutexでcvを待てるようにすると嬉しい
- どうしてこれが必要なのかと言うと、現状で「別socket等の監視をしたいが、同時に、ircがデータを受信した事も監視したい」という状況になった場合、cvを使う以外の選択肢が無い為
- シグナル対策
- 例えば、↑の項目でcvが提供されたとして、早速メインスレッドでcv待ちmutexロックしていると、待ち状態の間はシグナルが全く処理されなくなってしまう。これは困る
- 今のところ、(sample/ircbot.scmでは)mutexロックを1秒とかにして、シグナルを処理しているが、可能ならそういう事も考えなくすむのが好ましい。可能か?
これらの問題を解決する為には、構造を以下のように修正すればよい。
その他、修正した方が良さそうなポイントをメモしておく。
- message->eventがエラーオブジェクトを返すのは混乱を招く。エラー時は普通にエラー例外を投げて、呼び出し元がそれをオブジェクト化するか、例外のままにするのか選ぶ方が良い。
- 提供した方が良いユーティリティ手続きの洗い出し。NICKの正規性チェック手続き等は、提供して損は無い。他にも、rfcに近い部分は提供を考える事。
- 他には?
不具合報告
動作がおかしい等ありましたら、この辺に書いてください。その内直すかもしれません。
- 特に、ircサーバによって固有の動作が多い為、特定のircサーバでのみ動作がおかしい事が想定されます。なので、そういう時は、グローバルなircネットワークならそのサーバ名を、プライベートなircネットワークならircサーバのソフト名とバージョンを教えてもらえると助かります。
最終更新 : 2012/01/01 03:25:15 JST