Kouhei Sutou
kou****@clear*****
Thu May 8 16:43:41 JST 2014
> +exit(Droonga::SerfEventHandler.run(ARGV)) としているので、 > + def run(command_line_arguments) > + parse_command_line_arguments!(command_line_arguments) > + parse_event > + > + update_live_nodes > + output_live_nodes > + end は、成功したらtrue、失敗したらfalseを返すようにするのがよい と思います。 > + def changed_nodes > + @changed_nodes ||= parse_changed_nodes(@payload) > + end > + > + def live_nodes > + @live_nodes ||= load_live_nodes(@list_file) > + end 速度に影響がでるまではキャッシュしなくていいですよ。 def changed_nodes parse_changed_nodes(@payload) end def live_nodes load_live_nodes(@list_file) end 今のコードを見ると、何回も使っているわけでもないですし、そん なに重い処理でもなさそうなので、キャッシュがなくても速度はほ とんど変わらないんじゃないかと思います。 changed_nodesは一回計算したら変わらないみたいなので、 parse_eventの中で設定しちゃうのがいいんじゃないかと思いまし た。 > + def parse_event > + @event_name = ENV["SERF_EVENT"] > + case @event_name > + when "user" > + @event_name += ":#{ENV["SERF_USER_EVENT"]}" > + when "query" > + @event_name += ":#{ENV["SERF_USER_QUERY"]}" > + end > + > + @payload = STDIN.read > + end の @payload = STDIN.read を @changed_nodes = parse_changed_nodes(STDIN.read) みたいにして。 あ、parse_changed_nodesには標準入力をそのまま渡しちゃえるん じゃないですか?一度全部読み込んで文字列として渡すんじゃなく て。 @changed_nodes = parse_changed_nodes(STDIN) Rubyでは標準入力を参照するときは、多くの場合は$stdinの方が STDINよりも適切なんですよ。実は。STDINは標準入力の初期値で、 $stdinは現在の標準入力です。プログラム起動時の標準入力が必要 ならSTDINを参照するのが適切ですが、単に標準入力が欲しいとき は$stdinを参照するのが適切です。 > + def load_live_nodes(file) > + nodes = {} > + if file > + contents = file.read > + nodes = JSON.parse(contents) if contents and not contents.empty? > + end > + nodes > + rescue StandardError, LoadError, SyntaxError => error > + {} > + end これはrescueし過ぎじゃないですかねぇ。。。 どっかから持ってきましたね。 rescueするのはJSON::ParserErrorだけにするのがいいんじゃない ですかねぇ。 def load_live_nodes(file) return {} if file.nil? return {} unless file.exist? contents = file.read return {} if contents.empty? begin JSON.parse(contents) rescue JSON::ParserError {} end end In <d43a35209442f34585c443f06f50270aa342343c �� jenkins.clear-code.com> "[Groonga-commit] droonga/droonga-engine �� d43a352 [master] Implement droonga-handle-serf-event command" on Thu, 08 May 2014 16:11:40 +0900, YUKI Hiroshi <null+groonga �� clear-code.com> wrote: > YUKI Hiroshi 2014-05-08 16:11:40 +0900 (Thu, 08 May 2014) > > New Revision: d43a35209442f34585c443f06f50270aa342343c > https://github.com/droonga/droonga-engine/commit/d43a35209442f34585c443f06f50270aa342343c > > Message: > Implement droonga-handle-serf-event command > > Added files: > bin/droonga-handle-serf-event > lib/droonga/serf_event_handler.rb > > Added: bin/droonga-handle-serf-event (+20 -0) 100755 > =================================================================== > --- /dev/null > +++ bin/droonga-handle-serf-event 2014-05-08 16:11:40 +0900 (8235ca9) > @@ -0,0 +1,20 @@ > +#!/usr/bin/env ruby > +# > +# Copyright (C) 2014 Droonga Project > +# > +# This library is free software; you can redistribute it and/or > +# modify it under the terms of the GNU Lesser General Public > +# License version 2.1 as published by the Free Software Foundation. > +# > +# This library is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > +# Lesser General Public License for more details. > +# > +# You should have received a copy of the GNU Lesser General Public > +# License along with this library; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + > +require "droonga/serf_event_handler" > + > +exit(Droonga::SerfEventHandler.run(ARGV)) > > Added: lib/droonga/serf_event_handler.rb (+115 -0) 100644 > =================================================================== > --- /dev/null > +++ lib/droonga/serf_event_handler.rb 2014-05-08 16:11:40 +0900 (4195df1) > @@ -0,0 +1,115 @@ > +# Copyright (C) 2014 Droonga Project > +# > +# This library is free software; you can redistribute it and/or > +# modify it under the terms of the GNU Lesser General Public > +# License version 2.1 as published by the Free Software Foundation. > +# > +# This library is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > +# Lesser General Public License for more details. > +# > +# You should have received a copy of the GNU Lesser General Public > +# License along with this library; if not, write to the Free Software > +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA > + > +require "optparse" > +require "pathname" > +require "json" > + > +module Droonga > + class SerfEventHandler > + class << self > + def run(command_line_arguments) > + new.run(command_line_arguments) > + end > + end > + > + attr_writer :live_nodes > + > + def run(command_line_arguments) > + parse_command_line_arguments!(command_line_arguments) > + parse_event > + > + update_live_nodes > + output_live_nodes > + end > + > + def changed_nodes > + @changed_nodes ||= parse_changed_nodes(@payload) > + end > + > + def live_nodes > + @live_nodes ||= load_live_nodes(@list_file) > + end > + > + private > + def parse_command_line_arguments!(command_line_arguments) > + parser = OptionParser.new > + > + parser.on("--list-file=FILE", > + "Output list of live nodes to FILE") do |file| > + @list_file = Pathname(file) > + end > + > + parser.parse!(command_line_arguments) > + end > + > + def parse_event > + @event_name = ENV["SERF_EVENT"] > + case @event_name > + when "user" > + @event_name += ":#{ENV["SERF_USER_EVENT"]}" > + when "query" > + @event_name += ":#{ENV["SERF_USER_QUERY"]}" > + end > + > + @payload = STDIN.read > + end > + > + def parse_changed_nodes > + nodes = {} > + payload.each_line do |node| > + name, address, role, tags = node.strip.split(/\s+/) > + nodes[name] = { > + "address" => address, > + "role" => role, > + "tags" => tags, > + } > + end > + nodes > + end > + > + def load_live_nodes(file) > + nodes = {} > + if file > + contents = file.read > + nodes = JSON.parse(contents) if contents and not contents.empty? > + end > + nodes > + rescue StandardError, LoadError, SyntaxError => error > + {} > + end > + > + def update_live_nodes > + case @event_name > + when "member-join" > + live_nodes = live_nodes.merge(changed_nodes) > + when "member-leave", "member-failed" > + changed_nodes.each do |name, attributes| > + live_nodes.delete(name) > + end > + # when "user:XXX", "query:XXX" > + end > + end > + > + def output_live_nodes > + list_file_contents = JSON.pretty_generate(live_nodes) > + if @list_file > + @list_file.write(list_file_contents) > + else > + puts list_file_contents > + end > + end > + end > +end